From b3d5776767e4241b5cb5f3a9870767739d5ffe9f Mon Sep 17 00:00:00 2001 From: laphecet Date: Sun, 16 May 2010 22:26:01 +0000 Subject: [PATCH] Major update of the way we make QA of the occupancy, and of what we present to the DQM shifter. * DataMaker Now at the level of raw data, the occupancy (OccRaws) is really that of raw data, i.e. if one channel is on the data stream, it is counted (previously we first redid the pedestal subtraction). We also added the occupancy at the level of the calibrated digits (OccDigits) (this is the same thing we had before at the raw level) and at the recpoints level (OccRecPoints) (i.e. for only those digits that belong to a reconstructed cluster). In principle, OccRaws > OccDigits > OccRecPoints. Fixed a bug in the bin size of the buspatch occupancy. Adding accounting of empty events in the (previously known as readout error plot) readout status plot, to make it easier to spot raw data corruption. * DataChecker Follow-up the change of signature of AliQACheckerBase::Check method, so now checking (for Raws) is working again. * DQM We also added, for Raws, a plot with the DDL event size. It is obviously related to the occupancy, but the relationship between to two is not exactly straightforward. That plot is replacing the DDL occupancy one for the shifter. So now the shifter sees Mean event size per DDL and a summary of the readout errors (including the empty events). --- MUON/AliMUONQAChecker.cxx | 9 +- MUON/AliMUONQAChecker.h | 2 +- MUON/AliMUONQADataMakerRec.cxx | 88 +- MUON/AliMUONQADataMakerRec.h | 10 + MUON/AliMUONQAIndices.h | 39 +- MUON/AliMUONQAMappingCheck.cxx | 3 + MUON/AliMUONRecoParam.cxx | 30 +- MUON/AliMUONRecoParam.h | 33 +- MUON/AliMUONTrackerConditionDataMaker.cxx | 15 +- MUON/AliMUONTrackerConditionDataMaker.h | 5 +- MUON/AliMUONTrackerDataMaker.cxx | 71 +- MUON/AliMUONTrackerDataMaker.h | 22 +- MUON/AliMUONTrackerQAChecker.cxx | 421 +++++++--- MUON/AliMUONTrackerQAChecker.h | 29 +- MUON/AliMUONTrackerQADataMakerRec.cxx | 964 ++++++++++++++++------ MUON/AliMUONTrackerQADataMakerRec.h | 55 +- MUON/AliMUONVQADataMakerRec.h | 5 + MUON/AliMUONVTrackerDataMaker.h | 3 + 18 files changed, 1325 insertions(+), 479 deletions(-) diff --git a/MUON/AliMUONQAChecker.cxx b/MUON/AliMUONQAChecker.cxx index f7940b2bd5e..463ef7d00a0 100644 --- a/MUON/AliMUONQAChecker.cxx +++ b/MUON/AliMUONQAChecker.cxx @@ -51,8 +51,8 @@ AliMUONQAChecker::~AliMUONQAChecker() } //______________________________________________________________________________ -Double_t * -AliMUONQAChecker::Check(AliQAv1::ALITASK_t index, +void +AliMUONQAChecker::Check(Double_t* rv, AliQAv1::ALITASK_t index, TObjArray** list, const AliDetectorRecoParam * recoParam) { @@ -64,7 +64,7 @@ AliMUONQAChecker::Check(AliQAv1::ALITASK_t index, AliMUONVQAChecker* qac; const AliMUONRecoParam* muonRecoParam = static_cast(recoParam); AliMUONVQAChecker::ECheckCode* ecc(0x0); - Double_t* rv = new Double_t[AliRecoParam::kNSpecies]; + for ( Int_t i = 0; i < AliRecoParam::kNSpecies; ++i ) { rv[i] = -1.0; @@ -114,9 +114,6 @@ AliMUONQAChecker::Check(AliQAv1::ALITASK_t index, delete[] ecc; } - - - return rv; } //______________________________________________________________________________ diff --git a/MUON/AliMUONQAChecker.h b/MUON/AliMUONQAChecker.h index 955d12a3682..dade2c18e89 100644 --- a/MUON/AliMUONQAChecker.h +++ b/MUON/AliMUONQAChecker.h @@ -29,7 +29,7 @@ public: protected: - virtual Double_t* Check(AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * recoParam); + virtual void Check(Double_t* test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * recoParam); virtual void SetQA(AliQAv1::ALITASK_t index, Double_t * value) const; diff --git a/MUON/AliMUONQADataMakerRec.cxx b/MUON/AliMUONQADataMakerRec.cxx index 1805aadda01..d66990cc193 100644 --- a/MUON/AliMUONQADataMakerRec.cxx +++ b/MUON/AliMUONQADataMakerRec.cxx @@ -55,6 +55,17 @@ AliMUONQADataMakerRec::~AliMUONQADataMakerRec() delete fTrigger; } +//____________________________________________________________________________ +Int_t AliMUONQADataMakerRec::Add2List(TH1 * hist, const Int_t index, AliQAv1::TASKINDEX_t task, const Bool_t expert, const Bool_t image, const Bool_t saveForCorr) +{ + TObjArray** list = GetList(task); + if (list) + { + return Add2List(hist,index,list,expert,image,saveForCorr); + } + return -1; +} + //____________________________________________________________________________ void AliMUONQADataMakerRec::EndOfDetectorCycle(AliQAv1::TASKINDEX_t task, TObjArray** list) { @@ -64,33 +75,72 @@ void AliMUONQADataMakerRec::EndOfDetectorCycle(AliQAv1::TASKINDEX_t task, TObjAr { if (! IsValidEventSpecie(specie, list) ) continue; - SetEventSpecie(AliRecoParam::ConvertIndex(specie)); - + SetEventSpecie(AliRecoParam::ConvertIndex(specie)); // needed by the GetXXXData methods + if ( task == AliQAv1::kRAWS ) { - if (fTracker) fTracker->EndOfDetectorCycleRaws(specie,list); - if (fTrigger) fTrigger->EndOfDetectorCycleRaws(specie,list); - } - - if ( task == AliQAv1::kRECPOINTS ) + if ( fTracker ) fTracker->EndOfDetectorCycleRaws(specie,list); + if ( fTrigger ) fTrigger->EndOfDetectorCycleRaws(specie,list); + } + else if ( task == AliQAv1::kRECPOINTS ) { // normalize recpoints histograms - if (fTracker) fTracker->EndOfDetectorCycleRecPoints(specie,list); - if (fTrigger) fTrigger->EndOfDetectorCycleRecPoints(specie,list); + if ( fTracker ) fTracker->EndOfDetectorCycleRecPoints(specie,list); + if ( fTrigger ) fTrigger->EndOfDetectorCycleRecPoints(specie,list); } - - if ( task == AliQAv1::kESDS ) + else if ( task == AliQAv1::kESDS ) { // normalize esds histograms - if (fTracker) fTracker->EndOfDetectorCycleESDs(specie,list); - if (fTrigger) fTrigger->EndOfDetectorCycleESDs(specie,list); + if ( fTracker ) fTracker->EndOfDetectorCycleESDs(specie,list); + if ( fTrigger ) fTrigger->EndOfDetectorCycleESDs(specie,list); + } + else if ( task == AliQAv1::kDIGITSR ) + { + if ( fTracker ) fTracker->EndOfDetectorCycleDigits(specie,list); + if ( fTrigger ) fTrigger->EndOfDetectorCycleDigits(specie,list); + } + else + { + AliFatal(Form("Not implemented for task %s",AliQAv1::GetTaskName(task).Data())); } - } // loop on specie + } // loop on specie // do the QA checking AliQAChecker::Instance()->Run(AliQAv1::kMUON,task,list,const_cast(GetRecoParam())); } +//____________________________________________________________________________ +TObject* AliMUONQADataMakerRec::GetData(AliQAv1::TASKINDEX_t task, const Int_t index) +{ + TObjArray** list = GetList(task); + if (list) return GetData(list,index); + return 0x0; +} + +//____________________________________________________________________________ +TObjArray** AliMUONQADataMakerRec::GetList(AliQAv1::TASKINDEX_t task) +{ + // enum TASKINDEX_t { + // kNULLTASKINDEX=-1, kRAWS, kHITS, kSDIGITS, kDIGITS, kDIGITSR, kRECPOINTS, kTRACKSEGMENTS, kRECPARTICLES, kESDS, kNTASKINDEX }; + if ( task == AliQAv1::kRAWS ) + { + return fRawsQAList; + } + else if ( task == AliQAv1::kDIGITS || task == AliQAv1::kDIGITSR ) + { + return fDigitsQAList; + } + else if ( task == AliQAv1::kRECPOINTS ) + { + return fRecPointsQAList; + } + else + { + AliFatal(Form("task %s not supported here yet",AliQAv1::GetTaskName(task).Data())); + } + return 0x0; +} + //____________________________________________________________________________ void AliMUONQADataMakerRec::InitRaws() { @@ -151,7 +201,7 @@ void AliMUONQADataMakerRec::MakeDigits() { /// makes data from Digits - AliError("Not implemented"); + AliFatal("Not implemented"); } //__________________________________________________________________ @@ -160,7 +210,7 @@ void AliMUONQADataMakerRec::MakeDigits(TTree* digitsTree) /// makes data from Digits // Do nothing in case of calibration event - if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib ) return; + if ( GetEventSpecie() == AliRecoParam::kCalib ) return; if ( fTracker ) fTracker->MakeDigits(digitsTree); if ( fTrigger ) fTrigger->MakeDigits(digitsTree); @@ -172,7 +222,7 @@ void AliMUONQADataMakerRec::MakeRecPoints(TTree* clustersTree) /// Fill histograms from treeR // Do nothing in case of calibration event - if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib ) return; + if ( GetEventSpecie() == AliRecoParam::kCalib ) return; if ( fTracker ) fTracker->MakeRecPoints(clustersTree); if ( fTrigger ) fTrigger->MakeRecPoints(clustersTree); @@ -184,7 +234,7 @@ void AliMUONQADataMakerRec::MakeESDs(AliESDEvent* esd) /// make QA data from ESDs // Do nothing in case of calibration event - if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib ) return; + if ( GetEventSpecie() == AliRecoParam::kCalib ) return; if ( fTracker ) fTracker->MakeESDs(esd); if ( fTrigger ) fTrigger->MakeESDs(esd); @@ -223,7 +273,7 @@ void AliMUONQADataMakerRec::ResetDetector(AliQAv1::TASKINDEX_t task) } else { - AliError("Not implemented"); + AliFatal(Form("Not implemented for task %s",AliQAv1::GetTaskName(task).Data())); } } } diff --git a/MUON/AliMUONQADataMakerRec.h b/MUON/AliMUONQADataMakerRec.h index 861ee770303..899d1a2636b 100644 --- a/MUON/AliMUONQADataMakerRec.h +++ b/MUON/AliMUONQADataMakerRec.h @@ -44,12 +44,22 @@ public: virtual void ResetDetector(AliQAv1::TASKINDEX_t task); + using AliQADataMakerRec::Add2List; + using AliQADataMakerRec::GetData; + + Int_t Add2List(TH1 * hist, const Int_t index, AliQAv1::TASKINDEX_t task, const Bool_t expert, const Bool_t image, const Bool_t saveForCorr); + + TObject* GetData(AliQAv1::TASKINDEX_t task, const Int_t index) ; + private: /// Not implemented AliMUONQADataMakerRec(const AliMUONQADataMakerRec& qadm); /// Not implemented AliMUONQADataMakerRec& operator=(const AliMUONQADataMakerRec& qadm); + TObjArray** GetList(AliQAv1::TASKINDEX_t taks); + +private: AliMUONVQADataMakerRec* fTracker; ///< tracker sub-qadatamaker AliMUONVQADataMakerRec* fTrigger; ///< trigger sub-qadatamaker diff --git a/MUON/AliMUONQAIndices.h b/MUON/AliMUONQAIndices.h index d130f34079c..9e5722a6942 100644 --- a/MUON/AliMUONQAIndices.h +++ b/MUON/AliMUONQAIndices.h @@ -15,20 +15,25 @@ namespace AliMUONQAIndices { - /// Raw histograms indices + /// Raw/digits histograms indices enum ERaw { - kTrackerData = 3, ///< Accumulated data - kTrackerBusPatchOccupancy = 4, ///< Bus patch occupancies - kTrackerBusPatchNofPads = 5, ///< Number of pads per bus patch - kTrackerBusPatchNofManus = 6, ///< Number of manus per bus patch - kTrackerBusPatchConfig = 7, ///< Configuration of the tracker - kTrackerBusPatchParityErrors = 8, ///< Parity errors during readout of the tracker - kTrackerBusPatchTokenLostErrors = 9, ///< Token lost errors during readout of the tracker - kTrackerBusPatchPaddingErrors = 10, ///< Padding errors during readout of the tracker - kTrackerNofRawEventSeen = 11, ///< Number of events seen (and used) - kTrackerReadoutErrors = 12, ///< Integrated number of errors (and events for 1st bin) - kTrackerDDLOccupancy = 13, ///< DDL occupancy in percent - kTrackerDDLNofEvents = 14, ///< nof of events per DDL + + kTrackerData = 3, ///< Accumulated data + kTrackerBusPatchOccupancy = 4, ///< Bus patch occupancies + kTrackerReadoutStatusPerEvent = 6, ///< as kTrackerReadoutStatus but normalized by the number of events + kTrackerBusPatchConfig = 7, ///< Configuration of the tracker + kTrackerBusPatchParityErrors = 8, ///< Parity errors during readout of the tracker + kTrackerBusPatchTokenLostErrors = 9, ///< Token lost errors during readout of the tracker + kTrackerBusPatchPaddingErrors = 10, ///< Padding errors during readout of the tracker + kTrackerNofPhysicsEventsSeen = 11, ///< Number of events seen + kTrackerReadoutStatus = 12, ///< Status of readout (errors, missing pads, etc...) + kTrackerDDLOccupancy = 13, ///< DDL occupancy in percent + kTrackerDDLNofEventsSeen = 14, ///< nof of events per DDL (seen) + kTrackerDDLEventSize = 300, ///< event size per DDL + kTrackerDDLEventSizePerEvent = 15, ///< event size per DDL per event + kTrackerNofGoodPhysicsEventsUsed = 401, ///< Number of good physics events seen (and used) *WARNING* let 401 be unique in all levels, i.e. Raws,Digits,RecPoints + kTrackerDDLNofEventsUsed = 402, ///< nof of events per DDL (used) + kTriggerScalersTime = 22, ///< Trigger scalers acquisition time index kTriggerScalers = 23, ///< Trigger scalers histogram per plane index kTriggerScalersDisplay = 31, ///< Trigger scalers display histogram per plane index @@ -66,6 +71,7 @@ namespace AliMUONQAIndices kTriggerRatio4434SinceLastUpdate = 103, ///< Ratio 44/34 for the last kUpdateRatio4434 events vs Event Number kTriggerNumberOf34Dec = 104, ///< Number of Decision in coincidence 3/4 vs Local Board kTriggerNumberOf44Dec = 105 ///< Number of Decision in coincidence 4/4 vs Local Board + }; /// Rec points histograms indices @@ -189,12 +195,15 @@ namespace AliMUONQAIndices }; // Bins for tracker readout errors - enum ETrackerReadoutErrors + enum ETrackerReadoutStatus { kTrackerRawNofGlitchErrors = 0, ///< Bin for number of glitch errors kTrackerRawNofTokenLostErrors = 1, ///< Bin for number of token lost errors kTrackerRawNofParityErrors = 2, ///< Bin for number of parity errors - kTrackerRawNofPaddingErrors = 3 ///< Bin for number of padding errors + kTrackerRawNofPaddingErrors = 3, ///< Bin for number of padding errors + kTrackerRawNofEmptyEvents = 4, ///< Bin for number of empty events + kTrackerRawNofMissingBusPatchesFromConfig = 5 , ///< Bin for number of missing bus patches (in config) + kTrackerRawNofMissingBusPatchesFromDataStream = 6 ///< Bin for number of missing bus patches (in actual data) }; } diff --git a/MUON/AliMUONQAMappingCheck.cxx b/MUON/AliMUONQAMappingCheck.cxx index 3ade857adf5..78c66961afe 100644 --- a/MUON/AliMUONQAMappingCheck.cxx +++ b/MUON/AliMUONQAMappingCheck.cxx @@ -31,6 +31,7 @@ #include "AliMUONQAMappingCheck.h" #include "AliCDBManager.h" +#include "AliCodeTimer.h" #include "AliLog.h" #include "AliMUON2DMap.h" #include "AliMUONDigitCalibrator.h" @@ -66,6 +67,8 @@ fNumberOfLegitimateMonoCathodeClusters(0) { /// Ctor + AliCodeTimerAuto(Form("RUN %d",runNumber),0); + fGeometryTransformer->LoadGeometryData(); // Init the store with all the manus. Note that this is not strictly necessary, diff --git a/MUON/AliMUONRecoParam.cxx b/MUON/AliMUONRecoParam.cxx index b238512507d..b9c9fbeb28e 100644 --- a/MUON/AliMUONRecoParam.cxx +++ b/MUON/AliMUONRecoParam.cxx @@ -73,10 +73,13 @@ AliMUONRecoParam::AliMUONRecoParam() fMaxTriggerTracks(0), fMaxTrackCandidates(0), fSelectTrackOnSlope(kFALSE), - fMissingPadFractionLimit(0), + fMissingPadFractionLimit(-1), fFractionOfBuspatchOutsideOccupancyLimit(0), fAverageNoisePadCharge(0.22875), - fClusterChargeCut(2.0) + fClusterChargeCut(2.0), + fEventSizeSoftLimit(35.0), + fEventSizeHardLimit(45.0), + fTokenLostLimit(0.0) { /// Constructor @@ -302,9 +305,8 @@ void AliMUONRecoParam::SetCosmicParam() SetPedMeanLimits(20, 700); SetManuOccupancyLimits(-1.,0.01); // reject manu above occ=1% - SetBuspatchOccupancyLimits(-1,0.01); - SetMissingPadFractionLimit(0.1); // 10 % - SetFractionOfBuspatchOutsideOccupancyLimit(0.05); // 5 % + SetBuspatchOccupancyLimits(-1,0.05); + SetFractionOfBuspatchOutsideOccupancyLimit(0.10); // 10 % } @@ -494,8 +496,16 @@ void AliMUONRecoParam::Print(Option_t *option) const cout << Form("%e <= DE occupancy < %7.2f",DEOccupancyLowLimit(),DEOccupancyHighLimit()) << endl; cout << "'QAChecker' limits" << endl; - cout << Form("MissingPadFractionLimit = %5.2f %%",MissingPadFractionLimit()*100.0) << endl; cout << Form("FractionOfBuspatchOutsideOccupancyLimit = %5.2f %%",FractionOfBuspatchOutsideOccupancyLimit()*100.0) << endl; + cout << Form("Event size limit = %5.2f KB/event (soft) and %5.2f KB/event (hard)",fEventSizeSoftLimit,fEventSizeHardLimit) << endl; + if ( fTokenLostLimit > 0 ) + { + cout << Form("We tolerate up to %5.2f %% token lost errors per event",fTokenLostLimit) << endl; + } + else + { + cout << "We dot not tolerate any token lost error !" << endl; + } cout << "chamber non bending resolution = |"; for (Int_t iCh = 0; iCh < 10; iCh++) cout << Form(" %6.3f |",fDefaultNonBendingReso[iCh]); @@ -553,13 +563,17 @@ AliMUONRecoParam::SetDefaultLimits() fDEOccupancyLimits[0] = -1.0; fDEOccupancyLimits[1] = 1.0; - fMissingPadFractionLimit = 0.1; // 10 % - fFractionOfBuspatchOutsideOccupancyLimit = 0.05; // 5 % + fMissingPadFractionLimit = -1; // DEPRECATED + fFractionOfBuspatchOutsideOccupancyLimit = 0.10; // 10 % ChargeSigmaCut(4.0); // pad with charge < 4.0 x sigma will be removed (where sigma is the actual noise of that very pad, i.e. not the average) AverageNoisePadCharge(0.22875); // 0.22875 coulombs ~ 1.5 ADC channels ClusterChargeCut(2.0); // will cut cluster below 2.0 x LowestPadCharge() + + SetEventSizeLimits(35.0,45.0); + + SetTokenLostLimit(0.0); } diff --git a/MUON/AliMUONRecoParam.h b/MUON/AliMUONRecoParam.h index 3da391d24d4..964240680b8 100644 --- a/MUON/AliMUONRecoParam.h +++ b/MUON/AliMUONRecoParam.h @@ -300,11 +300,6 @@ class AliMUONRecoParam : public AliDetectorRecoParam /// Retrieve high value of DE occupancy limit Float_t DEOccupancyHighLimit() const { return fDEOccupancyLimits[1]; } - /// Set the missing pad fraction limit - void SetMissingPadFractionLimit(float v) { fMissingPadFractionLimit = v; } - /// Get the missing pad fraction limit - Float_t MissingPadFractionLimit() const { return fMissingPadFractionLimit; } - /// Set the fraction of buspatches outside the occupancy limits void SetFractionOfBuspatchOutsideOccupancyLimit(float v) { fFractionOfBuspatchOutsideOccupancyLimit = v; } /// Get the fraction of buspatches outside the occupancy limits @@ -312,7 +307,22 @@ class AliMUONRecoParam : public AliDetectorRecoParam virtual void Print(Option_t *option = "") const; - private: + /// Get the max event size (soft limit) + virtual Double_t EventSizeSoftLimit() const { return fEventSizeSoftLimit; } + + /// Get the max event size (hard limit) + virtual Double_t EventSizeHardLimit() const { return fEventSizeHardLimit; } + + /// Set the max event size limits + virtual void SetEventSizeLimits(Double_t soft, Double_t hard) { fEventSizeSoftLimit=soft; fEventSizeHardLimit=hard; } + + /// Get the percentage of token lost error we allow + virtual Double_t TokenLostLimit() const { return fTokenLostLimit; } + + /// Set the percentage of token lost error we allo + virtual void SetTokenLostLimit(Double_t limit) { fTokenLostLimit = limit; } + +private: void SetDefaultLimits(); @@ -403,19 +413,26 @@ class AliMUONRecoParam : public AliDetectorRecoParam Double32_t fBuspatchOccupancyLimits[2]; ///< low and high thresholds for bus patch occupancy cut Double32_t fDEOccupancyLimits[2]; ///< low and high thresholds for DE occupancy cut - Double32_t fMissingPadFractionLimit; ///< above this fraction, we consider we have too few pads alive... + Double32_t fMissingPadFractionLimit; ///< DEPRECATED Double32_t fFractionOfBuspatchOutsideOccupancyLimit; ///< above this limit, we consider we have too many buspatches out of the allowed occupancy range Double32_t fAverageNoisePadCharge; ///< the (truncated, typically at 10%) mean of the sigma of the pedestals, in femto-coulomb Double32_t fClusterChargeCut; ///< the cluster is cut if its charge is below fClusterChargeCut*LowestPadCharge() + Double32_t fEventSizeSoftLimit; ///< (soft) limit on mean event size per event (KB) + Double32_t fEventSizeHardLimit; ///< (hard) limit on mean event size per event (KB) + + Double32_t fTokenLostLimit; ///< limit on the fraction of token lost error per event we allow + // functions void SetLowFluxParam(); void SetHighFluxParam(); void SetCosmicParam(); void SetCalibrationParam(); - ClassDef(AliMUONRecoParam,166) // MUON reco parameters + ClassDef(AliMUONRecoParam,167) // MUON reco parameters + // we're at 167 not because we had that many versions, but because at some point (version 15->16) + // 166 was committed by error, and we did not to go reverse afterwards... }; #endif diff --git a/MUON/AliMUONTrackerConditionDataMaker.cxx b/MUON/AliMUONTrackerConditionDataMaker.cxx index 7e949dd00a7..7e46775c773 100644 --- a/MUON/AliMUONTrackerConditionDataMaker.cxx +++ b/MUON/AliMUONTrackerConditionDataMaker.cxx @@ -60,7 +60,8 @@ ClassImp(AliMUONTrackerConditionDataMaker) AliMUONTrackerConditionDataMaker::AliMUONTrackerConditionDataMaker(): AliMUONVTrackerDataMaker(), fData(0x0), -fSource("") +fSource(""), +fIsOwnerOfData(kTRUE) { /// default ctor to be able to stream } @@ -69,7 +70,8 @@ fSource("") AliMUONTrackerConditionDataMaker::AliMUONTrackerConditionDataMaker(Int_t runNumber, const char* ocdbPath, const char* type): AliMUONVTrackerDataMaker(), fData(0x0), -fSource(Form("%s-%010d-%s",ocdbPath,runNumber,type)) +fSource(Form("%s-%010d-%s",ocdbPath,runNumber,type)), +fIsOwnerOfData(kTRUE) { /// ctor from OCDB @@ -95,7 +97,8 @@ fSource(Form("%s-%010d-%s",ocdbPath,runNumber,type)) AliMUONTrackerConditionDataMaker::AliMUONTrackerConditionDataMaker(const char* filename, const char* type): AliMUONVTrackerDataMaker(), fData(0x0), -fSource(Form("%s-%s",filename,type)) +fSource(Form("%s-%s",filename,type)), +fIsOwnerOfData(kTRUE) { /// ctor from an ASCII file @@ -129,7 +132,9 @@ fSource(Form("%s-%s",filename,type)) AliMUONTrackerConditionDataMaker::AliMUONTrackerConditionDataMaker(const char* data, const char* type, Bool_t) : AliMUONVTrackerDataMaker(), fData(0x0), -fSource(Form("direct-%s",type)) +fSource(Form("direct-%s",type)), +fIsOwnerOfData(kTRUE) + { /// ctor from a string containing the ASCII data /// the last parameter is there just to distinguish this ctor from the previous one @@ -150,7 +155,7 @@ fSource(Form("direct-%s",type)) AliMUONTrackerConditionDataMaker::~AliMUONTrackerConditionDataMaker() { /// dtor - delete fData; + if ( fIsOwnerOfData ) delete fData; } diff --git a/MUON/AliMUONTrackerConditionDataMaker.h b/MUON/AliMUONTrackerConditionDataMaker.h index baced27f99d..a2ba94ca324 100644 --- a/MUON/AliMUONTrackerConditionDataMaker.h +++ b/MUON/AliMUONTrackerConditionDataMaker.h @@ -35,6 +35,8 @@ public: static AliMUONVTrackerData* CreateData(const char* type, AliMUONVStore& source, Int_t startOfValidity); + virtual void SetOwnerOfData(Bool_t flag) { fIsOwnerOfData = flag; } + /// Whether we've been properly initialized or not Bool_t IsValid() const { return (fData != 0x0); } @@ -82,8 +84,9 @@ private: private: AliMUONVTrackerData* fData; ///< our data TString fSource; ///< source name + Bool_t fIsOwnerOfData; ///< is fData ours or not - ClassDef(AliMUONTrackerConditionDataMaker,1) // Producer of AliMUONVTrackerData from condition data (either OCDB or ascii files) + ClassDef(AliMUONTrackerConditionDataMaker,2) // Producer of AliMUONVTrackerData from condition data (either OCDB or ascii files) }; #endif diff --git a/MUON/AliMUONTrackerDataMaker.cxx b/MUON/AliMUONTrackerDataMaker.cxx index 239d7c0d6c7..fa78ec0e2ed 100644 --- a/MUON/AliMUONTrackerDataMaker.cxx +++ b/MUON/AliMUONTrackerDataMaker.cxx @@ -53,6 +53,7 @@ AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(TRootIOCtor*) AliMUONVTrackerDataMaker(), fRawReader(0x0), fAccumulatedData(0x0), +fIsOwnerOfAccumulatedData(kTRUE), fOneEventData(0x0), fDigitCalibrator(0x0), fCalibrationData(0x0), @@ -63,7 +64,10 @@ fRunNumber(0), fIsRunning(kFALSE), fIsOwnerOfRawReader(kFALSE), fIsEventByEvent(kFALSE), -fLogger(0x0) +fLogger(0x0), +fLastEventWasEmpty(kFALSE), +fNumberOfPhysicsEvents(0), +fNumberOfGoodPhysicsEvents(0) { /// Root IO ctor } @@ -81,6 +85,7 @@ AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(const AliMUONRecoParam* recoPar AliMUONVTrackerDataMaker(), fRawReader(rawReader), fAccumulatedData(0x0), +fIsOwnerOfAccumulatedData(kTRUE), fOneEventData(new AliMUON2DMap(true)), fDigitCalibrator(0x0), fCalibrationData(0x0), @@ -91,7 +96,10 @@ fRunNumber(runNumber), fIsRunning(kFALSE), fIsOwnerOfRawReader(kFALSE), fIsEventByEvent(kFALSE), -fLogger(0x0) +fLogger(0x0), +fLastEventWasEmpty(kFALSE), +fNumberOfPhysicsEvents(0), +fNumberOfGoodPhysicsEvents(0) { /// Ctor in which this object will NOT be the owner of the reader /// and can NOT apply rewind to it, nor use Next on it. @@ -111,6 +119,7 @@ AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(const AliMUONRecoParam* recoPar AliMUONVTrackerDataMaker(), fRawReader(rawReader), fAccumulatedData(0x0), +fIsOwnerOfAccumulatedData(kTRUE), fOneEventData(new AliMUON2DMap(true)), fDigitCalibrator(0x0), fCalibrationData(0x0), @@ -121,7 +130,10 @@ fRunNumber(0), fIsRunning(kFALSE), fIsOwnerOfRawReader(kTRUE), fIsEventByEvent(kFALSE), -fLogger(0x0) +fLogger(0x0), +fLastEventWasEmpty(kFALSE), +fNumberOfPhysicsEvents(0), +fNumberOfGoodPhysicsEvents(0) { /// Ctor in which we take the ownership of the rawReader, so we can rewind /// and advance it as we wish @@ -142,6 +154,7 @@ AliMUONTrackerDataMaker::AliMUONTrackerDataMaker(AliRawReader* rawReader, Bool_t AliMUONVTrackerDataMaker(), fRawReader(rawReader), fAccumulatedData(0x0), +fIsOwnerOfAccumulatedData(kTRUE), fOneEventData(new AliMUON2DMap(true)), fDigitCalibrator(0x0), fCalibrationData(0x0), @@ -152,7 +165,10 @@ fRunNumber(0), fIsRunning(kFALSE), fIsOwnerOfRawReader(kTRUE), fIsEventByEvent(kFALSE), -fLogger(0x0) +fLogger(0x0), +fLastEventWasEmpty(kFALSE), +fNumberOfPhysicsEvents(0), +fNumberOfGoodPhysicsEvents(0) { /// Ctor from raw data reader if (fRawReader) @@ -253,7 +269,7 @@ AliMUONTrackerDataMaker::~AliMUONTrackerDataMaker() /// dtor delete fOneEventData; - delete fAccumulatedData; + if ( fIsOwnerOfAccumulatedData ) delete fAccumulatedData; if ( fIsOwnerOfRawReader ) delete fRawReader; delete fCalibrationData; delete fDigitCalibrator; @@ -279,7 +295,9 @@ AliMUONTrackerDataMaker::Add(const AliMUONTrackerDataMaker& other) fSource += other.fSource; fNumberOfEvents += other.fNumberOfEvents; - + fNumberOfPhysicsEvents += other.fNumberOfPhysicsEvents; + fNumberOfGoodPhysicsEvents += other.fNumberOfGoodPhysicsEvents; + TList list; list.Add(other.fAccumulatedData); @@ -302,9 +320,6 @@ AliMUONTrackerDataMaker::NextEvent() AliCodeTimerAuto("",0); - static Int_t nphysics(0); - static Int_t ngood(0); - if ( !IsRunning() ) return kTRUE; Bool_t ok = fRawReader->NextEvent(); @@ -314,22 +329,7 @@ AliMUONTrackerDataMaker::NextEvent() return kFALSE; } - Int_t eventType = fRawReader->GetType(); - - ++fNumberOfEvents; - - if (eventType != AliRawEventHeaderBase::kPhysicsEvent ) - { - return kTRUE; // for the moment - } - - ++nphysics; - - Bool_t pok = ProcessEvent(); - - if ( pok ) ++ngood; - - AliDebug(1,Form("n %10d nphysics %10d ngood %10d",fNumberOfEvents,nphysics,ngood)); + ProcessEvent(); return kTRUE; } @@ -347,6 +347,19 @@ Bool_t AliMUONTrackerDataMaker::ProcessEvent() /// duplicate this critical piece of calibration code ! /// + ++fNumberOfEvents; + + Int_t eventType = fRawReader->GetType(); + + if (eventType != AliRawEventHeaderBase::kPhysicsEvent ) + { + return kTRUE; // for the moment + } + + ++fNumberOfPhysicsEvents; + + fLastEventWasEmpty = kFALSE; + AliCodeTimerAuto("",0); AliMUONRawStreamTrackerHP stream(fRawReader); @@ -419,9 +432,13 @@ Bool_t AliMUONTrackerDataMaker::ProcessEvent() if (!badEvent) { - fAccumulatedData->Add(*fOneEventData,&nevents); + fAccumulatedData->Add(*fOneEventData,&nevents); + if ( fOneEventData->GetSize() == 0 ) fLastEventWasEmpty = kTRUE; + ++fNumberOfGoodPhysicsEvents; } + AliDebug(1,Form("n %10d nphysics %10d ngood %10d",fNumberOfEvents,fNumberOfPhysicsEvents,fNumberOfGoodPhysicsEvents)); + return !badEvent; } @@ -444,6 +461,8 @@ void AliMUONTrackerDataMaker::Rewind() { fRawReader->RewindEvents(); fNumberOfEvents=0; + fNumberOfPhysicsEvents=0; + fNumberOfGoodPhysicsEvents=0; } else { diff --git a/MUON/AliMUONTrackerDataMaker.h b/MUON/AliMUONTrackerDataMaker.h index 04eb5039767..a5577486e25 100644 --- a/MUON/AliMUONTrackerDataMaker.h +++ b/MUON/AliMUONTrackerDataMaker.h @@ -61,6 +61,9 @@ public: /// Get our accumulated data AliMUONVTrackerData* Data() const { return fAccumulatedData; } + /// Whether or not we're the owner of our fAccumulatedData + void SetOwnerOfData(Bool_t flag) { fIsOwnerOfAccumulatedData = flag; } + /// Whether we're only handling event-by-event data (i.e. no accumulation) Bool_t IsEventByEvent() const { return fIsEventByEvent; } @@ -92,7 +95,13 @@ public: /// Number of events seen Int_t NumberOfEvents() const { return fNumberOfEvents; } - + + /// Number of physics events seen + Int_t NumberOfPhysicsEvents() const { return fNumberOfPhysicsEvents; } + + /// Number of good physics events seen + Int_t NumberOfGoodPhysicsEvents() const { return fNumberOfGoodPhysicsEvents; } + Long64_t Merge(TCollection* li); void SetRawReader(AliRawReader* rawReader); @@ -100,6 +109,9 @@ public: /// Set the error logger void EnableErrorLogger(AliMUONLogger* logger) { fLogger = logger; } + /// Whether last decoded event was empty + Bool_t LastEventWasEmpty() const { return fLastEventWasEmpty; } + private: /// not implemented AliMUONTrackerDataMaker(const AliMUONTrackerDataMaker& rhs); @@ -115,7 +127,8 @@ private: private: AliRawReader* fRawReader; //!< reader of the data (owner or not) - AliMUONVTrackerData* fAccumulatedData; ///< data (owner) + AliMUONVTrackerData* fAccumulatedData; ///< data (owner or not) + Bool_t fIsOwnerOfAccumulatedData; ///< owner or not of fAccumulatedData AliMUONVStore* fOneEventData; ///< data for a single event (owner) AliMUONDigitCalibrator* fDigitCalibrator; //!< digit calibrator (if calibrating) AliMUONCalibrationData* fCalibrationData; ///< calibration data (if calibrating) @@ -128,8 +141,11 @@ private: Bool_t fIsEventByEvent; ///< we only keep one event's data (no accumulation) static Int_t fgkCounter; ///< to count the number of instances AliMUONLogger* fLogger; ///< error logger (not owner) + Bool_t fLastEventWasEmpty; ///< whether last decoded event was empty + Int_t fNumberOfPhysicsEvents; ///< number of physics events seen + Int_t fNumberOfGoodPhysicsEvents; ///< number of errors with no (fatal) readout error - ClassDef(AliMUONTrackerDataMaker,2) // Producer of AliMUONVTrackerData from raw + ClassDef(AliMUONTrackerDataMaker,4) // Producer of AliMUONVTrackerData from raw }; #endif diff --git a/MUON/AliMUONTrackerQAChecker.cxx b/MUON/AliMUONTrackerQAChecker.cxx index 81571f19f5c..6263ee9b2d7 100644 --- a/MUON/AliMUONTrackerQAChecker.cxx +++ b/MUON/AliMUONTrackerQAChecker.cxx @@ -34,15 +34,14 @@ #include "AliMpBusPatch.h" #include "AliMpDDLStore.h" #include "AliQAv1.h" -#include "AliQAv1.h" #include "Riostream.h" #include "TAxis.h" #include "TDirectory.h" +#include "TGaxis.h" #include "TH1.h" #include "TLine.h" #include "TMath.h" #include "TPaveText.h" -#include "TGaxis.h" #include "TVirtualPad.h" /// \cond CLASSIMP @@ -138,19 +137,72 @@ namespace { return 0; } + + //___________________________________________________________________________ + Int_t GetColorFromCheckCode(AliMUONVQAChecker::ECheckCode code) + { + const Int_t INFOCOLOR(kGreen); // green = INFO + const Int_t WARNINGCOLOR(kYellow); // yellow = WARNING + const Int_t ERRORCOLOR(kOrange); // orange = ERROR + const Int_t FATALCOLOR(kRed); // red = FATAL + + if ( code == AliMUONVQAChecker::kInfo ) return INFOCOLOR; + else if ( code == AliMUONVQAChecker::kWarning ) return WARNINGCOLOR; + else if ( code == AliMUONVQAChecker::kFatal) return FATALCOLOR; + else return ERRORCOLOR; + } + + const char* NOTENOUGHEVENTMESSAGE = "Not enough event to judge. Please wait a bit"; + const char* NOTIFYEXPERTMESSAGE = "PLEASE NOTIFY EXPERT !"; + const char* ALLISFINEMESSAGE = "All is fine. Just enjoy."; + + const int NOTENOUGHEVENTLIMIT = 50; //___________________________________________________________________________ - void SetPaveColor(TPaveText& text, AliMUONVQAChecker::ECheckCode code) + void SetupHisto(Int_t neventsseen, Int_t neventsused, const TObjArray& messages, TH1& histo, AliMUONVQAChecker::ECheckCode code, const char* extraopt="") { - const Int_t INFOCOLOR(3); // green = INFO - const Int_t WARNINGCOLOR(5); // yellow = WARNING - const Int_t ERRORCOLOR(6); // pink = ERROR - const Int_t FATALCOLOR(2); // red = FATAL - - if ( code == AliMUONVQAChecker::kInfo ) text.SetFillColor(INFOCOLOR); - else if ( code == AliMUONVQAChecker::kWarning ) text.SetFillColor(WARNINGCOLOR); - else if ( code == AliMUONVQAChecker::kFatal) text.SetFillColor(FATALCOLOR); - else text.SetFillColor(ERRORCOLOR); + Bool_t allIsFine(kFALSE); + + if ( code == AliMUONVQAChecker::kInfo ) + { + allIsFine = kTRUE; + } + + Double_t y1 = 0.99 - (messages.GetLast()+(allIsFine?1:0)+2)*0.075; + + TPaveText* text = new TPaveText(0.5,y1,0.99,0.99,"NDC"); + + text->AddText(Form("MCH RUN %d - %d events seen - %d events used",AliCDBManager::Instance()->GetRun(),neventsseen,neventsused)); + + TIter next(&messages); + TObjString* str; + + while ( ( str = static_cast(next()) ) ) + { + text->AddText(str->String()); + } + + if ( allIsFine ) + { + text->AddText(ALLISFINEMESSAGE); + } + + text->SetFillColor(GetColorFromCheckCode(code)); + + Int_t color = GetColorFromCheckCode(code); + + histo.SetFillStyle(1001); + histo.SetFillColor(color); + TString sopt("BAR"); + sopt += extraopt; + histo.SetOption(sopt.Data()); + + histo.SetTitle(kFALSE); + + TObject* title = histo.GetListOfFunctions()->FindObject("title"); + if (title) title->Delete(); + + histo.GetListOfFunctions()->Add(text); } } @@ -261,28 +313,81 @@ AliMUONTrackerQAChecker::CheckRaws(TObjArray ** list, const AliMUONRecoParam* re for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) { - TH1* hbp = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchOccupancy,AliRecoParam::ConvertIndex(specie)); - - TH1* hnpads = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchNofPads,AliRecoParam::ConvertIndex(specie)); + TH1* hneventsseen = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNofPhysicsEventsSeen,AliRecoParam::ConvertIndex(specie)); + TH1* hneventsused = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNofGoodPhysicsEventsUsed,AliRecoParam::ConvertIndex(specie)); + if (!hneventsseen || !hneventsused ) continue; + + Int_t neventsseen = TMath::Nint(hneventsseen->GetBinContent(1)); + Int_t neventsused = TMath::Nint(hneventsused->GetBinContent(1)); + + if ( !hneventsseen || !hneventsused ) + { + continue; + } + + AliMUONVQAChecker::ECheckCode c1 = AliMUONVQAChecker::kInfo; + AliMUONVQAChecker::ECheckCode c2 = AliMUONVQAChecker::kInfo; + AliMUONVQAChecker::ECheckCode c3 = AliMUONVQAChecker::kInfo; + + TH1* hbp = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchOccupancy,AliRecoParam::ConvertIndex(specie)); TH1* hbpconfig = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchConfig,AliRecoParam::ConvertIndex(specie)); + TH1* hddl = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLOccupancy,AliRecoParam::ConvertIndex(specie)); - TH1* hnevents = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNofRawEventSeen,AliRecoParam::ConvertIndex(specie)); - - TH1* hddl = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLOccupancy,AliRecoParam::ConvertIndex(specie)); - - TH1* hroe = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutErrors,AliRecoParam::ConvertIndex(specie)); - + if ( hbp && hbpconfig && hddl ) + { + c1 = BeautifyOccupancyHistograms(*hddl,*hbp,hbpconfig,neventsseen,neventsused,*recoParam); + } + else + { + AliError(Form("Could not BeautifyOccupancyHistograms : hddl=%p hbpconfig=%p hbp=%p",hddl,hbpconfig,hbp)); + } + TH1* hbuspatchtokenerrors = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchTokenLostErrors,AliRecoParam::ConvertIndex(specie)); + TH1* hrostatus = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutStatus,AliRecoParam::ConvertIndex(specie)); + TH1* hrostatusnorm = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutStatusPerEvent,AliRecoParam::ConvertIndex(specie)); - if ( !hbp || !hnpads || !hnevents || !hddl || !hroe || ! hbuspatchtokenerrors ) + if ( hrostatus && hrostatusnorm && hbuspatchtokenerrors ) { - continue; + c2 = BeautifyReadoutHistograms(*hrostatus,*hrostatusnorm,*hbuspatchtokenerrors, + neventsseen,neventsused,*recoParam); + } + else + { + AliError(Form("Could not BeautifyReadoutHistograms : hrostatus=%p hrostatusnorm=%p hbuspatchtokenerrors=%p", + hrostatus,hrostatusnorm,hbuspatchtokenerrors)); } - Int_t nevents = TMath::Nint(hnevents->GetBinContent(1)); - - rv[specie] = BeautifyHistograms(*hddl,*hbp,*hroe,hbpconfig,*hnpads,*hbuspatchtokenerrors,nevents,*recoParam); + + TH1* heventsize = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLEventSize,AliRecoParam::ConvertIndex(specie)); + TH1* heventsizeperevent = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLEventSizePerEvent,AliRecoParam::ConvertIndex(specie)); + + if ( heventsize && heventsizeperevent ) + { + c3 = BeautifyEventsizeHistograms(*heventsize,*heventsizeperevent, + neventsseen,neventsused,*recoParam); + } + else + { + AliError(Form("Could not BeautifyEventsizeHistograms heventsize=%p heventsizeperevent=%p",heventsize,heventsizeperevent)); + } + + if ( c1 == AliMUONVQAChecker::kFatal || c2 == AliMUONVQAChecker::kFatal || c3 == AliMUONVQAChecker::kFatal ) + { + rv[specie] = AliMUONVQAChecker::kFatal; + } + else if ( c1 == AliMUONVQAChecker::kError || c2 == AliMUONVQAChecker::kError || c3 == AliMUONVQAChecker::kError ) + { + rv[specie] = AliMUONVQAChecker::kError; + } + else if ( c1 == AliMUONVQAChecker::kWarning || c2 == AliMUONVQAChecker::kWarning || c3 == AliMUONVQAChecker::kWarning ) + { + rv[specie] = AliMUONVQAChecker::kWarning; + } + else + { + rv[specie] = AliMUONVQAChecker::kInfo; + } } return rv; @@ -290,16 +395,14 @@ AliMUONTrackerQAChecker::CheckRaws(TObjArray ** list, const AliMUONRecoParam* re //____________________________________________________________________________ AliMUONVQAChecker::ECheckCode -AliMUONTrackerQAChecker::BeautifyHistograms(TH1& hddl, - TH1& hbp, - TH1& hroe, - const TH1* hbuspatchconfig, - const TH1& hnpads, - const TH1& hbuspatchtokenerrors, - Int_t nevents, - const AliMUONRecoParam& recoParam) +AliMUONTrackerQAChecker::BeautifyOccupancyHistograms(TH1& hddl, + TH1& hbp, + const TH1* hbuspatchconfig, + Int_t neventsseen, + Int_t neventsused, + const AliMUONRecoParam& recoParam) { - /// Put labels, limits and so on on the TrackerBusPatchOccupancy and TrackerReadoutErrors histograms + /// Put labels, limits and so on on the TrackerBusPatchOccupancy histograms /// hbuspatchconfig and hbp must have the same bin definitions if ( hbuspatchconfig ) @@ -313,6 +416,9 @@ AliMUONTrackerQAChecker::BeautifyHistograms(TH1& hddl, } } + hbp.GetListOfFunctions()->Delete(); + hddl.GetListOfFunctions()->Delete(); + hddl.SetStats(kFALSE); hbp.SetXTitle("Absolute Bus Patch Id"); hbp.SetYTitle("Occupancy (percent)"); hbp.SetStats(kFALSE); @@ -337,23 +443,17 @@ AliMUONTrackerQAChecker::BeautifyHistograms(TH1& hddl, TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator()); AliMpBusPatch* bp(0x0); - Int_t nMissingPads(0); - Int_t nPads(0); Int_t nBusPatches(0); Int_t nMissingBusPatches(0); while ( ( bp = static_cast(next())) ) { - Int_t bin = hbp.FindBin(bp->GetId()); - Int_t n = TMath::Nint(hnpads.GetBinContent(bin)); - ++nBusPatches; - nPads += n; + Int_t bin = hbp.FindBin(bp->GetId()); - if ( hbp.GetBinContent(bin) <= 0 ) + if ( hbp.GetBinContent(bin) <= 0.0 ) { - nMissingPads += n; ++nMissingBusPatches; } } @@ -367,7 +467,6 @@ AliMUONTrackerQAChecker::BeautifyHistograms(TH1& hddl, Double_t alpha(0.1); // trim 10% of data Double_t tmean(0.0),tvar(0.0); Double_t ymin(0.0),ymax(0.0); - AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kFatal); // default value = serious problem if ( nBusPatches ) { @@ -416,115 +515,199 @@ AliMUONTrackerQAChecker::BeautifyHistograms(TH1& hddl, hbp.SetMaximum(ymax*1.4); - TPaveText* text = new TPaveText(0.30,0.50,0.99,0.99,"NDC"); - - text->AddText(Form("MCH RUN %d - %d events",AliCDBManager::Instance()->GetRun(),nevents)); + AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo); + + TObjArray messages; + messages.SetOwner(kTRUE); - if ( ok < 0 ) - { - text->AddText("Could not compute truncated mean. Not enough events ?"); - text->AddText(Form("nBusPatches=%d n=%d",nBusPatches,n)); - } - else if (!nPads || !nBusPatches) + if ( neventsseen < NOTENOUGHEVENTLIMIT ) { - text->AddText(Form("Could not get the total number of pads (%d) or total number of buspatches (%d). ERROR !!!", - nPads,nBusPatches)); + messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE)); } else { - Float_t missingPadFraction = nMissingPads*100.0/nPads; - Float_t missingBusPatchFraction = nMissingBusPatches*100.0/nBusPatches; - Float_t aboveLimitFraction = nBusPatchesAboveLimit*100.0/nBusPatches; - Float_t belowLimitFraction = nBusPatchesBelowLimit*100.0/nBusPatches; - - text->AddText(Form("%5.2f %% of missing buspatches (%d out of %d)",missingBusPatchFraction,nMissingBusPatches,nBusPatches)); - text->AddText(Form("%5.2f %% of missing pads (%d out of %d)",missingPadFraction,nMissingPads,nPads)); - text->AddText(Form("%5.2f %% bus patches above the %5.2f %% limit",aboveLimitFraction,maxToleratedOccupancy)); - text->AddText(Form("%5.2f %% bus patches below the %e %% limit",belowLimitFraction,minToleratedOccupancy)); - text->AddText(Form("Bus patch mean occupancy (truncated at %2d %%) is %7.2f %%",(Int_t)(alpha*100),tmean)); - - if ( missingPadFraction >= 100.0 ) + if ( ok < 0 ) { - rv = AliMUONVQAChecker::kFatal; + messages.Add(new TObjString("Could not compute truncated mean. Not enough events ?")); + + if ( neventsused < TMath::Nint(0.1*neventsseen) ) + { + messages.Add(new TObjString(Form("We've actually seen %d events, but used only %d !",neventsseen,neventsused))); + messages.Add(new TObjString("For a normal physics run, this is highly suspect !")); + messages.Add(new TObjString(NOTIFYEXPERTMESSAGE)); + rv = AliMUONVQAChecker::kFatal; + } } - - else if ( missingPadFraction > recoParam.MissingPadFractionLimit()*100.0 || - aboveLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 || - belowLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 ) + else if (!nBusPatches) { - rv = AliMUONVQAChecker::kError; + messages.Add(new TObjString(Form("Could not get the total number of buspatches (%d). ERROR !!!", + nBusPatches))); + messages.Add(new TObjString("Please check with expert !")); + rv = AliMUONVQAChecker::kFatal; } else { - rv = AliMUONVQAChecker::kInfo; + Float_t missingBusPatchFraction = nMissingBusPatches*100.0/nBusPatches; + Float_t aboveLimitFraction = nBusPatchesAboveLimit*100.0/nBusPatches; + Float_t belowLimitFraction = nBusPatchesBelowLimit*100.0/nBusPatches; + + messages.Add(new TObjString(Form("%5.2f %% of missing buspatches (%d out of %d)",missingBusPatchFraction,nMissingBusPatches,nBusPatches))); + messages.Add(new TObjString(Form("%5.2f %% bus patches above the %5.2f %% limit",aboveLimitFraction,maxToleratedOccupancy))); + messages.Add(new TObjString(Form("%5.2f %% bus patches below the %e %% limit",belowLimitFraction,minToleratedOccupancy))); + messages.Add(new TObjString(Form("Bus patch mean occupancy (truncated at %2d %%) is %7.2f %%",(Int_t)(alpha*100),tmean))); + + if ( aboveLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 || + belowLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 ) + { + rv = AliMUONVQAChecker::kError; + } + else + { + rv = AliMUONVQAChecker::kInfo; + } } } - hbp.GetListOfFunctions()->Add(text); + SetupHisto(neventsseen,neventsused,messages,hbp,rv); - - SetPaveColor(*text,rv); - /// Make as well a version for DDL occupancy, that'll be used by the shifter + SetupHisto(neventsseen,neventsused,messages,hddl,rv); - hddl.GetListOfFunctions()->Add(text->Clone()); - - Bool_t aboveOnePercent(kFALSE); - Bool_t aboveTwoPercent(kFALSE); - - for ( Int_t i = 1; i <= hddl.GetXaxis()->GetNbins(); ++i ) - { - Double_t b = hddl.GetBinContent(i); - if ( b > 1.0 ) aboveOnePercent = kTRUE; - if ( b > 2.0 ) aboveTwoPercent = kTRUE; - - } - hddl.SetMaximum(2); - hddl.SetFillStyle(0); - if ( aboveOnePercent ) - { - hddl.SetFillStyle(1001); - hddl.SetFillColor(kOrange); - } - if ( aboveTwoPercent ) - { - hddl.SetFillStyle(1001); - hddl.SetFillColor(kRed); - } - hddl.SetLineWidth(3); hddl.SetStats(kFALSE); - /// Finally make another pavetext for readout errors, in particular TokenLost ones ! + return rv; +} + +//______________________________________________________________________________ +AliMUONVQAChecker::ECheckCode +AliMUONTrackerQAChecker::BeautifyReadoutHistograms(TH1& hrostatus, + TH1& hrostatusnorm, + const TH1& hbuspatchtokenerrors, + Int_t neventsseen, + Int_t neventsused, + const AliMUONRecoParam& recoParam) +{ + /// Normalize and put some text on the readout error histogram + /// Note in particular the treatment of tokenlost errors ! + + hrostatus.GetListOfFunctions()->Delete(); + hrostatusnorm.GetListOfFunctions()->Delete(); + hrostatusnorm.Reset(); + hrostatusnorm.SetFillStyle(0); - Double_t tokenLost = hroe.GetBinContent(hroe.FindBin(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors)); + AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo); - AliInfo(Form("tokenLost=%e",tokenLost)); + TObjArray messages; + messages.SetOwner(kTRUE); - if ( tokenLost > 0 ) + if ( neventsseen < NOTENOUGHEVENTLIMIT ) { - TPaveText* errText = new TPaveText(0.30,0.50,0.9,0.9,"NDC"); + messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE)); + } + else + { + hrostatusnorm.Add(&hrostatus,100.0/neventsseen); + hrostatusnorm.SetOption("TEXT45"); // note : cannot use HIST option, otherwise the associated function (i.e. the tpavetext) is not drawn... + hrostatusnorm.SetMinimum(0.0); - errText->AddText(Form("MCH RUN %d - %d events",AliCDBManager::Instance()->GetRun(),nevents)); - errText->AddText("There are some token lost errors !"); - errText->AddText("PLEASE CHECK THE BUSY TIME FOR MUON !"); - errText->AddText("If above 5 ms please have the MUON expert"); - errText->AddText("check the following bus patches :"); + Double_t tokenLost = hrostatusnorm.GetBinContent(hrostatusnorm.FindBin(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors)); - for ( Int_t i = 1; i <= hbuspatchtokenerrors.GetNbinsX(); ++i ) + if ( tokenLost > recoParam.TokenLostLimit() ) { - if ( hbuspatchtokenerrors.GetBinContent(i) > 0 ) + rv = AliMUONVQAChecker::kError; + + messages.Add(new TObjString("There are some token lost errors !")); + messages.Add(new TObjString("PLEASE CHECK THE BUSY TIME FOR MUON !")); + messages.Add(new TObjString("If above 5 ms please have the MUON expert")); + messages.Add(new TObjString("check the following bus patches :")); + + for ( Int_t i = 1; i <= hbuspatchtokenerrors.GetNbinsX(); ++i ) { - errText->AddText(Form("BP %4d",i)); + if ( hbuspatchtokenerrors.GetBinContent(i) > 0 ) + { + messages.Add(new TObjString(Form("BP %4d",i))); + } } } - hroe.GetListOfFunctions()->Add(errText); + if ( hrostatusnorm.GetBinContent(hrostatusnorm.FindBin(AliMUONQAIndices::kTrackerRawNofEmptyEvents)) > 25.0 ) + { + messages.Add(new TObjString("Too many empty events !")); + messages.Add(new TObjString(NOTIFYEXPERTMESSAGE)); + rv = AliMUONVQAChecker::kFatal; + + } + } + + SetupHisto(neventsseen,neventsused,messages,hrostatusnorm,rv,"text45"); + + return rv; +} + +//______________________________________________________________________________ +AliMUONVQAChecker::ECheckCode +AliMUONTrackerQAChecker::BeautifyEventsizeHistograms(TH1& heventsize, + TH1& heventsizeperevent, + Int_t neventsseen, + Int_t neventsused, + const AliMUONRecoParam& recoParam) +{ + /// Normalize and put some text on the event size histogram + + AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo); + + heventsizeperevent.GetListOfFunctions()->Delete(); + + heventsizeperevent.Reset(); - rv = AliMUONVQAChecker::kFatal; + TObjArray messages; + messages.SetOwner(kTRUE); + + if ( neventsseen < NOTENOUGHEVENTLIMIT ) + { + messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE)); + } + else + { + heventsizeperevent.Add(&heventsize); + heventsizeperevent.Scale(1.0/neventsseen/1024.0); + heventsizeperevent.SetMinimum(0); + + Double_t totalEventSizePerEvent = heventsizeperevent.Integral(); + + TString msg; + TString action; + + if ( totalEventSizePerEvent > recoParam.EventSizeHardLimit() ) + { + rv = AliMUONVQAChecker::kFatal; + msg = "That is really too high."; + action = NOTIFYEXPERTMESSAGE; + } + else if ( totalEventSizePerEvent > recoParam.EventSizeSoftLimit() ) + { + msg = "That is a bit high."; + action = "Please keep an eye on it."; + rv = AliMUONVQAChecker::kError; + } + else + { + rv = AliMUONVQAChecker::kInfo; + } - SetPaveColor(*errText,rv); + messages.Add(new TObjString(Form(" %5.1f KB/event\n",totalEventSizePerEvent))); + if (msg.Length()>0) + { + messages.Add(new TObjString(msg)); + messages.Add(new TObjString(action)); + } } + SetupHisto(neventsseen,neventsused,messages,heventsizeperevent,rv); + return rv; } + + + diff --git a/MUON/AliMUONTrackerQAChecker.h b/MUON/AliMUONTrackerQAChecker.h index 28914051054..290d48facbe 100644 --- a/MUON/AliMUONTrackerQAChecker.h +++ b/MUON/AliMUONTrackerQAChecker.h @@ -30,15 +30,26 @@ private: AliMUONVQAChecker::ECheckCode MarkHisto(TH1& histo, AliMUONVQAChecker::ECheckCode value) const; - AliMUONVQAChecker::ECheckCode BeautifyHistograms(TH1& hddl, - TH1& hbp, - TH1& hroe, - const TH1* hbuspatchconfig, - const TH1& hnpads, - const TH1& hbuspatchtokenerrors, - Int_t nevents, - const AliMUONRecoParam& recoParam); - + AliMUONVQAChecker::ECheckCode BeautifyOccupancyHistograms(TH1& hddl, + TH1& hbp, + const TH1* hbuspatchconfig, + Int_t neventsseen, + Int_t neventsused, + const AliMUONRecoParam& recoParam); + + AliMUONVQAChecker::ECheckCode BeautifyReadoutHistograms(TH1& hroe, + TH1& hroenorm, + const TH1& hbuspatchtokenerrors, + Int_t neventsseen, + Int_t neventsused, + const AliMUONRecoParam& recoParam); + + AliMUONVQAChecker::ECheckCode BeautifyEventsizeHistograms(TH1& heventsize, + TH1& heventsizeperevent, + Int_t neventsseen, + Int_t neventsused, + const AliMUONRecoParam& recoParam); + ClassDef(AliMUONTrackerQAChecker,1) // MUON quality assurance checker }; diff --git a/MUON/AliMUONTrackerQADataMakerRec.cxx b/MUON/AliMUONTrackerQADataMakerRec.cxx index d1f51b8edb6..03e77e8d88d 100644 --- a/MUON/AliMUONTrackerQADataMakerRec.cxx +++ b/MUON/AliMUONTrackerQADataMakerRec.cxx @@ -1,4 +1,4 @@ -/************************************************************************** + /************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * @@ -18,52 +18,60 @@ // --- MUON header files --- #include "AliMUONTrackerQADataMakerRec.h" +#include "AliCDBManager.h" +#include "AliCodeTimer.h" #include "AliDAQ.h" -#include "AliQAv1.h" -#include "AliMpDDL.h" +#include "AliESDEvent.h" +#include "AliESDMuonTrack.h" +#include "AliLog.h" +#include "AliMUON2DMap.h" +#include "AliMUONCalibParamND.h" +#include "AliMUONCalibrationData.h" #include "AliMUONConstants.h" #include "AliMUONDigitMaker.h" +#include "AliMUONESDInterface.h" +#include "AliMUONLogger.h" +#include "AliMUONQADataMakerRec.h" #include "AliMUONQAIndices.h" #include "AliMUONQAMappingCheck.h" -#include "AliMUONLogger.h" +#include "AliMUONTrack.h" +#include "AliMUONTrackParam.h" +#include "AliMUONTrackerData.h" #include "AliMUONTrackerDataMaker.h" #include "AliMUONVCluster.h" #include "AliMUONVClusterStore.h" #include "AliMUONVDigit.h" +#include "AliMUONVDigit.h" #include "AliMUONVDigitStore.h" -#include "AliMUONVTrackerData.h" -#include "AliMUONTrack.h" -#include "AliMUONTrackParam.h" -#include "AliMUONESDInterface.h" -#include "AliMUONCalibrationData.h" #include "AliMpBusPatch.h" #include "AliMpConstants.h" +#include "AliMpDDL.h" #include "AliMpDDLStore.h" #include "AliMpDEIterator.h" #include "AliMpDEManager.h" #include "AliMpDetElement.h" - -// --- AliRoot header files --- -#include "AliCDBManager.h" -#include "AliESDEvent.h" -#include "AliESDMuonTrack.h" -#include "AliLog.h" +#include "AliMpManuIterator.h" +#include "AliQAv1.h" +#include "AliRawEquipment.h" +#include "AliRawEquipmentHeader.h" +#include "AliRawEventHeaderBase.h" #include "AliRawReader.h" -#include "AliCodeTimer.h" -#include "AliMUONVDigit.h" - -// --- ROOT system --- +#include "AliRawVEvent.h" +#include #include #include #include -#include #include +#include #include //----------------------------------------------------------------------------- /// \class AliMUONTrackerQADataMakerRec /// -/// MUON base class for quality assurance data (histo) maker +/// Quality assurance data (histo) maker for MUON tracker +/// +/// +/// Note that all the methods of this class shoud not be called when eventSpecie is AliRecoParam::kCalib ! /// /// \author C. Finck, D. Stocco, L. Aphecetche @@ -77,17 +85,25 @@ namespace { return ( x > 0.0 ? TMath::Sqrt(x) : 0.0 ); } + } + //____________________________________________________________________________ AliMUONTrackerQADataMakerRec::AliMUONTrackerQADataMakerRec(AliQADataMakerRec* master) : AliMUONVQADataMakerRec(master), -fDigitStore(AliMUONVDigitStore::Create("AliMUONDigitStoreV1")), +fDigitStore(0x0), fDigitMaker(new AliMUONDigitMaker(kTRUE)), fClusterStore(0x0), -fTrackerDataMaker(0x0), -fMappingCheckRecPoints(0x0), fCalibrationData(new AliMUONCalibrationData(AliCDBManager::Instance()->GetRun())), -fLogger(0x0) +fLogger(0x0), +fBusPatchConfig(0x0), +fBPxmin(0), +fBPxmax(0), +fBPnbins(0), +fTrackerDataMakerArray(0x0), +fTrackerCalDataArray(0x0), +fTrackerRecDataArray(0x0), +fMappingCheckRecPointsArray(0x0) { /// ctor } @@ -100,7 +116,7 @@ AliMUONTrackerQADataMakerRec::~AliMUONTrackerQADataMakerRec() delete fDigitMaker; delete fClusterStore; delete fCalibrationData; - delete fMappingCheckRecPoints; + delete fMappingCheckRecPointsArray; if (fLogger) { if ( fLogger->NumberOfEntries() != 0 ) @@ -109,11 +125,17 @@ AliMUONTrackerQADataMakerRec::~AliMUONTrackerQADataMakerRec() } delete fLogger; } + delete fTrackerDataMakerArray; + delete fTrackerCalDataArray; + delete fTrackerRecDataArray; + delete fBusPatchConfig; } //____________________________________________________________________________ -void AliMUONTrackerQADataMakerRec::InsertTrackerData(Int_t specie, TObjArray** list, - TObject* object, Int_t indexNumber, +void AliMUONTrackerQADataMakerRec::InsertTrackerData(Int_t specie, + TObjArray** list, + TObject* object, + Int_t indexNumber, Bool_t replace) { /// Insert an object to a given list @@ -122,13 +144,17 @@ void AliMUONTrackerQADataMakerRec::InsertTrackerData(Int_t specie, TObjArray** l TObject* o; TObject* old(0x0); Bool_t alreadyThere(kFALSE); + while ( ( o = next() ) && !alreadyThere ) { TString classname(o->ClassName()); if ( classname.Contains("TrackerData") ) { - alreadyThere = kTRUE; - old = o; + if ( !strcmp(object->GetName(),o->GetName()) ) + { + alreadyThere = kTRUE; + old = o; + } } } if ( (!alreadyThere && object) || (alreadyThere && replace) ) @@ -149,6 +175,8 @@ void AliMUONTrackerQADataMakerRec::EndOfDetectorCycleESDs(Int_t, TObjArray**) if (!GetESDsData(AliMUONQAIndices::kESDnClustersPerTrack)) return; + AliCodeTimerAuto("",0); + Double_t nTracks = GetESDsData(AliMUONQAIndices::kESDnClustersPerTrack)->GetEntries(); if (nTracks <= 0) return; @@ -325,6 +353,8 @@ void AliMUONTrackerQADataMakerRec::EndOfDetectorCycleRecPoints(Int_t specie, TOb if (!GetRecPointsData(AliMUONQAIndices::kTrackerClusterChargePerChMean)) return; + AliCodeTimerAuto("",0); + TH1* hTrackerClusterChargePerChMean = GetRecPointsData(AliMUONQAIndices::kTrackerClusterChargePerChMean); TH1* hTrackerClusterChargePerChSigma = GetRecPointsData(AliMUONQAIndices::kTrackerClusterChargePerChSigma); TH1* hTrackerClusterMultiplicityPerChMean = GetRecPointsData(AliMUONQAIndices::kTrackerClusterMultiplicityPerChMean); @@ -372,71 +402,130 @@ void AliMUONTrackerQADataMakerRec::EndOfDetectorCycleRecPoints(Int_t specie, TOb } } - if ( fMappingCheckRecPoints ) InsertTrackerData(specie,list,fMappingCheckRecPoints->CreateData("RecPoints"),AliMUONQAIndices::kTrackerRecPoints,kTRUE); + if ( MappingCheckRecPoints(specie) ) + { + InsertTrackerData(specie,list,MappingCheckRecPoints(specie)->CreateData("RecPoints"),AliMUONQAIndices::kTrackerRecPoints,kTRUE); + } + + if ( TrackerRecData(specie) ) + { + /// put the trackerdata in the pipeline + InsertTrackerData(specie,list,TrackerRecData(specie),AliMUONQAIndices::kTrackerData); + + TH1* hbp = GetRecPointsData(AliMUONQAIndices::kTrackerBusPatchOccupancy); + TH1* hnevents = GetRecPointsData(AliMUONQAIndices::kTrackerNofGoodPhysicsEventsUsed); + TH1* hddl = GetRecPointsData(AliMUONQAIndices::kTrackerDDLOccupancy); + TH1* hddlevents = GetRecPointsData(AliMUONQAIndices::kTrackerDDLNofEventsUsed); + + if ( !hbp || !hnevents || !hddl || !hddlevents) + { + AliError(Form("Missing some histograms : cannot work : hbp=%p hnevents=%p hddl=%p hddlevents=%p",hbp,hnevents,hddl,hddlevents)); + return; + } + + ProjectTrackerData(TrackerRecData(specie), + *hbp,*hnevents,*hddl,*hddlevents); + } + else + { + AliError(Form("TrackerRecData is null for specie %s",AliRecoParam::GetEventSpecieName(specie))); + } + } - //____________________________________________________________________________ -void AliMUONTrackerQADataMakerRec::EndOfDetectorCycleRaws(Int_t specie, TObjArray** list) +void AliMUONTrackerQADataMakerRec::EndOfDetectorCycleDigits(Int_t specie, TObjArray** list) { - /// create Raws histograms in Raws subdir + /// create digits histograms in digits subdir - if ( !GetRawsData(AliMUONQAIndices::kTrackerBusPatchOccupancy) ) return; - - if ( fTrackerDataMaker ) + if ( TrackerCalData(specie) ) { + AliCodeTimerAuto("",0); + /// put the trackerdata in the pipeline - InsertTrackerData(specie,list,fTrackerDataMaker->Data(),AliMUONQAIndices::kTrackerData); - - /// project the tracerdata into buspatch occupancies (for the experts) - TH1* hbp = GetRawsData(AliMUONQAIndices::kTrackerBusPatchOccupancy); - hbp->Reset(); - TIter nextBP(AliMpDDLStore::Instance()->CreateBusPatchIterator()); - AliMpBusPatch* bp(0x0); - AliMUONVTrackerData* data = fTrackerDataMaker->Data(); - Int_t occDim = 2; + InsertTrackerData(specie,list,TrackerCalData(specie),AliMUONQAIndices::kTrackerData); + + TH1* hbp = GetDigitsData(AliMUONQAIndices::kTrackerBusPatchOccupancy); + TH1* hnevents = GetDigitsData(AliMUONQAIndices::kTrackerNofGoodPhysicsEventsUsed); + TH1* hddl = GetDigitsData(AliMUONQAIndices::kTrackerDDLOccupancy); + TH1* hddlevents = GetDigitsData(AliMUONQAIndices::kTrackerDDLNofEventsUsed); - while ( ( bp = static_cast(nextBP())) ) + if ( !hbp || !hnevents || !hddl || !hddlevents) { - Int_t busPatchId = bp->GetId(); - Int_t bin = hbp->FindBin(busPatchId); - hbp->SetBinContent(bin,data->BusPatch(busPatchId,occDim)*100.0); // occupancy, in percent + AliError(Form("Missing some histograms : cannot work : hbp=%p hnevents=%p hddl=%p hddlevents=%p",hbp,hnevents,hddl,hddlevents)); + return; } - /// log the readout errors (for the shifter) - TH1* hnevents = GetRawsData(AliMUONQAIndices::kTrackerNofRawEventSeen); - hnevents->Reset(); - hnevents->Fill(0.0,fTrackerDataMaker->Data()->NumberOfEvents(-1)); - - if ( fLogger->NumberOfEntries() > 0 ) + ProjectTrackerData(TrackerCalData(specie), + *hbp,*hnevents,*hddl,*hddlevents); + } +} + +//____________________________________________________________________________ +AliMUONQADataMakerRec* AliMUONTrackerQADataMakerRec::Master() const +{ + /// Get our master + return static_cast(fMaster); +} + +//____________________________________________________________________________ +void AliMUONTrackerQADataMakerRec::ProjectTrackerData(AliMUONVTrackerData* data, + TH1& hbp, + TH1& hnevents, + TH1& hddl, + TH1& hddlevents) +{ + /// Project tracker data into shifter-friendly histograms + + AliCodeTimerAuto(Form("%s",data->Name()),0); + + /// project the tracerdata into buspatch occupancies (for the experts) + hbp.Reset(); + hbp.SetStats(kFALSE); + + TIter nextBP(AliMpDDLStore::Instance()->CreateBusPatchIterator()); + AliMpBusPatch* bp(0x0); + Int_t occDim = 2; + + while ( ( bp = static_cast(nextBP())) ) + { + Int_t busPatchId = bp->GetId(); + Int_t bin = hbp.FindBin(busPatchId); + if ( data->HasBusPatch(busPatchId) ) { - // readout errors - FillErrors(*fLogger); - fLogger->Clear(); + hbp.SetBinContent(bin,data->BusPatch(busPatchId,occDim)*100.0); // occupancy, in percent } - - /// project tracker data into DDL occupancies (for the shifter) - TH1* hddl = GetRawsData(AliMUONQAIndices::kTrackerDDLOccupancy); - hddl->Reset(); - TH1* hddlevents = GetRawsData(AliMUONQAIndices::kTrackerDDLNofEvents); - hddlevents->Reset(); + } + + /// log the readout errors (for the shifter) + hnevents.Reset(); + hnevents.SetStats(kFALSE); + hnevents.SetBinContent(1,data->NumberOfEvents(-1)); + + /// project tracker data into DDL occupancies (for the shifter) + hddl.Reset(); + hddl.SetStats(kFALSE); + hddlevents.Reset(); + hddlevents.SetStats(kFALSE); + + const Int_t nddls = AliDAQ::NumberOfDdls("MUONTRK"); + const Int_t offset = AliDAQ::DdlIDOffset("MUONTRK"); + + for ( Int_t iddl = 0; iddl < nddls; ++iddl ) + { + AliMpDDL* ddl = AliMpDDLStore::Instance()->GetDDL(iddl); + + Int_t ddlId = offset + ddl->GetId(); + Int_t npads = 0; + + Int_t nevents = data->NumberOfEvents(iddl); - const Int_t nddls = AliDAQ::NumberOfDdls("MUONTRK"); - const Int_t offset = AliDAQ::DdlIDOffset("MUONTRK"); + hddlevents.Fill(ddlId,nevents); - for ( Int_t iddl = 0; iddl < nddls; ++iddl ) + Double_t occ(0.0); + + if ( nevents > 0 ) { - AliMpDDL* ddl = AliMpDDLStore::Instance()->GetDDL(iddl); - - Int_t ddlId = offset + ddl->GetId(); - Int_t npads = 0; - - Int_t nevents = data->NumberOfEvents(iddl); - - hddlevents->Fill(ddlId,nevents); - - Double_t occ(0.0); - for ( Int_t ide = 0; ide < ddl->GetNofDEs(); ++ide ) { Int_t de = ddl->GetDEId(ide); @@ -446,18 +535,64 @@ void AliMUONTrackerQADataMakerRec::EndOfDetectorCycleRaws(Int_t specie, TObjArra occ += data->DetectionElement(de,4); } - if ( nevents > 0 && npads > 0 ) + if ( npads > 0 ) { occ = occ/npads/nevents; } - - hddl->Fill(ddlId,100.0*occ); // occ in percent + else + { + occ = 0.0; + } } + + hddl.Fill(ddlId,100.0*occ); // occ in percent } + + TPaveText* text = new TPaveText(0.50,0.8,0.9,0.9,"NDC"); + + text->AddText(Form("MCH RUN %d - %d events",AliCDBManager::Instance()->GetRun(),data->NumberOfEvents(-1))); + + hddl.GetListOfFunctions()->Add(text); } //____________________________________________________________________________ -void AliMUONTrackerQADataMakerRec::FillErrors(AliMUONLogger& log) +void AliMUONTrackerQADataMakerRec::EndOfDetectorCycleRaws(Int_t specie, TObjArray** list) +{ + /// create Raws histograms in Raws subdir + + if ( TrackerDataMaker(specie) && TrackerDataMaker(specie)->Data() ) + { + AliCodeTimerAuto("",0); + + /// put the trackerdata in the pipeline + InsertTrackerData(specie,list,TrackerDataMaker(specie)->Data(),AliMUONQAIndices::kTrackerData); + TrackerDataMaker(specie)->SetOwnerOfData(kFALSE); // now that it's attached to list, list will take care of the deletion + + TH1* hbp = GetRawsData(AliMUONQAIndices::kTrackerBusPatchOccupancy); + TH1* hnevents = GetRawsData(AliMUONQAIndices::kTrackerNofGoodPhysicsEventsUsed); + TH1* hddl = GetRawsData(AliMUONQAIndices::kTrackerDDLOccupancy); + TH1* hddlevents = GetRawsData(AliMUONQAIndices::kTrackerDDLNofEventsUsed); + + if ( !hbp || !hnevents || !hddl || !hddlevents) + { + AliError(Form("Missing some histograms : cannot work : hbp=%p hnevents=%p hddl=%p hddlevents=%p",hbp,hnevents,hddl,hddlevents)); + return; + } + + ProjectTrackerData(TrackerDataMaker(specie)->Data(), + *hbp,*hnevents,*hddl,*hddlevents); + + if ( fLogger->NumberOfEntries() > 0 ) + { + // readout errors + FillReadoutStatus(*fLogger,TrackerDataMaker(specie)->Data()); + fLogger->Clear(); + } + } +} + +//____________________________________________________________________________ +void AliMUONTrackerQADataMakerRec::FillReadoutStatus(AliMUONLogger& log, AliMUONVTrackerData* data) { log.ResetItr(); @@ -470,9 +605,9 @@ void AliMUONTrackerQADataMakerRec::FillErrors(AliMUONLogger& log) TH1* hpadding = GetRawsData(AliMUONQAIndices::kTrackerBusPatchPaddingErrors); - TH1* hroe = GetRawsData(AliMUONQAIndices::kTrackerReadoutErrors); + TH1* hrostatus = GetRawsData(AliMUONQAIndices::kTrackerReadoutStatus); - TH1* hnevents = GetRawsData(AliMUONQAIndices::kTrackerNofRawEventSeen); + TH1* hnevents = GetRawsData(AliMUONQAIndices::kTrackerNofPhysicsEventsSeen); Int_t nevents = TMath::Nint(hnevents->GetBinContent(1)); @@ -481,10 +616,14 @@ void AliMUONTrackerQADataMakerRec::FillErrors(AliMUONLogger& log) TPaveText* text = new TPaveText(0,0,0.99,0.99,"NDC"); text->AddText("FATAL : 0 event seen ? That's NOT normal..."); text->SetFillColor(2); // red = FATAL - hroe->GetListOfFunctions()->Add(text); + hrostatus->GetListOfFunctions()->Add(text); return; } + ///////////////////////////////////////////////////////////////// + /// Start by counting the number of errors + ///////////////////////////////////////////////////////////////// + while ( log.Next(msg,occurence) ) { AliDebug(1,Form("msg=%s occurence=%d",msg.Data(),occurence)); @@ -501,33 +640,34 @@ void AliMUONTrackerQADataMakerRec::FillErrors(AliMUONLogger& log) // Let's try to get all the suspected bus patches (i.e. one full FRT, as currently // we don't have more precise information to locate the faulty bus patch(es)). - AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatch); - Int_t frt = bp->GetFrtId(); - AliMpDDL* ddl = AliMpDDLStore::Instance()->GetDDL(bp->GetDdlId()); - Int_t* b = new Int_t[ddl->GetMaxDsp()]; - ddl->GetBusPerDsp(b); - Int_t nbus(0); - for ( Int_t i = 0; i < ddl->GetNofFrts() && !nbus; ++i ) + AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatch,kFALSE); + if (bp) { - if ( ddl->GetFrtId(i) == frt ) + Int_t frt = bp->GetFrtId(); + AliMpDDL* ddl = AliMpDDLStore::Instance()->GetDDL(bp->GetDdlId()); + Int_t* b = new Int_t[ddl->GetMaxDsp()]; + ddl->GetBusPerDsp(b); + Int_t nbus(0); + for ( Int_t i = 0; i < ddl->GetNofFrts() && !nbus; ++i ) { - nbus = b[i]; + if ( ddl->GetFrtId(i) == frt ) + { + nbus = b[i]; + } } - } - if (nbus<=0) - { - AliError("GOT NBUS<=0 ! THAT IS BAD ! CHECK !"); - nbus=1; - } - - delete[] b; + if (nbus<=0) + { + AliError("GOT NBUS<=0 ! THAT IS BAD ! CHECK !"); + nbus=1; + } + delete[] b; - while (nbus) { - htoken->Fill(buspatch+nbus-1,occurence); - --nbus; + while (nbus) { + htoken->Fill(buspatch+nbus-1,occurence); + --nbus; + } } - - hroe->Fill(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors,occurence); + hrostatus->Fill(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors,occurence); } if ( msg.Contains("Parity") ) @@ -535,12 +675,12 @@ void AliMUONTrackerQADataMakerRec::FillErrors(AliMUONLogger& log) Int_t buspatch; sscanf(msg.Data(),"Parity error in buspatch %d (0x%X).",&buspatch,&buspatch); hparity->Fill(buspatch,occurence); - hroe->Fill(1.0*AliMUONQAIndices::kTrackerRawNofParityErrors,occurence); + hrostatus->Fill(1.0*AliMUONQAIndices::kTrackerRawNofParityErrors,occurence); } if ( msg.Contains("Glitch") ) { - hroe->Fill(1.0*AliMUONQAIndices::kTrackerRawNofGlitchErrors,occurence); + hrostatus->Fill(1.0*AliMUONQAIndices::kTrackerRawNofGlitchErrors,occurence); } if ( msg.Contains("Padding") ) @@ -548,163 +688,305 @@ void AliMUONTrackerQADataMakerRec::FillErrors(AliMUONLogger& log) Int_t block, dsp, buspatch; sscanf(msg.Data(),"Padding word error for iBlock %d, iDsp %d, iBus %d.",&block,&dsp,&buspatch); hpadding->Fill(buspatch,occurence); - hroe->Fill(1.0*AliMUONQAIndices::kTrackerRawNofPaddingErrors,occurence); + hrostatus->Fill(1.0*AliMUONQAIndices::kTrackerRawNofPaddingErrors,occurence); + } + } + + ///////////////////////////////////////////////////////////////// + /// + /// Then make the status about number of missing bus patches + /// + ///////////////////////////////////////////////////////////////// + + Int_t nofBusPatchesNotInConfig(0); + + for ( int i = 1; i <= fBusPatchConfig->GetNbinsX(); ++i ) + { + Double_t buspatchId = fBusPatchConfig->GetBinCenter(i); + if ( TMath::Nint(buspatchId) != i ) + { + AliError(Form("buspathId=%e i=%d",buspatchId,i)); } + Double_t content = fBusPatchConfig->GetBinContent(i); + + if ( content <= 0. /* no content */ + && + AliMpDDLStore::Instance()->GetBusPatch(i,kFALSE) /* but a valid bus patch */ ) + { + ++nofBusPatchesNotInConfig; + } + } + + Double_t nbuspatches = fBusPatchConfig->GetEntries(); + + hrostatus->Fill(1.0*AliMUONQAIndices::kTrackerRawNofMissingBusPatchesFromConfig,nofBusPatchesNotInConfig*nevents/nbuspatches); + + Double_t nofBusPatchesNotInData(0); + + TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator()); + AliMpBusPatch* bp; + + while ( ( bp = static_cast(next()) ) ) + { + if ( !data->HasBusPatch(bp->GetId()) ) ++nofBusPatchesNotInData; } - /// Finally we normalize to the number of events, for the shifter plot only - hroe->Scale(100.0/nevents); + hrostatus->Fill(1.0*AliMUONQAIndices::kTrackerRawNofMissingBusPatchesFromDataStream,nofBusPatchesNotInData*nevents/nbuspatches); } +//____________________________________________________________________________ +void AliMUONTrackerQADataMakerRec::FillEventSize(const AliRawVEvent* cevent) +{ + /// Fill event size histogram(s) + + if (!cevent) + { + AliError("Got a null cevent..."); + return; + } + + AliRawVEvent* event = const_cast(cevent); // not good, but the Get*Event() methods are not const... + + TH1* hnevents = GetRawsData(AliMUONQAIndices::kTrackerNofPhysicsEventsSeen); + + TH1* hddlevents = GetRawsData(AliMUONQAIndices::kTrackerDDLNofEventsSeen); + + TH1* hDDLEventSize = GetRawsData(AliMUONQAIndices::kTrackerDDLEventSize); + + Double_t eventSize = 0; + + hnevents->Fill(0.0); + + for ( int i = 0; i < event->GetNSubEvents(); ++i ) + { + AliRawVEvent* sub = event->GetSubEvent(i); + + for ( int j = 0; j < sub->GetNEquipments(); ++j ) + { + AliRawVEquipment* eq = sub->GetEquipment(j); + + AliRawEquipmentHeader* equipmentHeader = eq->GetEquipmentHeader(); + + UInt_t uid = equipmentHeader->GetId(); + + int index; + + TString det(AliDAQ::DetectorNameFromDdlID(uid,index)); + + if (det=="MUONTRK") + { + UInt_t ddlsize = equipmentHeader->GetEquipmentSize(); + hDDLEventSize->Fill(uid,ddlsize); + hddlevents->Fill(uid); + eventSize += ddlsize; + } + } + } +} //____________________________________________________________________________ -void AliMUONTrackerQADataMakerRec::InitRaws() +void AliMUONTrackerQADataMakerRec::InitCommon() +{ + if (!fBusPatchConfig) + { + Int_t bpmin(999999); + Int_t bpmax(0); + + TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator()); + AliMpBusPatch* bp(0x0); + while ( ( bp = static_cast(next())) ) + { + bpmin = TMath::Min(bpmin,bp->GetId()); + bpmax = TMath::Max(bpmax,bp->GetId()); + } + + fBPxmin = bpmin-0.5; + fBPxmax = bpmax+0.5; + fBPnbins = TMath::Nint(fBPxmax-fBPxmin); + + AliMUONVStore* config = fCalibrationData->Config(); + + if (config) + { + fBusPatchConfig = new TH1F("hTrackerBusPatchConfig","Configuration of bus patches",fBPnbins,fBPxmin,fBPxmax); + fBusPatchConfig->SetDirectory(0); + } + else + { + AliWarning("Tracker configuration not found. Will not be able to cut on low occupancies"); + } + + next.Reset(); + while ( ( bp = static_cast(next())) ) + { + if ( config ) + { + Int_t nofManusInConfig(0); + + for ( Int_t imanu = 0; imanu < bp->GetNofManus(); ++imanu ) + { + Int_t manuId = bp->GetManuId(imanu); + if ( config->FindObject(bp->GetDEId(),manuId)) ++nofManusInConfig; + } + + if ( nofManusInConfig > 0 ) + { + fBusPatchConfig->Fill(bp->GetId(),1.0); + } + else + { + fBusPatchConfig->Fill(bp->GetId(),0.0); + } + } + else // no config, we assume all is there... + { + fBusPatchConfig->Fill(bp->GetId()); + } + } + } +} + +//____________________________________________________________________________ +void AliMUONTrackerQADataMakerRec::BookHistograms(AliQAv1::TASKINDEX_t task) { - /// create Raws histograms in Raws subdir - AliCodeTimerAuto("",0); + + InitCommon(); const Bool_t expert = kTRUE ; const Bool_t saveCorr = kTRUE ; const Bool_t image = kTRUE ; - - Int_t bpmin(999999); - Int_t bpmax(0); - TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator()); - AliMpBusPatch* bp(0x0); - while ( ( bp = static_cast(next())) ) + TH1* hbp = new TH1F("hTrackerBusPatchOccupancy","Occupancy of bus patches",fBPnbins,fBPxmin,fBPxmax); + + Master()->Add2List(hbp,AliMUONQAIndices::kTrackerBusPatchOccupancy, task, expert, !image, !saveCorr); + + TH1* h = new TH1F("hTrackerBusPatchParityErrors","Number of parity errors per bus patch",fBPnbins,fBPxmin,fBPxmax); + + Master()->Add2List(h,AliMUONQAIndices::kTrackerBusPatchParityErrors,task,expert,!image,!saveCorr); + + h = new TH1F("hTrackerBusPatchTokenLostErrors","Number of token lost errors per bus patch",fBPnbins,fBPxmin,fBPxmax); + Master()->Add2List(h,AliMUONQAIndices::kTrackerBusPatchTokenLostErrors,task,expert,!image,!saveCorr); + + h = new TH1F("hTrackerBusPatchPaddingErrors","Number of padding errors per bus patch",fBPnbins,fBPxmin,fBPxmax); + + Master()->Add2List(h,AliMUONQAIndices::kTrackerBusPatchPaddingErrors,task,expert,!image,!saveCorr); + + + TH1* hnevents(0x0); + + if ( task == AliQAv1::kRAWS ) { - bpmin = TMath::Min(bpmin,bp->GetId()); - bpmax = TMath::Max(bpmax,bp->GetId()); + // for raw data, we differentiate events seen from events used to be able to detect + // severe decoder errors that lead to no event decoded (i.e. zero event used) even if + // events are there (i.e non-zero event seen). + hnevents = new TH1F("kTrackerNofPhysicsEventsSeen","Number of physics events seen",1,-0.5,0.5); + // this one will count the number of physics event the rawdatamaker is *seeing* + TAxis* a = hnevents->GetXaxis(); + a->SetBinLabel(1,"NPhysicsEvents"); + hnevents->SetStats(kFALSE); + Master()->Add2List(hnevents,AliMUONQAIndices::kTrackerNofPhysicsEventsSeen,task,expert,!image,!saveCorr); } - Double_t xmin = bpmin-0.5; - Double_t xmax = bpmax+0.5; - Int_t nbins = bpmax-bpmin+1; - - TH1* hbp = new TH1F("hTrackerBusPatchOccupancy","Occupancy of bus patches",nbins,xmin,xmax); + hnevents = new TH1F("kTrackerNofGoodPhysicsEventsUsed","Number of good physics events used",1,-0.5,0.5); + // this one will get its content from the TrackerData, i.e. it will count the number of *good* physics events *used* + // (i.e. not empty and with no fatal readout error) + TAxis* a = hnevents->GetXaxis(); + a->SetBinLabel(1,"NGoodPhysicsEvents"); + hnevents->SetStats(kFALSE); - TH1* hbpnpads = new TH1F("hTrackerBusPatchNofPads","Number of pads per bus patch",nbins,xmin,xmax); + Master()->Add2List(hnevents,AliMUONQAIndices::kTrackerNofGoodPhysicsEventsUsed,task,expert,!image,!saveCorr); - TH1* hbpnmanus = new TH1F("hTrackerBusPatchNofManus","Number of manus per bus patch",nbins,xmin,xmax); + Master()->Add2List(static_cast(fBusPatchConfig->Clone()),AliMUONQAIndices::kTrackerBusPatchConfig, task,expert, !image, !saveCorr); - Add2RawsList(hbp,AliMUONQAIndices::kTrackerBusPatchOccupancy, expert, image, !saveCorr); - Add2RawsList(hbpnpads,AliMUONQAIndices::kTrackerBusPatchNofPads, expert, !image, !saveCorr); - Add2RawsList(hbpnmanus,AliMUONQAIndices::kTrackerBusPatchNofManus, expert, !image, !saveCorr); - - Add2RawsList(new TH1F("hTrackerBusPatchParityErrors","Number of parity errors per bus patch",nbins,xmin,xmax), - AliMUONQAIndices::kTrackerBusPatchParityErrors,expert,!image,!saveCorr); - - Add2RawsList(new TH1F("hTrackerBusPatchTokenLostErrors","Number of token lost errors per bus patch",nbins,xmin,xmax), - AliMUONQAIndices::kTrackerBusPatchTokenLostErrors,expert,!image,!saveCorr); + Int_t nbins = AliDAQ::NumberOfDdls("MUONTRK"); + const Int_t offset = AliDAQ::DdlIDOffset("MUONTRK"); + + Double_t xmin = offset - 0.5; + Double_t xmax = offset + nbins - 0.5; + + TString what(AliQAv1::GetTaskName(task)); + + h = new TH1F(Form("hTrackerDDL%sOccupancy",what.Data()),Form(";DDLId;DDL Occupancy in %% (from %s)",what.Data()),nbins,xmin,xmax); + + Master()->Add2List(h,AliMUONQAIndices::kTrackerDDLOccupancy,task,expert,!image,!saveCorr); - Add2RawsList(new TH1F("hTrackerBusPatchPaddingErrors","Number of padding errors per bus patch",nbins,xmin,xmax), - AliMUONQAIndices::kTrackerBusPatchPaddingErrors,expert,!image,!saveCorr); + if ( task == AliQAv1::kRAWS ) + { + // see above the comment about why we have event seen vs used for raw data. + h = new TH1F("hTrackerDDLNofEventsSeen","Number of events seen by DDL;DDLId",nbins,xmin,xmax); + Master()->Add2List(h,AliMUONQAIndices::kTrackerDDLNofEventsSeen,task,expert,!image,!saveCorr); + } + + h = new TH1F("hTrackerDDLNofEventsUsed","Number of events used by DDL;DDLId",nbins,xmin,xmax); + Master()->Add2List(h,AliMUONQAIndices::kTrackerDDLNofEventsUsed,task,expert,!image,!saveCorr); + +} - TH1* h = new TH1F("hTrackerReadoutErrors","Number of readout errors per event;;Error rate in %",4,-0.5,3.5); +//____________________________________________________________________________ +void AliMUONTrackerQADataMakerRec::InitRaws() +{ + /// create monitor objects for RAWS + + TrackerDataMaker(AliRecoParam::AConvert(Master()->GetEventSpecie()),kTRUE); + + /// Book histograms that are common to Raws and Digits + BookHistograms(AliQAv1::kRAWS); + + /// Now the Raws specific parts + TH1* h = new TH1F("hTrackerReadoutStatus","Readout status (x events)",7,-0.5,6.5); h->SetStats(kFALSE); - // The QA shifter will only see the summary plot below TAxis* a = h->GetXaxis(); a->SetBinLabel(h->FindBin(1.0*AliMUONQAIndices::kTrackerRawNofGlitchErrors),"Glitch errors"); a->SetBinLabel(h->FindBin(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors),"Token lost errors"); a->SetBinLabel(h->FindBin(1.0*AliMUONQAIndices::kTrackerRawNofParityErrors),"Parity errors"); a->SetBinLabel(h->FindBin(1.0*AliMUONQAIndices::kTrackerRawNofPaddingErrors),"Padding errors"); - - Add2RawsList(h,AliMUONQAIndices::kTrackerReadoutErrors,!expert,image,!saveCorr); - - TH1* hnevents = new TH1F("hTrackerNofRawEventSeen","Number of events seen",1,-0.5,0.5); - a = hnevents->GetXaxis(); - a->SetBinLabel(1,"Nevents"); - hnevents->SetStats(kFALSE); - Add2RawsList(hnevents,AliMUONQAIndices::kTrackerNofRawEventSeen,expert,!image,!saveCorr); - - const Bool_t histogram(kFALSE); - - if(!fTrackerDataMaker) - { - - AliMUONTrackerDataMaker* dm = new AliMUONTrackerDataMaker(GetRecoParam(), - AliCDBManager::Instance()->GetRun(), - 0x0, - "", - "NOGAIN", - histogram, - 0.0,0.0); - - fLogger = new AliMUONLogger(-1); - dm->EnableErrorLogger(fLogger); - fTrackerDataMaker = dm; - } + a->SetBinLabel(h->FindBin(1.0*AliMUONQAIndices::kTrackerRawNofEmptyEvents),"Empty events"); - fTrackerDataMaker->Data()->DisableChannelLevel(); // to save up disk space, we only store starting at the manu level + a->SetBinLabel(h->FindBin(1.0*AliMUONQAIndices::kTrackerRawNofMissingBusPatchesFromConfig),"Not readout bus patches"); + a->SetBinLabel(h->FindBin(1.0*AliMUONQAIndices::kTrackerRawNofMissingBusPatchesFromDataStream),"Missing bus patches"); - fTrackerDataMaker->SetRunning(kTRUE); + TH1* h1 = static_cast(h->Clone("hTrackerReadoutStatusPerEvent")); + h1->SetTitle("Readout status per event"); + h1->GetYaxis()->SetTitle("Percentage"); - next.Reset(); + // The QA shifter will only see the summary plot below - AliMUONVStore* config = fCalibrationData->Config(); + Add2RawsList(h,AliMUONQAIndices::kTrackerReadoutStatus,kTRUE,kFALSE,kFALSE); + Add2RawsList(h1,AliMUONQAIndices::kTrackerReadoutStatusPerEvent,kFALSE,kTRUE,kFALSE); - TH1* hbpconfig(0x0); + // Lastly the event size histograms - if (config) - { - hbpconfig = new TH1F("hTrackerBusPatchConfig","Configuration of bus patches",nbins,xmin,xmax); - Add2RawsList(hbpconfig,AliMUONQAIndices::kTrackerBusPatchConfig, expert, !image, !saveCorr); - } - else - { - AliWarning("Tracker configuration not found. Will not be able to cut on low occupancies"); - } - - while ( ( bp = static_cast(next())) ) - { - Int_t n(0); - Bool_t inConfig(kTRUE); - - for ( Int_t imanu = 0; imanu < bp->GetNofManus(); ++imanu ) - { - Int_t manuId = bp->GetManuId(imanu); - AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(bp->GetDEId()); - n += de->NofChannelsInManu(manuId); - if ( config && !config->FindObject(de->GetId(),manuId)) inConfig=kFALSE; - } - hbpnpads->Fill(bp->GetId(),n*1.0); - hbpnmanus->Fill(bp->GetId(),bp->GetNofManus()*1.0); - if ( hbpconfig && inConfig ) - { - hbpconfig->Fill(bp->GetId()); - } - } - - nbins = AliDAQ::NumberOfDdls("MUONTRK"); + Int_t nbins = AliDAQ::NumberOfDdls("MUONTRK"); const Int_t offset = AliDAQ::DdlIDOffset("MUONTRK"); - xmin = offset - 0.5; - xmax = offset + nbins - 0.5; - - Add2RawsList(new TH1F("hTrackerDDLOccupancy",";DDLId;DDL Occupancy in %",nbins,xmin,xmax), - AliMUONQAIndices::kTrackerDDLOccupancy,!expert,image,!saveCorr); - Add2RawsList(new TH1F("hTrackerDDLNofEvents","Number of events seen by DDL;DDLId",nbins,xmin,xmax), - AliMUONQAIndices::kTrackerDDLNofEvents,expert,!image,!saveCorr); + Double_t xmin = offset - 0.5; + Double_t xmax = offset + nbins - 0.5; + h = new TH1F("hTrackerDDLEventSize","DDL event size (bytes);DDL Id;Data size (bytes)",nbins,xmin,xmax); + h->SetStats(kFALSE); + Add2RawsList(h,AliMUONQAIndices::kTrackerDDLEventSize,kTRUE,kFALSE,kFALSE); + + h = new TH1F("hTrackerDDLMeanEventSize","DDL mean event size (KB) per event;DDL Id;Mean Event size (KB)",nbins,xmin,xmax); + h->SetStats(kFALSE); + Add2RawsList(h,AliMUONQAIndices::kTrackerDDLEventSizePerEvent,kFALSE,kTRUE,kFALSE); + } //__________________________________________________________________ void AliMUONTrackerQADataMakerRec::InitDigits() { - /// Initialized Digits spectra - const Bool_t expert = kTRUE ; - const Bool_t image = kTRUE ; + /// create monitor objects for DIGITS - TH1I* h0 = new TH1I("hDigitsDetElem", "Detection element distribution in Digits;Detection element Id;Counts", 1400, 100, 1500); - Add2DigitsList(h0, 0, !expert, image); + AliCodeTimerAuto("",0); + + TrackerCalData(AliRecoParam::AConvert(Master()->GetEventSpecie()),kTRUE); - TH1I* h1 = new TH1I("hDigitsADC", "ADC distribution in Digits;ACD value;Counts", 4096, 0, 4095); - Add2DigitsList(h1, 1, !expert, image); + /// Book histograms that are common to Raws and Digits + BookHistograms(AliQAv1::kDIGITSR); } //____________________________________________________________________________ @@ -716,6 +998,10 @@ void AliMUONTrackerQADataMakerRec::InitRecPoints() const Bool_t image = kTRUE ; AliCodeTimerAuto("",0); + + TrackerRecData(AliRecoParam::AConvert(Master()->GetEventSpecie()),kTRUE); + + BookHistograms(AliQAv1::kRECPOINTS); TH1I *h1I; TH1F *h1F; @@ -802,7 +1088,7 @@ void AliMUONTrackerQADataMakerRec::InitRecPoints() h1F->SetMarkerColor(kRed); Add2RecPointsList(h1F, AliMUONQAIndices::kTrackerClusterChargePerDEMean, !expert, image); - if (!fMappingCheckRecPoints) fMappingCheckRecPoints = new AliMUONQAMappingCheck(RunNumber()); + MappingCheckRecPoints(AliRecoParam::AConvert(Master()->GetEventSpecie()),kTRUE); } //____________________________________________________________________________ @@ -1043,27 +1329,43 @@ void AliMUONTrackerQADataMakerRec::MakeRaws(AliRawReader* rawReader) { /// make QA for rawdata tracker - AliCodeTimerAuto("",0); + AliCodeTimerAuto(Form("%s",AliRecoParam::GetEventSpecieName(AliRecoParam::AConvert(Master()->GetEventSpecie()))),0); + AliInfo(Form("rawReader class=%s",rawReader->ClassName())); + /// forces init GetRawsData(AliMUONQAIndices::kTrackerBusPatchOccupancy); - ((AliMUONTrackerDataMaker*)fTrackerDataMaker)->SetRawReader(rawReader); + AliMUONTrackerDataMaker* dm = static_cast(TrackerDataMaker(AliRecoParam::AConvert(Master()->GetEventSpecie()))); + + dm->SetRawReader(rawReader); - fTrackerDataMaker->ProcessEvent(); - + Int_t eventType = rawReader->GetType(); + if (eventType == AliRawEventHeaderBase::kPhysicsEvent ) + { + dm->ProcessEvent(); + + FillEventSize(rawReader->GetEvent()); + + if ( dm->LastEventWasEmpty() ) + { + TH1* hrostatus = GetRawsData(AliMUONQAIndices::kTrackerReadoutStatus); + + if (hrostatus) hrostatus->Fill(1.0*AliMUONQAIndices::kTrackerRawNofEmptyEvents); + } + } } //__________________________________________________________________ void AliMUONTrackerQADataMakerRec::MakeDigits(TTree* digitsTree) { /// makes data from Digits - - AliCodeTimerAuto("",0); + AliCodeTimerAuto(Form("%s",AliRecoParam::GetEventSpecieName(AliRecoParam::AConvert(Master()->GetEventSpecie()))),0); - // Do nothing in case of calibration event - if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib ) return; + /// forces init + + GetDigitsData(AliMUONQAIndices::kTrackerBusPatchOccupancy); if (!fDigitStore) fDigitStore = AliMUONVDigitStore::Create(*digitsTree); @@ -1074,14 +1376,33 @@ void AliMUONTrackerQADataMakerRec::MakeDigits(TTree* digitsTree) AliMUONVDigit* dig = 0x0; + AliMUON2DMap oneEventData(true); + while ( ( dig = static_cast(next()) ) ) + { + if ( dig->IsTracker() ) { - GetDigitsData(0)->Fill(dig->DetElemId()); - GetDigitsData(1)->Fill(dig->ADC()); + if ( dig->Charge() > 0.0 ) + { + + Int_t detElemId = dig->DetElemId(); + Int_t manuId = dig->ManuId(); + + AliMUONVCalibParam* param = static_cast(oneEventData.FindObject(detElemId,manuId)); + if (!param) + { + param = new AliMUONCalibParamND(1,AliMpConstants::ManuNofChannels(),detElemId,manuId, + AliMUONVCalibParam::InvalidFloatValue()); + oneEventData.Add(param); + } + param->SetValueAsDouble(dig->ManuChannel(),0,dig->Charge()); + } } + } + + TrackerCalData(AliRecoParam::AConvert(Master()->GetEventSpecie()))->Add(oneEventData); } - //____________________________________________________________________________ void AliMUONTrackerQADataMakerRec::MakeRecPoints(TTree* clustersTree) { @@ -1094,10 +1415,9 @@ void AliMUONTrackerQADataMakerRec::MakeRecPoints(TTree* clustersTree) // then we have clusters in TreeR, so let's take that opportunity // to QA them... - AliCodeTimerAuto("",0); - - // Do nothing in case of calibration event - if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib ) return; + AliCodeTimerAuto(Form("%s",AliRecoParam::GetEventSpecieName(AliRecoParam::AConvert(Master()->GetEventSpecie()))),0); + // Forces init by requesting an histogram + GetRecPointsData(AliMUONQAIndices::kTrackerBusPatchOccupancy); if (!fClusterStore) { @@ -1115,7 +1435,11 @@ void AliMUONTrackerQADataMakerRec::MakeRecPoints(TTree* clustersTree) TIter next(fClusterStore->CreateIterator()); AliMUONVCluster* cluster; - if ( fMappingCheckRecPoints ) fMappingCheckRecPoints->NewEvent(); + AliMUONQAMappingCheck* mcr = MappingCheckRecPoints(AliRecoParam::AConvert(Master()->GetEventSpecie())); + + if ( mcr ) mcr->NewEvent(); + + AliMUON2DMap oneEventData(true); while ( ( cluster = static_cast(next()) ) ) { @@ -1129,12 +1453,29 @@ void AliMUONTrackerQADataMakerRec::MakeRecPoints(TTree* clustersTree) GetRecPointsData(AliMUONQAIndices::kTrackerNumberOfClustersPerChamber)->Fill(chamberId); GetRecPointsData(AliMUONQAIndices::kTrackerClusterChargePerChamber+chamberId)->Fill(cluster->GetCharge()); GetRecPointsData(AliMUONQAIndices::kTrackerClusterMultiplicityPerChamber+chamberId)->Fill(cluster->GetNDigits()); - GetRecPointsData(AliMUONQAIndices::kTrackerClusterHitMapPerChamber+chamberId)->Fill(cluster->GetX(),cluster->GetY()); + GetRecPointsData(AliMUONQAIndices::kTrackerClusterHitMapPerChamber+chamberId)->Fill(cluster->GetX(),cluster->GetY()); - if ( fMappingCheckRecPoints ) fMappingCheckRecPoints->Store(*cluster); + if ( mcr ) mcr->Store(*cluster); + for ( int i = 0; i < cluster->GetNDigits(); ++i ) + { + UInt_t digitId = cluster->GetDigitId(i); + + Int_t manuId = AliMUONVDigit::ManuId(digitId); + Int_t manuChannel = AliMUONVDigit::ManuChannel(digitId); + + AliMUONVCalibParam* param = static_cast(oneEventData.FindObject(detElemId,manuId)); + if (!param) + { + param = new AliMUONCalibParamND(1,AliMpConstants::ManuNofChannels(),detElemId,manuId,AliMUONVCalibParam::InvalidFloatValue()); + oneEventData.Add(param); + } + param->SetValueAsDouble(manuChannel,0,1.0); + } } + TrackerRecData(AliRecoParam::AConvert(Master()->GetEventSpecie()))->Add(oneEventData); + fClusterStore->Clear(); } @@ -1143,11 +1484,8 @@ void AliMUONTrackerQADataMakerRec::MakeESDs(AliESDEvent* esd) { /// make QA data from ESDs - AliCodeTimerAuto("",0); - - // Do nothing in case of calibration event - if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib ) return; - + AliCodeTimerAuto(Form("%s",AliRecoParam::GetEventSpecieName(AliRecoParam::AConvert(Master()->GetEventSpecie()))),0); + // load ESD event in the interface AliMUONESDInterface esdInterface; if (GetRecoParam()) AliMUONESDInterface::ResetTracker(GetRecoParam(), kFALSE); @@ -1236,10 +1574,9 @@ void AliMUONTrackerQADataMakerRec::MakeESDs(AliESDEvent* esd) //____________________________________________________________________________ AliMUONVTrackerData* AliMUONTrackerQADataMakerRec::GetTrackerData() const { -/// Return tracker data - - return fTrackerDataMaker->Data(); + /// Return tracker data + return TrackerDataMaker(AliRecoParam::AConvert(Master()->GetEventSpecie()))->Data(); } //____________________________________________________________________________ @@ -1261,7 +1598,6 @@ AliMUONTrackerQADataMakerRec::ResetDetectorRaws(TObjArray* list) if ( hn.Contains("Tracker") ) { if ( !hn.Contains("hTrackerBusPatchNofPads") && - !hn.Contains("hTrackerBusPatchNofManus") && !hn.Contains("hTrackerBusPatchConfig" ) ) { AliDebug(1,Form("Resetting %s",hn.Data())); @@ -1288,3 +1624,135 @@ AliMUONTrackerQADataMakerRec::ResetDetectorRaws(TObjArray* list) } } } + +//____________________________________________________________________________ +TObjArray* AliMUONTrackerQADataMakerRec::GetArray(TObjArray*& array, Bool_t create) +{ + /// Get (or create) the array + + if ( ! array ) + { + if ( create ) + { + array = new TObjArray(AliRecoParam::kNSpecies); + } + } + + return array; +} + +//____________________________________________________________________________ +AliMUONVTrackerDataMaker* +AliMUONTrackerQADataMakerRec::TrackerDataMaker(Int_t specieIndex) const +{ + /// const version of the getter + if ( fTrackerDataMakerArray ) + { + return static_cast(fTrackerDataMakerArray->At(specieIndex)); + } + return 0x0; +} + +//____________________________________________________________________________ +AliMUONVTrackerDataMaker* +AliMUONTrackerQADataMakerRec::TrackerDataMaker(Int_t specieIndex, Bool_t create) +{ + /// Get (or create) TrackerDataMaker object for a given specie + + TObjArray* array = GetArray(fTrackerDataMakerArray,create); + TObject* o(0x0); + + if ( array ) + { + array->SetOwner(kTRUE); + o = array->At(specieIndex); + if (!o && create) + { + + AliMUONTrackerDataMaker* dm = new AliMUONTrackerDataMaker(0x0, + AliCDBManager::Instance()->GetRun(), + 0x0, + "", + "", + kFALSE, + 0.0,0.0); + + if (!fLogger) fLogger = new AliMUONLogger(-1); // note that we share the logger between species... should not be a big deal though + dm->EnableErrorLogger(fLogger); + dm->Data()->DisableChannelLevel(); // to save up disk space, we only store starting at the manu level + dm->Data()->SetName("RawCharges"); + dm->SetRunning(kTRUE); + + o = dm; + array->AddAt(o,specieIndex); + } + } + return static_cast(o); +} + +//____________________________________________________________________________ +AliMUONVTrackerData* +AliMUONTrackerQADataMakerRec::TrackerCalData(Int_t specieIndex, Bool_t create) +{ + TObjArray* array = GetArray(fTrackerCalDataArray,create); + TObject* o(0x0); + + if (array) + { + array->SetOwner(kFALSE); // as the tracker data will be attached to fQADigitsList which will become the owner + o = array->At(specieIndex); + if (!o && create) + { + AliMUONTrackerData* data = new AliMUONTrackerData("CalCharges",Form("Calibrated charges (fC) %s",GetRecoParam()->GetCalibrationMode()),1); + data->SetDimensionName(0,"charge"); + data->DisableChannelLevel(); // to save up disk space, we only store starting at the manu level + o=data; + array->AddAt(o,specieIndex); + } + } + return static_cast(o); +} + +//____________________________________________________________________________ +AliMUONVTrackerData* +AliMUONTrackerQADataMakerRec::TrackerRecData(Int_t specieIndex, Bool_t create) +{ + TObjArray* array = GetArray(fTrackerRecDataArray,create); + TObject* o(0x0); + + if (array) + { + array->SetOwner(kFALSE); // as the tracker data will be attached to fQARecPointsList which will become the owner + o = array->At(specieIndex); + if (!o && create) + { + AliMUONTrackerData* data = new AliMUONTrackerData("RecCharges",Form("Calibrated charges (fC) %s for digits belonging to a reconstructed cluster",GetRecoParam()->GetCalibrationMode()),1); + data->SetDimensionName(0,"one"); + data->DisableChannelLevel(); // to save up disk space, we only store starting at the manu level + o=data; + array->AddAt(o,specieIndex); + } + } + return static_cast(o); +} + +//____________________________________________________________________________ +AliMUONQAMappingCheck* +AliMUONTrackerQADataMakerRec::MappingCheckRecPoints(Int_t specieIndex, Bool_t create) +{ + TObjArray* array = GetArray(fMappingCheckRecPointsArray,create); + TObject* o(0x0); + + if (array) + { + array->SetOwner(kTRUE); + o = array->At(specieIndex); + if (!o && create) + { + AliMUONQAMappingCheck* mcheck = new AliMUONQAMappingCheck(RunNumber()); + o=mcheck; + array->AddAt(o,specieIndex); + } + } + return static_cast(o); +} diff --git a/MUON/AliMUONTrackerQADataMakerRec.h b/MUON/AliMUONTrackerQADataMakerRec.h index 1532082fad2..4a18908d44e 100644 --- a/MUON/AliMUONTrackerQADataMakerRec.h +++ b/MUON/AliMUONTrackerQADataMakerRec.h @@ -13,6 +13,7 @@ // --- AliRoot header files --- #include "AliMUONVQADataMakerRec.h" #include "AliMUONRecoParam.h" +#include "AliQAv1.h" class AliMUONDigitMaker; class AliMUONVClusterStore; @@ -23,6 +24,8 @@ class AliMUONVTrackerDataMaker; class AliMUONCalibrationData; class AliMUONQAMappingCheck; class AliMUONLogger; +class AliMUONQADataMakerRec; +class AliRawVEvent; class AliMUONTrackerQADataMakerRec: public AliMUONVQADataMakerRec { @@ -38,12 +41,10 @@ public: virtual void InitRecPoints(); void EndOfDetectorCycleRaws(Int_t specie, TObjArray** list); + void EndOfDetectorCycleDigits(Int_t specie, TObjArray** list); void EndOfDetectorCycleRecPoints(Int_t specie, TObjArray** list); void EndOfDetectorCycleESDs(Int_t specie, TObjArray** list); - /// Empty implementation - void EndOfDetectorCycleDigits(Int_t, TObjArray**) {} - virtual void MakeDigits(TTree* dig); virtual void MakeESDs(AliESDEvent* esd) ; virtual void MakeRaws(AliRawReader* rawReader); @@ -52,12 +53,39 @@ public: void ResetDetectorRaws(TObjArray* list); private: + + AliMUONQADataMakerRec* Master() const; + + void BookHistograms(AliQAv1::TASKINDEX_t task); + + void FillReadoutStatus(AliMUONLogger& log, AliMUONVTrackerData* data); + + void FillEventSize(const AliRawVEvent* event); + void InitCommon(); + void InsertTrackerData(Int_t specie, TObjArray** list, TObject* object, - Int_t indexNumber, Bool_t replace=kFALSE); + Int_t indexNumber, + Bool_t replace=kFALSE); + + void ProjectTrackerData(AliMUONVTrackerData* data, + TH1& hbp, + TH1& hnevents, + TH1& hddl, + TH1& hddlevents); - void FillErrors(AliMUONLogger& log); + AliMUONVTrackerDataMaker* TrackerDataMaker(Int_t specie) const; + + AliMUONVTrackerDataMaker* TrackerDataMaker(Int_t specie, Bool_t create); + + AliMUONQAMappingCheck* MappingCheckRecPoints(Int_t specie, Bool_t create=kFALSE); + AliMUONVTrackerData* TrackerCalData(Int_t specie, Bool_t create=kFALSE); + + AliMUONVTrackerData* TrackerRecData(Int_t specie, Bool_t create=kFALSE); + + TObjArray* GetArray(TObjArray*& array, Bool_t create); + private: /// Not implemented AliMUONTrackerQADataMakerRec(const AliMUONTrackerQADataMakerRec& rhs); @@ -68,17 +96,22 @@ private: AliMUONDigitMaker* fDigitMaker; //!< pointer to digit maker AliMUONVClusterStore* fClusterStore; //!< pointer to cluster store - AliMUONVTrackerDataMaker* fTrackerDataMaker; //!< tracker data accumulation (Raw) - - AliMUONQAMappingCheck* fMappingCheckRecPoints; //!< mapping cross-checker (RecPoints) - AliMUONCalibrationData* fCalibrationData; //!< Used to load Local, Regional and Global masks AliMUONLogger* fLogger; //!< (readout) error logger - static Double_t fgkRawNofEvents; //!< x-position to fill kTrackerReadoutErrors with nof events + TH1* fBusPatchConfig; //!< bus patch configuration + + Double_t fBPxmin; //!< min bin value for bus patch + Double_t fBPxmax; //!< max bin value for bus patch + Int_t fBPnbins; //!< number of bus patch bins + + TObjArray* fTrackerDataMakerArray; //!< tracker data accumulation (Raws) + TObjArray* fTrackerCalDataArray; //!< tracker data accumulation (calibrated digits) + TObjArray* fTrackerRecDataArray; //!< tracker data accumulation (only calibrated digits belonging to reconstructed clusters) + TObjArray* fMappingCheckRecPointsArray; //!< mapping cross-checker (RecPoints) - ClassDef(AliMUONTrackerQADataMakerRec,3) // MUON Quality assurance data maker + ClassDef(AliMUONTrackerQADataMakerRec,5) // MUON Quality assurance data maker }; #endif diff --git a/MUON/AliMUONVQADataMakerRec.h b/MUON/AliMUONVQADataMakerRec.h index 9ec0b3b3a5a..ce80a094a40 100644 --- a/MUON/AliMUONVQADataMakerRec.h +++ b/MUON/AliMUONVQADataMakerRec.h @@ -20,6 +20,10 @@ # include "AliRecoParam.h" #endif +#ifndef ALIQAv1_H +# include "AliQAv1.h" +#endif + class AliESDEvent; class AliQADataMakerRec; class AliMUONRecoParam; @@ -96,6 +100,7 @@ private: /// Not implemented AliMUONVQADataMakerRec& operator=(const AliMUONVQADataMakerRec& rhs); +protected: AliQADataMakerRec* fMaster; ///< master to get access to its methods ClassDef(AliMUONVQADataMakerRec,1) // Interface for a MUON QADataMakerRec diff --git a/MUON/AliMUONVTrackerDataMaker.h b/MUON/AliMUONVTrackerDataMaker.h index bbd783730e5..751c74be975 100644 --- a/MUON/AliMUONVTrackerDataMaker.h +++ b/MUON/AliMUONVTrackerDataMaker.h @@ -31,6 +31,9 @@ public: /// Our data virtual AliMUONVTrackerData* Data() const = 0; + /// Whether or not we're the owner of our AliMUONVTrackerData + virtual void SetOwnerOfData(Bool_t /*flag*/) { } + /// Whether we can be run virtual Bool_t IsRunnable() const = 0; -- 2.43.0