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