]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONDigitMaker.cxx
correct calculation of cluster error for Riemann fit
[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   AliMUONRawStreamTriggerHP* rawStreamTrigger =
312     dynamic_cast<AliMUONRawStreamTriggerHP*>(fRawStreamTrigger);
313
314   while (fRawStreamTrigger->NextDDL())
315   {
316     darcHeader = rawStreamTrigger->GetHeaders();
317     
318     // fill global trigger information
319     if (fTriggerStore) 
320     {
321       if (darcHeader->GetGlobalFlag()) 
322       {
323           AliMUONGlobalTrigger globalTrigger;
324           globalTrigger.SetFromGlobalResponse(darcHeader->GetGlobalOutput());
325           globalTrigger.SetFromGlobalInput(darcHeader->GetGlobalHeader()->fInput);
326           fTriggerStore->SetGlobal(globalTrigger);
327       }
328     }
329     
330     Int_t nReg = rawStreamTrigger->GetRegionalHeaderCount();
331     
332     for(Int_t iReg = 0; iReg < nReg ;iReg++)
333     {   //reg loop
334       
335
336       // crate info  
337       AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
338                                 GetTriggerCrate(fRawStreamTrigger->GetDDL(), iReg);
339       
340       if (!crate) 
341         fLogger->Log(Form("Missing crate number %d in DDL %d\n", iReg, fRawStreamTrigger->GetDDL()));
342      
343       
344       regHeader =  rawStreamTrigger->GetRegionalHeader(iReg);
345       
346       Int_t nLocal = regHeader->GetLocalStructCount();
347       for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
348       {
349         
350         localStruct = regHeader->GetLocalStruct(iLocal);
351         
352         // if card exist
353         if (localStruct) {
354           
355           loCircuit = crate->GetLocalBoardId(localStruct->GetId());
356
357           if ( !loCircuit ) continue; // empty slot
358
359           AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, kTRUE);
360
361           // skip copy cards
362           if( !localBoard->IsNotified()) 
363              continue;
364           
365           if (fTriggerStore)
366           {
367             // fill local trigger
368             AliMUONLocalTrigger localTrigger;
369             localTrigger.SetLoCircuit(loCircuit);
370             localTrigger.SetLoStripX((Int_t)localStruct->GetXPos());
371             localTrigger.SetLoStripY((Int_t)localStruct->GetYPos());
372             localTrigger.SetLoDev((Int_t)localStruct->GetXDev());
373             localTrigger.SetLoSdev((Int_t)localStruct->GetSXDev());
374             localTrigger.SetLoTrigY((Int_t)localStruct->GetTrigY());
375             localTrigger.SetLoLpt(localStruct->GetLpt());
376             localTrigger.SetLoHpt(localStruct->GetHpt());
377             localTrigger.SetX1Pattern(localStruct->GetX1());
378             localTrigger.SetX2Pattern(localStruct->GetX2());
379             localTrigger.SetX3Pattern(localStruct->GetX3());
380             localTrigger.SetX4Pattern(localStruct->GetX4());
381             localTrigger.SetY1Pattern(localStruct->GetY1());
382             localTrigger.SetY2Pattern(localStruct->GetY2());
383             localTrigger.SetY3Pattern(localStruct->GetY3());
384             localTrigger.SetY4Pattern(localStruct->GetY4());
385             fTriggerStore->Add(localTrigger);
386           }
387           
388           if ( fMakeTriggerDigits )
389           {
390             //FIXEME should find something better than a TArray
391             TArrayS xyPattern[2];
392             
393             localStruct->GetXPattern(xyPattern[0]);
394             localStruct->GetYPattern(xyPattern[1]);
395             
396             TriggerDigits(loCircuit, xyPattern, *fDigitStore);
397           }
398         } // if triggerY
399       } // iLocal
400     } // iReg
401   } // NextDDL
402   
403   return kOK;
404 }
405
406 //____________________________________________________________________
407 Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard, 
408                                        TArrayS* xyPattern,
409                                        AliMUONVDigitStore& digitStore) const
410 {
411   /// make digits for trigger from pattern, and add them to digitStore
412
413   AliCodeTimerAuto("");
414   
415   Int_t detElemId;
416
417   AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(nBoard);
418
419   Int_t n,b;
420
421   // loop over x1-4 and y1-4
422   for (Int_t iChamber = 0; iChamber < 4; ++iChamber)
423   {
424     for (Int_t iCath = 0; iCath < 2; ++iCath)
425     {
426       Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber); 
427       if (!pattern) continue;
428       
429       // get detElemId
430       detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(nBoard, iChamber);
431         
432         const AliMpVSegmentation* seg 
433           = AliMpSegmentation::Instance()
434           ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
435         
436         // loop over the 16 bits of pattern
437         for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) 
438         {
439           if ((pattern >> ibitxy) & 0x1) 
440           {            
441             // not quite sure about this
442             Int_t offset = 0;
443             if (iCath && localBoard->GetSwitch(6)) offset = -8;
444             
445             AliMpPad pad = seg->PadByLocation(nBoard,ibitxy+offset,kTRUE);
446                         
447             if (!pad.IsValid()) 
448             {
449               fLogger->Log(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
450                               detElemId, nBoard, ibitxy));
451               continue;
452             }
453
454             n = pad.GetLocalBoardId(0); // always take first location so that digits are not inserted several times
455             b = pad.GetLocalBoardChannel(0);
456
457             AliDebug(1,Form("Using localBoard %d ixy %d instead of %d,%d",
458                             n,b,nBoard,ibitxy));
459
460             AliMUONVDigit* digit = digitStore.Add(detElemId,n,b,iCath,AliMUONVDigitStore::kDeny);
461             
462             if (!digit)
463             {
464                 AliDebug(1, Form("Digit DE %04d LocalBoard %03d ibitxy %02d cath %d already in store",
465                                  detElemId,nBoard,ibitxy,iCath));
466                 continue;
467             }
468             
469             Int_t padX = pad.GetIx();
470             Int_t padY = pad.GetIy();
471             
472             // fill digit
473             digit->SetPadXY(padX,padY);
474             digit->SetCharge(1.);
475           }// xyPattern
476         }// ibitxy
477     }// cath
478   } // ichamber
479   
480   return kTRUE;
481 }
482
483 //______________________________________________________________________________
484 Bool_t 
485 AliMUONDigitMaker::TriggerToDigitsStore(const AliMUONVTriggerStore& triggerStore,
486                                         AliMUONVDigitStore& digitStore) const
487 {
488   //
489   /// make (S)Digit for trigger
490   //
491   
492   digitStore.Clear();
493   
494   AliMUONLocalTrigger* locTrg;
495   TIter next(triggerStore.CreateLocalIterator());
496   
497   while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) ) 
498   {
499     if (locTrg->IsNull()) continue;
500    
501     TArrayS xyPattern[2];
502     locTrg->GetXPattern(xyPattern[0]);
503     locTrg->GetYPattern(xyPattern[1]);
504
505     Int_t nBoard = locTrg->LoCircuit();
506     TriggerDigits(nBoard, xyPattern, digitStore);
507   }
508   return kTRUE;
509 }