From 8f29b706c05ce4de340dd708a2248f2d17bf160a Mon Sep 17 00:00:00 2001 From: laphecet Date: Wed, 2 Sep 2009 13:16:41 +0000 Subject: [PATCH] AMORE & QA fixes. - AliMUONQAChecker prevent the method AliMUONQAChecker::CheckRaws to return a NULL pointer if a TrackerData object is not present in the first specie (kDefault). Now it returns NULL only if there no TrackerData object at all. - AliMUONCalibrationData : add a bypass to force the usage of some external calibration data (for AMORE) - AliMUONTrackerDataWrapper : remove an uneeded method (Guillaume) - AliMUONQADataMakerRec : introducing the beautifier for presenting a nicer Raw Data QA to the shifter. This is just a first approach, as most of that should probably be done in the Checker on the longer term (to be discussed...) - AliMUONDigitCalibrator & AliMUONTrackerDataMaker : do not force the number of sigma to cut on the charge. Should be taken from the recoparam. This was impacting the QA only (forcing it to use a 3 sigma cut, where anywhere else we use 4 sigma cut). (Laurent) --- MUON/AliMUONCalibrationData.cxx | 18 ++ MUON/AliMUONCalibrationData.h | 9 +- MUON/AliMUONDigitCalibrator.cxx | 12 ++ MUON/AliMUONDigitCalibrator.h | 2 +- MUON/AliMUONQAChecker.cxx | 15 +- MUON/AliMUONQADataMakerRec.cxx | 279 +++++++++++++++++++++++++++++-- MUON/AliMUONQADataMakerRec.h | 14 +- MUON/AliMUONTrackerDataMaker.cxx | 2 +- MUON/AliMUONTrackerDataWrapper.h | 2 - 9 files changed, 327 insertions(+), 26 deletions(-) diff --git a/MUON/AliMUONCalibrationData.cxx b/MUON/AliMUONCalibrationData.cxx index 7e0cb208592..d3eb1ec0cb5 100644 --- a/MUON/AliMUONCalibrationData.cxx +++ b/MUON/AliMUONCalibrationData.cxx @@ -54,6 +54,9 @@ ClassImp(AliMUONCalibrationData) /// \endcond +AliMUONVStore* AliMUONCalibrationData::fBypassPedestals(0x0); +AliMUONVStore* AliMUONCalibrationData::fBypassGains(0x0); + //_____________________________________________________________________________ AliMUONCalibrationData::AliMUONCalibrationData(Int_t runNumber, Bool_t deferredInitialization) @@ -275,6 +278,8 @@ AliMUONVStore* AliMUONCalibrationData::Gains() const { /// Create (if needed) and return the internal store for gains. + if (fBypassGains) return fBypassGains; + if (!fGains) { fGains = CreateGains(fRunNumber); @@ -399,11 +404,24 @@ AliMUONCalibrationData::RejectList() const return fRejectList; } +//_____________________________________________________________________________ +void +AliMUONCalibrationData::BypassStores(AliMUONVStore* ped, AliMUONVStore* gain) +{ + /// Force the use of those pedestals and gains + fBypassPedestals = ped; + fBypassGains = gain; + +} + //_____________________________________________________________________________ AliMUONVStore* AliMUONCalibrationData::Pedestals() const { /// Return pedestals + + if (fBypassPedestals) return fBypassPedestals; + if (!fPedestals) { fPedestals = CreatePedestals(fRunNumber); diff --git a/MUON/AliMUONCalibrationData.h b/MUON/AliMUONCalibrationData.h index 33d1722132b..a8b912390f3 100644 --- a/MUON/AliMUONCalibrationData.h +++ b/MUON/AliMUONCalibrationData.h @@ -136,6 +136,8 @@ public: static void Check(Int_t runNumber); + static void BypassStores(AliMUONVStore* ped, AliMUONVStore* gain); + protected: /// Not implemented AliMUONCalibrationData(const AliMUONCalibrationData& other); @@ -161,8 +163,11 @@ private: mutable AliMUONVStore* fOccupancyMap; //!< occupancy map mutable AliMUONRejectList* fRejectList; //!< reject list - - ClassDef(AliMUONCalibrationData,11) // Storage for all MUON calibration data. + + static AliMUONVStore* fBypassPedestals; + static AliMUONVStore* fBypassGains; + + ClassDef(AliMUONCalibrationData,12) // Storage for all MUON calibration data. }; #endif diff --git a/MUON/AliMUONDigitCalibrator.cxx b/MUON/AliMUONDigitCalibrator.cxx index 75f6868a961..0566086a353 100644 --- a/MUON/AliMUONDigitCalibrator.cxx +++ b/MUON/AliMUONDigitCalibrator.cxx @@ -169,6 +169,11 @@ AliMUONDigitCalibrator::Ctor(const char* calibMode, fChargeSigmaCut = recoParams->ChargeSigmaCut(); } + else + { + fLogger->Log("No RecoParam available"); + fLogger->Log(Form("SigmaCut=%e",fChargeSigmaCut)); + } Bool_t deferredInitialization = kTRUE; @@ -270,6 +275,13 @@ AliMUONDigitCalibrator::CalibrateDigit(Int_t detElemId, Int_t manuId, Int_t manu /// Calibrate one digit /// Return the digit charge, in fC + if ( nsigmas < 0 ) + { + nsigmas = fChargeSigmaCut; + } + + fLogger->Log(Form("ChargeSigmaCut used = %e",nsigmas)); + AliMUONVCalibParam* pedestal = static_cast (fPedestals->FindObject(detElemId,manuId)); diff --git a/MUON/AliMUONDigitCalibrator.h b/MUON/AliMUONDigitCalibrator.h index 7aa0cc5c7cd..bd570ff4dc6 100644 --- a/MUON/AliMUONDigitCalibrator.h +++ b/MUON/AliMUONDigitCalibrator.h @@ -45,7 +45,7 @@ public: Int_t* statusMap=0x0) const; Float_t CalibrateDigit(Int_t detElemId, Int_t manuId, Int_t manuChannel, - Float_t adc, Float_t nsigmas, + Float_t adc, Float_t nsigmas=-1, Bool_t* isSaturated=0x0) const; Int_t PadStatus(Int_t detElemId, Int_t manuId, Int_t manuChannel) const; diff --git a/MUON/AliMUONQAChecker.cxx b/MUON/AliMUONQAChecker.cxx index 8c37384e27e..8b90d3f1984 100644 --- a/MUON/AliMUONQAChecker.cxx +++ b/MUON/AliMUONQAChecker.cxx @@ -170,6 +170,7 @@ AliMUONQAChecker::CheckRaws(TObjArray ** list) for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) rv[specie] = 1.0 ; + Bool_t IsAnyTrackerDataPresent = kFALSE; for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) { TIter next(list[specie]); TObject* object; @@ -185,10 +186,11 @@ AliMUONQAChecker::CheckRaws(TObjArray ** list) if ( !data ) { - AliError("Did not find TrackerData in the list !"); - return NULL; + AliWarning(Form("Did not find TrackerData for specie %s !",AliRecoParam::GetEventSpecieName(specie))); + continue; } + IsAnyTrackerDataPresent = kTRUE; AliMpManuIterator it; Int_t detElemId; Int_t manuId; @@ -204,7 +206,7 @@ AliMUONQAChecker::CheckRaws(TObjArray ** list) if (occ >= 0.75 ) ++n75; } - AliInfo(Form("n %d n50 %d n75 %d",n,n50,n75)); + AliDebug(1,Form("n %d n50 %d n75 %d",n,n50,n75)); if ( n == 0 ) { @@ -224,6 +226,13 @@ AliMUONQAChecker::CheckRaws(TObjArray ** list) rv[specie] = 0.9; } } + + if ( !IsAnyTrackerDataPresent ) + { + AliError("Did not find any TrackerData in the list !"); + return NULL; + } + return rv; } diff --git a/MUON/AliMUONQADataMakerRec.cxx b/MUON/AliMUONQADataMakerRec.cxx index 952605da39e..b2bb928e408 100644 --- a/MUON/AliMUONQADataMakerRec.cxx +++ b/MUON/AliMUONQADataMakerRec.cxx @@ -47,6 +47,7 @@ #include "AliMpDDLStore.h" #include "AliMpDEIterator.h" #include "AliMpDEManager.h" +#include "AliMpDetElement.h" #include "AliMpLocalBoard.h" #include "AliMpStationType.h" #include "AliMpTriggerCrate.h" @@ -72,7 +73,10 @@ #include #include #include +#include +#include #include +#include //----------------------------------------------------------------------------- /// \class AliMUONQADataMakerRec @@ -85,6 +89,97 @@ ClassImp(AliMUONQADataMakerRec) /// \endcond + +namespace { + + int trim(Int_t n, + Double_t* x, + Double_t alpha, + Double_t& tmean, + Double_t& tvar, + Double_t& min, + Double_t& max) + { + // + // Calculates the trimmed (tmean) mean + // of a sample (x) and estimates the variance (tvar) + // of that mean. + // + + // First check input parameters + + // number of observations + if ( n < 2 ) + { + return -1; + } + + if ( alpha < 0 || alpha >= 0.5 ) + // proportion of observations + // to be trimmed at each end of the sorted sample + { + return -2; + } + + // Input parameters are good. Let's move on. + + // Insure we use a sample sorted into ascending order. + + Int_t* indices = new Int_t[n]; + + TMath::Sort(n,x,indices,kFALSE); + + Double_t* sx = new Double_t[n]; + + for ( Int_t i = 0; i < n; ++i ) + { + sx[i] = x[indices[i]]; + } + delete[] indices; + + + // Number of observations trimmed at each end. + + Int_t k = static_cast(floorf(alpha * n)); + + double sum = 0.0; + + for ( Int_t i = k; i < n - k ; ++i ) + { + sum += sx[i]; + } + + tmean = sum / ( n - 2 * k ); + + double t2 = 0.0; + + for ( Int_t i = k; i < n - k; ++i ) + { + t2 += (sx[i] - tmean) * (sx[i] - tmean); + } + + tvar = ( + t2 + + k * (sx[k] - tmean) * (sx[k] - tmean) + + k * (sx[n - k - 1] - tmean) * (sx[n - k - 1] - tmean) + ) / (n * n); + + // get the min and max for the non-rejected values + min = DBL_MAX; + max = 0.0; + + for ( Int_t i = k; i < n-k; ++i ) + { + min = TMath::Min(min,sx[i]); + max = TMath::Max(max,sx[i]); + } + + delete[] sx; + + return 0; + } +} + //____________________________________________________________________________ AliMUONQADataMakerRec::AliMUONQADataMakerRec() : AliQADataMakerRec(AliQAv1::GetDetName(AliQAv1::kMUON), "MUON Quality Assurance Data Maker"), @@ -170,15 +265,17 @@ void AliMUONQADataMakerRec::EndOfDetectorCycle(AliQAv1::TASKINDEX_t task, TObjAr ///Detector specific actions at end of cycle AliCodeTimerAuto(""); - + + // Display trigger histos in a more user friendly way + DisplayTriggerInfo(task); + for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) { if (! IsValidEventSpecie(specie, list) ) - continue ; + continue ; SetEventSpecie(AliRecoParam::ConvertIndex(specie)) ; if ( task == AliQAv1::kRAWS && fTrackerDataMaker ) { - if ( !GetRawsData(kTrackerBusPatchOccupancy) ) continue; TIter next(list[specie]); @@ -191,7 +288,7 @@ void AliMUONQADataMakerRec::EndOfDetectorCycle(AliQAv1::TASKINDEX_t task, TObjAr } if (!alreadyThere && fTrackerDataMaker) { - AliDebug(AliQAv1::GetQADebugLevel(), "Adding fTrackerDataMaker to the list of qa objects"); + AliDebug(AliQAv1::GetQADebugLevel(), "Adding fTrackerData to the list of qa objects"); list[specie]->AddAt(fTrackerDataMaker->Data(),(Int_t)kTrackerData); } if ( fTrackerDataMaker ) @@ -207,8 +304,10 @@ void AliMUONQADataMakerRec::EndOfDetectorCycle(AliQAv1::TASKINDEX_t task, TObjAr { Int_t busPatchId = bp->GetId(); Int_t bin = hbp->FindBin(busPatchId); - hbp->SetBinContent(bin,data->BusPatch(busPatchId,occDim)); + hbp->SetBinContent(bin,data->BusPatch(busPatchId,occDim)*100.0); // occupancy, in percent } + + BeautifyTrackerBusPatchOccupancy(*hbp); } } @@ -443,9 +542,8 @@ void AliMUONQADataMakerRec::EndOfDetectorCycle(AliQAv1::TASKINDEX_t task, TObjAr // Display trigger histos in a more user friendly way DisplayTriggerInfo(task); - } // loop on specie - + // do the QA checking AliQAChecker::Instance()->Run(AliQAv1::kMUON, task, list) ; } @@ -497,21 +595,34 @@ void AliMUONQADataMakerRec::InitRaws() h10->GetYaxis()->SetTitle("Cumulated scaler time (s)"); Add2RawsList(h10, kTriggerScalersTime, !expert, !image, !saveCorr); - Int_t nbp(0); + Int_t bpmin(999999); + Int_t bpmax(0); + TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator()); - while (next()) + AliMpBusPatch* bp(0x0); + while ( ( bp = static_cast(next())) ) { - ++nbp; + bpmin = TMath::Min(bpmin,bp->GetId()); + bpmax = TMath::Max(bpmax,bp->GetId()); } - TH1* hbp = new TH1F("hTrackerBusPatchOccupancy","Occupancy of bus patches", - nbp,-0.5,nbp-0.5); + 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); + + TH1* hbpnpads = new TH1F("kTrackerBusPatchNofPads","Number of pads per bus patch",nbins,xmin,xmax); + + TH1* hbpnmanus = new TH1F("kTrackerBusPatchNofManus","Number of manus per bus patch",nbins,xmin,xmax); + Add2RawsList(hbp,kTrackerBusPatchOccupancy, !expert, image, !saveCorr); + Add2RawsList(hbpnpads,kTrackerBusPatchNofPads, expert, !image, !saveCorr); + Add2RawsList(hbpnmanus,kTrackerBusPatchNofManus, expert, !image, !saveCorr); const Bool_t histogram(kFALSE); - fTrackerDataMaker = new AliMUONTrackerDataMaker(GetMUONRecoParam(), + if(!fTrackerDataMaker) fTrackerDataMaker = new AliMUONTrackerDataMaker(GetMUONRecoParam(), AliCDBManager::Instance()->GetRun(), 0x0, "", @@ -1491,3 +1602,145 @@ AliMUONVTrackerData* AliMUONQADataMakerRec::GetTrackerData() const return fTrackerDataMaker->Data(); } + +//____________________________________________________________________________ +void +AliMUONQADataMakerRec::BeautifyTrackerBusPatchOccupancy(TH1& hbp) +{ + /// Put labels, limits and so on on the TrackerBusPatchOccupancy histogram + + hbp.SetXTitle("Absolute Bus Patch Id"); + hbp.SetYTitle("Occupancy (percent)"); + hbp.SetStats(kFALSE); + + Double_t xmin = hbp.GetXaxis()->GetXmin(); + Double_t xmax = hbp.GetXaxis()->GetXmax(); + + Double_t occMax(0.1); // 0.1% y-limit for the plot + Double_t occError(1.0); // 1.0% y-limit to count the "errors" + + TLine* line = new TLine(xmin,occError,xmax,occError); + line->SetLineColor(2); + line->SetLineWidth(3); + + hbp.GetListOfFunctions()->Add(line); + + TH1* hnpads = GetRawsData(kTrackerBusPatchNofPads); + hnpads->SetStats(kFALSE); + TH1* hnmanus = GetRawsData(kTrackerBusPatchNofManus); + hnmanus->SetStats(kFALSE); + + TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator()); + AliMpBusPatch* bp(0x0); + while ( ( bp = static_cast(next())) ) + { + Int_t n(0); + 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); + } + hnpads->Fill(bp->GetId(),n*1.0); + hnmanus->Fill(bp->GetId(),bp->GetNofManus()*1.0); + } + + next.Reset(); + + 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 = hnpads->GetBinContent(bin); + + ++nBusPatches; + + nPads += n; + + if ( hbp.GetBinContent(bin) <= 0 ) + { + nMissingPads += n; + ++nMissingBusPatches; + } + } + + next.Reset(); + + Double_t* x = new Double_t[nBusPatches]; + Int_t n(0); + Int_t nBusPatchesAboveLimit(0); + + while ( ( bp = static_cast(next())) ) + { + Int_t bin = hbp.FindBin(bp->GetId()); + if ( hbp.GetBinContent(bin) > 0 ) + { + x[n] = hbp.GetBinContent(bin); + ++n; + } + if ( hbp.GetBinContent(bin) > occError ) + { + ++nBusPatchesAboveLimit; + } + } + + Double_t alpha(0.1); // trim 10% of data + Double_t tmean,tvar; + Double_t ymin,ymax; + + // computed the truncated mean of the occupancy values, in order to get a + // reasonable y-range for the histogram (without giant peaks to the roof + // for misbehaving buspatches). + Int_t ok = trim(nBusPatches,x,alpha,tmean,tvar,ymin,ymax); + + if ( ok < 0 ) + { + ymax = occMax; + } + else + { + ymax = TMath::Max(ymax,occMax); + } + + hbp.SetMaximum(ymax*1.4); + + TPaveText* text = new TPaveText(0.55,0.85,0.99,0.99,"NDC"); + + if (ok < 0 ) + { + text->AddText("Could not compute truncated mean. Not enough events ?"); + text->SetFillColor(2); + } + else if (!nPads || !nBusPatches) + { + text->AddText("Could not get the total number of pads. ERROR !!!"); + text->SetFillColor(2); + } + else + { + Float_t missingPadFraction = nMissingPads*100.0/nPads; + Float_t missingBusPatchFraction = nMissingBusPatches*100.0/nBusPatches; + Float_t aboveLimitFraction = nBusPatchesAboveLimit*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,occError)); + text->AddText(Form("Truncated mean at %2d %% is %7.2f %%",(Int_t)(alpha*100),tmean)); + + if ( missingPadFraction > 10.0 || aboveLimitFraction > 5.0 ) + { + text->SetFillColor(2); + } + else + { + text->SetFillColor(3); + } + } + + hbp.GetListOfFunctions()->Add(text); +} + diff --git a/MUON/AliMUONQADataMakerRec.h b/MUON/AliMUONQADataMakerRec.h index b36af74e781..424edf2260f 100644 --- a/MUON/AliMUONQADataMakerRec.h +++ b/MUON/AliMUONQADataMakerRec.h @@ -30,14 +30,15 @@ public: virtual ~AliMUONQADataMakerRec(); AliMUONVTrackerData* GetTrackerData() const; - + + virtual void InitRaws(); + virtual void InitRecPoints(); + protected: virtual void StartOfDetectorCycle(); - virtual void InitRaws(); virtual void InitDigits(); - virtual void InitRecPoints(); virtual void InitESDs(); virtual void MakeRaws(AliRawReader* rawReader); @@ -55,6 +56,8 @@ private: 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 kTriggerScalers = 22, ///< Trigger scalers histogram per plane index kTriggerScalersDisplay = 30, ///< Trigger scalers display histogram per plane index kTriggerScalersTime = 38, ///< Trigger scalers acquisition time index @@ -149,6 +152,9 @@ private: kESDSumLocalChi2PerDE = 1011 ///< sum of local chi2 per DE }; +private: + void BeautifyTrackerBusPatchOccupancy(TH1& hbp); + private: void Ctor(); @@ -171,7 +177,7 @@ private: AliMUONVTrackerDataMaker* fTrackerDataMaker; //!< tracker data accumulation - ClassDef(AliMUONQADataMakerRec,6) // MUON Quality assurance data maker + ClassDef(AliMUONQADataMakerRec,7) // MUON Quality assurance data maker }; #endif diff --git a/MUON/AliMUONTrackerDataMaker.cxx b/MUON/AliMUONTrackerDataMaker.cxx index 278df70ab28..b80d844b0ec 100644 --- a/MUON/AliMUONTrackerDataMaker.cxx +++ b/MUON/AliMUONTrackerDataMaker.cxx @@ -387,7 +387,7 @@ Bool_t AliMUONTrackerDataMaker::ProcessEvent() { if ( fDigitCalibrator->IsValidDigit(detElemId, manuId, manuChannel) ) { - charge = fDigitCalibrator->CalibrateDigit(detElemId, manuId, manuChannel,adc,3.0); + charge = fDigitCalibrator->CalibrateDigit(detElemId, manuId, manuChannel,adc); } else { diff --git a/MUON/AliMUONTrackerDataWrapper.h b/MUON/AliMUONTrackerDataWrapper.h index 4a58afdbb90..e2f21449516 100644 --- a/MUON/AliMUONTrackerDataWrapper.h +++ b/MUON/AliMUONTrackerDataWrapper.h @@ -58,8 +58,6 @@ public: virtual Long64_t Merge(TCollection* li); - virtual void UpdateData(AliMUONVTrackerData* data=0x0) { fData = data; } - private: /// not implemented. AliMUONTrackerDataWrapper(const AliMUONTrackerDataWrapper& rhs); -- 2.43.0