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