]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONDigitMaker.cxx
- The default value of useFastDecoder in ctor changed to kFALSE,
[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 "AliLog.h"
48 #include "AliMUONDDLTrigger.h"
49 #include "AliMUONDarcHeader.h"
50 #include "AliMUONVDigit.h"
51 #include "AliMUONVDigitStore.h"
52 #include "AliMUONGlobalTrigger.h"
53 #include "AliMUONLocalStruct.h"
54 #include "AliMUONLocalTrigger.h"
55 #include "AliMUONRawStreamTracker.h"
56 #include "AliMUONRawStreamTrackerHP.h"
57 #include "AliMUONRawStreamTrigger.h"
58 #include "AliMUONRegHeader.h"
59 #include "AliMUONTriggerCircuit.h"
60 #include "AliMpTriggerCrate.h"
61 #include "AliMpLocalBoard.h"
62 #include "AliMUONVTriggerStore.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 "AliRawReader.h"
70 #include <TArrayS.h>
71
72 /// \cond CLASSIMP
73 ClassImp(AliMUONDigitMaker) // Class implementation in ROOT context
74 /// \endcond
75
76 //__________________________________________________________________________
77 AliMUONDigitMaker::AliMUONDigitMaker(Bool_t enableErrorLogger, Bool_t useFastDecoder)
78   : TObject(),
79     fScalerEvent(kFALSE),
80     fMakeTriggerDigits(kFALSE),
81     fRawStreamTracker(NULL),
82     fRawStreamTrigger(new AliMUONRawStreamTrigger()),    
83     fTrackerTimer(),
84     fTriggerTimer(),
85     fMappingTimer(),
86     fDigitStore(0x0),
87     fTriggerStore(0x0)
88 {
89   /// ctor 
90
91   AliDebug(1,"");
92   
93   CreateRawStreamTracker(useFastDecoder);
94
95   // Standard Constructor
96   if (enableErrorLogger) {
97     fRawStreamTracker->EnabbleErrorLogger();
98     fRawStreamTrigger->EnabbleErrorLogger();
99   }
100
101   fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
102   fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
103   fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
104   
105   SetMakeTriggerDigits();
106
107 }
108
109 //__________________________________________________________________________
110 AliMUONDigitMaker::~AliMUONDigitMaker()
111 {
112   /// clean up
113   /// and time processing measure
114
115   delete fRawStreamTracker;
116   delete fRawStreamTrigger;
117
118   AliDebug(1, Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
119                fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
120   AliDebug(1, Form("   Execution time for MUON tracker (mapping calls part) "
121                ": R:%.2fs C:%.2fs",
122                fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
123   AliDebug(1, Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
124                fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
125
126 }
127
128 //__________________________________________________________________________
129 void AliMUONDigitMaker::CreateRawStreamTracker(Bool_t useFastDecoder)
130 {
131 /// Create raw stream tracker according to the passed option
132
133   if (useFastDecoder)
134   {
135     AliInfo("Using fast decoder.");
136     fRawStreamTracker = new AliMUONRawStreamTrackerHP();
137   }
138   else
139     fRawStreamTracker = new AliMUONRawStreamTracker();
140 }    
141
142 //____________________________________________________________________
143 Int_t AliMUONDigitMaker::Raw2Digits(AliRawReader* rawReader, 
144                                     AliMUONVDigitStore* digitStore,
145                                     AliMUONVTriggerStore* triggerStore)
146 {
147   /// Main method to creates digit
148   /// for tracker 
149   /// and trigger
150
151   AliDebug(1,Form("rawReader=%p digitStore=%p triggerStore=%p",
152                   rawReader,digitStore,triggerStore));
153   
154   fDigitStore = digitStore;
155   fTriggerStore = triggerStore;
156   
157   if (!fDigitStore && !fTriggerStore)
158   {
159     AliError("No digit or trigger store given. Nothing to do...");
160     return kFALSE;
161   }
162   
163   if ( fDigitStore ) 
164   {
165     fDigitStore->Clear(); // insure we start with an empty container
166     ReadTrackerDDL(rawReader);
167   }
168   
169   if ( fTriggerStore || fMakeTriggerDigits ) 
170   {
171     if ( fTriggerStore ) fTriggerStore->Clear();
172     if ( fMakeTriggerDigits && !fDigitStore ) 
173     {
174       AliError("Asking for trigger digits but digitStore is null");
175     }
176     else
177     {
178       ReadTriggerDDL(rawReader);
179     }
180   }
181   
182   return kTRUE;
183 }
184
185 //____________________________________________________________________
186 Int_t AliMUONDigitMaker::ReadTrackerDDL(AliRawReader* rawReader)
187 {
188   /// Reading tracker DDL
189   /// filling the fDigitStore container, which must not be null
190
191   AliDebug(1,"");
192   
193   fTrackerTimer.Start(kFALSE);
194
195   // elex info
196   Int_t    buspatchId;
197   UChar_t  channelId;
198   UShort_t manuId;
199   UShort_t charge; 
200
201   fRawStreamTracker->SetReader(rawReader);
202   fRawStreamTracker->First();
203   
204   while ( fRawStreamTracker->Next(buspatchId,manuId,channelId,charge) )
205   {    
206     // getting DE from buspatch
207     Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
208
209     const AliMpVSegmentation* seg 
210       = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, 
211                                                                       manuId);  
212
213     AliMp::CathodType cathodeType = AliMpDEManager::GetCathod(detElemId, 
214                                                               seg->PlaneType());
215
216     AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,channelId),kFALSE);
217     
218     if (!pad.IsValid())
219     {
220       AliError(Form("No pad for detElemId: %d, manuId: %d, channelId: %d",
221                     detElemId, manuId, channelId));
222       continue;
223     } 
224     
225     AliMUONVDigit* digit = fDigitStore->Add(detElemId,manuId,channelId,cathodeType,
226                                             AliMUONVDigitStore::kDeny);
227     if (!digit)
228     {
229       AliError(Form("Digit DE %04d Manu %04d Channel %02d could not be added",
230                     detElemId, manuId, channelId));
231       continue;
232     }
233     
234     digit->SetPadXY(pad.GetIndices().GetFirst(),
235                    pad.GetIndices().GetSecond());
236     
237           digit->SetADC(charge);
238
239   }
240   
241   fTrackerTimer.Stop();
242
243   return kTRUE;
244 }
245
246 //____________________________________________________________________
247 Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
248 {
249   /// reading tracker DDL
250   /// filling the fTriggerStore container, which must not be null
251
252   AliDebug(1,"");
253   
254   AliMUONDDLTrigger*       ddlTrigger      = 0x0;
255   AliMUONDarcHeader*       darcHeader      = 0x0;
256   AliMUONRegHeader*        regHeader       = 0x0;
257   AliMUONLocalStruct*      localStruct     = 0x0;
258
259   Int_t loCircuit;
260
261   fTriggerTimer.Start(kFALSE);
262
263   fRawStreamTrigger->SetReader(rawReader);
264
265   while (fRawStreamTrigger->NextDDL()) 
266   {
267     ddlTrigger = fRawStreamTrigger->GetDDLTrigger();
268     darcHeader = ddlTrigger->GetDarcHeader();
269     
270     // fill global trigger information
271     if (fTriggerStore) 
272     {
273       if (darcHeader->GetGlobalFlag()) 
274       {
275           AliMUONGlobalTrigger globalTrigger;
276           globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
277           fTriggerStore->SetGlobal(globalTrigger);
278       }
279     }
280     
281     Int_t nReg = darcHeader->GetRegHeaderEntries();
282     
283     for(Int_t iReg = 0; iReg < nReg ;iReg++)
284     {   //reg loop
285       
286
287       // crate info  
288       AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
289                                 GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
290       
291       if (!crate) 
292         AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
293      
294       
295       regHeader =  darcHeader->GetRegHeaderEntry(iReg);
296       
297       Int_t nLocal = regHeader->GetLocalEntries();
298       for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
299       {  
300         
301         localStruct = regHeader->GetLocalEntry(iLocal);
302         
303         // if card exist
304         if (localStruct) {
305           
306           loCircuit = crate->GetLocalBoardId(localStruct->GetId());
307
308           if ( !loCircuit ) continue; // empty slot
309
310           AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, false);
311
312           // skip copy cards
313           if( !localBoard->IsNotified()) 
314              continue;
315           
316           if (fTriggerStore) 
317           {
318             // fill local trigger
319             AliMUONLocalTrigger localTrigger;
320             localTrigger.SetLocalStruct(loCircuit, *localStruct);
321             fTriggerStore->Add(localTrigger);
322           } 
323           
324           if ( fMakeTriggerDigits )
325           {
326             //FIXEME should find something better than a TArray
327             TArrayS xyPattern[2];
328             
329             localStruct->GetXPattern(xyPattern[0]);
330             localStruct->GetYPattern(xyPattern[1]);
331             
332             TriggerDigits(loCircuit, xyPattern, *fDigitStore);
333           }          
334         } // if triggerY
335       } // iLocal
336     } // iReg
337   } // NextDDL
338   
339   fTriggerTimer.Stop();
340
341   return kTRUE;
342
343 }
344
345 //____________________________________________________________________
346 Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard, 
347                                        TArrayS* xyPattern,
348                                        AliMUONVDigitStore& digitStore) const
349 {
350   /// make digits for trigger from pattern, and add them to digitStore
351
352   Int_t detElemId;
353
354   AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
355
356   Int_t n,b;
357
358   // loop over x1-4 and y1-4
359   for (Int_t iChamber = 0; iChamber < 4; ++iChamber)
360   {
361     for (Int_t iCath = 0; iCath < 2; ++iCath)
362     {
363       Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber); 
364       if (!pattern) continue;
365       
366       // get detElemId
367       detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(nBoard, iChamber);
368         
369         const AliMpVSegmentation* seg 
370           = AliMpSegmentation::Instance()
371           ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
372         
373         // loop over the 16 bits of pattern
374         for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) 
375         {
376           if ((pattern >> ibitxy) & 0x1) 
377           {            
378             // not quite sure about this
379             Int_t offset = 0;
380             if (iCath && localBoard->GetSwitch(6)) offset = -8;
381             
382             AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
383                         
384             if (!pad.IsValid()) 
385             {
386               AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
387                               detElemId, nBoard, ibitxy));
388               continue;
389             }
390
391             n = pad.GetLocation(0).GetFirst(); // always take first location so that digits are not inserted several times
392             b = pad.GetLocation(0).GetSecond();
393
394             AliDebug(1,Form("Using localBoard %d ixy %d instead of %d,%d",
395                             n,b,nBoard,ibitxy));
396
397             AliMUONVDigit* digit = digitStore.Add(detElemId,n,b,iCath,AliMUONVDigitStore::kDeny);
398             
399             if (!digit)
400             {
401                 AliDebug(1, Form("Digit DE %04d LocalBoard %03d ibitxy %02d cath %d already in store",
402                                  detElemId,nBoard,ibitxy,iCath));
403                 continue;
404             }
405             
406             Int_t padX = pad.GetIndices().GetFirst();
407             Int_t padY = pad.GetIndices().GetSecond();
408             
409             // fill digit
410             digit->SetPadXY(padX,padY);
411             digit->SetCharge(1.);
412           }// xyPattern
413         }// ibitxy
414     }// cath
415   } // ichamber
416   
417   return kTRUE;
418
419
420 //____________________________________________________________________
421 void  AliMUONDigitMaker::SetFastDecoder(Bool_t useFastDecoder)
422 {
423 /// Set fast raw data decoder
424
425   delete fRawStreamTracker;
426   CreateRawStreamTracker(useFastDecoder);
427 }  
428   
429     
430