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