Modifications to get summary plots about the readout errors for the tracker in the QA
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerDataMaker.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 /// \class AliMUONTrackerDataMaker
19 /// 
20 /// Implementation of VTrackerDataMaker to read raw data and 
21 /// calibrate it (if required)
22 /// 
23 /// \author Laurent Aphecetche, Subatech
24
25 #include "AliMUONTrackerDataMaker.h"
26
27 #include "AliCDBManager.h"
28 #include "AliCDBStorage.h"
29 #include "AliCodeTimer.h"
30 #include "AliDAQ.h"
31 #include "AliLog.h"
32 #include "AliMUON2DMap.h"
33 #include "AliMUONCalibParamND.h"
34 #include "AliMUONCalibrationData.h"
35 #include "AliMUONDigitCalibrator.h"
36 #include "AliMUONLogger.h"
37 #include "AliMUONRawStreamTrackerHP.h"
38 #include "AliMUONTrackerData.h"
39 #include "AliMpDDLStore.h"
40 #include "AliRawEventHeaderBase.h"
41 #include "AliRawReader.h"
42 #include "Riostream.h"
43
44 /// \cond CLASSIMP
45 ClassImp(AliMUONTrackerDataMaker)
46 /// \endcond
47
48 Int_t AliMUONTrackerDataMaker::fgkCounter(0);
49
50 //_____________________________________________________________________________
51 AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(TRootIOCtor*) 
52
53 AliMUONVTrackerDataMaker(),
54 fRawReader(0x0),
55 fAccumulatedData(0x0),
56 fOneEventData(0x0),
57 fDigitCalibrator(0x0),
58 fCalibrationData(0x0), 
59 fSource(""),
60 fOCDBPath(""),
61 fNumberOfEvents(0),
62 fRunNumber(0),
63 fIsRunning(kFALSE),
64 fIsOwnerOfRawReader(kFALSE),
65 fIsEventByEvent(kFALSE),
66 fLogger(0x0)
67 {
68 /// Root IO ctor
69 }
70
71 //_____________________________________________________________________________
72 AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(const AliMUONRecoParam* recoParam,
73                                                  Int_t runNumber,
74                                                  AliRawReader* rawReader,
75                                                  const char* cdbPath,
76                                                  const char* calibMode,
77                                                  Bool_t histogram,
78                                                  Double_t xmin,
79                                                  Double_t xmax)
80 :
81 AliMUONVTrackerDataMaker(),
82 fRawReader(rawReader),
83 fAccumulatedData(0x0),
84 fOneEventData(new AliMUON2DMap(true)),
85 fDigitCalibrator(0x0),
86 fCalibrationData(0x0), 
87 fSource(""),
88 fOCDBPath(cdbPath),
89 fNumberOfEvents(0),
90 fRunNumber(runNumber),
91 fIsRunning(kFALSE),
92 fIsOwnerOfRawReader(kFALSE),
93 fIsEventByEvent(kFALSE),
94 fLogger(0x0)
95 {
96   /// Ctor in which this object will NOT be the owner of the reader
97   /// and can NOT apply rewind to it, nor use Next on it. 
98   Ctor(recoParam,runNumber,calibMode,histogram,xmin,xmax);
99 }
100
101
102 //_____________________________________________________________________________
103 AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(const AliMUONRecoParam* recoParam,
104                                                  AliRawReader* rawReader,
105                                                  const char* cdbPath,
106                                                  const char* calibMode,
107                                                  Bool_t histogram,
108                                                  Double_t xmin,
109                                                  Double_t xmax)
110 :
111 AliMUONVTrackerDataMaker(),
112 fRawReader(rawReader),
113 fAccumulatedData(0x0),
114 fOneEventData(new AliMUON2DMap(true)),
115 fDigitCalibrator(0x0),
116 fCalibrationData(0x0), 
117 fSource(""),
118 fOCDBPath(cdbPath),
119 fNumberOfEvents(0),
120 fRunNumber(0),
121 fIsRunning(kFALSE),
122 fIsOwnerOfRawReader(kTRUE),
123 fIsEventByEvent(kFALSE),
124 fLogger(0x0)
125 {
126   /// Ctor in which we take the ownership of the rawReader, so we can rewind
127   /// and advance it as we wish
128   
129   if (fRawReader) 
130   {
131     fRawReader->NextEvent(); // to be sure to get run number available
132     fRunNumber = fRawReader->GetRunNumber();
133     fRawReader->RewindEvents();
134   }
135   
136   Ctor(recoParam,fRunNumber,calibMode,histogram,xmin,xmax);
137 }
138
139 //_____________________________________________________________________________
140 AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(AliRawReader* rawReader, Bool_t histogram)
141 :
142 AliMUONVTrackerDataMaker(),
143 fRawReader(rawReader),
144 fAccumulatedData(0x0),
145 fOneEventData(new AliMUON2DMap(true)),
146 fDigitCalibrator(0x0),
147 fCalibrationData(0x0), 
148 fSource(""),
149 fOCDBPath(""),
150 fNumberOfEvents(0),
151 fRunNumber(0),
152 fIsRunning(kFALSE),
153 fIsOwnerOfRawReader(kTRUE),
154 fIsEventByEvent(kFALSE),
155 fLogger(0x0)
156 {
157   /// Ctor from raw data reader
158   if (fRawReader) 
159   {
160     fRawReader->NextEvent(); // to be sure to get run number available
161     fRunNumber = fRawReader->GetRunNumber();
162     fRawReader->RewindEvents();
163   }
164   
165   Ctor(0x0,fRunNumber,"",histogram);
166   
167 }
168
169 //_____________________________________________________________________________
170 void 
171 AliMUONTrackerDataMaker::Ctor(const AliMUONRecoParam* recoParam,
172                               Int_t runNumber,
173                               const char* calibMode,
174                               Bool_t histogram,
175                               Double_t xmin, Double_t xmax)
176 {
177   /// "designated constructor"
178
179   Bool_t calibrate = ( strlen(calibMode) > 0 );
180   
181   TString name;
182   TString type("RAW");
183   
184   if ( calibrate ) 
185   {
186     TString scalib(calibMode);
187     scalib.ToUpper();
188     if ( scalib == "GAIN" ) type = "CALC";
189     if ( scalib == "NOGAIN" ) type = "CALZ";
190     if ( scalib == "GAINCONSTANTCAPA") type = "CALG";
191     if ( scalib == "INJECTIONGAIN" ) type = "CALE";
192   }
193   
194   if ( !fRunNumber ) 
195   {
196     ++fgkCounter;
197     name = Form("%s%s_%d",(histogram?"H":""),type.Data(),fgkCounter);
198   }
199   else
200   {
201     name = Form("%s%s%d",(histogram?"H":""),type.Data(),fRunNumber);
202   }
203   
204   fAccumulatedData = new AliMUONTrackerData(name.Data(),"charge values",1);
205   fAccumulatedData->SetDimensionName(0,(calibrate ? "Calibrated charge" : "Raw charge"));
206   if (histogram)
207   {
208     fAccumulatedData->MakeHistogramForDimension(0,kTRUE,xmin,xmax);
209   }
210   
211   if ( calibrate ) 
212   {
213     fCalibrationData = new AliMUONCalibrationData(runNumber);
214     
215     // force the reading of calibration NOW
216     // FIXME: not really elegant and error prone (as we have the list of calib data twice, 
217     // once here and once in the digitcalibrator class, hence the change of them getting
218     // out of sync)
219     // But with the current CDBManager implementation, I don't know how to solve
220     // this better (e.g. to avoid clearing cache messages and so on).
221
222     AliCDBStorage* storage(0x0);
223     
224     if ( fOCDBPath.Length() > 0 )
225     {
226       storage = AliCDBManager::Instance()->GetDefaultStorage();
227
228       if ( storage && ( storage->GetURI() != fOCDBPath.Data() ) )
229       {
230         AliCDBManager::Instance()->SetDefaultStorage(fOCDBPath.Data());
231       }
232     }
233     
234     fCalibrationData->Pedestals();
235     fCalibrationData->Gains();
236     fCalibrationData->Neighbours();
237     fCalibrationData->HV();
238     fCalibrationData->Capacitances();
239     
240     if ( storage && ( storage->GetURI() != fOCDBPath.Data() ) )
241     {
242       AliCDBManager::Instance()->SetDefaultStorage(storage);
243     }
244     
245     fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData,recoParam,calibMode);
246     //FIXME: get the reco param from GUI and/or from OCDB if not used from the QA code ?
247   }
248 }
249
250 //_____________________________________________________________________________
251 AliMUONTrackerDataMaker::~AliMUONTrackerDataMaker()
252 {
253 /// dtor
254
255   delete fOneEventData;
256   delete fAccumulatedData;
257   if ( fIsOwnerOfRawReader ) delete fRawReader;
258   delete fCalibrationData;
259   delete fDigitCalibrator;
260 }
261
262 //_____________________________________________________________________________
263 Bool_t 
264 AliMUONTrackerDataMaker::Add(const AliMUONTrackerDataMaker& other)
265 {
266   /// Adds other to this
267     
268   if (!fAccumulatedData) return kFALSE;
269   
270   if ( fIsEventByEvent )
271   {
272     AliError("Cannot add event by event objects !");
273     return kFALSE;
274   }
275   
276   if ( fRunNumber != other.fRunNumber ) fRunNumber = -1;
277   
278   fSource += "\n";
279   fSource += other.fSource;
280   
281   fNumberOfEvents += other.fNumberOfEvents;
282   
283   TList list;
284   list.Add(other.fAccumulatedData);
285   
286   fAccumulatedData->Merge(&list);
287   
288   return kTRUE;
289 }
290
291 //_____________________________________________________________________________
292 Bool_t 
293 AliMUONTrackerDataMaker::NextEvent()
294 {
295   /// Read and process next event
296   
297   if ( !fIsOwnerOfRawReader ) 
298   {
299     AliError("I'm not the owner of the raw reader. Cannot use NextEvent");
300     return kFALSE;
301   }
302   
303   AliCodeTimerAuto("",0);
304   
305   static Int_t nphysics(0);
306   static Int_t ngood(0);
307   
308   if ( !IsRunning() ) return kTRUE;
309   
310   Bool_t ok = fRawReader->NextEvent();
311   
312   if (!ok) 
313   {
314     return kFALSE;
315   }
316   
317   Int_t eventType = fRawReader->GetType();
318   
319   ++fNumberOfEvents;
320   
321   if (eventType != AliRawEventHeaderBase::kPhysicsEvent ) 
322   {
323     return kTRUE; // for the moment
324   }
325   
326   ++nphysics;
327   
328         Bool_t pok = ProcessEvent();
329         
330         if ( pok ) ++ngood;
331         
332         AliDebug(1,Form("n %10d nphysics %10d ngood %10d",fNumberOfEvents,nphysics,ngood));
333         
334         return kTRUE;  
335 }
336
337 //_____________________________________________________________________________
338 Bool_t AliMUONTrackerDataMaker::ProcessEvent()
339 {
340   /// Process current event 
341   /// 
342   /// Note that in case of calibration, we do not simply reuse the 
343   /// AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore&) method, 
344   /// as this would require filling first a digitStore, and then calibrate it,
345   /// and then convert it into a VStore, all this taking too much time.
346   /// But we *do* reuse the AliMUONDigitCalibrator::CalibrateDigit in order not to 
347   /// duplicate this critical piece of calibration code !
348   ///
349   
350   AliCodeTimerAuto("",0);
351   
352   AliMUONRawStreamTrackerHP stream(fRawReader);
353
354   stream.DisableWarnings();
355   stream.DisableRawReaderErrorLogger();
356   stream.DisableMUONErrorLogger();
357   
358   if (fLogger)
359   {
360     stream.EnableMUONErrorLogger();  
361     stream.SetMUONErrorLogger(fLogger);    
362     stream.SetLoggingDetailLevel(AliMUONRawStreamTrackerHP::kMediumErrorDetail);
363   }
364   
365   const Int_t nddls = AliDAQ::NumberOfDdls("MUONTRK");
366   TArrayI nevents(nddls);
367   
368   for ( Int_t i = 0; i < nddls; ++i ) 
369   {
370     nevents[i] = 0;
371   }
372   
373   fOneEventData->Clear();
374   
375   Int_t buspatchId;
376   UShort_t  manuId;
377   UChar_t manuChannel;
378   UShort_t adc;
379   
380   stream.First();
381   
382   while ( stream.Next(buspatchId,manuId,manuChannel,adc,kTRUE) )
383   {    
384     Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
385     
386     Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus(buspatchId);
387     
388     nevents[ddl] = 1;
389     
390     AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fOneEventData->FindObject(detElemId,manuId));
391     if (!param)
392     {
393       param = new AliMUONCalibParamND(1,64,detElemId,manuId,
394                                       AliMUONVCalibParam::InvalidFloatValue());
395       fOneEventData->Add(param);
396     }
397     
398     Double_t charge(adc);
399     
400     if ( fDigitCalibrator ) 
401     {
402       if ( fDigitCalibrator->IsValidDigit(detElemId, manuId, manuChannel) )
403       {
404         charge = fDigitCalibrator->CalibrateDigit(detElemId, manuId, manuChannel,adc);
405       }
406       else
407       {
408         charge = 0.0;
409       }
410     }
411     
412     if (charge > 0.0 ) 
413     {
414       param->SetValueAsDouble(manuChannel,0,charge);
415     }
416   }
417   
418         Bool_t badEvent = stream.HasPaddingError() || stream.HasGlitchError();
419
420         if (!badEvent)
421   {
422     fAccumulatedData->Add(*fOneEventData,&nevents);    
423   }
424     
425   return !badEvent;
426 }
427
428
429 //_____________________________________________________________________________
430 void 
431 AliMUONTrackerDataMaker::Print(Option_t*) const
432 {
433   /// Printout
434   
435   cout << "Source=" << Source() << " Running=" << ( IsRunning() ? "YES" : "NO")
436   << endl;
437 }
438
439 //_____________________________________________________________________________
440 void AliMUONTrackerDataMaker::Rewind()
441 {
442   /// Rewind events
443   if ( fIsOwnerOfRawReader ) 
444   {
445     fRawReader->RewindEvents();
446     fNumberOfEvents=0;  
447   }
448   else
449   {
450     AliError("Wrong usage of this class : cannot rewind as I am not owner of the raw reader !");
451   }
452 }
453
454 //_____________________________________________________________________________
455 Long64_t AliMUONTrackerDataMaker::Merge(TCollection* list)
456 {
457   /// Merge objects in collection
458   
459   if (!list) return 0;
460   
461   if ( list->IsEmpty() ) return NumberOfEvents();
462   
463   TIter next(list);
464   const TObject* o(0x0);
465   
466   while ( ( o = next() ) )
467   {
468     const AliMUONTrackerDataMaker* data = dynamic_cast<const AliMUONTrackerDataMaker*>(o);
469     if (!o)
470     {
471       AliError(Form("Object named %s is not an AliMUONTrackerDataMaker ! Skipping it",
472                     o->GetName()));
473     }
474     else
475     {
476       Bool_t ok = Add(*data);
477       if (!ok)
478       {
479         AliError("Got incompatible objects");
480       }
481     }
482   }
483   
484   return NumberOfEvents();
485 }
486
487 //_____________________________________________________________________________
488 void 
489 AliMUONTrackerDataMaker::SetRawReader(AliRawReader* rawReader)
490 {
491   /// Change the rawreader (only works if isowner=true)
492   
493   if ( fIsOwnerOfRawReader ) 
494         {
495     AliFatal("Improper use of this class ! Cannot change raw reader in this case");
496         }
497         
498   fRawReader = rawReader;
499   
500 }