bug fixed
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitMaker.cxx
CommitLineData
a3283a4c 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
3d1463c8 16// $Id$
17
18//-----------------------------------------------------------------------------
9265505b 19/// \class AliMUONDigitMaker
8c51a32f 20/// MUON Digit maker from rawdata.
a3283a4c 21///
22/// Raw2Digits:
23/// Using real mapping for tracker
24/// Indranil Das (Adapted for runloader: Ch. Finck) july 05
8c51a32f 25///
26/// Implemented non-constant buspatch numbers for tracking
27/// with correct DDL id.
28/// (Ch. Finck, dec 05)
29///
a3283a4c 30/// Add reader for scaler trigger events
31/// Use memcpy instead of assignment elt by elt
32/// (Ch. Finck, Jan 06)
8c51a32f 33///
34/// Using new interface with AliMUONRawStreamTracker(Trigger)
35/// (New interface of AliMUONRawReader class)
36/// (further details could be found in Alice-note)
37/// (Ch. Finck, March 06)
38///
39/// Add (S)Digit maker tracker (for free)
40/// and for trigger. Create trigger inverse mapping.
78649106 41///
42/// \author Ch. Finck, oct 06
3d1463c8 43//-----------------------------------------------------------------------------
a3283a4c 44
a3283a4c 45#include "AliMUONDigitMaker.h"
a3283a4c 46
a3283a4c 47#include "AliMUONDDLTrigger.h"
48#include "AliMUONDarcHeader.h"
40e382ae 49#include "AliMUONVDigit.h"
50#include "AliMUONVDigitStore.h"
51#include "AliMUONGlobalTrigger.h"
a3283a4c 52#include "AliMUONLocalStruct.h"
a3283a4c 53#include "AliMUONLocalTrigger.h"
0145e89a 54#include "AliMUONLogger.h"
e3a2b9c9 55#include "AliMUONRawStreamTrackerHP.h"
481d8064 56#include "AliMUONRawStreamTriggerHP.h"
40e382ae 57#include "AliMUONRegHeader.h"
be63c782 58#include "AliMUONVTriggerStore.h"
7ead8580 59#include "AliMpCDB.h"
be63c782 60#include "AliMpDetElement.h"
d9b1ecb0 61#include "AliMpTriggerCrate.h"
62#include "AliMpLocalBoard.h"
40e382ae 63#include "AliMpCathodType.h"
64#include "AliMpDDLStore.h"
65#include "AliMpDEManager.h"
66#include "AliMpPad.h"
9265505b 67#include "AliMpSegmentation.h"
a3283a4c 68#include "AliMpVSegmentation.h"
be63c782 69#include "AliCodeTimer.h"
70#include "AliLog.h"
9265505b 71#include "AliRawReader.h"
7771752e 72#include <TArrayS.h>
9265505b 73
9265505b 74/// \cond CLASSIMP
a3283a4c 75ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
9265505b 76/// \endcond
77
a3283a4c 78//__________________________________________________________________________
b6f591ae 79AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger, Bool_t a, Bool_t b) :
80TObject(),
81fScalerEvent(kFALSE),
82fMakeTriggerDigits(kFALSE),
83fRawStreamTracker(new AliMUONRawStreamTrackerHP),
84fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
85fDigitStore(0x0),
86fTriggerStore(0x0),
9074a9a9 87fLogger(new AliMUONLogger(10000)){
b6f591ae 88 /// ctor
89
90 if ( !a || !b ) AliFatal("no longer supported");
91
92 AliDebug(1,"");
93
94 // Standard Constructor
95 if (enableErrorLogger)
96 {
97 fRawStreamTracker->EnabbleErrorLogger();
98 fRawStreamTrigger->EnabbleErrorLogger();
99 }
100 else
101 {
102 fRawStreamTracker->DisableWarnings();
103 }
104
105 SetMakeTriggerDigits();
106
7ead8580 107 // Load mapping
108 if ( ! AliMpCDB::LoadDDLStore() ) {
109 AliFatal("Could not access mapping from OCDB !");
110 }
b6f591ae 111}
112
113//__________________________________________________________________________
114AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger) :
115TObject(),
9f5dcca3 116 fScalerEvent(kFALSE),
40e382ae 117 fMakeTriggerDigits(kFALSE),
b6f591ae 118 fRawStreamTracker(new AliMUONRawStreamTrackerHP),
119 fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
40e382ae 120 fDigitStore(0x0),
0145e89a 121 fTriggerStore(0x0),
122 fLogger(new AliMUONLogger(10000))
a3283a4c 123{
40e382ae 124 /// ctor
a3283a4c 125
126 AliDebug(1,"");
e3a2b9c9 127
a3283a4c 128 // Standard Constructor
b6f591ae 129 if (enableErrorLogger)
130 {
3c7f5307 131 fRawStreamTracker->EnabbleErrorLogger();
132 fRawStreamTrigger->EnabbleErrorLogger();
133 }
b6f591ae 134 else
135 {
136 fRawStreamTracker->DisableWarnings();
137 }
a3283a4c 138
40e382ae 139 SetMakeTriggerDigits();
a3283a4c 140
7ead8580 141 // Load mapping
142 if ( ! AliMpCDB::LoadDDLStore() ) {
143 AliFatal("Could not access mapping from OCDB !");
144 }
a3283a4c 145}
146
147//__________________________________________________________________________
9f5dcca3 148AliMUONDigitMaker::~AliMUONDigitMaker()
a3283a4c 149{
9265505b 150 /// clean up
151 /// and time processing measure
152
a3283a4c 153 delete fRawStreamTracker;
154 delete fRawStreamTrigger;
0145e89a 155 delete fLogger;
a3283a4c 156}
157
158//____________________________________________________________________
be63c782 159void
160AliMUONDigitMaker::Print(Option_t*) const
161{
162 /// Printout
163
164 cout << "RawStreamerTracker class=" << fRawStreamTracker->ClassName()
165 << " MakeTriggerDigits=" << fMakeTriggerDigits
166 << " ScalerEvent=" << fScalerEvent
167 << " DigitStore=" << fDigitStore
168 << " TriggerStore=" << fTriggerStore << endl;
169
170 if ( fLogger ) fLogger->Print();
171}
172
173//____________________________________________________________________
174Int_t
175AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader,
176 AliMUONVDigitStore* digitStore,
177 AliMUONVTriggerStore* triggerStore)
a3283a4c 178{
9265505b 179 /// Main method to creates digit
180 /// for tracker
181 /// and trigger
a3283a4c 182
40e382ae 183 AliDebug(1,Form("rawReader=%p digitStore=%p triggerStore=%p",
184 rawReader,digitStore,triggerStore));
185
186 fDigitStore = digitStore;
187 fTriggerStore = triggerStore;
188
189 if (!fDigitStore && !fTriggerStore)
190 {
0145e89a 191 fLogger->Log("No digit or trigger store given. Nothing to do...");
be63c782 192 return kTriggerBAD & kTrackerBAD;
40e382ae 193 }
194
be63c782 195 Int_t tracker(kOK);
196 Int_t trigger(kOK);
197
40e382ae 198 if ( fDigitStore )
199 {
200 fDigitStore->Clear(); // insure we start with an empty container
be63c782 201 tracker = ReadTrackerDDL(rawReader);
40e382ae 202 }
203
204 if ( fTriggerStore || fMakeTriggerDigits )
205 {
206 if ( fTriggerStore ) fTriggerStore->Clear();
207 if ( fMakeTriggerDigits && !fDigitStore )
208 {
0145e89a 209 fLogger->Log("Asking for trigger digits but digitStore is null");
40e382ae 210 }
211 else
212 {
be63c782 213 trigger = ReadTriggerDDL(rawReader);
40e382ae 214 }
215 }
216
be63c782 217 return tracker | trigger;
a3283a4c 218}
219
220//____________________________________________________________________
be63c782 221Int_t
222AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
a3283a4c 223{
40e382ae 224 /// Reading tracker DDL
225 /// filling the fDigitStore container, which must not be null
a3283a4c 226
40e382ae 227 AliDebug(1,"");
228
99c136e1 229 AliCodeTimerAuto("",0);
a3283a4c 230
231 // elex info
232 Int_t buspatchId;
233 UChar_t channelId;
234 UShort_t manuId;
a3283a4c 235 UShort_t charge;
a3283a4c 236
a3283a4c 237 fRawStreamTracker->SetReader(rawReader);
1bc885f3 238 fRawStreamTracker->First();
239
b6f591ae 240 while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge,kTRUE) )
1bc885f3 241 {
40e382ae 242 // getting DE from buspatch
243 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
a3283a4c 244
be63c782 245 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
246
247 if (!de)
248 {
1130977f 249 fLogger->Log(Form("DE %04d does not exist !", detElemId));
be63c782 250 continue;
251 }
252
253 if (!de->IsConnectedChannel(manuId,channelId))
254 {
255 // non connected pad, do nothing (this is not an error !)
256 continue;
257 }
258
40e382ae 259 const AliMpVSegmentation* seg
260 = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,
261 manuId);
a3283a4c 262
0145e89a 263 if (!seg)
264 {
265 fLogger->Log(Form("(DE,MANUID)=(%04d,%04d) is not valid",detElemId,manuId));
266 continue;
267 }
268
be63c782 269 AliMp::CathodType cathodeType = de->GetCathodType(seg->PlaneType());
1bc885f3 270
168e9c4d 271 AliMpPad pad = seg->PadByLocation(manuId,channelId,kFALSE);
be63c782 272
40e382ae 273 if (!pad.IsValid())
274 {
0145e89a 275 fLogger->Log(Form("No pad for detElemId: %d, manuId: %d, channelId: %d",
40e382ae 276 detElemId, manuId, channelId));
277 continue;
278 }
be63c782 279
40e382ae 280 AliMUONVDigit* digit = fDigitStore->Add(detElemId,manuId,channelId,cathodeType,
281 AliMUONVDigitStore::kDeny);
be63c782 282
40e382ae 283 if (!digit)
284 {
0145e89a 285 fLogger->Log(Form("Digit DE %04d Manu %04d Channel %02d could not be added",
40e382ae 286 detElemId, manuId, channelId));
287 continue;
288 }
289
168e9c4d 290 digit->SetPadXY(pad.GetIx(),pad.GetIy());
40e382ae 291
168e9c4d 292 digit->SetADC(charge);
9265505b 293
40e382ae 294 }
a3283a4c 295
be63c782 296 if ( fRawStreamTracker->IsErrorMessage() )
297 {
298 return kTrackerBAD;
299 }
300
301 return kOK;
a3283a4c 302}
303
304//____________________________________________________________________
be63c782 305Int_t
306AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
a3283a4c 307{
481d8064 308 /// reading tracker DDL like ReadTriggerDDL but with fast decoder interface.
309 /// filling the fTriggerStore container, which must not be null
310
311 const AliMUONRawStreamTriggerHP::AliHeader* darcHeader = 0x0;
312 const AliMUONRawStreamTriggerHP::AliRegionalHeader* regHeader = 0x0;
313 const AliMUONRawStreamTriggerHP::AliLocalStruct* localStruct = 0x0;
314
315 Int_t loCircuit;
316
317 fRawStreamTrigger->SetReader(rawReader);
481d8064 318
319 while (fRawStreamTrigger->NextDDL())
320 {
818aff28 321 darcHeader = fRawStreamTrigger->GetHeaders();
481d8064 322
323 // fill global trigger information
324 if (fTriggerStore)
325 {
326 if (darcHeader->GetGlobalFlag())
327 {
328 AliMUONGlobalTrigger globalTrigger;
329 globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
a90f8830 330 globalTrigger.SetFromGlobalInput(darcHeader->GetGlobalHeader()->fInput);
481d8064 331 fTriggerStore->SetGlobal(globalTrigger);
332 }
333 }
334
818aff28 335 Int_t nReg = fRawStreamTrigger->GetRegionalHeaderCount();
481d8064 336
337 for(Int_t iReg = 0; iReg < nReg ;iReg++)
338 { //reg loop
339
340
341 // crate info
342 AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
343 GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
344
9481a918 345 if (!crate) {
481d8064 346 fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
9481a918 347 continue;
348 }
481d8064 349
818aff28 350 regHeader = fRawStreamTrigger->GetRegionalHeader(iReg);
481d8064 351
352 Int_t nLocal = regHeader->GetLocalStructCount();
353 for(Int_t iLocal = 0; iLocal < nLocal; iLocal++)
354 {
355
356 localStruct = regHeader->GetLocalStruct(iLocal);
357
358 // if card exist
359 if (localStruct) {
360
361 loCircuit = crate->GetLocalBoardId(localStruct->GetId());
362
363 if ( !loCircuit ) continue; // empty slot
364
1ffbeb9d 365 AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, kTRUE);
481d8064 366
367 // skip copy cards
368 if( !localBoard->IsNotified())
369 continue;
370
371 if (fTriggerStore)
372 {
373 // fill local trigger
374 AliMUONLocalTrigger localTrigger;
a026ce9e 375 localTrigger.SetLocalStruct(loCircuit, *localStruct);
481d8064 376 fTriggerStore->Add(localTrigger);
377 }
378
379 if ( fMakeTriggerDigits )
380 {
381 //FIXEME should find something better than a TArray
382 TArrayS xyPattern[2];
383
384 localStruct->GetXPattern(xyPattern[0]);
385 localStruct->GetYPattern(xyPattern[1]);
386
387 TriggerDigits(loCircuit, xyPattern, *fDigitStore);
388 }
389 } // if triggerY
390 } // iLocal
391 } // iReg
392 } // NextDDL
393
394 return kOK;
395}
396
397//____________________________________________________________________
7771752e 398Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard,
57e2ad1a 399 const TArrayS* xyPattern,
40e382ae 400 AliMUONVDigitStore& digitStore) const
d2d759cf 401{
40e382ae 402 /// make digits for trigger from pattern, and add them to digitStore
d2d759cf 403
99c136e1 404 AliCodeTimerAuto("",0);
0145e89a 405
d9b1ecb0 406 Int_t detElemId;
407
408 AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
409
8c0b5e70 410 Int_t n,b;
411
d2d759cf 412 // loop over x1-4 and y1-4
40e382ae 413 for (Int_t iChamber = 0; iChamber < 4; ++iChamber)
414 {
415 for (Int_t iCath = 0; iCath < 2; ++iCath)
416 {
7771752e 417 Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber);
418 if (!pattern) continue;
40e382ae 419
7771752e 420 // get detElemId
d9b1ecb0 421 detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(nBoard, iChamber);
40e382ae 422
423 const AliMpVSegmentation* seg
424 = AliMpSegmentation::Instance()
425 ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));
426
427 // loop over the 16 bits of pattern
428 for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy)
429 {
430 if ((pattern >> ibitxy) & 0x1)
431 {
432 // not quite sure about this
433 Int_t offset = 0;
dc5d3949 434 if (iCath && localBoard->GetSwitch(AliMpLocalBoard::kZeroAllYLSB)) offset = -8;
40e382ae 435
168e9c4d 436 AliMpPad pad = seg->PadByLocation(nBoard,ibitxy+offset,kTRUE);
40e382ae 437
438 if (!pad.IsValid())
439 {
0145e89a 440 fLogger->Log(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
40e382ae 441 detElemId, nBoard, ibitxy));
442 continue;
443 }
8c0b5e70 444
168e9c4d 445 n = pad.GetLocalBoardId(0); // always take first location so that digits are not inserted several times
446 b = pad.GetLocalBoardChannel(0);
8c0b5e70 447
448 AliDebug(1,Form("Using localBoard %d ixy %d instead of %d,%d",
449 n,b,nBoard,ibitxy));
450
451 AliMUONVDigit* digit = digitStore.Add(detElemId,n,b,iCath,AliMUONVDigitStore::kDeny);
40e382ae 452
453 if (!digit)
454 {
8c0b5e70 455 AliDebug(1, Form("Digit DE %04d LocalBoard %03d ibitxy %02d cath %d already in store",
456 detElemId,nBoard,ibitxy,iCath));
457 continue;
40e382ae 458 }
459
168e9c4d 460 Int_t padX = pad.GetIx();
461 Int_t padY = pad.GetIy();
40e382ae 462
463 // fill digit
464 digit->SetPadXY(padX,padY);
465 digit->SetCharge(1.);
466 }// xyPattern
467 }// ibitxy
7771752e 468 }// cath
469 } // ichamber
40e382ae 470
d2d759cf 471 return kTRUE;
481d8064 472}
d61f56df 473
54355f2c 474//______________________________________________________________________________
475Bool_t
476AliMUONDigitMaker::TriggerToDigitsStore(const AliMUONVTriggerStore& triggerStore,
477 AliMUONVDigitStore& digitStore) const
478{
479 //
480 /// make (S)Digit for trigger
481 //
482
483 digitStore.Clear();
484
485 AliMUONLocalTrigger* locTrg;
486 TIter next(triggerStore.CreateLocalIterator());
487
488 while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) )
489 {
490 if (locTrg->IsNull()) continue;
491
492 TArrayS xyPattern[2];
493 locTrg->GetXPattern(xyPattern[0]);
494 locTrg->GetYPattern(xyPattern[1]);
495
496 Int_t nBoard = locTrg->LoCircuit();
497 TriggerDigits(nBoard, xyPattern, digitStore);
498 }
499 return kTRUE;
500}
9074a9a9 501
502//______________________________________________________________________________
503void
504AliMUONDigitMaker::SetTryRecover(Bool_t flag)
505{
506 /// Instruct the decoder to try to recover corrupted raw data.
507 /// Only use for specific cases for which you know it will work...
508 fRawStreamTracker->TryRecover(flag);
509}