minor coverity defect: added protection for self-assignment
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerDataMaker.cxx
CommitLineData
b6f591ae 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"
64c2397e 36#include "AliMUONLogger.h"
b6f591ae 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
45ClassImp(AliMUONTrackerDataMaker)
46/// \endcond
47
48Int_t AliMUONTrackerDataMaker::fgkCounter(0);
49
50//_____________________________________________________________________________
51AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(TRootIOCtor*)
52:
53AliMUONVTrackerDataMaker(),
54fRawReader(0x0),
55fAccumulatedData(0x0),
b3d57767 56fIsOwnerOfAccumulatedData(kTRUE),
b6f591ae 57fOneEventData(0x0),
58fDigitCalibrator(0x0),
59fCalibrationData(0x0),
60fSource(""),
61fOCDBPath(""),
62fNumberOfEvents(0),
63fRunNumber(0),
64fIsRunning(kFALSE),
65fIsOwnerOfRawReader(kFALSE),
64c2397e 66fIsEventByEvent(kFALSE),
b3d57767 67fLogger(0x0),
68fLastEventWasEmpty(kFALSE),
69fNumberOfPhysicsEvents(0),
9074a9a9 70fNumberOfGoodPhysicsEvents(0),
71fTryRecover(kFALSE),
72fFirstEvent(-1),
73fLastEvent(-1)
b6f591ae 74{
cddcc1f3 75/// Root IO ctor
b6f591ae 76}
77
78//_____________________________________________________________________________
79AliMUONTrackerDataMaker::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:
88AliMUONVTrackerDataMaker(),
89fRawReader(rawReader),
90fAccumulatedData(0x0),
b3d57767 91fIsOwnerOfAccumulatedData(kTRUE),
b6f591ae 92fOneEventData(new AliMUON2DMap(true)),
93fDigitCalibrator(0x0),
94fCalibrationData(0x0),
95fSource(""),
96fOCDBPath(cdbPath),
97fNumberOfEvents(0),
98fRunNumber(runNumber),
99fIsRunning(kFALSE),
100fIsOwnerOfRawReader(kFALSE),
64c2397e 101fIsEventByEvent(kFALSE),
b3d57767 102fLogger(0x0),
103fLastEventWasEmpty(kFALSE),
104fNumberOfPhysicsEvents(0),
9074a9a9 105fNumberOfGoodPhysicsEvents(0),
106fTryRecover(kFALSE),
107fFirstEvent(-1),
108fLastEvent(-1)
b6f591ae 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//_____________________________________________________________________________
117AliMUONTrackerDataMaker::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:
125AliMUONVTrackerDataMaker(),
126fRawReader(rawReader),
127fAccumulatedData(0x0),
b3d57767 128fIsOwnerOfAccumulatedData(kTRUE),
b6f591ae 129fOneEventData(new AliMUON2DMap(true)),
130fDigitCalibrator(0x0),
131fCalibrationData(0x0),
132fSource(""),
133fOCDBPath(cdbPath),
134fNumberOfEvents(0),
135fRunNumber(0),
136fIsRunning(kFALSE),
137fIsOwnerOfRawReader(kTRUE),
64c2397e 138fIsEventByEvent(kFALSE),
b3d57767 139fLogger(0x0),
140fLastEventWasEmpty(kFALSE),
141fNumberOfPhysicsEvents(0),
9074a9a9 142fNumberOfGoodPhysicsEvents(0),
143fTryRecover(kFALSE),
144fFirstEvent(-1),
145fLastEvent(-1)
b6f591ae 146{
147 /// Ctor in which we take the ownership of the rawReader, so we can rewind
148 /// and advance it as we wish
149
101dbec2 150 if ( fRawReader && fRawReader->NextEvent() )
b6f591ae 151 {
b6f591ae 152 fRunNumber = fRawReader->GetRunNumber();
153 fRawReader->RewindEvents();
154 }
155
156 Ctor(recoParam,fRunNumber,calibMode,histogram,xmin,xmax);
157}
158
159//_____________________________________________________________________________
160AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(AliRawReader* rawReader, Bool_t histogram)
161:
162AliMUONVTrackerDataMaker(),
163fRawReader(rawReader),
164fAccumulatedData(0x0),
b3d57767 165fIsOwnerOfAccumulatedData(kTRUE),
b6f591ae 166fOneEventData(new AliMUON2DMap(true)),
167fDigitCalibrator(0x0),
168fCalibrationData(0x0),
169fSource(""),
170fOCDBPath(""),
171fNumberOfEvents(0),
172fRunNumber(0),
173fIsRunning(kFALSE),
174fIsOwnerOfRawReader(kTRUE),
64c2397e 175fIsEventByEvent(kFALSE),
b3d57767 176fLogger(0x0),
177fLastEventWasEmpty(kFALSE),
178fNumberOfPhysicsEvents(0),
9074a9a9 179fNumberOfGoodPhysicsEvents(0),
180fTryRecover(kFALSE),
181fFirstEvent(-1),
182fLastEvent(-1)
b6f591ae 183{
ca04ed6c 184 /// Ctor from raw data reader
101dbec2 185 if ( fRawReader && fRawReader->NextEvent() )
b6f591ae 186 {
b6f591ae 187 fRunNumber = fRawReader->GetRunNumber();
188 fRawReader->RewindEvents();
189 }
190
191 Ctor(0x0,fRunNumber,"",histogram);
192
193}
194
195//_____________________________________________________________________________
196void
197AliMUONTrackerDataMaker::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"
f2bc8ba0 204
205 Bool_t calibrate = ( strlen(calibMode) > 0 );
b6f591ae 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";
66cdf5b3 217 if ( scalib == "INJECTIONGAIN" ) type = "CALE";
b6f591ae 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).
ed66881d 247
248 AliCDBStorage* storage(0x0);
b6f591ae 249
ed66881d 250 if ( fOCDBPath.Length() > 0 )
b6f591ae 251 {
ed66881d 252 storage = AliCDBManager::Instance()->GetDefaultStorage();
253
254 if ( storage && ( storage->GetURI() != fOCDBPath.Data() ) )
255 {
256 AliCDBManager::Instance()->SetDefaultStorage(fOCDBPath.Data());
257 }
b6f591ae 258 }
259
260 fCalibrationData->Pedestals();
261 fCalibrationData->Gains();
262 fCalibrationData->Neighbours();
263 fCalibrationData->HV();
264 fCalibrationData->Capacitances();
265
ed66881d 266 if ( storage && ( storage->GetURI() != fOCDBPath.Data() ) )
b6f591ae 267 {
268 AliCDBManager::Instance()->SetDefaultStorage(storage);
269 }
270
05315e71 271 fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData,recoParam);
b6f591ae 272 //FIXME: get the reco param from GUI and/or from OCDB if not used from the QA code ?
273 }
274}
275
276//_____________________________________________________________________________
277AliMUONTrackerDataMaker::~AliMUONTrackerDataMaker()
278{
cddcc1f3 279/// dtor
280
b6f591ae 281 delete fOneEventData;
b3d57767 282 if ( fIsOwnerOfAccumulatedData ) delete fAccumulatedData;
b6f591ae 283 if ( fIsOwnerOfRawReader ) delete fRawReader;
284 delete fCalibrationData;
285 delete fDigitCalibrator;
286}
287
288//_____________________________________________________________________________
289Bool_t
290AliMUONTrackerDataMaker::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;
b3d57767 308 fNumberOfPhysicsEvents += other.fNumberOfPhysicsEvents;
309 fNumberOfGoodPhysicsEvents += other.fNumberOfGoodPhysicsEvents;
310
b6f591ae 311 TList list;
312 list.Add(other.fAccumulatedData);
313
314 fAccumulatedData->Merge(&list);
315
316 return kTRUE;
317}
318
319//_____________________________________________________________________________
320Bool_t
321AliMUONTrackerDataMaker::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
99c136e1 331 AliCodeTimerAuto("",0);
b6f591ae 332
b6f591ae 333 if ( !IsRunning() ) return kTRUE;
334
9074a9a9 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 }
b6f591ae 361
362 if (!ok)
363 {
364 return kFALSE;
365 }
366
b3d57767 367 ProcessEvent();
b6f591ae 368
369 return kTRUE;
370}
371
372//_____________________________________________________________________________
373Bool_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
b3d57767 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
99c136e1 398 AliCodeTimerAuto("",0);
b6f591ae 399
400 AliMUONRawStreamTrackerHP stream(fRawReader);
64c2397e 401
b6f591ae 402 stream.DisableWarnings();
64c2397e 403 stream.DisableRawReaderErrorLogger();
404 stream.DisableMUONErrorLogger();
9074a9a9 405
406 if ( fTryRecover )
407 {
408 stream.TryRecover(kTRUE);
409 }
410 else
411 {
412 stream.TryRecover(kFALSE);
413 }
64c2397e 414
415 if (fLogger)
416 {
417 stream.EnableMUONErrorLogger();
418 stream.SetMUONErrorLogger(fLogger);
419 stream.SetLoggingDetailLevel(AliMUONRawStreamTrackerHP::kMediumErrorDetail);
420 }
b6f591ae 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 {
8f29b706 461 charge = fDigitCalibrator->CalibrateDigit(detElemId, manuId, manuChannel,adc);
b6f591ae 462 }
2b8a1212 463 else
464 {
465 charge = 0.0;
466 }
b6f591ae 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 {
b3d57767 479 fAccumulatedData->Add(*fOneEventData,&nevents);
480 if ( fOneEventData->GetSize() == 0 ) fLastEventWasEmpty = kTRUE;
481 ++fNumberOfGoodPhysicsEvents;
b6f591ae 482 }
64c2397e 483
b3d57767 484 AliDebug(1,Form("n %10d nphysics %10d ngood %10d",fNumberOfEvents,fNumberOfPhysicsEvents,fNumberOfGoodPhysicsEvents));
485
b6f591ae 486 return !badEvent;
487}
488
489
490//_____________________________________________________________________________
491void
492AliMUONTrackerDataMaker::Print(Option_t*) const
493{
494 /// Printout
495
496 cout << "Source=" << Source() << " Running=" << ( IsRunning() ? "YES" : "NO")
497 << endl;
498}
499
500//_____________________________________________________________________________
501void AliMUONTrackerDataMaker::Rewind()
502{
503 /// Rewind events
504 if ( fIsOwnerOfRawReader )
505 {
506 fRawReader->RewindEvents();
507 fNumberOfEvents=0;
b3d57767 508 fNumberOfPhysicsEvents=0;
509 fNumberOfGoodPhysicsEvents=0;
b6f591ae 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//_____________________________________________________________________________
518Long64_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);
747b5cbb 532 if (!data)
b6f591ae 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//_____________________________________________________________________________
551void
552AliMUONTrackerDataMaker::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}