]>
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 | |
02a27b50 | 20 | @ingroup FMD_rec |
c2fc1258 | 21 | */ |
e802be3e | 22 | //____________________________________________________________________ |
23 | // | |
24 | // Class to read ADC values from a AliRawReader object. | |
25 | // | |
7684b53c | 26 | // This class uses the AliFMDRawStreamer class to read the ALTRO |
27 | // formatted data. | |
28 | // | |
29 | // +-------+ | |
30 | // | TTask | | |
31 | // +-------+ | |
32 | // ^ | |
33 | // | | |
34 | // +-----------------+ <<references>> +--------------+ | |
35 | // | AliFMDRawReader |<>----------------| AliRawReader | | |
36 | // +-----------------+ +--------------+ | |
37 | // | ^ | |
38 | // | <<uses>> | | |
39 | // V | | |
40 | // +-----------------+ <<uses>> | | |
41 | // | AliFMDRawStream |------------------------+ | |
42 | // +-----------------+ | |
43 | // | | |
44 | // V | |
45 | // +----------------+ | |
46 | // | AliAltroStream | | |
47 | // +----------------+ | |
48 | // | |
f95a63c4 | 49 | // #include <AliLog.h> // ALILOG_H |
50 | #include "AliFMDDebug.h" // Better debug macros | |
1a1fdef7 | 51 | #include "AliFMDParameters.h" // ALIFMDPARAMETERS_H |
e802be3e | 52 | #include "AliFMDDigit.h" // ALIFMDDIGIT_H |
faf80567 | 53 | #include "AliFMDSDigit.h" // ALIFMDSDIGIT_H |
e2c858f2 | 54 | // #include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H |
3effc6e7 | 55 | #include "AliRawReader.h" // ALIRAWREADER_H |
e802be3e | 56 | #include "AliFMDRawReader.h" // ALIFMDRAWREADER_H |
3effc6e7 | 57 | #include "AliFMDDebug.h" |
58 | #include "AliFMDCalibSampleRate.h" | |
59 | #include "AliFMDCalibStripRange.h" | |
b995fc28 | 60 | #include "AliFMDAltroMapping.h" |
c2fc1258 | 61 | // #include "AliFMDAltroIO.h" // ALIFMDALTROIO_H |
e2c858f2 | 62 | #include "AliAltroRawStreamV3.h" |
3effc6e7 | 63 | #include <TArrayS.h> // ROOT_TArrayS |
1a1fdef7 | 64 | #include <TTree.h> // ROOT_TTree |
65 | #include <TClonesArray.h> // ROOT_TClonesArray | |
3effc6e7 | 66 | #include <TString.h> |
7af3df7f | 67 | #include <iostream> |
68 | #include <climits> | |
02a27b50 | 69 | // #include <iomanip> |
e802be3e | 70 | |
71 | //____________________________________________________________________ | |
925e6570 | 72 | ClassImp(AliFMDRawReader) |
1a1fdef7 | 73 | #if 0 |
74 | ; // This is here to keep Emacs for indenting the next line | |
75 | #endif | |
e802be3e | 76 | |
77 | //____________________________________________________________________ | |
1a1fdef7 | 78 | AliFMDRawReader::AliFMDRawReader(AliRawReader* reader, TTree* tree) |
e802be3e | 79 | : TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"), |
1a1fdef7 | 80 | fTree(tree), |
81 | fReader(reader), | |
faf80567 | 82 | // fSampleRate(1), |
3effc6e7 | 83 | fData(0), |
f38b1653 | 84 | fNbytes(0), |
e2c858f2 | 85 | fMinStrip(0), |
86 | fMaxStrip(127), | |
87 | fPreSamp(14+5), | |
60e95d46 | 88 | fSeen(0) |
e802be3e | 89 | { |
56b1929b | 90 | // Default CTOR |
faf80567 | 91 | for (Int_t i = 0; i < 3; i++) { |
92 | fSampleRate[i] = 0; | |
93 | fZeroSuppress[i] = kFALSE; | |
94 | fNoiseFactor[i] = 1; | |
95 | } | |
e802be3e | 96 | } |
97 | ||
c2fc1258 | 98 | //____________________________________________________________________ |
99 | void | |
100 | AliFMDRawReader::Exec(Option_t*) | |
101 | { | |
02a27b50 | 102 | // Read the data |
c2fc1258 | 103 | TClonesArray* array = new TClonesArray("AliFMDDigit"); |
104 | if (!fTree) { | |
105 | AliError("No tree"); | |
106 | return; | |
107 | } | |
108 | fTree->Branch("FMD", &array); | |
3effc6e7 | 109 | |
110 | ||
c2fc1258 | 111 | ReadAdcs(array); |
112 | Int_t nWrite = fTree->Fill(); | |
f95a63c4 | 113 | AliFMDDebug(1, ("Got a grand total of %d digits, wrote %d bytes to tree", |
bf37515f | 114 | array->GetEntriesFast(), nWrite)); |
c2fc1258 | 115 | } |
116 | ||
e2c858f2 | 117 | //____________________________________________________________________ |
118 | Int_t | |
119 | AliFMDRawReader::NewDDL(AliAltroRawStreamV3& input, UShort_t& det) | |
120 | { | |
121 | // Process a new DDL. Sets the internal data members fZeroSuppress, | |
122 | // fSampleRate, and fNoiseFactor based on information in the RCU trailer. | |
123 | // | |
124 | // Parameters: | |
125 | // input Input stream | |
126 | // det On return, the detector number | |
127 | // | |
128 | // Return value: | |
129 | // negative value in case of problems, the DDL number otherwise | |
130 | ||
131 | // Get the DDL number | |
132 | UInt_t ddl = input.GetDDLNumber(); | |
133 | AliFMDDebug(2, ("DDL number %d", ddl)); | |
134 | ||
3afd9281 | 135 | /* Note, previously, the ALTROCFG1 register was interpreted as |
136 | * | |
137 | * Bits Value Description | |
138 | * 0- 3 0/1 1st Baseline filter, mode | |
139 | * 4- 5 Over-1 2nd baseline filter, # of pre-samples | |
140 | * 6- 9 factor 2nd baseline filter, # of post-samples | |
141 | * 10- 0 2nd baseline filter, enable | |
142 | * 11-12 00 Zero suppression, glitch filter mode | |
143 | * 13-15 001 Zero suppression, # of post samples | |
144 | * 16-17 01 Zero suppression, # of pre samples | |
145 | * 18 0/1 Zero suppression, enable | |
146 | * | |
147 | * The interpretation used in AliAltroRawStreamerV3 - which | |
148 | * corresponds directly to ALTRO DPCFG register - is | |
149 | * | |
150 | * Bits Value Description | |
151 | * 0- 3 0/1 1st Baseline filter, mode | |
152 | * 4 0 Polarity (if '1', then "1's inverse") | |
153 | * 5- 6 01 Zero suppression, # of pre samples | |
154 | * 7-10 0001 Zero suppression, # of post samples | |
155 | * 11 0 2nd baseline filter, enable | |
156 | * 12-13 00 Zero suppression, glitch filter mode | |
157 | * 14-16 factor 2nd baseline filter, # of post-samples | |
158 | * 17-18 01 2nd baseline filter, # of pre-samples | |
159 | * 19 0/1 Zero suppression, enable | |
160 | * | |
161 | * Writing 'x' for variable values, that means we have the | |
162 | * following patterns for the 2 cases | |
163 | * | |
164 | * bit # 20 16 12 8 4 0 | |
165 | * old |0x01|0010|00xx|xxxx|xxxx| | |
166 | * new |x01x|xx00|0000|1010|xxxx| | |
167 | * | |
168 | * That means that we can check if bits 10-13 are '1000' or | |
169 | * '0000', which will tell us if the value was written with the | |
170 | * new or the old interpretation. That is, we can check that | |
171 | * | |
172 | * if (((altrocfg1 >> 10) & 0x8) == 0x8) { | |
173 | * // old interpretation | |
174 | * } | |
175 | * else { | |
176 | * // New interpretation | |
177 | * } | |
178 | * | |
179 | * That means, that we should never | |
180 | * | |
181 | * - change the # of zero suppression post samples | |
182 | * - Turn on 2nd baseline correction | |
183 | * - Change the zero-suppression glitch filter mode | |
184 | * | |
185 | * This change as introduced in version 1.2 of Rcu++ | |
186 | */ | |
187 | UInt_t cfg1 = input.GetAltroCFG1(); | |
188 | if (((cfg1 >> 10) & 0x8) == 0x8) { | |
189 | UInt_t cfg2 = input.GetAltroCFG2(); | |
4b25407d | 190 | AliFMDDebug(3, ("We have data from older MiniConf 0x%x cfg2=0x%08x", |
191 | ((cfg1 >> 10) & 0x8), cfg2)); | |
192 | fZeroSuppress[ddl] = (cfg1 >> 0) & 0x1; | |
193 | fNoiseFactor[ddl] = (cfg1 >> 6) & 0xF; | |
194 | fSampleRate[ddl] = (cfg2 >> 20) & 0xF; | |
3afd9281 | 195 | } |
196 | else { | |
4b25407d | 197 | AliFMDDebug(3, ("We have data from newer MiniConf 0x%x", |
198 | ((cfg1 >> 10) & 0x8))); | |
3afd9281 | 199 | fZeroSuppress[ddl] = input.GetZeroSupp(); |
200 | // WARNING: We store the noise factor in the 2nd baseline | |
201 | // filters excluded post samples, since we'll never use that | |
202 | // mode. | |
203 | fNoiseFactor[ddl] = input.GetNPostsamples(); | |
204 | // WARNING: We store the sample rate in the number of pre-trigger | |
205 | // samples, since we'll never use that mode. | |
206 | fSampleRate[ddl] = input.GetNPretriggerSamples(); | |
207 | } | |
e2c858f2 | 208 | AliFMDDebug(3, ("RCU @ DDL %d zero suppression: %s", |
209 | ddl, (fZeroSuppress[ddl] ? "yes" : "no"))); | |
3afd9281 | 210 | AliFMDDebug(3, ("RCU @ DDL %d noise factor: %d", ddl,fNoiseFactor[ddl])); |
e2c858f2 | 211 | AliFMDDebug(3, ("RCU @ DDL %d sample rate: %d", ddl,fSampleRate[ddl])); |
212 | ||
3afd9281 | 213 | |
e2c858f2 | 214 | // Get Errors seen |
215 | Int_t nChAddrMismatch = input.GetNChAddrMismatch(); | |
216 | Int_t nChLenMismatch = input.GetNChLengthMismatch(); | |
217 | if (nChAddrMismatch != 0) | |
218 | AliWarning(Form("Got %d channels with address mis-matches for 0x%03x", | |
219 | nChAddrMismatch, ddl)); | |
220 | if (nChLenMismatch != 0) | |
221 | AliWarning(Form("Got %d channels with length mis-matches for 0x%03x", | |
222 | nChLenMismatch, ddl)); | |
223 | ||
224 | // Map DDL number to the detector number | |
225 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
226 | AliFMDAltroMapping* map = pars->GetAltroMap(); | |
227 | if (map->DDL2Detector(ddl) < 0) return -1; | |
228 | det = map->DDL2Detector(ddl); | |
229 | ||
230 | if (AliLog::GetDebugLevel("FMD", 0) > 5) | |
231 | input.PrintRCUTrailer(); | |
232 | return ddl; | |
233 | } | |
234 | ||
235 | //____________________________________________________________________ | |
236 | Int_t | |
237 | AliFMDRawReader::NewChannel(AliAltroRawStreamV3& input, UShort_t det, | |
238 | Char_t& ring, UShort_t& sec, Short_t& strbase) | |
239 | { | |
240 | // Processs a new channel. Sets the internal data members | |
241 | // fMinStrip, fMaxStrip, and fPreSamp. | |
242 | // | |
243 | // Parameter: | |
244 | // input Input stream | |
245 | // ring On return, the ring identifier | |
246 | // sec On return, the sector number | |
247 | // strbase On return, the strip base | |
248 | // | |
249 | // Return value | |
250 | // negative value in case of problems, hardware address otherwise | |
251 | ||
252 | // Get the hardware address, and map that to detector coordinates | |
253 | UShort_t board, chip, channel; | |
254 | Int_t ddl = input.GetDDLNumber(); | |
255 | Int_t hwaddr = input.GetHWAddress(); | |
256 | if (input.IsChannelBad()) { | |
257 | AliError(Form("Channel 0x%03x is marked as bad!", hwaddr)); | |
258 | } | |
259 | ||
260 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
261 | AliFMDAltroMapping* map = pars->GetAltroMap(); | |
262 | // Map to hardware stuff | |
263 | map->ChannelAddress(hwaddr, board, chip, channel); | |
264 | // Then try to map to detector address | |
265 | if (!map->Channel2StripBase(board, chip, channel, ring, sec, strbase)) { | |
266 | AliError(Form("Failed to get detector id from DDL %d, " | |
267 | "hardware address 0x%03x", ddl, hwaddr)); | |
268 | return -1; | |
269 | } | |
4b25407d | 270 | AliFMDDebug(4, ("Board: 0x%02x, Altro: 0x%x, Channel: 0x%x", |
e2c858f2 | 271 | board, chip, channel)); |
272 | ||
273 | // Get the 'conditions' | |
274 | fMinStrip = pars->GetMinStrip(det, ring, sec, strbase); | |
275 | fMaxStrip = pars->GetMaxStrip(det, ring, sec, strbase); | |
276 | fPreSamp = pars->GetPreSamples(det, ring, sec, strbase); | |
277 | if (fSampleRate[ddl] == 0) | |
278 | fSampleRate[ddl] = pars->GetSampleRate(det, ring, sec, strbase); | |
279 | ||
280 | return hwaddr; | |
281 | } | |
282 | ||
283 | //____________________________________________________________________ | |
284 | Int_t | |
285 | AliFMDRawReader::NewSample(AliAltroRawStreamV3& input, | |
286 | Int_t i, UShort_t t, UShort_t sec, | |
287 | UShort_t strbase, Short_t& str, UShort_t& samp) | |
288 | { | |
289 | // Process a new timebin | |
290 | // | |
291 | // Parameters: | |
292 | // input Input stream | |
293 | // i Index into bunch data | |
294 | // t Time | |
295 | // strbase Base of strip numbers for this channel | |
296 | // str On return, the strip number | |
297 | // samp On return, the sample number | |
298 | // | |
299 | // Return value | |
300 | // negative value in case of problems, ADC value otherwise | |
301 | if (t < fPreSamp) return -1; | |
302 | ||
303 | Int_t ddl = input.GetDDLNumber(); | |
304 | Int_t hwa = input.GetHWAddress(); | |
305 | const UShort_t* data = input.GetSignals(); | |
306 | Short_t adc = data[i]; | |
307 | AliFMDDebug(10, ("0x%04x/0x%03x/%04d %4d", ddl, hwa, t, adc)); | |
308 | ||
309 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
310 | AliFMDAltroMapping* map = pars->GetAltroMap(); | |
311 | ||
312 | samp = 0; | |
313 | Short_t stroff = 0; | |
314 | map->Timebin2Strip(sec, t, fPreSamp, fSampleRate[ddl], stroff, samp); | |
315 | str = strbase + stroff; | |
316 | ||
86878381 | 317 | AliFMDDebug(20, ("0x%04x/0x%03x/%04d=%4d maps to strip %3d sample %d " |
e2c858f2 | 318 | "(pre: %d, min: %d, max: %d, rate: %d)", |
86878381 | 319 | ddl, hwa, t, adc, str, samp, fPreSamp, |
e2c858f2 | 320 | fMinStrip, fMaxStrip, fSampleRate[ddl])); |
321 | if (str < 0) { | |
322 | AliFMDDebug(10, ("Got presamples at timebin %d", i)); | |
323 | return -1; | |
324 | } | |
325 | ||
326 | // VA1 Local strip number | |
327 | Short_t lstrip = (t - fPreSamp) / fSampleRate[ddl] + fMinStrip; | |
328 | ||
329 | AliFMDDebug(15, ("Checking if strip %d (%d) in range [%d,%d]", | |
330 | lstrip, str, fMinStrip, fMaxStrip)); | |
331 | if (lstrip < fMinStrip || lstrip > fMaxStrip) { | |
86878381 | 332 | AliFMDDebug(10, ("Strip %03d-%d (%d,%d) from t=%d out of range (%3d->%3d)", |
e2c858f2 | 333 | str, samp, lstrip, stroff, t, fMinStrip, fMaxStrip)); |
86878381 | 334 | adc = -1; |
e2c858f2 | 335 | } |
336 | // Possibly do pedestal subtraction of signal | |
337 | if (adc > 1023) | |
338 | AliWarning(Form("ADC value out of range: %4d", adc)); | |
339 | return adc; | |
340 | } | |
341 | ||
b5014544 | 342 | //____________________________________________________________________ |
343 | Bool_t | |
faf80567 | 344 | AliFMDRawReader::NextSample(UShort_t& det, Char_t& rng, UShort_t& sec, |
345 | UShort_t& str, UShort_t& sam, UShort_t& rat, | |
346 | Short_t& adc, Bool_t& zs, UShort_t& fac) | |
b5014544 | 347 | { |
348 | // Scan current event for next signal. It returns kFALSE when | |
349 | // there's no more data in the event. | |
e2c858f2 | 350 | static AliAltroRawStreamV3 stream(fReader); // = 0; |
b5014544 | 351 | static Int_t ddl = -1; |
b5014544 | 352 | static UShort_t tdet = 0; |
353 | static Char_t trng = '\0'; | |
354 | static UShort_t tsec = 0; | |
355 | static Short_t tstr = 0; | |
356 | static Short_t bstr = -1; | |
e2c858f2 | 357 | static UShort_t tsam = 0; |
faf80567 | 358 | static UInt_t trate = 0; |
b5014544 | 359 | static Int_t hwaddr = -1; |
e2c858f2 | 360 | static UShort_t start = 0; |
361 | static UShort_t length = 0; | |
362 | static Short_t t = -1; | |
363 | static Int_t i = 0; | |
364 | // First entry! | |
b5014544 | 365 | if (stream.GetDDLNumber() < 0) { |
366 | fReader->Select("FMD"); | |
367 | ||
b5014544 | 368 | // Reset variables |
369 | ddl = -1; | |
faf80567 | 370 | trate = 0; |
b5014544 | 371 | tdet = 0; |
372 | trng = '\0'; | |
373 | tsec = 0; | |
374 | tstr = 0; | |
faf80567 | 375 | tsam = -1; |
b5014544 | 376 | hwaddr = -1; |
377 | } | |
e2c858f2 | 378 | |
b5014544 | 379 | do { |
e2c858f2 | 380 | if (t < start - length + 1) { |
381 | if (!stream.NextBunch()) { | |
382 | if (!stream.NextChannel()) { | |
383 | if (!stream.NextDDL()) { | |
384 | stream.Reset(); | |
385 | return kFALSE; | |
386 | } | |
387 | ddl = NewDDL(stream, tdet); | |
388 | } | |
389 | hwaddr = NewChannel(stream, tdet, trng, tsec, bstr); | |
390 | } | |
391 | start = stream.GetStartTimeBin(); | |
392 | length = stream.GetBunchLength(); | |
393 | t = start; | |
394 | i = 0; | |
b5014544 | 395 | } |
e2c858f2 | 396 | Int_t tadc = NewSample(stream, i, t, tsec, bstr, tstr, tsam); |
397 | if (tadc >= 0) { | |
398 | det = tdet; | |
399 | rng = trng; | |
400 | sec = tsec; | |
401 | str = tstr; | |
402 | sam = tsam; | |
403 | adc = tadc; | |
404 | rat = fSampleRate[ddl]; | |
405 | zs = fZeroSuppress[ddl]; | |
406 | fac = fNoiseFactor[ddl]; | |
407 | t--; | |
408 | i++; | |
409 | break; | |
b5014544 | 410 | } |
b5014544 | 411 | } while (true); |
e2c858f2 | 412 | |
b5014544 | 413 | return kTRUE; |
414 | } | |
415 | ||
e2c858f2 | 416 | |
faf80567 | 417 | //____________________________________________________________________ |
418 | Bool_t | |
419 | AliFMDRawReader::NextSignal(UShort_t& det, Char_t& rng, | |
420 | UShort_t& sec, UShort_t& str, | |
421 | Short_t& adc, Bool_t& zs, | |
422 | UShort_t& fac) | |
423 | { | |
424 | ||
425 | do { | |
426 | UShort_t samp, rate; | |
427 | if (!NextSample(det, rng, sec, str, samp, rate, adc, zs, fac)) | |
428 | return kFALSE; | |
429 | ||
430 | Bool_t take = kFALSE; | |
431 | switch (rate) { | |
432 | case 1: take = kTRUE; break; | |
433 | case 2: if (samp == 1) take = kTRUE; break; | |
434 | case 3: if (samp == 1) take = kTRUE; break; | |
435 | case 4: if (samp == 2) take = kTRUE; break; | |
436 | default: if (samp == rate-2) take = kTRUE; break; | |
437 | } | |
438 | if (!take) continue; | |
439 | break; | |
440 | } while (true); | |
441 | return kTRUE; | |
442 | } | |
443 | ||
444 | //____________________________________________________________________ | |
445 | Bool_t | |
446 | AliFMDRawReader::SelectSample(UShort_t samp, UShort_t rate) | |
447 | { | |
e2c858f2 | 448 | // Check if the passed sample is the one we need |
faf80567 | 449 | Bool_t take = kFALSE; |
450 | switch (rate) { | |
451 | case 1: take = kTRUE; break; | |
452 | case 2: if (samp == 1) take = kTRUE; break; | |
453 | case 3: if (samp == 1) take = kTRUE; break; | |
454 | case 4: if (samp == 2) take = kTRUE; break; | |
455 | default: if (samp == rate-2) take = kTRUE; break; | |
456 | } | |
457 | ||
458 | return take; | |
459 | } | |
460 | ||
c2fc1258 | 461 | //____________________________________________________________________ |
462 | Bool_t | |
463 | AliFMDRawReader::ReadAdcs(TClonesArray* array) | |
464 | { | |
e2c858f2 | 465 | // Read ADC values from raw input into passed TClonesArray of AliFMDDigit |
466 | // objects. | |
467 | AliFMDDebug(2, ("Reading ADC values into a TClonesArray")); | |
468 | ||
c2fc1258 | 469 | // Read raw data into the digits array, using AliFMDAltroReader. |
470 | if (!array) { | |
471 | AliError("No TClonesArray passed"); | |
472 | return kFALSE; | |
473 | } | |
f38b1653 | 474 | const UShort_t kUShortMax = (1 << 16) - 1; |
475 | fSeen.Reset(kUShortMax); | |
f38b1653 | 476 | |
e2c858f2 | 477 | AliAltroRawStreamV3 input(fReader); |
478 | input.Reset(); | |
479 | input.SelectRawData("FMD"); | |
1e8f773e | 480 | |
e2c858f2 | 481 | // Loop over input RORCs |
482 | while (input.NextDDL()) { | |
483 | UShort_t det = 0; | |
484 | Int_t ddl = NewDDL(input, det); | |
485 | if (ddl < 0) break; | |
486 | ||
487 | while (input.NextChannel()) { | |
488 | // Get the hardware address, and map that to detector coordinates | |
1e8f773e | 489 | Char_t ring; |
e2c858f2 | 490 | UShort_t sec; |
491 | Short_t strbase; | |
492 | Int_t hwaddr = NewChannel(input, det, ring, sec, strbase); | |
493 | if (hwaddr < 0) break; | |
494 | ||
495 | // Loop over bunches | |
496 | while (input.NextBunch()) { | |
497 | // Get Lenght of bunch, and pointer to the data | |
498 | const UShort_t* data = input.GetSignals(); | |
499 | UShort_t start = input.GetStartTimeBin(); | |
500 | UShort_t length = input.GetBunchLength(); | |
501 | ||
502 | // Loop over the data and store it. | |
503 | for (Int_t i = 0; i < length; i++) { | |
504 | // Time | |
505 | Short_t str; | |
506 | UShort_t samp; | |
507 | Int_t t = start - i; | |
508 | Int_t adc = NewSample(input, i, t, sec, strbase, str, samp); | |
509 | if (adc < 0) continue; | |
510 | UShort_t counts = adc; | |
511 | ||
512 | AliFMDDebug(10, ("FMD%d%c[%02d,%03d]-%d: %4d", | |
513 | det, ring, sec, str, samp, counts)); | |
514 | // Check the cache of indicies | |
515 | Int_t idx = fSeen(det, ring, sec, str); | |
86878381 | 516 | AliFMDDigit* digit = 0; |
e2c858f2 | 517 | if (idx == kUShortMax) { |
518 | // We haven't seen this strip yet. | |
519 | fSeen(det, ring, sec, str) = idx = array->GetEntriesFast(); | |
520 | AliFMDDebug(7,("making digit for FMD%d%c[%2d,%3d]-%d " | |
521 | "from timebin %4d", | |
522 | det, ring, sec, str, samp, t)); | |
86878381 | 523 | digit = new ((*array)[idx]) AliFMDDigit(det, ring, sec, str); |
524 | digit->SetDefaultCounts(fSampleRate[ddl]); | |
e2c858f2 | 525 | } |
86878381 | 526 | else |
527 | digit = static_cast<AliFMDDigit*>(array->At(idx)); | |
e2c858f2 | 528 | AliFMDDebug(10, ("Setting FMD%d%c[%2d,%3d]-%d " |
529 | "from timebin %4d=%4d (%4d)", | |
530 | det, ring, sec, str, samp, t, counts, data[i])); | |
531 | digit->SetCount(samp, counts); | |
532 | } // for (i) | |
533 | } // while (bunch) | |
534 | } // while (channel) | |
535 | } // while (ddl) | |
d760ea03 | 536 | return kTRUE; |
537 | } | |
538 | ||
3effc6e7 | 539 | //____________________________________________________________________ |
540 | Bool_t AliFMDRawReader::ReadSODevent(AliFMDCalibSampleRate* sampleRate, | |
541 | AliFMDCalibStripRange* stripRange, | |
542 | TArrayS &pulseSize, | |
408bf2b4 | 543 | TArrayS &pulseLength, |
544 | Bool_t* detectors) | |
f38b1653 | 545 | { |
3effc6e7 | 546 | |
547 | AliFMDDebug(0, ("Start of SOD/EOD")); | |
548 | ||
549 | UInt_t shift_clk[18]; | |
550 | UInt_t sample_clk[18]; | |
551 | UInt_t strip_low[18]; | |
552 | UInt_t strip_high[18]; | |
553 | UInt_t pulse_size[18]; | |
554 | UInt_t pulse_length[18]; | |
b995fc28 | 555 | AliFMDParameters* param = AliFMDParameters::Instance(); |
556 | AliFMDAltroMapping* map = param->GetAltroMap(); | |
3effc6e7 | 557 | |
86878381 | 558 | AliAltroRawStreamV3 streamer(fReader); |
559 | streamer.Reset(); | |
560 | streamer.SelectRawData("FMD"); | |
561 | //fReader->GetDDLID(); | |
86878381 | 562 | while (streamer.NextDDL()) { |
563 | Int_t ddl = streamer.GetDDLNumber(); | |
564 | Int_t detID = fReader->GetDetectorID(); | |
565 | if (detectors) detectors[map->DDL2Detector(ddl)-1] = kTRUE; | |
566 | AliFMDDebug(0, (" From reader: DDL number is %d , det ID is %d",ddl,detID)); | |
567 | ||
568 | ULong_t nPayloadWords = streamer.GetRCUPayloadSizeInSOD(); | |
569 | UChar_t* payloadData = streamer.GetRCUPayloadInSOD(); | |
570 | UInt_t* payloadWords = reinterpret_cast<UInt_t*>(payloadData); | |
571 | //UInt_t* payloadWords = streamer.GetRCUPayloadInSOD(); | |
572 | ||
a0354a2a | 573 | //std::cout<<nPayloadWords<<" "<<ddl<<std::endl; |
86878381 | 574 | for (ULong_t i = 1; i <= nPayloadWords ; i++, payloadWords++) { |
575 | UInt_t payloadWord = *payloadWords; // Get32bitWord(i); | |
3effc6e7 | 576 | |
a0354a2a | 577 | //std::cout<<i<<Form(" word: 0x%x",payloadWord)<<std::endl; |
f38b1653 | 578 | // address is only 24 bit |
579 | UInt_t address = (0xffffff & payloadWord); | |
580 | UInt_t type = ((address >> 21) & 0xf); | |
581 | UInt_t error = ((address >> 20) & 0x1); | |
582 | UInt_t bcast = ((address >> 18) & 0x1); | |
583 | UInt_t bc_not_altro = ((address >> 17) & 0x1); | |
584 | UInt_t board = ((address >> 12) & 0x1f); | |
585 | UInt_t instruction = 0; | |
586 | UInt_t chip = 0; | |
587 | UInt_t channel = 0; | |
588 | if(bc_not_altro) | |
589 | instruction = address & 0xfff; | |
590 | else { | |
591 | chip = ((address >> 9) & 0x7); | |
592 | channel = ((address >> 5) & 0x5); | |
593 | instruction = (address & 0x1f); | |
594 | } | |
76d06ffa | 595 | |
f38b1653 | 596 | Bool_t readDataWord = kFALSE; |
597 | switch(type) { | |
598 | case 0x0: // Fec read | |
599 | readDataWord = kTRUE; | |
600 | case 0x1: // Fec cmd | |
601 | case 0x2: // Fec write | |
86878381 | 602 | i++; |
603 | payloadWords++; | |
f38b1653 | 604 | break; |
605 | case 0x4: // Loop | |
606 | case 0x5: // Wait | |
607 | break; | |
608 | case 0x6: // End sequence | |
609 | case 0x7: // End Mem | |
86878381 | 610 | i = nPayloadWords + 1; |
f38b1653 | 611 | break; |
612 | default: | |
613 | break; | |
614 | } | |
76d06ffa | 615 | |
f38b1653 | 616 | //Don't read unless we have a FEC_RD |
617 | if(!readDataWord) continue; | |
618 | ||
86878381 | 619 | UInt_t dataWord = *payloadWords;//Get32bitWord(i); |
f38b1653 | 620 | UInt_t data = (0xFFFFF & dataWord) ; |
621 | //UInt_t data = (0xFFFF & dataWord) ; | |
3effc6e7 | 622 | |
f38b1653 | 623 | if(error) { |
624 | AliWarning(Form("error bit detected at Word 0x%06x; " | |
625 | "error % d, type %d, bc_not_altro %d, " | |
626 | "bcast %d, board 0x%02x, chip 0x%x, " | |
627 | "channel 0x%02x, instruction 0x%03x", | |
628 | address, error, type, bc_not_altro, | |
629 | bcast,board,chip,channel,instruction)); | |
630 | //process error | |
631 | continue; | |
632 | } | |
3effc6e7 | 633 | |
634 | ||
f38b1653 | 635 | switch(instruction) { |
3effc6e7 | 636 | |
f38b1653 | 637 | case 0x01: break; // First ADC T |
638 | case 0x02: break; // I 3.3 V | |
639 | case 0x03: break; // I 2.5 V altro digital | |
640 | case 0x04: break; // I 2.5 V altro analog | |
641 | case 0x05: break; // I 2.5 V VA | |
642 | case 0x06: break; // First ADC T | |
643 | case 0x07: break; // I 3.3 V | |
644 | case 0x08: break; // I 2.5 V altro digital | |
645 | case 0x09: break; // I 2.5 V altro analog | |
646 | case 0x0A: break; // I 2.5 V VA | |
647 | case 0x2D: break; // Second ADC T | |
648 | case 0x2E: break; // I 1.5 V VA | |
649 | case 0x2F: break; // I -2.0 V | |
650 | case 0x30: break; // I -2.0 V VA | |
651 | case 0x31: break; // 2.5 V Digital driver | |
652 | case 0x32: break; // Second ADC T | |
653 | case 0x33: break; // I 1.5 V VA | |
654 | case 0x34: break; // I -2.0 V | |
655 | case 0x35: break; // I -2.0 V VA | |
656 | case 0x36: break; // 2.5 V Digital driver | |
657 | case 0x37: break; // Third ADC T | |
658 | case 0x38: break; // Temperature sens. 1 | |
659 | case 0x39: break; // Temperature sens. 2 | |
660 | case 0x3A: break; // U 2.5 altro digital (m) | |
661 | case 0x3B: break; // U 2.5 altro analog (m) | |
662 | case 0x3C: break; // Third ADC T | |
663 | case 0x3D: break; // Temperature sens. 1 | |
664 | case 0x3E: break; // Temperature sens. 2 | |
665 | case 0x3F: break; // U 2.5 altro digital (m) | |
666 | case 0x40: break; // U 2.5 altro analog (m) | |
667 | case 0x41: break; // Forth ADC T | |
668 | case 0x42: break; // U 2.5 VA (m) | |
669 | case 0x43: break; // U 1.5 VA (m) | |
670 | case 0x44: break; // U -2.0 VA (m) | |
671 | case 0x45: break; // U -2.0 (m) | |
672 | case 0x46: break; // Forth ADC T | |
673 | case 0x47: break; // U 2.5 VA (m) | |
674 | case 0x48: break; // U 1.5 VA (m) | |
675 | case 0x49: break; // U -2.0 VA (m) | |
676 | case 0x4A: break; // U -2.0 (m) | |
677 | // Counters | |
678 | case 0x0B: break; // L1 trigger CouNTer | |
679 | case 0x0C: break; // L2 trigger CouNTer | |
680 | case 0x0D: break; // Sampling CLK CouNTer | |
681 | case 0x0E: break; // DSTB CouNTer | |
682 | // Test mode | |
683 | case 0x0F: break; // Test mode word | |
684 | case 0x10: break; // Undersampling ratio. | |
685 | // Configuration and status | |
686 | case 0x11: break; // Config/Status Register 0 | |
687 | case 0x12: break; // Config/Status Register 1 | |
688 | case 0x13: break; // Config/Status Register 2 | |
689 | case 0x14: break; // Config/Status Register 3 | |
690 | case 0x15: break; // Free | |
691 | // Comands: | |
692 | case 0x16: break; // Latch L1, L2, SCLK Counters | |
693 | case 0x17: break; // Clear counters | |
694 | case 0x18: break; // Clear CSR1 | |
695 | case 0x19: break; // rstb ALTROs | |
696 | case 0x1A: break; // rstb BC | |
697 | case 0x1B: break; // Start conversion | |
698 | case 0x1C: break; // Scan event length | |
699 | case 0x1D: break; // Read event length | |
700 | case 0x1E: break; // Start test mode | |
701 | case 0x1F: break; // Read acquisition memory | |
702 | // FMD | |
703 | case 0x20: break; // FMDD status | |
704 | case 0x21: break; // L0 counters | |
705 | case 0x22: break; // FMD: Wait to hold | |
706 | case 0x23: break; // FMD: L1 timeout | |
707 | case 0x24: break; // FMD: L2 timeout | |
708 | case 0x25: // FMD: Shift clk | |
709 | shift_clk[board] = ((data >> 8 ) & 0xFF); | |
710 | break; | |
711 | case 0x26: // FMD: Strips | |
712 | strip_low[board] = ((data >> 0 ) & 0xFF); | |
713 | strip_high[board] = ((data >> 8 ) & 0xFF); | |
714 | break; | |
715 | case 0x27: // FMD: Cal pulse | |
716 | pulse_size[board] = ((data >> 8 ) & 0xFF); | |
717 | break; | |
718 | case 0x28: break; // FMD: Shape bias | |
719 | case 0x29: break; // FMD: Shape ref | |
720 | case 0x2A: break; // FMD: Preamp ref | |
721 | case 0x2B: // FMD: Sample clk | |
722 | sample_clk[board] = ((data >> 8 ) & 0xFF); | |
723 | break; | |
724 | case 0x2C: break; // FMD: Commands | |
725 | case 0x4B: // FMD: Cal events | |
726 | pulse_length[board] = ((data >> 0 ) & 0xFF); | |
727 | break; | |
728 | default: break; | |
3effc6e7 | 729 | |
f38b1653 | 730 | } |
731 | AliFMDDebug(50, ("instruction 0x%x, dataword 0x%x", | |
732 | instruction,dataWord)); | |
86878381 | 733 | } // End of loop over Result memory event |
3effc6e7 | 734 | |
f38b1653 | 735 | UShort_t det,sector; |
736 | Short_t strip; | |
3effc6e7 | 737 | Char_t ring; |
76d06ffa | 738 | |
3effc6e7 | 739 | const UInt_t boards[4] = {0,1,16,17}; |
740 | for(Int_t i=0;i<4;i++) { | |
f38b1653 | 741 | if(ddl==0 && (i==1 || i==3)) continue; |
742 | ||
3effc6e7 | 743 | UInt_t chip =0, channel=0; |
b995fc28 | 744 | det = map->DDL2Detector(ddl); |
745 | map->Channel2StripBase(boards[i], chip, channel, ring, sector, strip); | |
76d06ffa | 746 | |
747 | UInt_t samplerate = 1; | |
76d06ffa | 748 | if(sample_clk[boards[i]] == 0) { |
f38b1653 | 749 | if(ddl == 0) { |
750 | Int_t sample1 = sample_clk[boards[0]]; | |
751 | Int_t sample2 = sample_clk[boards[2]]; | |
752 | if(sample1) sample_clk[boards[i]] = sample1; | |
753 | else sample_clk[boards[i]] = sample2; | |
754 | } | |
755 | else { | |
756 | Int_t sample1 = sample_clk[boards[0]]; | |
757 | Int_t sample2 = sample_clk[boards[1]]; | |
758 | Int_t sample3 = sample_clk[boards[2]]; | |
759 | Int_t sample4 = sample_clk[boards[3]]; | |
760 | Int_t agreement = 0; | |
761 | if(sample1 == sample2) agreement++; | |
762 | if(sample1 == sample3) agreement++; | |
763 | if(sample1 == sample4) agreement++; | |
764 | if(sample2 == sample3) agreement++; | |
765 | if(sample2 == sample4) agreement++; | |
766 | if(sample3 == sample4) agreement++; | |
76d06ffa | 767 | |
f38b1653 | 768 | Int_t idx = 0; |
769 | if(i<3) idx = i+1; | |
770 | else idx = i-1; | |
771 | if(agreement == 3) { | |
772 | sample_clk[boards[i]] = sample_clk[boards[idx]]; | |
773 | shift_clk[boards[i]] = shift_clk[boards[idx]]; | |
774 | strip_low[boards[i]] = strip_low[boards[idx]]; | |
775 | strip_high[boards[i]] = strip_high[boards[idx]]; | |
776 | pulse_length[boards[i]] = pulse_length[boards[idx]]; | |
777 | pulse_size[boards[i]] = pulse_size[boards[idx]]; | |
778 | AliFMDDebug(0, ("Vote taken for ddl %d, board 0x%x", | |
779 | ddl,boards[i])); | |
76d06ffa | 780 | } |
f38b1653 | 781 | } |
76d06ffa | 782 | } |
783 | ||
3effc6e7 | 784 | if(sample_clk[boards[i]]) |
f38b1653 | 785 | samplerate = shift_clk[boards[i]]/sample_clk[boards[i]]; |
3effc6e7 | 786 | sampleRate->Set(det,ring,sector,0,samplerate); |
f38b1653 | 787 | stripRange->Set(det,ring,sector,0, |
788 | strip_low[boards[i]],strip_high[boards[i]]); | |
3effc6e7 | 789 | |
76d06ffa | 790 | AliFMDDebug(20, ("det %d, ring %c, ",det,ring)); |
f38b1653 | 791 | pulseLength.AddAt(pulse_length[boards[i]], |
792 | GetHalfringIndex(det,ring,boards[i]/16)); | |
793 | pulseSize.AddAt(pulse_size[boards[i]], | |
794 | GetHalfringIndex(det,ring,boards[i]/16)); | |
76d06ffa | 795 | |
3effc6e7 | 796 | |
76d06ffa | 797 | |
798 | AliFMDDebug(20, (": Board: 0x%02x\n" | |
f38b1653 | 799 | "\tstrip_low %3d, strip_high %3d\n" |
800 | "\tshift_clk %3d, sample_clk %3d\n" | |
801 | "\tpulse_size %3d, pulse_length %3d", | |
802 | boards[i], | |
803 | strip_low[boards[i]], strip_high[boards[i]], | |
804 | shift_clk[boards[i]], sample_clk[boards[i]], | |
805 | pulse_size[boards[i]],pulse_length[boards[i]])); | |
86878381 | 806 | } |
3effc6e7 | 807 | |
86878381 | 808 | } |
3effc6e7 | 809 | |
810 | AliFMDParameters::Instance()->SetSampleRate(sampleRate); | |
811 | AliFMDParameters::Instance()->SetStripRange(stripRange); | |
812 | ||
813 | AliFMDDebug(0, ("End of SOD/EOD")); | |
814 | ||
7af3df7f | 815 | return kTRUE; |
3effc6e7 | 816 | } |
817 | //____________________________________________________________________ | |
818 | ||
819 | UInt_t AliFMDRawReader::Get32bitWord(Int_t idx) | |
820 | { | |
821 | // This method returns the 32 bit word at a given | |
822 | // position inside the raw data payload. | |
823 | // The 'index' points to the beginning of the next word. | |
824 | // The method is supposed to be endian (platform) | |
825 | // independent. | |
826 | if (!fData) { | |
827 | AliFatal("Raw data paylod buffer is not yet initialized !"); | |
828 | } | |
829 | ||
830 | Int_t index = 4*idx; | |
831 | ||
832 | if (index < 4) { | |
833 | // fRawReader->AddFatalErrorLog(k32bitWordReadErr,Form("pos = %d",index)); | |
834 | // PrintDebug(); | |
835 | AliWarning(Form("Invalid raw data payload position (%d) !",index)); | |
836 | } | |
837 | ||
838 | UInt_t word = 0; | |
76d06ffa | 839 | |
3effc6e7 | 840 | word = fData[--index] << 24; |
841 | word |= fData[--index] << 16; | |
842 | word |= fData[--index] << 8; | |
843 | word |= fData[--index] << 0 ; | |
e802be3e | 844 | |
3effc6e7 | 845 | return word; |
846 | } | |
847 | //_____________________________________________________________________ | |
f38b1653 | 848 | Int_t AliFMDRawReader::GetHalfringIndex(UShort_t det, Char_t ring, |
849 | UShort_t board) { | |
3effc6e7 | 850 | |
851 | UShort_t iring = (ring == 'I' ? 1 : 0); | |
852 | ||
853 | Int_t index = (((det-1) << 2) | (iring << 1) | (board << 0)); | |
854 | ||
76d06ffa | 855 | return index-2; |
3effc6e7 | 856 | |
857 | } | |
e2c858f2 | 858 | |
e802be3e | 859 | //____________________________________________________________________ |
860 | // | |
861 | // EOF | |
862 | // | |
6c652449 | 863 |