Fix histo name
[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 "AliMUONRawStreamTrackerHP.h"
56 #include "AliMUONRawStreamTriggerHP.h"
57 #include "AliMUONRegHeader.h"
58 #include "AliMUONTriggerCircuit.h"
59 #include "AliMUONVTriggerStore.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
75 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
76 /// \endcond
77
78 //__________________________________________________________________________
79 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger, Bool_t a, Bool_t b) :
80 TObject(),
81 fScalerEvent(kFALSE),
82 fMakeTriggerDigits(kFALSE),
83 fRawStreamTracker(new AliMUONRawStreamTrackerHP),
84 fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
85 fDigitStore(0x0),
86 fTriggerStore(0x0),
87 fLogger(new AliMUONLogger(10000))
88 {
89   /// ctor 
90   
91   if  ( !a || !b ) AliFatal("no longer supported");
92   
93   AliDebug(1,"");
94   
95   // Standard Constructor
96   if (enableErrorLogger) 
97   {
98     fRawStreamTracker->EnabbleErrorLogger();
99     fRawStreamTrigger->EnabbleErrorLogger();
100   }
101   else
102   {
103     fRawStreamTracker->DisableWarnings();
104   }
105   
106   SetMakeTriggerDigits();
107   
108 }
109
110 //__________________________________________________________________________
111 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger) :
112 TObject(),
113     fScalerEvent(kFALSE),
114     fMakeTriggerDigits(kFALSE),
115     fRawStreamTracker(new AliMUONRawStreamTrackerHP),
116     fRawStreamTrigger(new AliMUONRawStreamTriggerHP),
117     fDigitStore(0x0),
118     fTriggerStore(0x0),
119   fLogger(new AliMUONLogger(10000))
120 {
121   /// ctor 
122
123   AliDebug(1,"");
124   
125   // Standard Constructor
126   if (enableErrorLogger) 
127   {
128     fRawStreamTracker->EnabbleErrorLogger();
129     fRawStreamTrigger->EnabbleErrorLogger();
130   }
131   else
132   {
133     fRawStreamTracker->DisableWarnings();
134   }
135
136   SetMakeTriggerDigits();
137
138 }
139
140 //__________________________________________________________________________
141 AliMUONDigitMaker::~AliMUONDigitMaker()
142 {
143   /// clean up
144   /// and time processing measure
145
146   delete fRawStreamTracker;
147   delete fRawStreamTrigger;
148   delete fLogger;
149 }
150
151 //____________________________________________________________________
152 void
153 AliMUONDigitMaker::Print(Option_t*) const
154 {
155   /// Printout
156
157   cout << "RawStreamerTracker class=" << fRawStreamTracker->ClassName()
158        << " MakeTriggerDigits=" << fMakeTriggerDigits
159        << " ScalerEvent=" << fScalerEvent
160        << " DigitStore=" << fDigitStore
161        << " TriggerStore=" << fTriggerStore << endl;
162
163   if ( fLogger ) fLogger->Print();
164 }
165
166 //____________________________________________________________________
167 Int_t
168 AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader, 
169                                         AliMUONVDigitStore* digitStore,
170                                         AliMUONVTriggerStore* triggerStore)
171 {
172   /// Main method to creates digit
173   /// for tracker 
174   /// and trigger
175
176   AliDebug(1,Form("rawReader=%p digitStore=%p triggerStore=%p",
177                   rawReader,digitStore,triggerStore));
178   
179   fDigitStore = digitStore;
180   fTriggerStore = triggerStore;
181   
182   if (!fDigitStore && !fTriggerStore)
183   {
184     fLogger->Log("No digit or trigger store given. Nothing to do...");
185     return kTriggerBAD & kTrackerBAD;
186   }
187   
188   Int_t tracker(kOK);
189   Int_t trigger(kOK);
190   
191   if ( fDigitStore ) 
192   {
193     fDigitStore->Clear(); // insure we start with an empty container
194     tracker = ReadTrackerDDL(rawReader);
195   }
196   
197   if ( fTriggerStore || fMakeTriggerDigits ) 
198   {
199     if ( fTriggerStore ) fTriggerStore->Clear();
200     if ( fMakeTriggerDigits && !fDigitStore ) 
201     {
202       fLogger->Log("Asking for trigger digits but digitStore is null");
203     }
204     else
205     {
206       trigger = ReadTriggerDDL(rawReader);
207     }
208   }
209   
210   return tracker | trigger;
211 }
212
213 //____________________________________________________________________
214 Int_t
215 AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
216 {
217   /// Reading tracker DDL
218   /// filling the fDigitStore container, which must not be null
219
220   AliDebug(1,"");
221   
222   AliCodeTimerAuto("");
223
224   // elex info
225   Int_t    buspatchId;
226   UChar_t  channelId;
227   UShort_t manuId;
228   UShort_t charge; 
229
230   fRawStreamTracker->SetReader(rawReader);
231   fRawStreamTracker->First();
232   
233   while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge,kTRUE) )
234   {    
235     // getting DE from buspatch
236     Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
237
238     AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
239
240     if (!de)
241       {
242         fLogger->Log(Form("DE %04d does not exist !"));
243         continue;
244       }
245
246     if (!de->IsConnectedChannel(manuId,channelId))
247       {
248         // non connected pad, do nothing (this is not an error !)
249         continue;
250       }
251
252     const AliMpVSegmentation* seg 
253       = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, 
254                                                                       manuId);  
255
256     if (!seg)
257     {
258       fLogger->Log(Form("(DE,MANUID)=(%04d,%04d) is not valid",detElemId,manuId));
259       continue;
260     }
261     
262     AliMp::CathodType cathodeType = de->GetCathodType(seg->PlaneType());
263
264     AliMpPad pad = seg->PadByLocation(manuId,channelId,kFALSE);
265
266     if (!pad.IsValid())
267     {
268       fLogger->Log(Form("No pad for detElemId: %d, manuId: %d, channelId: %d",
269                     detElemId, manuId, channelId));
270       continue;
271     } 
272
273     AliMUONVDigit* digit = fDigitStore->Add(detElemId,manuId,channelId,cathodeType,
274                                             AliMUONVDigitStore::kDeny);
275
276     if (!digit)
277     {
278       fLogger->Log(Form("Digit DE %04d Manu %04d Channel %02d could not be added",
279                     detElemId, manuId, channelId));
280       continue;
281     }
282     
283     digit->SetPadXY(pad.GetIx(),pad.GetIy());
284     
285     digit->SetADC(charge);
286
287   }
288   
289   if ( fRawStreamTracker->IsErrorMessage() ) 
290   {
291     return kTrackerBAD;
292   }
293   
294   return kOK;
295 }
296
297 //____________________________________________________________________
298 Int_t
299 AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
300 {
301   /// reading tracker DDL like ReadTriggerDDL but with fast decoder interface.
302   /// filling the fTriggerStore container, which must not be null
303
304   const AliMUONRawStreamTriggerHP::AliHeader*          darcHeader  = 0x0;
305   const AliMUONRawStreamTriggerHP::AliRegionalHeader*  regHeader   = 0x0;
306   const AliMUONRawStreamTriggerHP::AliLocalStruct*     localStruct = 0x0;
307
308   Int_t loCircuit;
309
310   fRawStreamTrigger->SetReader(rawReader);
311
312   while (fRawStreamTrigger->NextDDL())
313   {
314     darcHeader = fRawStreamTrigger->GetHeaders();
315     
316     // fill global trigger information
317     if (fTriggerStore) 
318     {
319       if (darcHeader->GetGlobalFlag()) 
320       {
321           AliMUONGlobalTrigger globalTrigger;
322           globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
323           globalTrigger.SetFromGlobalInput(darcHeader->GetGlobalHeader()->fInput);
324           fTriggerStore->SetGlobal(globalTrigger);
325       }
326     }
327     
328     Int_t nReg = fRawStreamTrigger->GetRegionalHeaderCount();
329     
330     for(Int_t iReg = 0; iReg < nReg ;iReg++)
331     {   //reg loop
332       
333
334       // crate info  
335       AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
336                                 GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
337       
338       if (!crate) 
339         fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
340      
341       
342       regHeader =  fRawStreamTrigger->GetRegionalHeader(iReg);
343       
344       Int_t nLocal = regHeader->GetLocalStructCount();
345       for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
346       {
347         
348         localStruct = regHeader->GetLocalStruct(iLocal);
349         
350         // if card exist
351         if (localStruct) {
352           
353           loCircuit = crate->GetLocalBoardId(localStruct->GetId());
354
355           if ( !loCircuit ) continue; // empty slot
356
357           AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, kTRUE);
358
359           // skip copy cards
360           if( !localBoard->IsNotified()) 
361              continue;
362           
363           if (fTriggerStore)
364           {
365             // fill local trigger
366             AliMUONLocalTrigger localTrigger;
367             localTrigger.SetLoCircuit(loCircuit);
368             localTrigger.SetLoStripX((Int_t)localStruct->GetXPos());
369             localTrigger.SetLoStripY((Int_t)localStruct->GetYPos());
370             localTrigger.SetLoDev((Int_t)localStruct->GetXDev());
371             localTrigger.SetLoSdev((Int_t)localStruct->GetSXDev());
372             localTrigger.SetLoTrigY((Int_t)localStruct->GetTrigY());
373             localTrigger.SetLoLpt(localStruct->GetLpt());
374             localTrigger.SetLoHpt(localStruct->GetHpt());
375             localTrigger.SetX1Pattern(localStruct->GetX1());
376             localTrigger.SetX2Pattern(localStruct->GetX2());
377             localTrigger.SetX3Pattern(localStruct->GetX3());
378             localTrigger.SetX4Pattern(localStruct->GetX4());
379             localTrigger.SetY1Pattern(localStruct->GetY1());
380             localTrigger.SetY2Pattern(localStruct->GetY2());
381             localTrigger.SetY3Pattern(localStruct->GetY3());
382             localTrigger.SetY4Pattern(localStruct->GetY4());
383             fTriggerStore->Add(localTrigger);
384           }
385           
386           if ( fMakeTriggerDigits )
387           {
388             //FIXEME should find something better than a TArray
389             TArrayS xyPattern[2];
390             
391             localStruct->GetXPattern(xyPattern[0]);
392             localStruct->GetYPattern(xyPattern[1]);
393             
394             TriggerDigits(loCircuit, xyPattern, *fDigitStore);
395           }
396         } // if triggerY
397       } // iLocal
398     } // iReg
399   } // NextDDL
400   
401   return kOK;
402 }
403
404 //____________________________________________________________________
405 Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard, 
406                                        TArrayS* xyPattern,
407                                        AliMUONVDigitStore& digitStore) const
408 {
409   /// make digits for trigger from pattern, and add them to digitStore
410
411   AliCodeTimerAuto("");
412   
413   Int_t detElemId;
414
415   AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
416
417   Int_t n,b;
418
419   // loop over x1-4 and y1-4
420   for (Int_t iChamber = 0; iChamber < 4; ++iChamber)
421   {
422     for (Int_t iCath = 0; iCath < 2; ++iCath)
423     {
424       Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber); 
425       if (!pattern) continue;
426       
427       // get detElemId
428       detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(nBoard, iChamber);
429         
430         const AliMpVSegmentation* seg 
431           = AliMpSegmentation::Instance()
432           ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
433         
434         // loop over the 16 bits of pattern
435         for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) 
436         {
437           if ((pattern >> ibitxy) & 0x1) 
438           {            
439             // not quite sure about this
440             Int_t offset = 0;
441             if (iCath && localBoard->GetSwitch(6)) offset = -8;
442             
443             AliMpPad pad = seg->PadByLocation(nBoard,ibitxy+offset,kTRUE);
444                         
445             if (!pad.IsValid()) 
446             {
447               fLogger->Log(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
448                               detElemId, nBoard, ibitxy));
449               continue;
450             }
451
452             n = pad.GetLocalBoardId(0); // always take first location so that digits are not inserted several times
453             b = pad.GetLocalBoardChannel(0);
454
455             AliDebug(1,Form("Using localBoard %d ixy %d instead of %d,%d",
456                             n,b,nBoard,ibitxy));
457
458             AliMUONVDigit* digit = digitStore.Add(detElemId,n,b,iCath,AliMUONVDigitStore::kDeny);
459             
460             if (!digit)
461             {
462                 AliDebug(1, Form("Digit DE %04d LocalBoard %03d ibitxy %02d cath %d already in store",
463                                  detElemId,nBoard,ibitxy,iCath));
464                 continue;
465             }
466             
467             Int_t padX = pad.GetIx();
468             Int_t padY = pad.GetIy();
469             
470             // fill digit
471             digit->SetPadXY(padX,padY);
472             digit->SetCharge(1.);
473           }// xyPattern
474         }// ibitxy
475     }// cath
476   } // ichamber
477   
478   return kTRUE;
479 }
480
481 //______________________________________________________________________________
482 Bool_t 
483 AliMUONDigitMaker::TriggerToDigitsStore(const AliMUONVTriggerStore& triggerStore,
484                                         AliMUONVDigitStore& digitStore) const
485 {
486   //
487   /// make (S)Digit for trigger
488   //
489   
490   digitStore.Clear();
491   
492   AliMUONLocalTrigger* locTrg;
493   TIter next(triggerStore.CreateLocalIterator());
494   
495   while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) ) 
496   {
497     if (locTrg->IsNull()) continue;
498    
499     TArrayS xyPattern[2];
500     locTrg->GetXPattern(xyPattern[0]);
501     locTrg->GetYPattern(xyPattern[1]);
502
503     Int_t nBoard = locTrg->LoCircuit();
504     TriggerDigits(nBoard, xyPattern, digitStore);
505   }
506   return kTRUE;
507 }