]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDRawReader.cxx
More Next50 classes
[u/mrichter/AliRoot.git] / FMD / AliFMDRawReader.cxx
CommitLineData
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 73ClassImp(AliFMDRawReader)
1a1fdef7 74#if 0
75 ; // This is here to keep Emacs for indenting the next line
76#endif
e802be3e 77
78//____________________________________________________________________
1a1fdef7 79AliFMDRawReader::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//____________________________________________________________________
106void
107AliFMDRawReader::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//____________________________________________________________________
126void
127AliFMDRawReader::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//____________________________________________________________________
134void
135AliFMDRawReader::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//____________________________________________________________________
161Int_t
162AliFMDRawReader::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//____________________________________________________________________
294Int_t
09b6c804 295AliFMDRawReader::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//____________________________________________________________________
347Bool_t
348AliFMDRawReader::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//____________________________________________________________________
386Int_t
09b6c804 387AliFMDRawReader::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 445Int_t
faf80567 446AliFMDRawReader::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 595Int_t
faf80567 596AliFMDRawReader::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//____________________________________________________________________
630Bool_t
631AliFMDRawReader::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//____________________________________________________________________
647Bool_t
648AliFMDRawReader::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//____________________________________________________________________
783Bool_t
784AliFMDRawReader::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//____________________________________________________________________
865Bool_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
1172UInt_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 1201Int_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