]>
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" |
f4b75c28 | 61 | #include "AliFMDUShortMap.h" |
c2fc1258 | 62 | // #include "AliFMDAltroIO.h" // ALIFMDALTROIO_H |
e2c858f2 | 63 | #include "AliAltroRawStreamV3.h" |
3effc6e7 | 64 | #include <TArrayS.h> // ROOT_TArrayS |
1a1fdef7 | 65 | #include <TTree.h> // ROOT_TTree |
66 | #include <TClonesArray.h> // ROOT_TClonesArray | |
3effc6e7 | 67 | #include <TString.h> |
7af3df7f | 68 | #include <iostream> |
69 | #include <climits> | |
02a27b50 | 70 | // #include <iomanip> |
e802be3e | 71 | |
72 | //____________________________________________________________________ | |
925e6570 | 73 | ClassImp(AliFMDRawReader) |
1a1fdef7 | 74 | #if 0 |
75 | ; // This is here to keep Emacs for indenting the next line | |
76 | #endif | |
e802be3e | 77 | |
78 | //____________________________________________________________________ | |
1a1fdef7 | 79 | AliFMDRawReader::AliFMDRawReader(AliRawReader* reader, TTree* tree) |
e802be3e | 80 | : TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"), |
1a1fdef7 | 81 | fTree(tree), |
82 | fReader(reader), | |
faf80567 | 83 | // fSampleRate(1), |
3effc6e7 | 84 | fData(0), |
f38b1653 | 85 | fNbytes(0), |
e2c858f2 | 86 | fMinStrip(0), |
87 | fMaxStrip(127), | |
88 | fPreSamp(14+5), | |
8c79980b | 89 | fSeen(0), |
90 | fVerbose(false), | |
91 | fErrors("TObject"), | |
92 | fNErrChanLen(0), | |
93 | fNErrAddress(0) | |
e802be3e | 94 | { |
56b1929b | 95 | // Default CTOR |
faf80567 | 96 | for (Int_t i = 0; i < 3; i++) { |
97 | fSampleRate[i] = 0; | |
98 | fZeroSuppress[i] = kFALSE; | |
99 | fNoiseFactor[i] = 1; | |
87a5f9c6 | 100 | fL1Phase[i] = 0; |
0661bdda | 101 | fNErrors[i] = 0; |
faf80567 | 102 | } |
e802be3e | 103 | } |
104 | ||
c2fc1258 | 105 | //____________________________________________________________________ |
106 | void | |
107 | AliFMDRawReader::Exec(Option_t*) | |
108 | { | |
02a27b50 | 109 | // Read the data |
c2fc1258 | 110 | TClonesArray* array = new TClonesArray("AliFMDDigit"); |
111 | if (!fTree) { | |
112 | AliError("No tree"); | |
113 | return; | |
114 | } | |
115 | fTree->Branch("FMD", &array); | |
3effc6e7 | 116 | |
117 | ||
c2fc1258 | 118 | ReadAdcs(array); |
119 | Int_t nWrite = fTree->Fill(); | |
ca20eb4a | 120 | AliDebugF(1,"Got a grand total of %d digits, wrote %d bytes to tree", |
121 | array->GetEntriesFast(), nWrite); | |
3915b9ac | 122 | delete array; |
c2fc1258 | 123 | } |
124 | ||
8c79980b | 125 | //____________________________________________________________________ |
126 | void | |
127 | AliFMDRawReader::AddError(Int_t ddl, Int_t hwaddr) | |
128 | { | |
129 | Int_t nErr = fErrors.GetEntries(); | |
130 | TObject* o = new (fErrors[nErr]) TObject; | |
550157b2 | 131 | o->SetUniqueID((ddl & 0xFF) << 12 | (hwaddr & 0xFFF)); |
8c79980b | 132 | } |
133 | //____________________________________________________________________ | |
134 | void | |
135 | AliFMDRawReader::ReadbackError(const AliAltroRawStreamV3& input, | |
136 | const char* format, ...) | |
137 | { | |
138 | static char buf[512]; | |
139 | va_list ap; | |
140 | va_start(ap, format); | |
141 | vsnprintf(buf, 511, format, ap); | |
142 | buf[511] = '\0'; | |
143 | va_end(ap); | |
144 | ||
145 | // { AliWarning(buf); } | |
146 | if (AliDebugLevel() > 10) { | |
147 | AliLog::Flush(); | |
148 | AliWarning(buf); | |
149 | input.HexDumpChannel(); | |
150 | } | |
151 | ||
152 | Int_t ddl = input.GetDDLNumber(); | |
153 | Int_t hwaddr = input.GetHWAddress(); | |
154 | ||
155 | fReader->AddMinorErrorLog(AliAltroRawStreamV3::kAltroPayloadErr,buf); | |
156 | AddError(ddl, hwaddr); | |
157 | fNErrors[ddl]++; | |
158 | } | |
159 | ||
e2c858f2 | 160 | //____________________________________________________________________ |
161 | Int_t | |
162 | AliFMDRawReader::NewDDL(AliAltroRawStreamV3& input, UShort_t& det) | |
163 | { | |
164 | // Process a new DDL. Sets the internal data members fZeroSuppress, | |
165 | // fSampleRate, and fNoiseFactor based on information in the RCU trailer. | |
166 | // | |
167 | // Parameters: | |
168 | // input Input stream | |
169 | // det On return, the detector number | |
170 | // | |
171 | // Return value: | |
172 | // negative value in case of problems, the DDL number otherwise | |
173 | ||
174 | // Get the DDL number | |
175 | UInt_t ddl = input.GetDDLNumber(); | |
ca20eb4a | 176 | AliDebugF(2,"DDL number %d", ddl); |
e2c858f2 | 177 | |
09b6c804 | 178 | // Note, previously, the ALTROCFG1 register was interpreted as |
179 | // | |
180 | // Bits Value Description | |
181 | // 0- 3 0/1 1st Baseline filter, mode | |
182 | // 4- 5 Over-1 2nd baseline filter, # of pre-samples | |
183 | // 6- 9 factor 2nd baseline filter, # of post-samples | |
184 | // 10- 0 2nd baseline filter, enable | |
185 | // 11-12 00 Zero suppression, glitch filter mode | |
186 | // 13-15 001 Zero suppression, # of post samples | |
187 | // 16-17 01 Zero suppression, # of pre samples | |
188 | // 18 0/1 Zero suppression, enable | |
189 | // | |
190 | // The interpretation used in AliAltroRawStreamerV3 - which | |
191 | // corresponds directly to ALTRO DPCFG register - is | |
192 | // | |
193 | // Bits Value Description | |
194 | // 0- 3 0/1 1st Baseline filter, mode | |
195 | // 4 0 Polarity (if '1', then "1's inverse") | |
196 | // 5- 6 01 Zero suppression, # of pre samples | |
197 | // 7-10 0001 Zero suppression, # of post samples | |
198 | // 11 0 2nd baseline filter, enable | |
199 | // 12-13 00 Zero suppression, glitch filter mode | |
200 | // 14-16 factor 2nd baseline filter, # of post-samples | |
201 | // 17-18 01 2nd baseline filter, # of pre-samples | |
202 | // 19 0/1 Zero suppression, enable | |
203 | // | |
ca20eb4a | 204 | // From ALTRO DPCF2 we get |
205 | // | |
206 | // 20-23 rate Pre-samples | |
207 | // | |
09b6c804 | 208 | // Writing 'x' for variable values, that means we have the |
209 | // following patterns for the 2 cases | |
210 | // | |
211 | // bit # 20 16 12 8 4 0 | |
212 | // old |0x01|0010|00xx|xxxx|xxxx| | |
213 | // new |x01x|xx00|0000|1010|xxxx| | |
214 | // | |
215 | // That means that we can check if bits 10-13 are '1000' or | |
216 | // '0000', which will tell us if the value was written with the | |
217 | // new or the old interpretation. That is, we can check that | |
218 | // | |
219 | // if (((altrocfg1 >> 10) & 0x8) == 0x8) { | |
220 | // // old interpretation | |
221 | // } | |
222 | // else { | |
223 | // // New interpretation | |
224 | // } | |
225 | // | |
226 | // That means, that we should never | |
227 | // | |
228 | // - change the # of zero suppression post samples | |
229 | // - Turn on 2nd baseline correction | |
230 | // - Change the zero-suppression glitch filter mode | |
231 | // | |
232 | // This change as introduced in version 1.2 of Rcu++ | |
233 | // | |
3afd9281 | 234 | UInt_t cfg1 = input.GetAltroCFG1(); |
235 | if (((cfg1 >> 10) & 0x8) == 0x8) { | |
236 | UInt_t cfg2 = input.GetAltroCFG2(); | |
ca20eb4a | 237 | AliDebugF(3,"We have data from older MiniConf 0x%x cfg2=0x%08x", |
238 | ((cfg1 >> 10) & 0x8), cfg2); | |
4b25407d | 239 | fZeroSuppress[ddl] = (cfg1 >> 0) & 0x1; |
240 | fNoiseFactor[ddl] = (cfg1 >> 6) & 0xF; | |
241 | fSampleRate[ddl] = (cfg2 >> 20) & 0xF; | |
3afd9281 | 242 | } |
243 | else { | |
ca20eb4a | 244 | AliDebugF(3,"We have data from newer MiniConf 0x%x", |
245 | ((cfg1 >> 10) & 0x8)); | |
3afd9281 | 246 | fZeroSuppress[ddl] = input.GetZeroSupp(); |
247 | // WARNING: We store the noise factor in the 2nd baseline | |
248 | // filters excluded post samples, since we'll never use that | |
249 | // mode. | |
ca20eb4a | 250 | // fNoiseFactor[ddl] = input.GetNPostsamples(); |
251 | fNoiseFactor[ddl] = input.GetNNonZSPostsamples(); | |
3afd9281 | 252 | // WARNING: We store the sample rate in the number of pre-trigger |
253 | // samples, since we'll never use that mode. | |
254 | fSampleRate[ddl] = input.GetNPretriggerSamples(); | |
f4b75c28 | 255 | // |
3afd9281 | 256 | } |
ca20eb4a | 257 | AliDebugF(10,"Phase of DDL=%d is %g (%d)", ddl, input.GetL1Phase(), |
258 | input.GetAltroCFG2() & 0x1F); | |
f4b75c28 | 259 | fL1Phase[ddl] = input.GetAltroCFG2() & 0x1F; // input.GetL1Phase(); |
ca20eb4a | 260 | AliDebugF(3,"RCU @ DDL %d zero suppression: %s", |
261 | ddl, (fZeroSuppress[ddl] ? "yes" : "no")); | |
262 | AliDebugF(3,"RCU @ DDL %d noise factor: %d", ddl,fNoiseFactor[ddl]); | |
263 | AliDebugF(3,"RCU @ DDL %d sample rate: %d", ddl,fSampleRate[ddl]); | |
264 | ||
265 | ||
e2c858f2 | 266 | // Get Errors seen |
267 | Int_t nChAddrMismatch = input.GetNChAddrMismatch(); | |
268 | Int_t nChLenMismatch = input.GetNChLengthMismatch(); | |
8c79980b | 269 | if (nChAddrMismatch != 0) { |
270 | ReadbackError(input, | |
271 | "Got %d channels with address mis-matches for 0x%03x", | |
272 | nChAddrMismatch, ddl); | |
273 | fNErrAddress += nChAddrMismatch; | |
274 | } | |
275 | if (nChLenMismatch != 0) { | |
276 | ReadbackError(input, | |
277 | "Got %d channels with length mis-matches for 0x%03x", | |
278 | nChLenMismatch, ddl); | |
279 | fNErrChanLen += nChLenMismatch; | |
280 | } | |
e2c858f2 | 281 | |
282 | // Map DDL number to the detector number | |
283 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
284 | AliFMDAltroMapping* map = pars->GetAltroMap(); | |
285 | if (map->DDL2Detector(ddl) < 0) return -1; | |
286 | det = map->DDL2Detector(ddl); | |
287 | ||
288 | if (AliLog::GetDebugLevel("FMD", 0) > 5) | |
289 | input.PrintRCUTrailer(); | |
290 | return ddl; | |
291 | } | |
292 | ||
293 | //____________________________________________________________________ | |
294 | Int_t | |
09b6c804 | 295 | AliFMDRawReader::NewChannel(const AliAltroRawStreamV3& input, UShort_t det, |
e2c858f2 | 296 | Char_t& ring, UShort_t& sec, Short_t& strbase) |
297 | { | |
298 | // Processs a new channel. Sets the internal data members | |
299 | // fMinStrip, fMaxStrip, and fPreSamp. | |
300 | // | |
301 | // Parameter: | |
302 | // input Input stream | |
303 | // ring On return, the ring identifier | |
304 | // sec On return, the sector number | |
305 | // strbase On return, the strip base | |
306 | // | |
307 | // Return value | |
308 | // negative value in case of problems, hardware address otherwise | |
309 | ||
310 | // Get the hardware address, and map that to detector coordinates | |
311 | UShort_t board, chip, channel; | |
312 | Int_t ddl = input.GetDDLNumber(); | |
313 | Int_t hwaddr = input.GetHWAddress(); | |
314 | if (input.IsChannelBad()) { | |
8c79980b | 315 | ReadbackError(input, "Ignoring channel %03d/0x%03x with errors", |
316 | ddl, hwaddr); | |
f4b75c28 | 317 | return 0xFFFF; |
e2c858f2 | 318 | } |
319 | ||
320 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
321 | AliFMDAltroMapping* map = pars->GetAltroMap(); | |
322 | // Map to hardware stuff | |
323 | map->ChannelAddress(hwaddr, board, chip, channel); | |
324 | // Then try to map to detector address | |
325 | if (!map->Channel2StripBase(board, chip, channel, ring, sec, strbase)) { | |
ca20eb4a | 326 | AliErrorF("Failed to get detector id from DDL %d, " |
327 | "hardware address 0x%03x", ddl, hwaddr); | |
e2c858f2 | 328 | return -1; |
329 | } | |
ca20eb4a | 330 | AliDebugF(7,"Board: 0x%02x, Altro: 0x%x, Channel: 0x%x", |
331 | board, chip, channel); | |
e2c858f2 | 332 | |
333 | // Get the 'conditions' | |
334 | fMinStrip = pars->GetMinStrip(det, ring, sec, strbase); | |
335 | fMaxStrip = pars->GetMaxStrip(det, ring, sec, strbase); | |
336 | fPreSamp = pars->GetPreSamples(det, ring, sec, strbase); | |
838120cd | 337 | if (fSampleRate[ddl] == 0) { |
ca20eb4a | 338 | AliDebugF(7,"Get sample rate for RCU @ DDL %d from OCDB", ddl); |
e2c858f2 | 339 | fSampleRate[ddl] = pars->GetSampleRate(det, ring, sec, strbase); |
838120cd | 340 | } |
ca20eb4a | 341 | AliDebugF(7,"RCU @ DDL %d sample rate: %d", ddl,fSampleRate[ddl]); |
e2c858f2 | 342 | |
343 | return hwaddr; | |
344 | } | |
345 | ||
f4b75c28 | 346 | //____________________________________________________________________ |
347 | Bool_t | |
348 | AliFMDRawReader::NewBunch(const AliAltroRawStreamV3& input, | |
349 | UShort_t& start, UShort_t& length) | |
350 | { | |
351 | // | |
352 | // Do some checks on the bunch data | |
353 | // | |
354 | Int_t ddl = input.GetDDLNumber(); | |
355 | Int_t hwaddr = input.GetHWAddress(); | |
356 | UShort_t nSamples = input.GetNSamplesPerCh() + fPreSamp; | |
357 | UShort_t tstart = input.GetStartTimeBin(); | |
358 | length = input.GetBunchLength(); | |
359 | ||
360 | if (tstart >= nSamples) { | |
8c79980b | 361 | ReadbackError(input, |
362 | "Bunch in %03d/0x%03x has an start time greater " | |
363 | "than number of samples: 0x%x >= 0x%x", | |
364 | ddl, hwaddr, tstart, nSamples); | |
f4b75c28 | 365 | return false; |
366 | } | |
367 | if ((int(tstart) - length + 1) < 0) { | |
8c79980b | 368 | ReadbackError(input, |
369 | "Bunch in %03d/0x%03x has an invalid length and " | |
370 | "start time: 0x%x,0x%x (%d-%d+1=%d<0)", | |
371 | ddl, hwaddr, length, tstart, tstart, length, | |
372 | int(tstart)-length+1); | |
f4b75c28 | 373 | return false; |
374 | } | |
375 | if (tstart >= start) { | |
8c79980b | 376 | ReadbackError(input, |
377 | "Bunch in %03d/0x%03x has early start time: " | |
378 | "0x%x >= 0x%x", ddl, hwaddr, tstart, start); | |
f4b75c28 | 379 | return false; |
380 | } | |
381 | start = tstart; | |
382 | return true; | |
383 | } | |
384 | ||
e2c858f2 | 385 | //____________________________________________________________________ |
386 | Int_t | |
09b6c804 | 387 | AliFMDRawReader::NewSample(const AliAltroRawStreamV3& input, |
e2c858f2 | 388 | Int_t i, UShort_t t, UShort_t sec, |
389 | UShort_t strbase, Short_t& str, UShort_t& samp) | |
390 | { | |
391 | // Process a new timebin | |
392 | // | |
393 | // Parameters: | |
394 | // input Input stream | |
395 | // i Index into bunch data | |
396 | // t Time | |
397 | // strbase Base of strip numbers for this channel | |
398 | // str On return, the strip number | |
399 | // samp On return, the sample number | |
400 | // | |
401 | // Return value | |
402 | // negative value in case of problems, ADC value otherwise | |
403 | if (t < fPreSamp) return -1; | |
404 | ||
405 | Int_t ddl = input.GetDDLNumber(); | |
406 | Int_t hwa = input.GetHWAddress(); | |
407 | const UShort_t* data = input.GetSignals(); | |
408 | Short_t adc = data[i]; | |
ca20eb4a | 409 | AliDebugF(10,"0x%04x/0x%03x/%04d %4d", ddl, hwa, t, adc); |
e2c858f2 | 410 | |
411 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
412 | AliFMDAltroMapping* map = pars->GetAltroMap(); | |
413 | ||
414 | samp = 0; | |
415 | Short_t stroff = 0; | |
416 | map->Timebin2Strip(sec, t, fPreSamp, fSampleRate[ddl], stroff, samp); | |
417 | str = strbase + stroff; | |
418 | ||
ca20eb4a | 419 | AliDebugF(20,"0x%04x/0x%03x/%04d=%4d maps to strip %3d sample %d " |
420 | "(pre: %d, min: %d, max: %d, rate: %d)", | |
421 | ddl, hwa, t, adc, str, samp, fPreSamp, | |
422 | fMinStrip, fMaxStrip, fSampleRate[ddl]); | |
e2c858f2 | 423 | if (str < 0) { |
ca20eb4a | 424 | AliDebugF(10,"Got presamples at timebin %d", i); |
e2c858f2 | 425 | return -1; |
426 | } | |
427 | ||
428 | // VA1 Local strip number | |
429 | Short_t lstrip = (t - fPreSamp) / fSampleRate[ddl] + fMinStrip; | |
430 | ||
ca20eb4a | 431 | AliDebugF(15,"Checking if strip %d (%d) in range [%d,%d]", |
432 | lstrip, str, fMinStrip, fMaxStrip); | |
e2c858f2 | 433 | if (lstrip < fMinStrip || lstrip > fMaxStrip) { |
ca20eb4a | 434 | AliDebugF(10,"Strip %03d-%d (%d,%d) from t=%d out of range (%3d->%3d)", |
435 | str, samp, lstrip, stroff, t, fMinStrip, fMaxStrip); | |
86878381 | 436 | adc = -1; |
e2c858f2 | 437 | } |
438 | // Possibly do pedestal subtraction of signal | |
439 | if (adc > 1023) | |
ca20eb4a | 440 | AliWarningF("ADC value out of range: %4d", adc); |
e2c858f2 | 441 | return adc; |
442 | } | |
443 | ||
b5014544 | 444 | //____________________________________________________________________ |
f4b75c28 | 445 | Int_t |
faf80567 | 446 | AliFMDRawReader::NextSample(UShort_t& det, Char_t& rng, UShort_t& sec, |
447 | UShort_t& str, UShort_t& sam, UShort_t& rat, | |
448 | Short_t& adc, Bool_t& zs, UShort_t& fac) | |
b5014544 | 449 | { |
450 | // Scan current event for next signal. It returns kFALSE when | |
451 | // there's no more data in the event. | |
f4b75c28 | 452 | // |
453 | // Note, that this member function is in principle very fast, but | |
454 | // contains less error checking. In particular, channels that have | |
455 | // bad bunches cannot be checked here. Seeing a bad bunch will only | |
456 | // skip the remainder of the channel and not reset the already read | |
457 | // digits. This is potentially dangerous. | |
458 | // | |
459 | // Parameters: | |
460 | // det On return, contain the detector number | |
461 | // rng On return, contain the ring identifier | |
462 | // sec On return, contain the sector number | |
463 | // str On return, contain the strip number | |
464 | // sam On return, contain the sample number | |
465 | // rat On return, contain the sample rate | |
466 | // adc On return, contain the ADC counts | |
467 | // zs On return, contain the zero-supp. flag | |
468 | // fac On return, contain the zero-supp. noise factor | |
469 | // | |
470 | // Return values: | |
471 | // 0 No more data | |
472 | // -1 Read sample belongs to a bad bunch | |
473 | // >0 Good status - contains bit mask of values | |
474 | // Bit 1 New DDL | |
475 | // Bit 2 New Channel | |
476 | // Bit 3 New Bunch | |
477 | // Bit 4 New Sample | |
e2c858f2 | 478 | static AliAltroRawStreamV3 stream(fReader); // = 0; |
b5014544 | 479 | static Int_t ddl = -1; |
b5014544 | 480 | static UShort_t tdet = 0; |
481 | static Char_t trng = '\0'; | |
482 | static UShort_t tsec = 0; | |
483 | static Short_t tstr = 0; | |
484 | static Short_t bstr = -1; | |
e2c858f2 | 485 | static UShort_t tsam = 0; |
ab5a8e9c | 486 | // static UInt_t trate = 0; |
b5014544 | 487 | static Int_t hwaddr = -1; |
e2c858f2 | 488 | static UShort_t start = 0; |
489 | static UShort_t length = 0; | |
490 | static Short_t t = -1; | |
491 | static Int_t i = 0; | |
492 | // First entry! | |
b5014544 | 493 | if (stream.GetDDLNumber() < 0) { |
f4b75c28 | 494 | fReader->Reset(); |
b5014544 | 495 | fReader->Select("FMD"); |
f4b75c28 | 496 | stream.Reset(); |
497 | stream.SelectRawData("FMD"); | |
498 | stream.SetCheckAltroPayload(false); | |
499 | for (Int_t j = 0; j < kNDDL; j++) fNErrors[j] = 0; | |
b5014544 | 500 | |
b5014544 | 501 | // Reset variables |
502 | ddl = -1; | |
ab5a8e9c | 503 | // trate= 0; |
b5014544 | 504 | tdet = 0; |
505 | trng = '\0'; | |
506 | tsec = 0; | |
507 | tstr = 0; | |
faf80567 | 508 | tsam = -1; |
b5014544 | 509 | hwaddr = -1; |
510 | } | |
e2c858f2 | 511 | |
f4b75c28 | 512 | UShort_t ret = 0; |
b5014544 | 513 | do { |
ca20eb4a | 514 | AliDebugF(15, "t=%4d, start=%4d, length=%4d", t, start, length); |
e2c858f2 | 515 | if (t < start - length + 1) { |
ca20eb4a | 516 | AliDebugF(10,"Time t=%d < start-length+1=%d-%d+1 (%3d/0x%03x)", |
517 | t, start, length, ddl, hwaddr); | |
f4b75c28 | 518 | if (hwaddr > 0xFFF || |
519 | hwaddr < 0 || | |
520 | !stream.NextBunch()) { | |
521 | if (AliDebugLevel() >= 10 && hwaddr > 0xFFF) { | |
522 | AliDebug(10,"Last channel read was marked bad"); | |
523 | } | |
524 | if (AliDebugLevel() >= 10 && hwaddr < 0) { | |
525 | AliDebug(10,"No more channels"); | |
526 | } | |
527 | AliDebug(10,"No next bunch, or first entry"); | |
528 | if (ddl < 0 || !stream.NextChannel()) { | |
529 | if (AliDebugLevel() >= 10 && ddl < 0) { | |
530 | AliDebug(10,"No DDL"); | |
531 | } | |
532 | AliDebug(10,"No next channel, or first entry"); | |
e2c858f2 | 533 | if (!stream.NextDDL()) { |
f4b75c28 | 534 | AliDebug(10,"No more DDLs"); |
e2c858f2 | 535 | stream.Reset(); |
f4b75c28 | 536 | return 0; |
e2c858f2 | 537 | } |
538 | ddl = NewDDL(stream, tdet); | |
ca20eb4a | 539 | AliDebugF(5,"New DDL: %d (%d)", ddl, tdet); |
f4b75c28 | 540 | ret |= 0x1; |
541 | continue; | |
e2c858f2 | 542 | } |
543 | hwaddr = NewChannel(stream, tdet, trng, tsec, bstr); | |
f4b75c28 | 544 | if (hwaddr > 0xFFF) fNErrors[ddl] += 1; |
ca20eb4a | 545 | AliDebugF(5,"New Channel: %3d/0x%03x", ddl, hwaddr); |
f4b75c28 | 546 | start = 1024; |
547 | ret |= 0x2; | |
548 | continue; | |
e2c858f2 | 549 | } |
f4b75c28 | 550 | if (!NewBunch(stream, start, length)) { |
551 | // AliWarning(Form("Bad bunch in %3d/0x%03x read - " | |
552 | // "should progress to next channel " | |
553 | // "(t=%4d,start=%4d,length=%4d)", | |
554 | // ddl, hwaddr, t,start, length)); | |
555 | hwaddr = 0xFFFF; // Bad channel | |
556 | return -1; | |
557 | } | |
ca20eb4a | 558 | AliDebugF(5, "New bunch in %3d/0x%03x: start=0x%03x, length=%4d", |
559 | ddl, hwaddr, start, length); | |
f4b75c28 | 560 | ret |= 0x4; |
e2c858f2 | 561 | t = start; |
562 | i = 0; | |
ca20eb4a | 563 | AliDebugF(10,"Got new bunch FMD%d%c[%2d], bunch @ %d, length=%d", |
564 | tdet, trng, tsec, start, length); | |
b5014544 | 565 | } |
e2c858f2 | 566 | Int_t tadc = NewSample(stream, i, t, tsec, bstr, tstr, tsam); |
ca20eb4a | 567 | AliDebugF(10,"New sample FMD%d%c[%2d,%3d]-%d = 0x%03x", |
568 | tdet, trng, tsec, tstr, tsam, tadc); | |
f4b75c28 | 569 | ret |= 0x8; |
e2c858f2 | 570 | if (tadc >= 0) { |
571 | det = tdet; | |
572 | rng = trng; | |
573 | sec = tsec; | |
574 | str = tstr; | |
575 | sam = tsam; | |
576 | adc = tadc; | |
577 | rat = fSampleRate[ddl]; | |
578 | zs = fZeroSuppress[ddl]; | |
579 | fac = fNoiseFactor[ddl]; | |
580 | t--; | |
581 | i++; | |
ca20eb4a | 582 | AliDebugF(10,"Returning FMD%d%c[%2d,%3d]-%d = 0x%03x (%d,%d,%d)", |
583 | det, rng, sec, str, sam, adc, rat, zs, fac); | |
e2c858f2 | 584 | break; |
b5014544 | 585 | } |
f4b75c28 | 586 | t--; |
587 | i++; | |
b5014544 | 588 | } while (true); |
ca20eb4a | 589 | AliDebugF(5,"Returning 0x%02x", ret); |
f4b75c28 | 590 | return ret; |
b5014544 | 591 | } |
592 | ||
e2c858f2 | 593 | |
faf80567 | 594 | //____________________________________________________________________ |
f4b75c28 | 595 | Int_t |
faf80567 | 596 | AliFMDRawReader::NextSignal(UShort_t& det, Char_t& rng, |
597 | UShort_t& sec, UShort_t& str, | |
598 | Short_t& adc, Bool_t& zs, | |
599 | UShort_t& fac) | |
600 | { | |
09b6c804 | 601 | // |
602 | // Get the next signal | |
603 | // | |
604 | // Parameters: | |
605 | // det On return, the detector | |
606 | // rng On return, the ring | |
607 | // sec On return, the sector | |
608 | // str On return, the strip | |
609 | // adc On return, the ADC value | |
610 | // zs On return, whether zero-supp. is enabled | |
611 | // fac On return, the usd noise factor | |
612 | // | |
613 | // Return: | |
614 | // true if valid data is returned | |
615 | // | |
f4b75c28 | 616 | Int_t ret = 0; |
faf80567 | 617 | do { |
618 | UShort_t samp, rate; | |
f4b75c28 | 619 | if ((ret = NextSample(det, rng, sec, str, samp, rate, adc, zs, fac)) <= 0) |
620 | return ret; | |
621 | ||
622 | Bool_t take = SelectSample(samp, rate); | |
faf80567 | 623 | if (!take) continue; |
624 | break; | |
625 | } while (true); | |
f4b75c28 | 626 | return ret; |
faf80567 | 627 | } |
628 | ||
629 | //____________________________________________________________________ | |
630 | Bool_t | |
631 | AliFMDRawReader::SelectSample(UShort_t samp, UShort_t rate) | |
632 | { | |
e2c858f2 | 633 | // Check if the passed sample is the one we need |
faf80567 | 634 | Bool_t take = kFALSE; |
635 | switch (rate) { | |
636 | case 1: take = kTRUE; break; | |
637 | case 2: if (samp == 1) take = kTRUE; break; | |
638 | case 3: if (samp == 1) take = kTRUE; break; | |
639 | case 4: if (samp == 2) take = kTRUE; break; | |
640 | default: if (samp == rate-2) take = kTRUE; break; | |
641 | } | |
642 | ||
643 | return take; | |
644 | } | |
645 | ||
c2fc1258 | 646 | //____________________________________________________________________ |
647 | Bool_t | |
648 | AliFMDRawReader::ReadAdcs(TClonesArray* array) | |
649 | { | |
e2c858f2 | 650 | // Read ADC values from raw input into passed TClonesArray of AliFMDDigit |
651 | // objects. | |
ca20eb4a | 652 | AliDebug(3,"Reading ADC values into a TClonesArray"); |
e2c858f2 | 653 | |
c2fc1258 | 654 | // Read raw data into the digits array, using AliFMDAltroReader. |
655 | if (!array) { | |
656 | AliError("No TClonesArray passed"); | |
657 | return kFALSE; | |
658 | } | |
8c79980b | 659 | // static ULong_t unique = 0; |
f38b1653 | 660 | const UShort_t kUShortMax = (1 << 16) - 1; |
661 | fSeen.Reset(kUShortMax); | |
8c79980b | 662 | fErrors.Clear(); |
663 | fNErrChanLen = 0; | |
664 | fNErrAddress = 0; | |
f4b75c28 | 665 | for (Int_t ddl = 0; ddl < kNDDL; ddl++) fNErrors[ddl] = 0; |
f38b1653 | 666 | |
e2c858f2 | 667 | AliAltroRawStreamV3 input(fReader); |
668 | input.Reset(); | |
f4b75c28 | 669 | input.SetCheckAltroPayload(false); |
e2c858f2 | 670 | input.SelectRawData("FMD"); |
1e8f773e | 671 | |
e2c858f2 | 672 | // Loop over input RORCs |
673 | while (input.NextDDL()) { | |
674 | UShort_t det = 0; | |
675 | Int_t ddl = NewDDL(input, det); | |
676 | if (ddl < 0) break; | |
f4b75c28 | 677 | fNErrors[ddl] = 0; |
e2c858f2 | 678 | |
679 | while (input.NextChannel()) { | |
680 | // Get the hardware address, and map that to detector coordinates | |
1e8f773e | 681 | Char_t ring; |
e2c858f2 | 682 | UShort_t sec; |
683 | Short_t strbase; | |
f4b75c28 | 684 | Int_t hwaddr = NewChannel(input, det, ring, sec, strbase); |
e2c858f2 | 685 | if (hwaddr < 0) break; |
f4b75c28 | 686 | if (hwaddr > 0xFFF) continue; |
e2c858f2 | 687 | |
f4b75c28 | 688 | UShort_t start = 0x3FF; |
689 | Bool_t errors = false; | |
690 | Int_t first = -1; | |
691 | Int_t last = -1; | |
e2c858f2 | 692 | // Loop over bunches |
693 | while (input.NextBunch()) { | |
694 | // Get Lenght of bunch, and pointer to the data | |
695 | const UShort_t* data = input.GetSignals(); | |
f4b75c28 | 696 | UShort_t length; |
697 | if (!NewBunch(input, start, length)) { | |
698 | errors = true; | |
699 | break; | |
700 | } | |
701 | ||
e2c858f2 | 702 | |
703 | // Loop over the data and store it. | |
704 | for (Int_t i = 0; i < length; i++) { | |
705 | // Time | |
706 | Short_t str; | |
707 | UShort_t samp; | |
708 | Int_t t = start - i; | |
709 | Int_t adc = NewSample(input, i, t, sec, strbase, str, samp); | |
ca20eb4a | 710 | if (adc <= 0) continue; |
e2c858f2 | 711 | UShort_t counts = adc; |
712 | ||
ca20eb4a | 713 | AliDebugF(10,"FMD%d%c[%02d,%03d]-%d: %4d", |
714 | det, ring, sec, str, samp, counts); | |
e2c858f2 | 715 | // Check the cache of indicies |
716 | Int_t idx = fSeen(det, ring, sec, str); | |
86878381 | 717 | AliFMDDigit* digit = 0; |
e2c858f2 | 718 | if (idx == kUShortMax) { |
719 | // We haven't seen this strip yet. | |
720 | fSeen(det, ring, sec, str) = idx = array->GetEntriesFast(); | |
ca20eb4a | 721 | AliDebugF(7, "making digit @ %5d for FMD%d%c[%2d,%3d]-%d " |
722 | "from %3d/0x%03x/%4d (def: %d)", | |
723 | idx, det, ring, sec, str, samp, ddl, hwaddr, t, | |
724 | fSampleRate[ddl]); | |
86878381 | 725 | digit = new ((*array)[idx]) AliFMDDigit(det, ring, sec, str); |
726 | digit->SetDefaultCounts(fSampleRate[ddl]); | |
e2c858f2 | 727 | } |
f4b75c28 | 728 | else { |
86878381 | 729 | digit = static_cast<AliFMDDigit*>(array->At(idx)); |
f4b75c28 | 730 | } |
731 | if (first < 0) first = idx; | |
732 | last = idx; | |
ca20eb4a | 733 | AliDebugF(5,"Setting FMD%d%c[%2d,%3d]-%d from timebin " |
734 | "%4d=%4d (%4d)", det, ring, sec, str, samp, t, | |
735 | counts, data[i]); | |
e2c858f2 | 736 | digit->SetCount(samp, counts); |
ca20eb4a | 737 | if (AliLog::GetDebugLevel("FMD","") >= 5) digit->Print(); |
e2c858f2 | 738 | } // for (i) |
739 | } // while (bunch) | |
f4b75c28 | 740 | if (errors) { |
550157b2 | 741 | AliDebugF(2,"Channel %3d/0x%03x contain errors, " |
742 | "resetting index %d to %d", ddl, hwaddr, first, last); | |
f4b75c28 | 743 | if (first >= 0) { |
744 | for (Int_t i = first; i <= last; i++) { | |
745 | AliFMDDigit* digit = static_cast<AliFMDDigit*>(array->At(i)); | |
746 | for (Int_t j = 0; j < fSampleRate[ddl]; j++) { | |
ca20eb4a | 747 | AliDebugF(10,"Resetting strip %s=%d", |
748 | digit->GetName(),digit->Counts()); | |
f4b75c28 | 749 | digit->SetCount(j, kBadSignal); |
750 | } | |
751 | } | |
752 | } | |
753 | } | |
754 | // if (errors && (AliDebugLevel() > 0)) input.HexDumpChannel(); | |
755 | } // while (channel) | |
756 | } // while (ddl) | |
8c79980b | 757 | if (fNErrors[0] > 0 || fNErrors[1] > 0 || fNErrors[2] > 0 || |
758 | fNErrChanLen > 0 || fNErrAddress > 0) { | |
759 | // AliLog::Flush(); | |
760 | AliLog::SetPrintRepetitions(false); | |
761 | AliWarningF("R/O errors: FMD1=%d, FMD2=%d, FMD3=%d, " | |
762 | "Channel Length=%d, address=%d", | |
763 | fNErrors[0], fNErrors[1], fNErrors[2], | |
764 | fNErrChanLen, fNErrAddress); | |
765 | AliLog::SetPrintRepetitions(true); | |
766 | } | |
767 | if (fVerbose && fErrors.GetEntries() > 0) { | |
768 | TString msg; | |
769 | Int_t nErr = fErrors.GetEntries(); | |
770 | for (Int_t i = 0; i < nErr; i++) { | |
771 | UInt_t where = fErrors.At(i)->GetUniqueID(); | |
772 | if (i % 6 == 0) msg.Append("\n"); | |
773 | msg.Append(Form(" %3d/0x%03x", (where >> 12) & 0xFF, (where & 0xFFF))); | |
774 | } | |
775 | // AliLog::Flush(); | |
776 | AliLog::SetPrintRepetitions(false); | |
777 | AliWarningF("Got %d errors in channels %s", nErr, msg.Data()); | |
778 | AliLog::SetPrintRepetitions(true); | |
779 | } | |
f4b75c28 | 780 | return kTRUE; |
781 | } | |
782 | //____________________________________________________________________ | |
783 | Bool_t | |
784 | AliFMDRawReader::ReadAdcs(AliFMDUShortMap& map) | |
785 | { | |
786 | // Read ADC values from raw input into passed TClonesArray of AliFMDDigit | |
787 | // objects. | |
ca20eb4a | 788 | AliDebug(3,"Reading ADC values into a map"); |
f4b75c28 | 789 | |
589e63e3 | 790 | // const UShort_t kUShortMax = (1 << 16) - 1; |
f4b75c28 | 791 | for (Int_t ddl = 0; ddl < kNDDL; ddl++) fNErrors[ddl] = 0; |
792 | ||
793 | AliAltroRawStreamV3 input(fReader); | |
794 | input.Reset(); | |
795 | input.SetCheckAltroPayload(false); | |
796 | input.SelectRawData("FMD"); | |
797 | ||
798 | // Loop over input RORCs | |
799 | while (input.NextDDL()) { | |
800 | UShort_t det = 0; | |
801 | Int_t ddl = NewDDL(input, det); | |
802 | if (ddl < 0) break; | |
803 | fNErrors[ddl] = 0; | |
804 | ||
805 | while (input.NextChannel()) { | |
806 | // Get the hardware address, and map that to detector coordinates | |
807 | Char_t ring; | |
808 | UShort_t sec; | |
809 | Short_t strbase; | |
810 | Int_t hwaddr = NewChannel(input, det, ring, sec, strbase); | |
811 | if (hwaddr < 0) break; | |
812 | if (hwaddr > 0xFFF) continue; | |
813 | ||
814 | UShort_t start = 0x3FF; | |
815 | Bool_t errors = false; | |
816 | Int_t first = -1; | |
817 | Int_t last = -1; | |
818 | // Loop over bunches | |
819 | while (input.NextBunch()) { | |
820 | // Get Lenght of bunch, and pointer to the data | |
589e63e3 | 821 | // const UShort_t* data = input.GetSignals(); |
f4b75c28 | 822 | UShort_t length; |
823 | if (!NewBunch(input, start, length)) { | |
824 | errors = true; | |
825 | break; | |
826 | } | |
827 | ||
828 | ||
829 | // Loop over the data and store it. | |
830 | for (Int_t i = 0; i < length; i++) { | |
831 | // Time | |
832 | Short_t str; | |
833 | UShort_t samp; | |
834 | Int_t t = start - i; | |
835 | Int_t adc = NewSample(input, i, t, sec, strbase, str, samp); | |
836 | if (adc < 0) continue; | |
837 | UShort_t counts = adc; | |
838 | ||
ca20eb4a | 839 | AliDebugF(10, "FMD%d%c[%02d,%03d]-%d: %4d", |
840 | det, ring, sec, str, samp, counts); | |
f4b75c28 | 841 | if (SelectSample(samp, fSampleRate[ddl])) |
842 | map(det,ring,sec,str) = counts; | |
843 | if (first < 0) first = str; | |
844 | last = str; | |
845 | } // for (i) | |
846 | } // while (bunch) | |
847 | if (errors) { | |
550157b2 | 848 | AliDebugF(2, "Channel %3d/0x%03x contain errors, " |
849 | "resetting strips %d to %d", ddl, hwaddr, first, last); | |
f4b75c28 | 850 | if (first >= 0) { |
851 | Int_t ds = first <= last ? 1 : -1; | |
852 | for (Int_t i = first; i != last+ds; i += ds) { | |
ca20eb4a | 853 | AliDebugF(10, "Resetting strip FMD%d%c[%02d,%03d]=%d", |
854 | det,ring,sec,i,map(det,ring,sec,i)); | |
f4b75c28 | 855 | map(det,ring,sec,i) = kBadSignal; |
856 | } | |
857 | } | |
858 | } | |
e2c858f2 | 859 | } // while (channel) |
860 | } // while (ddl) | |
d760ea03 | 861 | return kTRUE; |
862 | } | |
863 | ||
3effc6e7 | 864 | //____________________________________________________________________ |
865 | Bool_t AliFMDRawReader::ReadSODevent(AliFMDCalibSampleRate* sampleRate, | |
866 | AliFMDCalibStripRange* stripRange, | |
867 | TArrayS &pulseSize, | |
408bf2b4 | 868 | TArrayS &pulseLength, |
869 | Bool_t* detectors) | |
f38b1653 | 870 | { |
09b6c804 | 871 | // |
872 | // Read SOD event into passed objects. | |
873 | // | |
874 | // Parameters: | |
875 | // samplerate The sample rate object to fill | |
876 | // striprange The strip range object to fill | |
877 | // pulseSize The pulse size object to fill | |
878 | // pulseLength The pulse length (in events) object to fill | |
879 | // | |
880 | // Return: | |
881 | // @c true on success | |
882 | // | |
ca20eb4a | 883 | AliDebug(0,"Start of SOD/EOD"); |
3effc6e7 | 884 | |
885 | UInt_t shift_clk[18]; | |
886 | UInt_t sample_clk[18]; | |
887 | UInt_t strip_low[18]; | |
888 | UInt_t strip_high[18]; | |
889 | UInt_t pulse_size[18]; | |
890 | UInt_t pulse_length[18]; | |
1986c52b | 891 | for (size_t i = 0; i < 18; i++) { |
892 | shift_clk[i] = 0; | |
893 | sample_clk[i] = 0; | |
894 | strip_low[i] = 0; | |
895 | strip_high[i] = 0; | |
896 | pulse_size[i] = 0; | |
897 | pulse_length[i] = 0; | |
898 | } | |
b995fc28 | 899 | AliFMDParameters* param = AliFMDParameters::Instance(); |
900 | AliFMDAltroMapping* map = param->GetAltroMap(); | |
3effc6e7 | 901 | |
86878381 | 902 | AliAltroRawStreamV3 streamer(fReader); |
903 | streamer.Reset(); | |
904 | streamer.SelectRawData("FMD"); | |
905 | //fReader->GetDDLID(); | |
86878381 | 906 | while (streamer.NextDDL()) { |
907 | Int_t ddl = streamer.GetDDLNumber(); | |
908 | Int_t detID = fReader->GetDetectorID(); | |
909 | if (detectors) detectors[map->DDL2Detector(ddl)-1] = kTRUE; | |
ca20eb4a | 910 | AliDebugF(0," From reader: DDL number is %d , det ID is %d",ddl,detID); |
133f1578 | 911 | |
86878381 | 912 | ULong_t nPayloadWords = streamer.GetRCUPayloadSizeInSOD(); |
913 | UChar_t* payloadData = streamer.GetRCUPayloadInSOD(); | |
914 | UInt_t* payloadWords = reinterpret_cast<UInt_t*>(payloadData); | |
915 | //UInt_t* payloadWords = streamer.GetRCUPayloadInSOD(); | |
916 | ||
a0354a2a | 917 | //std::cout<<nPayloadWords<<" "<<ddl<<std::endl; |
86878381 | 918 | for (ULong_t i = 1; i <= nPayloadWords ; i++, payloadWords++) { |
919 | UInt_t payloadWord = *payloadWords; // Get32bitWord(i); | |
3effc6e7 | 920 | |
a0354a2a | 921 | //std::cout<<i<<Form(" word: 0x%x",payloadWord)<<std::endl; |
f38b1653 | 922 | // address is only 24 bit |
923 | UInt_t address = (0xffffff & payloadWord); | |
924 | UInt_t type = ((address >> 21) & 0xf); | |
925 | UInt_t error = ((address >> 20) & 0x1); | |
926 | UInt_t bcast = ((address >> 18) & 0x1); | |
927 | UInt_t bc_not_altro = ((address >> 17) & 0x1); | |
928 | UInt_t board = ((address >> 12) & 0x1f); | |
929 | UInt_t instruction = 0; | |
930 | UInt_t chip = 0; | |
931 | UInt_t channel = 0; | |
932 | if(bc_not_altro) | |
933 | instruction = address & 0xfff; | |
934 | else { | |
935 | chip = ((address >> 9) & 0x7); | |
936 | channel = ((address >> 5) & 0x5); | |
937 | instruction = (address & 0x1f); | |
938 | } | |
76d06ffa | 939 | |
f38b1653 | 940 | Bool_t readDataWord = kFALSE; |
941 | switch(type) { | |
942 | case 0x0: // Fec read | |
943 | readDataWord = kTRUE; | |
944 | case 0x1: // Fec cmd | |
945 | case 0x2: // Fec write | |
86878381 | 946 | i++; |
947 | payloadWords++; | |
f38b1653 | 948 | break; |
949 | case 0x4: // Loop | |
950 | case 0x5: // Wait | |
951 | break; | |
952 | case 0x6: // End sequence | |
953 | case 0x7: // End Mem | |
86878381 | 954 | i = nPayloadWords + 1; |
f38b1653 | 955 | break; |
956 | default: | |
957 | break; | |
958 | } | |
76d06ffa | 959 | |
f38b1653 | 960 | //Don't read unless we have a FEC_RD |
961 | if(!readDataWord) continue; | |
962 | ||
86878381 | 963 | UInt_t dataWord = *payloadWords;//Get32bitWord(i); |
f38b1653 | 964 | UInt_t data = (0xFFFFF & dataWord) ; |
965 | //UInt_t data = (0xFFFF & dataWord) ; | |
3effc6e7 | 966 | |
f38b1653 | 967 | if(error) { |
ca20eb4a | 968 | AliWarningF("error bit detected at Word 0x%06x; " |
969 | "error % d, type %d, bc_not_altro %d, " | |
970 | "bcast %d, board 0x%02x, chip 0x%x, " | |
971 | "channel 0x%02x, instruction 0x%03x", | |
972 | address, error, type, bc_not_altro, | |
973 | bcast,board,chip,channel,instruction); | |
f38b1653 | 974 | //process error |
975 | continue; | |
976 | } | |
3effc6e7 | 977 | |
978 | ||
f38b1653 | 979 | switch(instruction) { |
3effc6e7 | 980 | |
f38b1653 | 981 | case 0x01: break; // First ADC T |
982 | case 0x02: break; // I 3.3 V | |
983 | case 0x03: break; // I 2.5 V altro digital | |
984 | case 0x04: break; // I 2.5 V altro analog | |
985 | case 0x05: break; // I 2.5 V VA | |
986 | case 0x06: break; // First ADC T | |
987 | case 0x07: break; // I 3.3 V | |
988 | case 0x08: break; // I 2.5 V altro digital | |
989 | case 0x09: break; // I 2.5 V altro analog | |
990 | case 0x0A: break; // I 2.5 V VA | |
991 | case 0x2D: break; // Second ADC T | |
992 | case 0x2E: break; // I 1.5 V VA | |
993 | case 0x2F: break; // I -2.0 V | |
994 | case 0x30: break; // I -2.0 V VA | |
995 | case 0x31: break; // 2.5 V Digital driver | |
996 | case 0x32: break; // Second ADC T | |
997 | case 0x33: break; // I 1.5 V VA | |
998 | case 0x34: break; // I -2.0 V | |
999 | case 0x35: break; // I -2.0 V VA | |
1000 | case 0x36: break; // 2.5 V Digital driver | |
1001 | case 0x37: break; // Third ADC T | |
1002 | case 0x38: break; // Temperature sens. 1 | |
1003 | case 0x39: break; // Temperature sens. 2 | |
1004 | case 0x3A: break; // U 2.5 altro digital (m) | |
1005 | case 0x3B: break; // U 2.5 altro analog (m) | |
1006 | case 0x3C: break; // Third ADC T | |
1007 | case 0x3D: break; // Temperature sens. 1 | |
1008 | case 0x3E: break; // Temperature sens. 2 | |
1009 | case 0x3F: break; // U 2.5 altro digital (m) | |
1010 | case 0x40: break; // U 2.5 altro analog (m) | |
1011 | case 0x41: break; // Forth ADC T | |
1012 | case 0x42: break; // U 2.5 VA (m) | |
1013 | case 0x43: break; // U 1.5 VA (m) | |
1014 | case 0x44: break; // U -2.0 VA (m) | |
1015 | case 0x45: break; // U -2.0 (m) | |
1016 | case 0x46: break; // Forth ADC T | |
1017 | case 0x47: break; // U 2.5 VA (m) | |
1018 | case 0x48: break; // U 1.5 VA (m) | |
1019 | case 0x49: break; // U -2.0 VA (m) | |
1020 | case 0x4A: break; // U -2.0 (m) | |
1021 | // Counters | |
1022 | case 0x0B: break; // L1 trigger CouNTer | |
1023 | case 0x0C: break; // L2 trigger CouNTer | |
1024 | case 0x0D: break; // Sampling CLK CouNTer | |
1025 | case 0x0E: break; // DSTB CouNTer | |
1026 | // Test mode | |
1027 | case 0x0F: break; // Test mode word | |
1028 | case 0x10: break; // Undersampling ratio. | |
1029 | // Configuration and status | |
1030 | case 0x11: break; // Config/Status Register 0 | |
1031 | case 0x12: break; // Config/Status Register 1 | |
1032 | case 0x13: break; // Config/Status Register 2 | |
1033 | case 0x14: break; // Config/Status Register 3 | |
1034 | case 0x15: break; // Free | |
1035 | // Comands: | |
1036 | case 0x16: break; // Latch L1, L2, SCLK Counters | |
1037 | case 0x17: break; // Clear counters | |
1038 | case 0x18: break; // Clear CSR1 | |
1039 | case 0x19: break; // rstb ALTROs | |
1040 | case 0x1A: break; // rstb BC | |
1041 | case 0x1B: break; // Start conversion | |
1042 | case 0x1C: break; // Scan event length | |
1043 | case 0x1D: break; // Read event length | |
1044 | case 0x1E: break; // Start test mode | |
1045 | case 0x1F: break; // Read acquisition memory | |
1046 | // FMD | |
1047 | case 0x20: break; // FMDD status | |
1048 | case 0x21: break; // L0 counters | |
1049 | case 0x22: break; // FMD: Wait to hold | |
1050 | case 0x23: break; // FMD: L1 timeout | |
1051 | case 0x24: break; // FMD: L2 timeout | |
1052 | case 0x25: // FMD: Shift clk | |
1053 | shift_clk[board] = ((data >> 8 ) & 0xFF); | |
ca20eb4a | 1054 | AliDebugF(30, "Read shift_clk=%d for board 0x%02x", |
1055 | shift_clk[board], board); | |
f38b1653 | 1056 | break; |
1057 | case 0x26: // FMD: Strips | |
1058 | strip_low[board] = ((data >> 0 ) & 0xFF); | |
1059 | strip_high[board] = ((data >> 8 ) & 0xFF); | |
1060 | break; | |
1061 | case 0x27: // FMD: Cal pulse | |
1062 | pulse_size[board] = ((data >> 8 ) & 0xFF); | |
1063 | break; | |
1064 | case 0x28: break; // FMD: Shape bias | |
1065 | case 0x29: break; // FMD: Shape ref | |
1066 | case 0x2A: break; // FMD: Preamp ref | |
1067 | case 0x2B: // FMD: Sample clk | |
1068 | sample_clk[board] = ((data >> 8 ) & 0xFF); | |
ca20eb4a | 1069 | AliDebugF(30,"Read sample_clk=%d for board 0x%02x", |
1070 | sample_clk[board], board); | |
f38b1653 | 1071 | break; |
1072 | case 0x2C: break; // FMD: Commands | |
1073 | case 0x4B: // FMD: Cal events | |
1074 | pulse_length[board] = ((data >> 0 ) & 0xFF); | |
1075 | break; | |
1076 | default: break; | |
3effc6e7 | 1077 | |
f38b1653 | 1078 | } |
ca20eb4a | 1079 | AliDebugF(50,"instruction 0x%x, dataword 0x%x", |
1080 | instruction,dataWord); | |
86878381 | 1081 | } // End of loop over Result memory event |
3effc6e7 | 1082 | |
133f1578 | 1083 | UShort_t det = 0; |
1084 | UShort_t sector = 0; | |
1085 | Short_t strip = -1; | |
1086 | Char_t ring = '\0'; | |
76d06ffa | 1087 | |
3effc6e7 | 1088 | const UInt_t boards[4] = {0,1,16,17}; |
1089 | for(Int_t i=0;i<4;i++) { | |
f38b1653 | 1090 | if(ddl==0 && (i==1 || i==3)) continue; |
1091 | ||
3effc6e7 | 1092 | UInt_t chip =0, channel=0; |
b995fc28 | 1093 | det = map->DDL2Detector(ddl); |
1094 | map->Channel2StripBase(boards[i], chip, channel, ring, sector, strip); | |
76d06ffa | 1095 | |
1986c52b | 1096 | UInt_t samplerate = 0; |
1097 | #if USE_VOTE | |
76d06ffa | 1098 | if(sample_clk[boards[i]] == 0) { |
f38b1653 | 1099 | if(ddl == 0) { |
1100 | Int_t sample1 = sample_clk[boards[0]]; | |
1101 | Int_t sample2 = sample_clk[boards[2]]; | |
1102 | if(sample1) sample_clk[boards[i]] = sample1; | |
1103 | else sample_clk[boards[i]] = sample2; | |
1104 | } | |
1105 | else { | |
1106 | Int_t sample1 = sample_clk[boards[0]]; | |
1107 | Int_t sample2 = sample_clk[boards[1]]; | |
1108 | Int_t sample3 = sample_clk[boards[2]]; | |
1109 | Int_t sample4 = sample_clk[boards[3]]; | |
1110 | Int_t agreement = 0; | |
1111 | if(sample1 == sample2) agreement++; | |
1112 | if(sample1 == sample3) agreement++; | |
1113 | if(sample1 == sample4) agreement++; | |
1114 | if(sample2 == sample3) agreement++; | |
1115 | if(sample2 == sample4) agreement++; | |
1116 | if(sample3 == sample4) agreement++; | |
76d06ffa | 1117 | |
f38b1653 | 1118 | Int_t idx = 0; |
1119 | if(i<3) idx = i+1; | |
1120 | else idx = i-1; | |
1121 | if(agreement == 3) { | |
1122 | sample_clk[boards[i]] = sample_clk[boards[idx]]; | |
1123 | shift_clk[boards[i]] = shift_clk[boards[idx]]; | |
1124 | strip_low[boards[i]] = strip_low[boards[idx]]; | |
1125 | strip_high[boards[i]] = strip_high[boards[idx]]; | |
1126 | pulse_length[boards[i]] = pulse_length[boards[idx]]; | |
1127 | pulse_size[boards[i]] = pulse_size[boards[idx]]; | |
ca20eb4a | 1128 | AliDebugF(3,"Vote taken for ddl %d, board 0x%x", |
1129 | ddl,boards[i]); | |
76d06ffa | 1130 | } |
f38b1653 | 1131 | } |
76d06ffa | 1132 | } |
1986c52b | 1133 | #endif |
76d06ffa | 1134 | |
3effc6e7 | 1135 | if(sample_clk[boards[i]]) |
f38b1653 | 1136 | samplerate = shift_clk[boards[i]]/sample_clk[boards[i]]; |
ca20eb4a | 1137 | AliDebugF(10,"Sample rate for board 0x%02x is %d", |
1138 | boards[i], samplerate); | |
3effc6e7 | 1139 | sampleRate->Set(det,ring,sector,0,samplerate); |
f38b1653 | 1140 | stripRange->Set(det,ring,sector,0, |
1141 | strip_low[boards[i]],strip_high[boards[i]]); | |
3effc6e7 | 1142 | |
ca20eb4a | 1143 | AliDebugF(20,"det %d, ring %c, ",det,ring); |
f38b1653 | 1144 | pulseLength.AddAt(pulse_length[boards[i]], |
1145 | GetHalfringIndex(det,ring,boards[i]/16)); | |
1146 | pulseSize.AddAt(pulse_size[boards[i]], | |
1147 | GetHalfringIndex(det,ring,boards[i]/16)); | |
76d06ffa | 1148 | |
3effc6e7 | 1149 | |
76d06ffa | 1150 | |
ca20eb4a | 1151 | AliDebugF(20,": Board: 0x%02x\n" |
1152 | "\tstrip_low %3d, strip_high %3d\n" | |
1153 | "\tshift_clk %3d, sample_clk %3d\n" | |
1154 | "\tpulse_size %3d, pulse_length %3d", | |
1155 | boards[i], | |
1156 | strip_low[boards[i]], strip_high[boards[i]], | |
1157 | shift_clk[boards[i]], sample_clk[boards[i]], | |
1158 | pulse_size[boards[i]],pulse_length[boards[i]]); | |
86878381 | 1159 | } |
1986c52b | 1160 | |
1161 | } | |
3effc6e7 | 1162 | |
1163 | AliFMDParameters::Instance()->SetSampleRate(sampleRate); | |
1164 | AliFMDParameters::Instance()->SetStripRange(stripRange); | |
1165 | ||
ca20eb4a | 1166 | AliDebug(0,"End of SOD/EOD"); |
3effc6e7 | 1167 | |
7af3df7f | 1168 | return kTRUE; |
3effc6e7 | 1169 | } |
1170 | //____________________________________________________________________ | |
1171 | ||
1172 | UInt_t AliFMDRawReader::Get32bitWord(Int_t idx) | |
1173 | { | |
1174 | // This method returns the 32 bit word at a given | |
1175 | // position inside the raw data payload. | |
1176 | // The 'index' points to the beginning of the next word. | |
1177 | // The method is supposed to be endian (platform) | |
1178 | // independent. | |
1179 | if (!fData) { | |
1180 | AliFatal("Raw data paylod buffer is not yet initialized !"); | |
1181 | } | |
1182 | ||
1183 | Int_t index = 4*idx; | |
1184 | ||
1185 | if (index < 4) { | |
1186 | // fRawReader->AddFatalErrorLog(k32bitWordReadErr,Form("pos = %d",index)); | |
1187 | // PrintDebug(); | |
ca20eb4a | 1188 | AliWarningF("Invalid raw data payload position (%d) !",index); |
3effc6e7 | 1189 | } |
1190 | ||
1191 | UInt_t word = 0; | |
76d06ffa | 1192 | |
3effc6e7 | 1193 | word = fData[--index] << 24; |
1194 | word |= fData[--index] << 16; | |
1195 | word |= fData[--index] << 8; | |
1196 | word |= fData[--index] << 0 ; | |
e802be3e | 1197 | |
3effc6e7 | 1198 | return word; |
1199 | } | |
1200 | //_____________________________________________________________________ | |
f38b1653 | 1201 | Int_t AliFMDRawReader::GetHalfringIndex(UShort_t det, Char_t ring, |
09b6c804 | 1202 | UShort_t board) const |
1203 | { | |
1204 | // | |
1205 | // Get short index for a given half-ring | |
1206 | // | |
1207 | // Parameters: | |
1208 | // det Detector number | |
1209 | // ring Ring identifer | |
1210 | // board Board number | |
1211 | // | |
1212 | // Return: | |
1213 | // | |
1214 | // | |
3effc6e7 | 1215 | UShort_t iring = (ring == 'I' ? 1 : 0); |
1216 | ||
1217 | Int_t index = (((det-1) << 2) | (iring << 1) | (board << 0)); | |
1218 | ||
76d06ffa | 1219 | return index-2; |
3effc6e7 | 1220 | |
1221 | } | |
e2c858f2 | 1222 | |
e802be3e | 1223 | //____________________________________________________________________ |
1224 | // | |
1225 | // EOF | |
1226 | // | |
6c652449 | 1227 |