]>
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 | **************************************************************************/ | |
e802be3e | 15 | /* $Id$ */ |
c2fc1258 | 16 | /** @file AliFMDRawReader.cxx |
17 | @author Christian Holm Christensen <cholm@nbi.dk> | |
18 | @date Mon Mar 27 12:45:23 2006 | |
19 | @brief Class to read raw data | |
20 | */ | |
e802be3e | 21 | //____________________________________________________________________ |
22 | // | |
23 | // Class to read ADC values from a AliRawReader object. | |
24 | // | |
7684b53c | 25 | // This class uses the AliFMDRawStreamer class to read the ALTRO |
26 | // formatted data. | |
27 | // | |
28 | // +-------+ | |
29 | // | TTask | | |
30 | // +-------+ | |
31 | // ^ | |
32 | // | | |
33 | // +-----------------+ <<references>> +--------------+ | |
34 | // | AliFMDRawReader |<>----------------| AliRawReader | | |
35 | // +-----------------+ +--------------+ | |
36 | // | ^ | |
37 | // | <<uses>> | | |
38 | // V | | |
39 | // +-----------------+ <<uses>> | | |
40 | // | AliFMDRawStream |------------------------+ | |
41 | // +-----------------+ | |
42 | // | | |
43 | // V | |
44 | // +----------------+ | |
45 | // | AliAltroStream | | |
46 | // +----------------+ | |
47 | // | |
56b1929b | 48 | #include <AliLog.h> // ALILOG_H |
1a1fdef7 | 49 | #include "AliFMDParameters.h" // ALIFMDPARAMETERS_H |
e802be3e | 50 | #include "AliFMDDigit.h" // ALIFMDDIGIT_H |
51 | #include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H | |
52 | #include "AliRawReader.h" // ALIRAWREADER_H | |
53 | #include "AliFMDRawReader.h" // ALIFMDRAWREADER_H | |
c2fc1258 | 54 | // #include "AliFMDAltroIO.h" // ALIFMDALTROIO_H |
56b1929b | 55 | #include <TArrayI.h> // ROOT_TArrayI |
1a1fdef7 | 56 | #include <TTree.h> // ROOT_TTree |
57 | #include <TClonesArray.h> // ROOT_TClonesArray | |
1e8f773e | 58 | #include <iostream> |
59 | #include <iomanip> | |
60 | #include <sstream> | |
61 | #define PRETTY_HEX(N,X) \ | |
62 | " 0x" << std::setfill('0') << std::setw(N) << std::hex << X \ | |
63 | << std::setfill(' ') << std::dec | |
e802be3e | 64 | |
65 | //____________________________________________________________________ | |
925e6570 | 66 | ClassImp(AliFMDRawReader) |
1a1fdef7 | 67 | #if 0 |
68 | ; // This is here to keep Emacs for indenting the next line | |
69 | #endif | |
e802be3e | 70 | |
71 | //____________________________________________________________________ | |
1a1fdef7 | 72 | AliFMDRawReader::AliFMDRawReader(AliRawReader* reader, TTree* tree) |
e802be3e | 73 | : TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"), |
1a1fdef7 | 74 | fTree(tree), |
75 | fReader(reader), | |
76 | fSampleRate(1) | |
e802be3e | 77 | { |
56b1929b | 78 | // Default CTOR |
e802be3e | 79 | } |
80 | ||
c2fc1258 | 81 | //____________________________________________________________________ |
82 | void | |
83 | AliFMDRawReader::Exec(Option_t*) | |
84 | { | |
85 | TClonesArray* array = new TClonesArray("AliFMDDigit"); | |
86 | if (!fTree) { | |
87 | AliError("No tree"); | |
88 | return; | |
89 | } | |
90 | fTree->Branch("FMD", &array); | |
91 | ReadAdcs(array); | |
92 | Int_t nWrite = fTree->Fill(); | |
93 | AliDebug(1, Form("Got a grand total of %d digits, wrote %d bytes to tree", | |
94 | array->GetEntries(), nWrite)); | |
95 | } | |
96 | ||
97 | ||
98 | #if 1 | |
99 | //____________________________________________________________________ | |
100 | Bool_t | |
101 | AliFMDRawReader::ReadAdcs(TClonesArray* array) | |
102 | { | |
103 | // Read raw data into the digits array, using AliFMDAltroReader. | |
104 | if (!array) { | |
105 | AliError("No TClonesArray passed"); | |
106 | return kFALSE; | |
107 | } | |
108 | if (!fReader->ReadHeader()) { | |
109 | AliError("Couldn't read header"); | |
110 | return kFALSE; | |
111 | } | |
112 | // Get sample rate | |
113 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
114 | AliFMDRawStream input(fReader); | |
c2fc1258 | 115 | |
116 | UShort_t stripMin = 0; | |
117 | UShort_t stripMax = 127; | |
118 | UShort_t preSamp = 0; | |
119 | ||
120 | UInt_t ddl = 0; | |
121 | UInt_t rate = 0; | |
122 | UInt_t last = 0; | |
123 | UInt_t hwaddr = 0; | |
124 | // Data array is approx twice the size needed. | |
125 | UShort_t data[2048]; | |
126 | while (input.ReadChannel(ddl, hwaddr, last, data)) { | |
127 | AliDebug(5, Form("Read channel 0x%x of size %d", hwaddr, last)); | |
128 | UShort_t det, sec, str; | |
129 | Char_t ring; | |
130 | if (!pars->Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) { | |
131 | AliError(Form("Failed to get detector id from DDL %d " | |
132 | "and hardware address 0x%x", ddl, hwaddr)); | |
133 | continue; | |
134 | } | |
135 | rate = pars->GetSampleRate(det, ring, sec, str); | |
136 | stripMin = pars->GetMinStrip(det, ring, sec, str); | |
137 | stripMax = pars->GetMaxStrip(det, ring, sec, str); | |
138 | AliDebug(5, Form("DDL 0x%04x, address 0x%03x maps to FMD%d%c[%2d,%3d]", | |
139 | ddl, hwaddr, det, ring, sec, str)); | |
140 | ||
141 | // Loop over the `timebins', and make the digits | |
142 | for (size_t i = 0; i < last; i++) { | |
143 | if (i < preSamp) continue; | |
144 | Int_t n = array->GetEntries(); | |
145 | UShort_t curStr = str + stripMin + i / rate; | |
146 | if ((curStr-str) > stripMax) { | |
147 | AliError(Form("Current strip is %d but DB says max is %d", | |
148 | curStr, stripMax)); | |
149 | } | |
150 | AliDebug(5, Form("making digit for FMD%d%c[%2d,%3d] from sample %4d", | |
151 | det, ring, sec, curStr, i)); | |
152 | new ((*array)[n]) AliFMDDigit(det, ring, sec, curStr, data[i], | |
153 | (rate >= 2 ? data[i+1] : 0), | |
154 | (rate >= 3 ? data[i+2] : 0)); | |
155 | if (rate >= 2) i++; | |
156 | if (rate >= 3) i++; | |
157 | } | |
158 | } | |
159 | return kTRUE; | |
160 | } | |
161 | #else | |
1e8f773e | 162 | //____________________________________________________________________ |
d760ea03 | 163 | Bool_t |
164 | AliFMDRawReader::ReadAdcs(TClonesArray* array) | |
1e8f773e | 165 | { |
166 | // Read raw data into the digits array, using AliFMDAltroReader. | |
d760ea03 | 167 | if (!array) { |
168 | AliError("No TClonesArray passed"); | |
169 | return kFALSE; | |
170 | } | |
1e8f773e | 171 | if (!fReader->ReadHeader()) { |
d760ea03 | 172 | AliError("Couldn't read header"); |
173 | return kFALSE; | |
1e8f773e | 174 | } |
1e8f773e | 175 | // Get sample rate |
176 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
177 | ||
178 | // Select FMD DDL's | |
179 | fReader->Select(AliFMDParameters::kBaseDDL>>8); | |
180 | ||
181 | UShort_t stripMin = 0; | |
182 | UShort_t stripMax = 127; | |
183 | UShort_t preSamp = 0; | |
184 | ||
185 | do { | |
186 | UChar_t* cdata; | |
187 | if (!fReader->ReadNextData(cdata)) break; | |
188 | size_t nchar = fReader->GetDataSize(); | |
189 | UShort_t ddl = AliFMDParameters::kBaseDDL + fReader->GetDDLID(); | |
c2fc1258 | 190 | UShort_t rate = 0; |
1e8f773e | 191 | AliDebug(1, Form("Reading %d bytes (%d 10bit words) from %d", |
192 | nchar, nchar * 8 / 10, ddl)); | |
193 | // Make a stream to read from | |
194 | std::string str((char*)(cdata), nchar); | |
195 | std::istringstream s(str); | |
196 | // Prep the reader class. | |
197 | AliFMDAltroReader r(s); | |
198 | // Data array is approx twice the size needed. | |
199 | UShort_t data[2048], hwaddr, last; | |
200 | while (r.ReadChannel(hwaddr, last, data) > 0) { | |
201 | AliDebug(5, Form("Read channel 0x%x of size %d", hwaddr, last)); | |
202 | UShort_t det, sec, str; | |
203 | Char_t ring; | |
204 | if (!pars->Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) { | |
205 | AliError(Form("Failed to detector id from DDL %d " | |
206 | "and hardware address 0x%x", ddl, hwaddr)); | |
207 | continue; | |
208 | } | |
c2fc1258 | 209 | rate = pars->GetSampleRate(det, ring, sec, str); |
210 | stripMin = pars->GetMinStrip(det, ring, sec, str); | |
211 | stripMax = pars->GetMaxStrip(det, ring, sec, str); | |
1e8f773e | 212 | AliDebug(5, Form("DDL 0x%04x, address 0x%03x maps to FMD%d%c[%2d,%3d]", |
213 | ddl, hwaddr, det, ring, sec, str)); | |
214 | ||
215 | // Loop over the `timebins', and make the digits | |
216 | for (size_t i = 0; i < last; i++) { | |
217 | if (i < preSamp) continue; | |
d760ea03 | 218 | Int_t n = array->GetEntries(); |
1e8f773e | 219 | UShort_t curStr = str + stripMin + i / rate; |
220 | if ((curStr-str) > stripMax) { | |
221 | AliError(Form("Current strip is %d but DB says max is %d", | |
222 | curStr, stripMax)); | |
223 | } | |
224 | AliDebug(5, Form("making digit for FMD%d%c[%2d,%3d] from sample %4d", | |
225 | det, ring, sec, curStr, i)); | |
226 | new ((*array)[n]) AliFMDDigit(det, ring, sec, curStr, data[i], | |
227 | (rate >= 2 ? data[i+1] : 0), | |
228 | (rate >= 3 ? data[i+2] : 0)); | |
229 | if (rate >= 2) i++; | |
230 | if (rate >= 3) i++; | |
231 | } | |
232 | if (r.IsBof()) break; | |
233 | } | |
234 | } while (true); | |
d760ea03 | 235 | return kTRUE; |
236 | } | |
237 | ||
238 | ||
239 | ||
1e8f773e | 240 | // This is the old method, for comparison. It's really ugly, and far |
241 | // too convoluted. | |
e802be3e | 242 | //____________________________________________________________________ |
243 | void | |
244 | AliFMDRawReader::Exec(Option_t*) | |
245 | { | |
56b1929b | 246 | // Read raw data into the digits array |
e802be3e | 247 | if (!fReader->ReadHeader()) { |
248 | Error("ReadAdcs", "Couldn't read header"); | |
249 | return; | |
250 | } | |
251 | ||
1a1fdef7 | 252 | Int_t n = 0; |
253 | TClonesArray* array = new TClonesArray("AliFMDDigit"); | |
254 | fTree->Branch("FMD", &array); | |
255 | ||
8f6ee336 | 256 | // Get sample rate |
257 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
258 | fSampleRate = pars->GetSampleRate(AliFMDParameters::kBaseDDL); | |
259 | ||
e802be3e | 260 | // Use AliAltroRawStream to read the ALTRO format. No need to |
261 | // reinvent the wheel :-) | |
262 | AliFMDRawStream input(fReader, fSampleRate); | |
263 | // Select FMD DDL's | |
8f6ee336 | 264 | fReader->Select(AliFMDParameters::kBaseDDL); |
e802be3e | 265 | |
266 | Int_t oldDDL = -1; | |
267 | Int_t count = 0; | |
268 | UShort_t detector = 1; // Must be one here | |
269 | UShort_t oldDetector = 0; | |
270 | Bool_t next = kTRUE; | |
271 | ||
272 | // local Cache | |
273 | TArrayI counts(10); | |
274 | counts.Reset(-1); | |
275 | ||
276 | // Loop over data in file | |
277 | while (next) { | |
278 | next = input.Next(); | |
279 | ||
280 | count++; | |
281 | Int_t ddl = fReader->GetDDLID(); | |
1e8f773e | 282 | AliDebug(10, Form("Current DDL is %d", ddl)); |
e802be3e | 283 | if (ddl != oldDDL || input.IsNewStrip() || !next) { |
284 | // Make a new digit, if we have some data (oldDetector == 0, | |
285 | // means that we haven't really read anything yet - that is, | |
286 | // it's the first time we get here). | |
287 | if (oldDetector > 0) { | |
288 | // Got a new strip. | |
289 | AliDebug(10, Form("Add a new strip: FMD%d%c[%2d,%3d] " | |
290 | "(current: FMD%d%c[%2d,%3d])", | |
291 | oldDetector, input.PrevRing(), | |
292 | input.PrevSector() , input.PrevStrip(), | |
293 | detector , input.Ring(), input.Sector(), | |
294 | input.Strip())); | |
1a1fdef7 | 295 | new ((*array)[n]) AliFMDDigit(oldDetector, |
296 | input.PrevRing(), | |
297 | input.PrevSector(), | |
298 | input.PrevStrip(), | |
299 | counts[0], counts[1], counts[2]); | |
300 | n++; | |
e802be3e | 301 | #if 0 |
302 | AliFMDDigit* digit = | |
303 | static_cast<AliFMDDigit*>(fFMD->Digits()-> | |
304 | UncheckedAt(fFMD->GetNdigits()-1)); | |
305 | #endif | |
306 | } | |
307 | ||
308 | if (!next) { | |
309 | AliDebug(10, Form("Read %d channels for FMD%d", | |
310 | count + 1, detector)); | |
311 | break; | |
312 | } | |
313 | ||
314 | ||
315 | // If we got a new DDL, it means we have a new detector. | |
316 | if (ddl != oldDDL) { | |
317 | if (detector != 0) | |
1e8f773e | 318 | AliDebug(10, Form("Read %d channels for FMD%d", count + 1, detector)); |
e802be3e | 319 | // Reset counts, and update the DDL cache |
320 | count = 0; | |
321 | oldDDL = ddl; | |
322 | // Check that we're processing a FMD detector | |
323 | Int_t detId = fReader->GetDetectorID(); | |
1a1fdef7 | 324 | if (detId != (AliFMDParameters::kBaseDDL >> 8)) { |
1e8f773e | 325 | AliError(Form("Detector ID %d != %d", |
326 | detId, (AliFMDParameters::kBaseDDL >> 8))); | |
e802be3e | 327 | break; |
328 | } | |
329 | // Figure out what detector we're deling with | |
330 | oldDetector = detector; | |
331 | switch (ddl) { | |
332 | case 0: detector = 1; break; | |
333 | case 1: detector = 2; break; | |
334 | case 2: detector = 3; break; | |
335 | default: | |
1e8f773e | 336 | AliError(Form("Unknown DDL 0x%x for FMD", ddl)); |
e802be3e | 337 | return; |
338 | } | |
339 | AliDebug(10, Form("Reading ADCs for 0x%x - That is FMD%d", | |
340 | fReader->GetEquipmentId(), detector)); | |
341 | } | |
342 | counts.Reset(-1); | |
343 | } | |
344 | ||
345 | counts[input.Sample()] = input.Count(); | |
346 | ||
347 | AliDebug(10, Form("ADC of FMD%d%c[%2d,%3d] += %d", | |
348 | detector, input.Ring(), input.Sector(), | |
349 | input.Strip(), input.Count())); | |
350 | oldDetector = detector; | |
351 | } | |
1a1fdef7 | 352 | fTree->Fill(); |
e802be3e | 353 | return; |
354 | ||
355 | } | |
1e8f773e | 356 | #endif |
e802be3e | 357 | |
358 | //____________________________________________________________________ | |
359 | // | |
360 | // EOF | |
361 | // |