]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONDigitMaker.cxx
Replacement of AliMpIntPair object with algoritmic
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitMaker.cxx
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 "AliMUONRawStreamTracker.h"
56 #include "AliMUONRawStreamTrackerHP.h"
57 #include "AliMUONRawStreamTrigger.h"
58 #include "AliMUONRawStreamTriggerHP.h"
59 #include "AliMUONRegHeader.h"
60 #include "AliMUONTriggerCircuit.h"
61 #include "AliMUONVTriggerStore.h"
62 #include "AliMpDetElement.h"
63 #include "AliMpTriggerCrate.h"
64 #include "AliMpLocalBoard.h"
65 #include "AliMpCathodType.h"
66 #include "AliMpDDLStore.h"
67 #include "AliMpDEManager.h"
68 #include "AliMpPad.h"
69 #include "AliMpSegmentation.h"
70 #include "AliMpVSegmentation.h"
71 #include "AliCodeTimer.h"
72 #include "AliLog.h"
73 #include "AliRawReader.h"
74 #include <TArrayS.h>
75
76 /// \cond CLASSIMP
77 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
78 /// \endcond
79
80 //__________________________________________________________________________
81 AliMUONDigitMaker::AliMUONDigitMaker(
82       Bool_t enableErrorLogger,
83       Bool_t useFastTrackerDecoder, Bool_t useFastTriggerDecoder
84   ) :
85     TObject(),
86     fScalerEvent(kFALSE),
87     fMakeTriggerDigits(kFALSE),
88     fRawStreamTracker(NULL),
89     fRawStreamTrigger(NULL),
90     fDigitStore(0x0),
91     fTriggerStore(0x0),
92   fLogger(new AliMUONLogger(10000))
93 {
94   /// ctor 
95
96   AliDebug(1,"");
97   
98   CreateRawStreamTracker(useFastTrackerDecoder);
99   CreateRawStreamTrigger(useFastTriggerDecoder);
100
101   // Standard Constructor
102   if (enableErrorLogger) {
103     fRawStreamTracker->EnabbleErrorLogger();
104     fRawStreamTrigger->EnabbleErrorLogger();
105   }
106
107   SetMakeTriggerDigits();
108
109 }
110
111 //__________________________________________________________________________
112 AliMUONDigitMaker::~AliMUONDigitMaker()
113 {
114   /// clean up
115   /// and time processing measure
116
117   delete fRawStreamTracker;
118   delete fRawStreamTrigger;
119   delete fLogger;
120 }
121
122 //__________________________________________________________________________
123 void AliMUONDigitMaker::CreateRawStreamTracker(Bool_t useFastDecoder)
124 {
125 /// Create raw stream tracker according to the passed option
126
127   if (useFastDecoder)
128   {
129     fRawStreamTracker = new AliMUONRawStreamTrackerHP();
130   }
131   else {
132     AliInfo("Using non-high performance tracker decoder.");
133     fRawStreamTracker = new AliMUONRawStreamTracker();
134   }  
135 }
136
137 //__________________________________________________________________________
138 void AliMUONDigitMaker::CreateRawStreamTrigger(Bool_t useFastDecoder)
139 {
140 /// Create raw stream trigger according to the passed option
141
142   if (useFastDecoder)
143   {
144     fRawStreamTrigger = new AliMUONRawStreamTriggerHP();
145   }
146   else {
147     AliInfo("Using non-high performance tracker decoder.");
148     fRawStreamTrigger = new AliMUONRawStreamTrigger();
149   }  
150 }
151
152 //____________________________________________________________________
153 void
154 AliMUONDigitMaker::Print(Option_t*) const
155 {
156   /// Printout
157
158   cout << "RawStreamerTracker class=" << fRawStreamTracker->ClassName()
159        << " MakeTriggerDigits=" << fMakeTriggerDigits
160        << " ScalerEvent=" << fScalerEvent
161        << " DigitStore=" << fDigitStore
162        << " TriggerStore=" << fTriggerStore << endl;
163
164   if ( fLogger ) fLogger->Print();
165 }
166
167 //____________________________________________________________________
168 Int_t
169 AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader, 
170                                         AliMUONVDigitStore* digitStore,
171                                         AliMUONVTriggerStore* triggerStore)
172 {
173   /// Main method to creates digit
174   /// for tracker 
175   /// and trigger
176
177   AliDebug(1,Form("rawReader=%p digitStore=%p triggerStore=%p",
178                   rawReader,digitStore,triggerStore));
179   
180   fDigitStore = digitStore;
181   fTriggerStore = triggerStore;
182   
183   if (!fDigitStore && !fTriggerStore)
184   {
185     fLogger->Log("No digit or trigger store given. Nothing to do...");
186     return kTriggerBAD & kTrackerBAD;
187   }
188   
189   Int_t tracker(kOK);
190   Int_t trigger(kOK);
191   
192   if ( fDigitStore ) 
193   {
194     fDigitStore->Clear(); // insure we start with an empty container
195     tracker = ReadTrackerDDL(rawReader);
196   }
197   
198   if ( fTriggerStore || fMakeTriggerDigits ) 
199   {
200     if ( fTriggerStore ) fTriggerStore->Clear();
201     if ( fMakeTriggerDigits && !fDigitStore ) 
202     {
203       fLogger->Log("Asking for trigger digits but digitStore is null");
204     }
205     else
206     {
207       trigger = ReadTriggerDDL(rawReader);
208     }
209   }
210   
211   return tracker | trigger;
212 }
213
214 //____________________________________________________________________
215 Int_t
216 AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
217 {
218   /// Reading tracker DDL
219   /// filling the fDigitStore container, which must not be null
220
221   AliDebug(1,"");
222   
223   AliCodeTimerAuto("");
224
225   // elex info
226   Int_t    buspatchId;
227   UChar_t  channelId;
228   UShort_t manuId;
229   UShort_t charge; 
230
231   fRawStreamTracker->SetReader(rawReader);
232   fRawStreamTracker->First();
233   
234   while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge) )
235   {    
236     // getting DE from buspatch
237     Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
238
239     AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
240
241     if (!de)
242       {
243         fLogger->Log(Form("DE %04d does not exist !"));
244         continue;
245       }
246
247     if (!de->IsConnectedChannel(manuId,channelId))
248       {
249         // non connected pad, do nothing (this is not an error !)
250         continue;
251       }
252
253     const AliMpVSegmentation* seg 
254       = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, 
255                                                                       manuId);  
256
257     if (!seg)
258     {
259       fLogger->Log(Form("(DE,MANUID)=(%04d,%04d) is not valid",detElemId,manuId));
260       continue;
261     }
262     
263     AliMp::CathodType cathodeType = de->GetCathodType(seg->PlaneType());
264
265     AliMpPad pad = seg->PadByLocation(manuId,channelId,kFALSE);
266
267     if (!pad.IsValid())
268     {
269       fLogger->Log(Form("No pad for detElemId: %d, manuId: %d, channelId: %d",
270                     detElemId, manuId, channelId));
271       continue;
272     } 
273
274     AliMUONVDigit* digit = fDigitStore->Add(detElemId,manuId,channelId,cathodeType,
275                                             AliMUONVDigitStore::kDeny);
276
277     if (!digit)
278     {
279       fLogger->Log(Form("Digit DE %04d Manu %04d Channel %02d could not be added",
280                     detElemId, manuId, channelId));
281       continue;
282     }
283     
284     digit->SetPadXY(pad.GetIx(),pad.GetIy());
285     
286     digit->SetADC(charge);
287
288   }
289   
290   if ( fRawStreamTracker->IsErrorMessage() ) 
291   {
292     return kTrackerBAD;
293   }
294   
295   return kOK;
296 }
297
298 //____________________________________________________________________
299 Int_t
300 AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
301 {
302   /// reading tracker DDL
303   /// filling the fTriggerStore container, which must not be null
304
305   AliDebug(1,"");
306   
307   AliMUONDDLTrigger*       ddlTrigger      = 0x0;
308   AliMUONDarcHeader*       darcHeader      = 0x0;
309   AliMUONRegHeader*        regHeader       = 0x0;
310   AliMUONLocalStruct*      localStruct     = 0x0;
311
312   Int_t loCircuit;
313
314   AliCodeTimerAuto("");
315   
316   if (UsingFastTriggerDecoder()) return ReadTriggerDDLFast(rawReader);
317
318   fRawStreamTrigger->SetReader(rawReader);
319
320   while (fRawStreamTrigger->NextDDL()) 
321   {
322     ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
323     darcHeader = ddlTrigger->GetDarcHeader();
324     
325     // fill global trigger information
326     if (fTriggerStore) 
327     {
328       if (darcHeader->GetGlobalFlag()) 
329       {
330           AliMUONGlobalTrigger globalTrigger;
331           globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
332           fTriggerStore->SetGlobal(globalTrigger);
333       }
334     }
335     
336     Int_t nReg = darcHeader->GetRegHeaderEntries();
337     
338     for(Int_t iReg = 0; iReg < nReg ;iReg++)
339     {   //reg loop
340       
341
342       // crate info  
343       AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
344                                 GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
345       
346       if (!crate) 
347         fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
348      
349       
350       regHeader =  darcHeader->GetRegHeaderEntry(iReg);
351       
352       Int_t nLocal = regHeader->GetLocalEntries();
353       for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
354       {  
355         
356         localStruct = regHeader->GetLocalEntry(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, false);
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 //____________________________________________________________________
398 Int_t
399 AliMUONDigitMaker::ReadTriggerDDLFast(AliRawReader* rawReader)
400 {
401   /// reading tracker DDL like ReadTriggerDDL but with fast decoder interface.
402   /// filling the fTriggerStore container, which must not be null
403
404   const AliMUONRawStreamTriggerHP::AliHeader*          darcHeader  = 0x0;
405   const AliMUONRawStreamTriggerHP::AliRegionalHeader*  regHeader   = 0x0;
406   const AliMUONRawStreamTriggerHP::AliLocalStruct*     localStruct = 0x0;
407
408   Int_t loCircuit;
409
410   fRawStreamTrigger->SetReader(rawReader);
411   AliMUONRawStreamTriggerHP* rawStreamTrigger =
412     dynamic_cast<AliMUONRawStreamTriggerHP*>(fRawStreamTrigger);
413
414   while (fRawStreamTrigger->NextDDL())
415   {
416     darcHeader = rawStreamTrigger->GetHeaders();
417     
418     // fill global trigger information
419     if (fTriggerStore) 
420     {
421       if (darcHeader->GetGlobalFlag()) 
422       {
423           AliMUONGlobalTrigger globalTrigger;
424           globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
425           fTriggerStore->SetGlobal(globalTrigger);
426       }
427     }
428     
429     Int_t nReg = rawStreamTrigger->GetRegionalHeaderCount();
430     
431     for(Int_t iReg = 0; iReg < nReg ;iReg++)
432     {   //reg loop
433       
434
435       // crate info  
436       AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
437                                 GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
438       
439       if (!crate) 
440         fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
441      
442       
443       regHeader =  rawStreamTrigger->GetRegionalHeader(iReg);
444       
445       Int_t nLocal = regHeader->GetLocalStructCount();
446       for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
447       {
448         
449         localStruct = regHeader->GetLocalStruct(iLocal);
450         
451         // if card exist
452         if (localStruct) {
453           
454           loCircuit = crate->GetLocalBoardId(localStruct->GetId());
455
456           if ( !loCircuit ) continue; // empty slot
457
458           AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, kTRUE);
459
460           // skip copy cards
461           if( !localBoard->IsNotified()) 
462              continue;
463           
464           if (fTriggerStore)
465           {
466             // fill local trigger
467             AliMUONLocalTrigger localTrigger;
468             localTrigger.SetLoCircuit(loCircuit);
469             localTrigger.SetLoStripX((Int_t)localStruct->GetXPos());
470             localTrigger.SetLoStripY((Int_t)localStruct->GetYPos());
471             localTrigger.SetLoDev((Int_t)localStruct->GetXDev());
472             localTrigger.SetLoSdev((Int_t)localStruct->GetSXDev());
473             localTrigger.SetLoTrigY((Int_t)localStruct->GetTrigY());
474             localTrigger.SetLoLpt(localStruct->GetLpt());
475             localTrigger.SetLoHpt(localStruct->GetHpt());
476             localTrigger.SetX1Pattern(localStruct->GetX1());
477             localTrigger.SetX2Pattern(localStruct->GetX2());
478             localTrigger.SetX3Pattern(localStruct->GetX3());
479             localTrigger.SetX4Pattern(localStruct->GetX4());
480             localTrigger.SetY1Pattern(localStruct->GetY1());
481             localTrigger.SetY2Pattern(localStruct->GetY2());
482             localTrigger.SetY3Pattern(localStruct->GetY3());
483             localTrigger.SetY4Pattern(localStruct->GetY4());
484             fTriggerStore->Add(localTrigger);
485           }
486           
487           if ( fMakeTriggerDigits )
488           {
489             //FIXEME should find something better than a TArray
490             TArrayS xyPattern[2];
491             
492             localStruct->GetXPattern(xyPattern[0]);
493             localStruct->GetYPattern(xyPattern[1]);
494             
495             TriggerDigits(loCircuit, xyPattern, *fDigitStore);
496           }
497         } // if triggerY
498       } // iLocal
499     } // iReg
500   } // NextDDL
501   
502   return kOK;
503 }
504
505 //____________________________________________________________________
506 Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard, 
507                                        TArrayS* xyPattern,
508                                        AliMUONVDigitStore& digitStore) const
509 {
510   /// make digits for trigger from pattern, and add them to digitStore
511
512   AliCodeTimerAuto("");
513   
514   Int_t detElemId;
515
516   AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
517
518   Int_t n,b;
519
520   // loop over x1-4 and y1-4
521   for (Int_t iChamber = 0; iChamber < 4; ++iChamber)
522   {
523     for (Int_t iCath = 0; iCath < 2; ++iCath)
524     {
525       Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber); 
526       if (!pattern) continue;
527       
528       // get detElemId
529       detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(nBoard, iChamber);
530         
531         const AliMpVSegmentation* seg 
532           = AliMpSegmentation::Instance()
533           ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
534         
535         // loop over the 16 bits of pattern
536         for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) 
537         {
538           if ((pattern >> ibitxy) & 0x1) 
539           {            
540             // not quite sure about this
541             Int_t offset = 0;
542             if (iCath && localBoard->GetSwitch(6)) offset = -8;
543             
544             AliMpPad pad = seg->PadByLocation(nBoard,ibitxy+offset,kTRUE);
545                         
546             if (!pad.IsValid()) 
547             {
548               fLogger->Log(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
549                               detElemId, nBoard, ibitxy));
550               continue;
551             }
552
553             n = pad.GetLocalBoardId(0); // always take first location so that digits are not inserted several times
554             b = pad.GetLocalBoardChannel(0);
555
556             AliDebug(1,Form("Using localBoard %d ixy %d instead of %d,%d",
557                             n,b,nBoard,ibitxy));
558
559             AliMUONVDigit* digit = digitStore.Add(detElemId,n,b,iCath,AliMUONVDigitStore::kDeny);
560             
561             if (!digit)
562             {
563                 AliDebug(1, Form("Digit DE %04d LocalBoard %03d ibitxy %02d cath %d already in store",
564                                  detElemId,nBoard,ibitxy,iCath));
565                 continue;
566             }
567             
568             Int_t padX = pad.GetIx();
569             Int_t padY = pad.GetIy();
570             
571             // fill digit
572             digit->SetPadXY(padX,padY);
573             digit->SetCharge(1.);
574           }// xyPattern
575         }// ibitxy
576     }// cath
577   } // ichamber
578   
579   return kTRUE;
580 }
581
582 //______________________________________________________________________________
583 Bool_t 
584 AliMUONDigitMaker::TriggerToDigitsStore(const AliMUONVTriggerStore& triggerStore,
585                                         AliMUONVDigitStore& digitStore) const
586 {
587   //
588   /// make (S)Digit for trigger
589   //
590   
591   digitStore.Clear();
592   
593   AliMUONLocalTrigger* locTrg;
594   TIter next(triggerStore.CreateLocalIterator());
595   
596   while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) ) 
597   {
598     if (locTrg->IsNull()) continue;
599    
600     TArrayS xyPattern[2];
601     locTrg->GetXPattern(xyPattern[0]);
602     locTrg->GetYPattern(xyPattern[1]);
603
604     Int_t nBoard = locTrg->LoCircuit();
605     TriggerDigits(nBoard, xyPattern, digitStore);
606   }
607   return kTRUE;
608 }
609
610 //____________________________________________________________________
611 Bool_t AliMUONDigitMaker::UsingFastTrackerDecoder() const
612 {
613 /// Returns kTRUE if the digit maker is using the high performance decoder for
614 /// tracker DDL stream decoding.
615
616   return (fRawStreamTracker->IsA() == AliMUONRawStreamTrackerHP::Class());
617 }
618
619 //____________________________________________________________________
620 Bool_t AliMUONDigitMaker::UsingFastTriggerDecoder() const
621 {
622 /// Returns kTRUE if the digit maker is using the high performance decoder for
623 /// trigger DDL stream decoding.
624
625   return (fRawStreamTrigger->IsA() == AliMUONRawStreamTriggerHP::Class());
626 }
627
628 //____________________________________________________________________
629 void  AliMUONDigitMaker::SetFastTrackerDecoder(Bool_t useFastDecoder)
630 {
631 /// Set fast raw data decoder
632
633   delete fRawStreamTracker;
634   CreateRawStreamTracker(useFastDecoder);
635 }
636
637 //____________________________________________________________________
638 void  AliMUONDigitMaker::SetFastTriggerDecoder(Bool_t useFastDecoder)
639 {
640 /// Set fast raw data decoder
641
642   delete fRawStreamTrigger;
643   CreateRawStreamTrigger(useFastDecoder);
644 }
645