]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - MUON/AliMUONDigitMaker.cxx
Changes for #93172: Improve trigger chamber efficiency calculation
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitMaker.cxx
... / ...
CommitLineData
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
16// $Id$
17
18//-----------------------------------------------------------------------------
19/// \class AliMUONDigitMaker
20/// MUON Digit maker from rawdata.
21///
22/// Raw2Digits:
23/// Using real mapping for tracker
24/// Indranil Das (Adapted for runloader: Ch. Finck) july 05
25///
26/// Implemented non-constant buspatch numbers for tracking
27/// with correct DDL id.
28/// (Ch. Finck, dec 05)
29///
30/// Add reader for scaler trigger events
31/// Use memcpy instead of assignment elt by elt
32/// (Ch. Finck, Jan 06)
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.
41///
42/// \author Ch. Finck, oct 06
43//-----------------------------------------------------------------------------
44
45#include "AliMUONDigitMaker.h"
46
47#include "AliMUONDDLTrigger.h"
48#include "AliMUONDarcHeader.h"
49#include "AliMUONVDigit.h"
50#include "AliMUONVDigitStore.h"
51#include "AliMUONGlobalTrigger.h"
52#include "AliMUONLocalStruct.h"
53#include "AliMUONLocalTrigger.h"
54#include "AliMUONLogger.h"
55#include "AliMUONRawStreamTrackerHP.h"
56#include "AliMUONRawStreamTriggerHP.h"
57#include "AliMUONRegHeader.h"
58#include "AliMUONVTriggerStore.h"
59#include "AliMpCDB.h"
60#include "AliMpDetElement.h"
61#include "AliMpTriggerCrate.h"
62#include "AliMpLocalBoard.h"
63#include "AliMpCathodType.h"
64#include "AliMpDDLStore.h"
65#include "AliMpDEManager.h"
66#include "AliMpPad.h"
67#include "AliMpSegmentation.h"
68#include "AliMpVSegmentation.h"
69#include "AliCodeTimer.h"
70#include "AliLog.h"
71#include "AliRawReader.h"
72#include <TArrayS.h>
73
74/// \cond CLASSIMP
75ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
76/// \endcond
77
78//__________________________________________________________________________
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),
87fLogger(new AliMUONLogger(10000)){
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
107 // Load mapping
108 if ( ! AliMpCDB::LoadDDLStore() ) {
109 AliFatal("Could not access mapping from OCDB !");
110 }
111}
112
113//__________________________________________________________________________
114AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger) :
115TObject(),
116 fScalerEvent(kFALSE),
117 fMakeTriggerDigits(kFALSE),
118 fRawStreamTracker(new AliMUONRawStreamTrackerHP),
119 fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
120 fDigitStore(0x0),
121 fTriggerStore(0x0),
122 fLogger(new AliMUONLogger(10000))
123{
124 /// ctor
125
126 AliDebug(1,"");
127
128 // Standard Constructor
129 if (enableErrorLogger)
130 {
131 fRawStreamTracker->EnabbleErrorLogger();
132 fRawStreamTrigger->EnabbleErrorLogger();
133 }
134 else
135 {
136 fRawStreamTracker->DisableWarnings();
137 }
138
139 SetMakeTriggerDigits();
140
141 // Load mapping
142 if ( ! AliMpCDB::LoadDDLStore() ) {
143 AliFatal("Could not access mapping from OCDB !");
144 }
145}
146
147//__________________________________________________________________________
148AliMUONDigitMaker::~AliMUONDigitMaker()
149{
150 /// clean up
151 /// and time processing measure
152
153 delete fRawStreamTracker;
154 delete fRawStreamTrigger;
155 delete fLogger;
156}
157
158//____________________________________________________________________
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)
178{
179 /// Main method to creates digit
180 /// for tracker
181 /// and trigger
182
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 {
191 fLogger->Log("No digit or trigger store given. Nothing to do...");
192 return kTriggerBAD & kTrackerBAD;
193 }
194
195 Int_t tracker(kOK);
196 Int_t trigger(kOK);
197
198 if ( fDigitStore )
199 {
200 fDigitStore->Clear(); // insure we start with an empty container
201 tracker = ReadTrackerDDL(rawReader);
202 }
203
204 if ( fTriggerStore || fMakeTriggerDigits )
205 {
206 if ( fTriggerStore ) fTriggerStore->Clear();
207 if ( fMakeTriggerDigits && !fDigitStore )
208 {
209 fLogger->Log("Asking for trigger digits but digitStore is null");
210 }
211 else
212 {
213 trigger = ReadTriggerDDL(rawReader);
214 }
215 }
216
217 return tracker | trigger;
218}
219
220//____________________________________________________________________
221Int_t
222AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
223{
224 /// Reading tracker DDL
225 /// filling the fDigitStore container, which must not be null
226
227 AliDebug(1,"");
228
229 AliCodeTimerAuto("",0);
230
231 // elex info
232 Int_t buspatchId;
233 UChar_t channelId;
234 UShort_t manuId;
235 UShort_t charge;
236
237 fRawStreamTracker->SetReader(rawReader);
238 fRawStreamTracker->First();
239
240 while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge,kTRUE) )
241 {
242 // getting DE from buspatch
243 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
244
245 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
246
247 if (!de)
248 {
249 fLogger->Log(Form("DE %04d does not exist !", detElemId));
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
259 const AliMpVSegmentation* seg
260 = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,
261 manuId);
262
263 if (!seg)
264 {
265 fLogger->Log(Form("(DE,MANUID)=(%04d,%04d) is not valid",detElemId,manuId));
266 continue;
267 }
268
269 AliMp::CathodType cathodeType = de->GetCathodType(seg->PlaneType());
270
271 AliMpPad pad = seg->PadByLocation(manuId,channelId,kFALSE);
272
273 if (!pad.IsValid())
274 {
275 fLogger->Log(Form("No pad for detElemId: %d, manuId: %d, channelId: %d",
276 detElemId, manuId, channelId));
277 continue;
278 }
279
280 AliMUONVDigit* digit = fDigitStore->Add(detElemId,manuId,channelId,cathodeType,
281 AliMUONVDigitStore::kDeny);
282
283 if (!digit)
284 {
285 fLogger->Log(Form("Digit DE %04d Manu %04d Channel %02d could not be added",
286 detElemId, manuId, channelId));
287 continue;
288 }
289
290 digit->SetPadXY(pad.GetIx(),pad.GetIy());
291
292 digit->SetADC(charge);
293
294 }
295
296 if ( fRawStreamTracker->IsErrorMessage() )
297 {
298 return kTrackerBAD;
299 }
300
301 return kOK;
302}
303
304//____________________________________________________________________
305Int_t
306AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
307{
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);
318
319 while (fRawStreamTrigger->NextDDL())
320 {
321 darcHeader = fRawStreamTrigger->GetHeaders();
322
323 // fill global trigger information
324 if (fTriggerStore)
325 {
326 if (darcHeader->GetGlobalFlag())
327 {
328 AliMUONGlobalTrigger globalTrigger;
329 globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
330 globalTrigger.SetFromGlobalInput(darcHeader->GetGlobalHeader()->fInput);
331 fTriggerStore->SetGlobal(globalTrigger);
332 }
333 }
334
335 Int_t nReg = fRawStreamTrigger->GetRegionalHeaderCount();
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
345 if (!crate) {
346 fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
347 continue;
348 }
349
350 regHeader = fRawStreamTrigger->GetRegionalHeader(iReg);
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
365 AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, kTRUE);
366
367 // skip copy cards
368 if( !localBoard->IsNotified())
369 continue;
370
371 if (fTriggerStore)
372 {
373 // fill local trigger
374 AliMUONLocalTrigger localTrigger;
375 localTrigger.SetLocalStruct(loCircuit, *localStruct);
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//____________________________________________________________________
398Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard,
399 const TArrayS* xyPattern,
400 AliMUONVDigitStore& digitStore, Bool_t warn) const
401{
402 /// make digits for trigger from pattern, and add them to digitStore
403
404 AliCodeTimerAuto("",0);
405
406 Int_t detElemId;
407
408 AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
409
410 Int_t n,b;
411
412 // loop over x1-4 and y1-4
413 for (Int_t iChamber = 0; iChamber < 4; ++iChamber)
414 {
415 for (Int_t iCath = 0; iCath < 2; ++iCath)
416 {
417 Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber);
418 if (!pattern) continue;
419
420 // get detElemId
421 detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(nBoard, iChamber);
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;
434 if (iCath && localBoard->GetSwitch(AliMpLocalBoard::kZeroAllYLSB)) offset = -8;
435
436 AliMpPad pad = seg->PadByLocation(nBoard,ibitxy+offset,warn);
437
438 if (!pad.IsValid())
439 {
440 fLogger->Log(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
441 detElemId, nBoard, ibitxy));
442 continue;
443 }
444
445 n = pad.GetLocalBoardId(0); // always take first location so that digits are not inserted several times
446 b = pad.GetLocalBoardChannel(0);
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);
452
453 if (!digit)
454 {
455 AliDebug(1, Form("Digit DE %04d LocalBoard %03d ibitxy %02d cath %d already in store",
456 detElemId,nBoard,ibitxy,iCath));
457 continue;
458 }
459
460 Int_t padX = pad.GetIx();
461 Int_t padY = pad.GetIy();
462
463 // fill digit
464 digit->SetPadXY(padX,padY);
465 digit->SetCharge(1.);
466 }// xyPattern
467 }// ibitxy
468 }// cath
469 } // ichamber
470
471 return kTRUE;
472}
473
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}
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}