// --- MUON header files ---
#include "AliMUONTrackerQADataMakerRec.h"
+#include "AliDAQ.h"
#include "AliQAv1.h"
+#include "AliMpDDL.h"
#include "AliMUONConstants.h"
#include "AliMUONDigitMaker.h"
#include "AliMUONQAIndices.h"
#include "AliMUONQAMappingCheck.h"
+#include "AliMUONLogger.h"
#include "AliMUONTrackerDataMaker.h"
#include "AliMUONVCluster.h"
#include "AliMUONVClusterStore.h"
#include <TH2F.h>
#include <Riostream.h>
#include <TMath.h>
+#include <TPaveText.h>
//-----------------------------------------------------------------------------
/// \class AliMUONTrackerQADataMakerRec
ClassImp(AliMUONTrackerQADataMakerRec)
/// \endcond
+Double_t AliMUONTrackerQADataMakerRec::fgkRawNofGlitchErrors(0.0);
+Double_t AliMUONTrackerQADataMakerRec::fgkRawNofTokenLostErrors(1.0);
+Double_t AliMUONTrackerQADataMakerRec::fgkRawNofParityErrors(2.0);
+Double_t AliMUONTrackerQADataMakerRec::fgkRawNofPaddingErrors(3.0);
+
//____________________________________________________________________________
AliMUONTrackerQADataMakerRec::AliMUONTrackerQADataMakerRec(AliQADataMakerRec* master) :
AliMUONVQADataMakerRec(master),
fClusterStore(0x0),
fTrackerDataMaker(0x0),
fMappingCheckRecPoints(0x0),
-fCalibrationData(new AliMUONCalibrationData(AliCDBManager::Instance()->GetRun()))
+fCalibrationData(new AliMUONCalibrationData(AliCDBManager::Instance()->GetRun())),
+fLogger(0x0)
{
/// ctor
}
delete fTrackerDataMaker;
delete fCalibrationData;
delete fMappingCheckRecPoints;
+ if (fLogger)
+ {
+ if ( fLogger->NumberOfEntries() != 0 )
+ {
+ AliError("Some unprocessed logged errors are still there... Please check");
+ }
+ delete fLogger;
+ }
}
//____________________________________________________________________________
if ( fTrackerDataMaker )
{
+ /// 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());
Int_t bin = hbp->FindBin(busPatchId);
hbp->SetBinContent(bin,data->BusPatch(busPatchId,occDim)*100.0); // occupancy, in percent
}
+
+ /// 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 )
+ {
+ // readout errors
+ FillErrors(*fLogger);
+ fLogger->Clear();
+ }
+
+ /// project tracker data into DDL occupancies (for the shifter)
+ TH1* hddl = GetRawsData(AliMUONQAIndices::kTrackerDDLOccupancy);
+ hddl->Reset();
+ TH1* hddlevents = GetRawsData(AliMUONQAIndices::kTrackerDDLNofEvents);
+ hddlevents->Reset();
+
+ 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);
+
+ hddlevents->Fill(ddlId,nevents);
+
+ Double_t occ(0.0);
+
+ for ( Int_t ide = 0; ide < ddl->GetNofDEs(); ++ide )
+ {
+ Int_t de = ddl->GetDEId(ide);
+
+ npads += TMath::Nint(data->DetectionElement(de,3));
+
+ occ += data->DetectionElement(de,4);
+ }
+
+ if ( nevents > 0 && npads > 0 )
+ {
+ occ = occ/npads/nevents;
+ }
+
+ hddl->Fill(ddlId,100.0*occ); // occ in percent
+ }
}
}
+//____________________________________________________________________________
+void AliMUONTrackerQADataMakerRec::FillErrors(AliMUONLogger& log)
+{
+ log.ResetItr();
+
+ TString msg;
+ Int_t occurence;
+
+ TH1* hparity = GetRawsData(AliMUONQAIndices::kTrackerBusPatchParityErrors);
+
+ TH1* htoken = GetRawsData(AliMUONQAIndices::kTrackerBusPatchTokenLostErrors);
+
+ TH1* hpadding = GetRawsData(AliMUONQAIndices::kTrackerBusPatchPaddingErrors);
+
+ TH1* hroe = GetRawsData(AliMUONQAIndices::kTrackerReadoutErrors);
+
+ TH1* hnevents = GetRawsData(AliMUONQAIndices::kTrackerNofRawEventSeen);
+
+ Int_t nevents = TMath::Nint(hnevents->GetBinContent(1));
+
+ if ( !nevents )
+ {
+ 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);
+ return;
+ }
+
+ while ( log.Next(msg,occurence) )
+ {
+ AliDebug(1,Form("msg=%s occurence=%d",msg.Data(),occurence));
+
+ if ( msg.Contains("token") )
+ {
+ Int_t dsp(-1),ddl(-1),ecode(-1);
+
+ sscanf(msg.Data(),"Lost token error detected in DSP 0x%X of DDL %d and code %d.",
+ &dsp,&ddl,&ecode);
+ Int_t localBP = ((dsp >> 16)- 4)*5 + 1;
+ Int_t buspatch = localBP + ddl*100;
+ htoken->Fill(buspatch,occurence);
+ hroe->Fill(fgkRawNofTokenLostErrors,occurence);
+ AliDebug(1,Form("DDL %d DSP %d busPatch %d",ddl,dsp,buspatch));
+ }
+
+ if ( msg.Contains("Parity") )
+ {
+ Int_t buspatch;
+ sscanf(msg.Data(),"Parity error in buspatch %d (0x%X).",&buspatch,&buspatch);
+ hparity->Fill(buspatch,occurence);
+ hroe->Fill(fgkRawNofParityErrors,occurence);
+ }
+
+ if ( msg.Contains("Glitch") )
+ {
+ hroe->Fill(fgkRawNofGlitchErrors,occurence);
+ }
+
+ if ( msg.Contains("Padding") )
+ {
+ 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(fgkRawNofPaddingErrors,occurence);
+ }
+ }
+
+ /// Finally we normalize to the number of events, for the shifter plot only
+ hroe->Scale(100.0/nevents);
+}
+
+
//____________________________________________________________________________
void AliMUONTrackerQADataMakerRec::InitRaws()
{
const Bool_t saveCorr = kTRUE ;
const Bool_t image = kTRUE ;
- Int_t bpmin(999999);
+ Int_t bpmin(999999);
Int_t bpmax(0);
TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
TH1* hbp = new TH1F("hTrackerBusPatchOccupancy","Occupancy of bus patches",nbins,xmin,xmax);
-
TH1* hbpnpads = new TH1F("hTrackerBusPatchNofPads","Number of pads per bus patch",nbins,xmin,xmax);
TH1* hbpnmanus = new TH1F("hTrackerBusPatchNofManus","Number of manus per bus patch",nbins,xmin,xmax);
- Add2RawsList(hbp,AliMUONQAIndices::kTrackerBusPatchOccupancy, !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);
+
+ Add2RawsList(new TH1F("hTrackerBusPatchPaddingErrors","Number of padding errors per bus patch",nbins,xmin,xmax),
+ AliMUONQAIndices::kTrackerBusPatchPaddingErrors,expert,!image,!saveCorr);
+
+ TH1* h = new TH1F("hTrackerReadoutErrors","Number of readout errors per event;;Error rate in %",4,-0.5,3.5);
+ h->SetStats(kFALSE);
+
+ // The QA shifter will only see the summary plot below
+ TAxis* a = h->GetXaxis();
+
+ a->SetBinLabel(h->FindBin(fgkRawNofGlitchErrors),"Glitch errors");
+ a->SetBinLabel(h->FindBin(fgkRawNofTokenLostErrors),"Token lost errors");
+ a->SetBinLabel(h->FindBin(fgkRawNofParityErrors),"Parity errors");
+ a->SetBinLabel(h->FindBin(fgkRawNofPaddingErrors),"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)
{
- fTrackerDataMaker = new AliMUONTrackerDataMaker(GetRecoParam(),
+
+ AliMUONTrackerDataMaker* dm = new AliMUONTrackerDataMaker(GetRecoParam(),
AliCDBManager::Instance()->GetRun(),
0x0,
"",
"NOGAIN",
histogram,
0.0,0.0);
+
+ fLogger = new AliMUONLogger(-1);
+ dm->EnableErrorLogger(fLogger);
+ fTrackerDataMaker = dm;
}
fTrackerDataMaker->Data()->DisableChannelLevel(); // to save up disk space, we only store starting at the manu level
hbpconfig->Fill(bp->GetId());
}
}
+
+ 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);
+
}
//__________________________________________________________________
((AliMUONTrackerDataMaker*)fTrackerDataMaker)->SetRawReader(rawReader);
fTrackerDataMaker->ProcessEvent();
+
+
}
//__________________________________________________________________
return fTrackerDataMaker->Data();
}
+
+//____________________________________________________________________________
+void
+AliMUONTrackerQADataMakerRec::ResetDetectorRaws(TObjArray* list)
+{
+ /// Reset those histograms that must be reset (and only those), plus
+ /// the trackerdata itself.
+
+ TIter next(list);
+ TObject* o;
+ while ( ( o = next() ) )
+ {
+ TH1* h = dynamic_cast<TH1*>(o);
+ if (h)
+ {
+ TString hn(h->GetName());
+
+ if ( hn.Contains("Tracker") )
+ {
+ if ( !hn.Contains("hTrackerBusPatchNofPads") &&
+ !hn.Contains("hTrackerBusPatchNofManus") &&
+ !hn.Contains("hTrackerBusPatchConfig" ) )
+ {
+ AliDebug(1,Form("Resetting %s",hn.Data()));
+ h->Reset();
+ }
+ }
+ else
+ {
+ AliDebug(1,Form("Will not reset histogram %s",hn.Data()));
+ }
+ }
+ else
+ {
+ AliMUONVTrackerData* d = dynamic_cast<AliMUONVTrackerData*>(o);
+ if (d)
+ {
+ AliDebug(1,Form("Resetting %s",d->GetName()));
+ d->Clear();
+ }
+ else
+ {
+ AliError(Form("Found an object of class %s. Do not know how to reset.",o->ClassName()));
+ }
+ }
+ }
+}