]>
Commit | Line | Data |
---|---|---|
e802be3e | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | /* $Id$ */ | |
17 | ||
18 | //____________________________________________________________________ | |
19 | // | |
20 | // Class to write ADC values to a raw data file | |
21 | // | |
22 | #include "AliLog.h" // ALILOG_H | |
23 | #include "AliFMD.h" // ALIFMD_H | |
24 | #include "AliFMDDigit.h" // ALIFMDDIGIT_H | |
25 | #include "AliFMDRawWriter.h" // ALIFMDRAWREADER_H | |
26 | #include "AliAltroBuffer.h" // ALIALTROBUFFER_H | |
27 | #include "AliLoader.h" // ALILOADER_H | |
28 | #include "TArrayI.h" // ROOT_TArrayI | |
29 | #include <TClonesArray.h> // ROOT_TClonesArray | |
30 | ||
31 | //____________________________________________________________________ | |
32 | ClassImp(AliFMDRawWriter); | |
33 | ||
34 | //____________________________________________________________________ | |
35 | AliFMDRawWriter::AliFMDRawWriter(AliFMD* fmd) | |
36 | : TTask("FMDRawWriter", "Writer of Raw ADC values from the FMD"), | |
37 | fFMD(fmd) | |
38 | { | |
39 | SetSampleRate(); | |
40 | } | |
41 | ||
42 | ||
43 | //____________________________________________________________________ | |
44 | void | |
45 | AliFMDRawWriter::Exec(Option_t*) | |
46 | { | |
47 | // Turn digits into raw data. | |
48 | // | |
49 | // Digits are read from the Digit branch, and processed to make | |
50 | // three DDL files, one for each of the sub-detectors FMD1, FMD2, | |
51 | // and FMD3. | |
52 | // | |
53 | // The raw data files consists of a header, followed by ALTRO | |
54 | // formatted blocks. | |
55 | // | |
56 | // +-------------+ | |
57 | // | Header | | |
58 | // +-------------+ | |
59 | // | ALTRO Block | | |
60 | // | ... | | |
61 | // +-------------+ | |
62 | // DDL file | |
63 | // | |
64 | // An ALTRO formatted block, in the FMD context, consists of a | |
65 | // number of counts followed by a trailer. | |
66 | // | |
67 | // +------------------+ | |
68 | // | Count | | |
69 | // | ... | | |
70 | // | possible fillers | | |
71 | // +------------------+ | |
72 | // | Trailer | | |
73 | // +------------------+ | |
74 | // ALTRO block | |
75 | // | |
76 | // The counts are listed backwards, that is, starting with the | |
77 | // latest count, and ending in the first. | |
78 | // | |
79 | // Each count consist of 1 or more ADC samples of the VA1_ALICE | |
80 | // pre-amp. signal. Just how many samples are used depends on | |
81 | // whether the ALTRO over samples the pre-amp. Each sample is a | |
82 | // 10-bit word, and the samples are grouped into 40-bit blocks | |
83 | // | |
84 | // +------------------------------------+ | |
85 | // | S(n) | S(n-1) | S(n-2) | S(n-3) | | |
86 | // | ... | ... | ... | ... | | |
87 | // | S(2) | S(1) | AA | AA | | |
88 | // +------------------------------------+ | |
89 | // Counts + possible filler | |
90 | // | |
91 | // The trailer of the number of words of signales, the starting | |
92 | // strip number, the sector number, and the ring ID; each 10-bit | |
93 | // words, packed into 40-bits. | |
94 | // | |
95 | // +------------------------------------+ | |
96 | // | # words | start | sector | ring | | |
97 | // +------------------------------------+ | |
98 | // Trailer | |
99 | // | |
100 | // Note, that this method assumes that the digits are ordered. | |
101 | // | |
102 | AliLoader* loader = fFMD->GetLoader(); | |
103 | loader->LoadDigits(); | |
104 | TTree* digitTree = loader->TreeD(); | |
105 | if (!digitTree) { | |
106 | Error("Digits2Raw", "no digit tree"); | |
107 | return; | |
108 | } | |
109 | ||
110 | TClonesArray* digits = new TClonesArray("AliFMDDigit", 1000); | |
111 | fFMD->SetTreeAddress(); | |
112 | TBranch* digitBranch = digitTree->GetBranch(fFMD->GetName()); | |
113 | if (!digitBranch) { | |
114 | Error("Digits2Raw", "no branch for %s", fFMD->GetName()); | |
115 | return; | |
116 | } | |
117 | digitBranch->SetAddress(&digits); | |
118 | ||
119 | Int_t nEvents = Int_t(digitTree->GetEntries()); | |
120 | for (Int_t event = 0; event < nEvents; event++) { | |
121 | fFMD->ResetDigits(); | |
122 | digitTree->GetEvent(event); | |
123 | ||
124 | Int_t nDigits = digits->GetEntries(); | |
125 | if (nDigits < 1) continue; | |
126 | ||
127 | ||
128 | UShort_t prevDetector = 0; | |
129 | Char_t prevRing = '\0'; | |
130 | UShort_t prevSector = 0; | |
131 | // UShort_t prevStrip = 0; | |
132 | ||
133 | // The first seen strip number for a channel | |
134 | UShort_t startStrip = 0; | |
135 | ||
136 | // Which channel number in the ALTRO channel we're at | |
137 | UShort_t offset = 0; | |
138 | ||
139 | // How many times the ALTRO Samples one VA1_ALICE channel | |
140 | Int_t sampleRate = 1; | |
141 | ||
142 | // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel | |
143 | // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate' | |
144 | TArrayI channel(128 * sampleRate); | |
145 | ||
146 | // The Altro buffer | |
147 | AliAltroBuffer* altro = 0; | |
148 | ||
149 | // Loop over the digits in the event. Note, that we assume the | |
150 | // the digits are in order in the branch. If they were not, we'd | |
151 | // have to cache all channels before we could write the data to | |
152 | // the ALTRO buffer, or we'd have to set up a map of the digits. | |
153 | for (Int_t i = 0; i < nDigits; i++) { | |
154 | // Get the digit | |
155 | AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i)); | |
156 | ||
157 | UShort_t det = digit->Detector(); | |
158 | Char_t ring = digit->Ring(); | |
159 | UShort_t sector = digit->Sector(); | |
160 | UShort_t strip = digit->Strip(); | |
161 | if (det != prevDetector) { | |
162 | AliDebug(10, Form("FMD: New DDL, was %d, now %d", | |
163 | AliFMD::kBaseDDL + prevDetector - 1, | |
164 | AliFMD::kBaseDDL + det - 1)); | |
165 | // If an altro exists, delete the object, flushing the data to | |
166 | // disk, and closing the file. | |
167 | if (altro) { | |
168 | // When the first argument is false, we write the real | |
169 | // header. | |
170 | AliDebug(10, Form("New altro: Write channel at %d Strip: %d " | |
171 | "Sector: %d Ring: %d", | |
172 | i, startStrip, prevSector, prevRing)); | |
173 | // TPC to FMD translations | |
174 | // | |
175 | // TPC FMD | |
176 | // ----------+----------- | |
177 | // pad | strip | |
178 | // row | sector | |
179 | // sector | ring | |
180 | // | |
181 | altro->WriteChannel(Int_t(startStrip), | |
182 | Int_t(prevSector), | |
183 | Int_t((prevRing == 'I' ? 0 : 1)), | |
184 | channel.fN, channel.fArray, 0); | |
185 | altro->Flush(); | |
186 | altro->WriteDataHeader(kFALSE, kFALSE); | |
187 | delete altro; | |
188 | altro = 0; | |
189 | } | |
190 | ||
191 | prevDetector = det; | |
192 | // Need to open a new DDL! | |
193 | Int_t ddlId = AliFMD::kBaseDDL + det - 1; | |
194 | TString filename(Form("%s_%d.ddl", fFMD->GetName(), ddlId)); | |
195 | ||
196 | AliDebug(10, Form("New altro buffer with DDL file %s", | |
197 | filename.Data())); | |
198 | AliDebug(10, Form("New altro at %d", i)); | |
199 | // Create a new altro buffer - a `1' as the second argument | |
200 | // means `write mode' | |
201 | altro = new AliAltroBuffer(filename.Data(), 1); | |
202 | ||
203 | // Write a dummy (first argument is true) header to the DDL | |
204 | // file - later on, when we close the file, we write the real | |
205 | // header | |
206 | altro->WriteDataHeader(kTRUE, kFALSE); | |
207 | ||
208 | // Figure out the sample rate | |
209 | if (fSampleRate > 0) sampleRate = fSampleRate; | |
210 | else { | |
211 | if (digit->Count2() >= 0) sampleRate = 2; | |
212 | if (digit->Count3() >= 0) sampleRate = 3; | |
213 | } | |
214 | ||
215 | channel.Set(128 * sampleRate); | |
216 | offset = 0; | |
217 | prevRing = ring; | |
218 | prevSector = sector; | |
219 | startStrip = strip; | |
220 | } | |
221 | else if (offset == 128 | |
222 | || digit->Ring() != prevRing | |
223 | || digit->Sector() != prevSector) { | |
224 | // Force a new Altro channel | |
225 | AliDebug(10, Form("Flushing channel to disk because %s", | |
226 | (offset == 128 ? "channel is full" : | |
227 | (ring != prevRing ? "new ring up" : | |
228 | "new sector up")))); | |
229 | AliDebug(10, Form("New Channel: Write channel at %d Strip: %d " | |
230 | "Sector: %d Ring: %d", | |
231 | i, startStrip, prevSector, prevRing)); | |
232 | altro->WriteChannel(Int_t(startStrip), | |
233 | Int_t(prevSector), | |
234 | Int_t((prevRing == 'I' ? 0 : 1)), | |
235 | channel.fN, channel.fArray, 0); | |
236 | // Reset and update channel variables | |
237 | channel.Reset(0); | |
238 | offset = 0; | |
239 | startStrip = strip; | |
240 | prevRing = ring; | |
241 | prevSector = sector; | |
242 | } | |
243 | ||
244 | // Store the counts of the ADC in the channel buffer | |
245 | channel[offset * sampleRate] = digit->Count1(); | |
246 | if (sampleRate > 1) | |
247 | channel[offset * sampleRate + 1] = digit->Count2(); | |
248 | if (sampleRate > 2) | |
249 | channel[offset * sampleRate + 2] = digit->Count3(); | |
250 | offset++; | |
251 | } | |
252 | // Finally, we need to close the final ALTRO buffer if it wasn't | |
253 | // already | |
254 | if (altro) { | |
255 | altro->Flush(); | |
256 | altro->WriteDataHeader(kFALSE, kFALSE); | |
257 | delete altro; | |
258 | } | |
259 | } | |
260 | loader->UnloadDigits(); | |
261 | } | |
262 | ||
263 | //____________________________________________________________________ | |
264 | // | |
265 | // EOF | |
266 | // |