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