Produces the data needed to calculate the quality assurance.
All data must be mergeable objects.
P. Christiansen, Lund, January 2008
-*/
-/*
- Implementation:
+ Updated June 2010:
+ ==================
+
+ The "beautification" of the online DQM histograms have been moved to
+ an amore macro.
- We have chosen to have the histograms as non-persistent meber to
- allow better debugging. In the copy constructor we then have to
- assign the pointers to the existing histograms in the copied
- list. This have been implemented but not tested.
+ The per event RAW histograms have been modified in AliTPCdataQA and
+ the copies have therefore also been modified here.
+
+ The AliTPCdataQA can now be configured a bit from here: time bin
+ range (extended default range to 1-1000, event range at start:
+ 0-100000, 1000 events per bin). (At least the parameters are not
+ hardcoded:-)
+
+ Implementation:
+ ===============
For the QA of the RAW data we use the class, AliTPCdataQA, from the
existing TPC Calibration framework (which is more advanced than the
- standard QA framework) and extract the histograms at the end. This
- has been tested with zero-suppressed data. The Analyse method of the
- AliTPCdataQA class is called in the method, EndOfDetectorCycle, and
- there also: 1d histogram(s) are projected and added to the QA list.
-*/
-
-/*
- TODO:
- Sumw2 for RAW histogram(s)?
- RecPoints and ESD could have many more histograms
+ standard QA framework) and extract the histograms at the end. The
+ Analyse method of the AliTPCdataQA class is called in the method,
+ EndOfDetectorCycle, and there also: 1d histogram(s) are projected
+ and added to the QA list.
*/
#include "AliTPCQADataMakerRec.h"
#include <TClonesArray.h>
#include <TString.h>
#include <TSystem.h>
+#include <TBox.h>
+#include <TLine.h>
+#include <TAxis.h>
// --- Standard library ---
#include "AliTPCclusterMI.h"
#include "AliSimDigits.h"
+
ClassImp(AliTPCQADataMakerRec)
//____________________________________________________________________________
AliTPCQADataMakerRec::AliTPCQADataMakerRec() :
- AliQADataMakerRec(AliQAv1::GetDetName(AliQAv1::kTPC),
- "TPC Rec Quality Assurance Data Maker"),
- fTPCdataQA(NULL)
+AliQADataMakerRec(AliQAv1::GetDetName(AliQAv1::kTPC),
+ "TPC Rec Quality Assurance Data Maker"),
+fTPCdataQA(NULL),
+fRawMaxEvents(100000),
+fRawEventsPerBin(1000),
+fRawFirstTimeBin(1),
+fRawLastTimeBin(1000)
{
// ctor
fTPCdataQA = new AliTPCdataQA*[AliRecoParam::kNSpecies] ;
//____________________________________________________________________________
AliTPCQADataMakerRec::AliTPCQADataMakerRec(const AliTPCQADataMakerRec& qadm) :
AliQADataMakerRec(),
- fTPCdataQA(NULL)
+ fTPCdataQA(NULL),
+ fRawMaxEvents(qadm.GetRawMaxEvents()),
+ fRawEventsPerBin(qadm.GetRawEventsPerBin()),
+ fRawFirstTimeBin(qadm.GetRawFirstTimeBin()),
+ fRawLastTimeBin(qadm.GetRawLastTimeBin())
{
//copy ctor
// Does not copy the calibration object, instead InitRaws have to be
// RAW data files with no TPC data
SetEventSpecie(AliRecoParam::ConvertIndex(specie)) ;
- TH1F * histRawsOccupancy = (TH1F*)GetRawsData(kOccupancy) ;
- TH1F * histRawsOccupancyVsSector = (TH1F*)GetRawsData(kOccupancyVsSector) ;
- TH1F * histRawsNClustersPerEventVsSector = (TH1F*)GetRawsData(kNClustersPerEventVsSector) ;
- TH1F * histRawsQVsSector = (TH1F*)GetRawsData(kQVsSector) ;
- TH1F * histRawsQmaxVsSector = (TH1F*)GetRawsData(kQmaxVsSector) ;
+ TH1F * histRawsOccupancy = (TH1F*)GetRawsData(kRawsOccupancy) ;
+ TH1F * histRawsOccupancyVsSector = (TH1F*)GetRawsData(kRawsOccupancyVsSector) ;
+ TH1F * histRawsNClustersPerEventVsSector = (TH1F*)GetRawsData(kRawsNClustersPerEventVsSector) ;
+ TH1F * histRawsQVsSector = (TH1F*)GetRawsData(kRawsQVsSector) ;
+ TH1F * histRawsQmaxVsSector = (TH1F*)GetRawsData(kRawsQmaxVsSector) ;
+ TH1F * histRawsOccupancyVsEvent = (TH1F*)GetRawsData(kRawsOccupancyVsEvent) ;
+ TH1F * histRawsNclustersVsEvent = (TH1F*)GetRawsData(kRawsNclustersVsEvent) ;
if ( !histRawsOccupancy ||
- !histRawsOccupancyVsSector ||
- !histRawsNClustersPerEventVsSector ||
- !histRawsQVsSector ||
- !histRawsQmaxVsSector) {
+ !histRawsOccupancyVsSector ||
+ !histRawsNClustersPerEventVsSector ||
+ !histRawsQVsSector ||
+ !histRawsQmaxVsSector ||
+ !histRawsOccupancyVsEvent ||
+ !histRawsNclustersVsEvent ) {
AliError("Something very wrong here, corrupted memory ?????. Please check\n") ;
continue ;
}
histRawsQVsSector->Reset();
histRawsQmaxVsSector->Reset();
- TH1F* hNorm72 = new TH1F("hNorm72", "histogram to normalize 72 sectors",
- 72, 0, 72);
- hNorm72->Sumw2();
- TH1F* hNorm108 = new TH1F("hNorm108", "histogram to normalize 108 sectors (medium and long pads are split up)",
- 108, 0, 108);
- hNorm108->Sumw2();
+ TH1F* hNormOcc = new TH1F("hNormOcc", 0, 72, 0, 72);
+ hNormOcc->Sumw2();
+ TH1F* hNormNclusters = new TH1F("hNormNclusters", 0, 72, 0, 72);
+ hNormNclusters->Sumw2();
for (Int_t iSec = 0; iSec < 72; iSec++) {
const Int_t nRows = occupancyROC->GetNrows();
for (Int_t iRow = 0; iRow < nRows; iRow++) {
- Int_t helpSector = iSec;
- if(iRow>=64)
- helpSector += 36; // OROC (long pads)
-
const Int_t nPads = occupancyROC->GetNPads(iRow);
for (Int_t iPad = 0; iPad < nPads; iPad++) {
-
+
histRawsOccupancy->Fill(occupancyROC->GetValue(iRow, iPad));
- hNorm72->Fill(iSec);
+ hNormOcc->Fill(iSec);
histRawsOccupancyVsSector
- ->Fill(iSec, occupancyROC->GetValue(iRow, iPad));
-
+ ->Fill(iSec, occupancyROC->GetValue(iRow, iPad));
+
const Int_t nClusters = TMath::Nint(nclusterROC->GetValue(iRow, iPad));
-
- if(nClusters>0) {
+ if(nClusters>0) {
+
+ hNormNclusters->Fill(iSec,nClusters);
histRawsNClustersPerEventVsSector->Fill(iSec, nClusters);
- hNorm108->Fill(helpSector, nClusters);
- histRawsQVsSector->Fill(helpSector,
- nClusters*qROC->GetValue(iRow, iPad));
- histRawsQmaxVsSector->Fill(helpSector,
- nClusters*qmaxROC->GetValue(iRow, iPad));
+ histRawsQVsSector->Fill(iSec,
+ nClusters*qROC->GetValue(iRow, iPad));
+ histRawsQmaxVsSector->Fill(iSec,
+ nClusters*qmaxROC->GetValue(iRow, iPad));
}
}
}
} // end loop over sectors
+ // update event histograms - copy info from TPDdataQA histos
+ const TH1F* hQAOccVsEvent = fTPCdataQA[specie]->GetHistOccupancyVsEvent();
+ const TH1F* hQANclVsEvent = fTPCdataQA[specie]->GetHistNclustersVsEvent();
+
+ // In case the histogram limits have changed we have to update
+ // them here
+ if(histRawsOccupancy->GetXaxis()->GetXmax()!=
+ hQAOccVsEvent->GetXaxis()->GetXmax()) {
+
+ histRawsOccupancyVsEvent->GetXaxis()->Set(histRawsOccupancyVsEvent->GetXaxis()->GetNbins(), hQAOccVsEvent->GetXaxis()->GetXmin(), hQAOccVsEvent->GetXaxis()->GetXmax());
+
+ histRawsNclustersVsEvent->GetXaxis()->Set(histRawsOccupancyVsEvent->GetXaxis()->GetNbins(), hQANclVsEvent->GetXaxis()->GetXmin(), hQANclVsEvent->GetXaxis()->GetXmax());
+ }
+
+ // reset the number of entries
+ histRawsOccupancyVsEvent->SetEntries(0);
+ histRawsNclustersVsEvent->SetEntries(0);
+
+ // the two event histograms should have the same number of bins
+ const Int_t nBins = hQAOccVsEvent->GetXaxis()->GetNbins();
+ for(Int_t bin = 1; bin <= nBins; bin++) {
+
+ histRawsOccupancyVsEvent->SetBinContent(bin, hQAOccVsEvent->GetBinContent(bin));
+ histRawsNclustersVsEvent->SetBinContent(bin, hQANclVsEvent->GetBinContent(bin));
+ }
+
// Normalize histograms
- histRawsOccupancyVsSector->Divide(hNorm72);
+ histRawsOccupancyVsSector->Divide(hNormOcc);
histRawsNClustersPerEventVsSector->Scale(1.0/Float_t(eventCounter));
- histRawsQVsSector->Divide(hNorm108);
- histRawsQmaxVsSector->Divide(hNorm108);
- delete hNorm72;
- delete hNorm108;
+ histRawsQVsSector->Divide(hNormNclusters);
+ histRawsQmaxVsSector->Divide(hNormNclusters);
+ delete hNormOcc;
+ delete hNormNclusters;
+
}
}
}
AliQAChecker::Instance()->Run(AliQAv1::kTPC, task, list) ;
}
+
//____________________________________________________________________________
void AliTPCQADataMakerRec::InitESDs()
{
const Bool_t image = kTRUE ;
for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
- fTPCdataQA[specie] = new AliTPCdataQA(AliRecoParam::ConvertIndex(specie));
+
+ // It might happen that we will be in this method a few times because
+ // we create all dataQAs at the first call to this method
+ if(fTPCdataQA[specie]!=0) // data QA already created
+ continue;
+
+ fTPCdataQA[specie] =
+ new AliTPCdataQA(AliRecoParam::ConvertIndex(specie));
LoadMaps(); // Load Altro maps
fTPCdataQA[specie]->SetAltroMapping(fMapping); // set Altro mapping
- fTPCdataQA[specie]->SetRangeTime(100, 920); // set time bin interval
+ fTPCdataQA[specie]->SetRangeTime(fRawFirstTimeBin, fRawLastTimeBin); // set time bin interval
+ fTPCdataQA[specie]->SetMaxEvents(fRawMaxEvents);
+ fTPCdataQA[specie]->SetEventsPerBin(fRawEventsPerBin);
// Add2RawsList(fTPCdataQA, kTPCdataQ, !expert, image, !saveCorrA); // This is used by the AMORE monitoring <------- THIS WILL FAIL (YS)
}
new TH1F("hRawsOccupancy", "Occupancy (all pads); Occupancy; Counts",
100, 0, 1);
histRawsOccupancy->Sumw2();
- Add2RawsList(histRawsOccupancy, kOccupancy, !expert, image, !saveCorr);
+ Add2RawsList(histRawsOccupancy, kRawsOccupancy, expert, !image, !saveCorr);
TH1F * histRawsOccupancyVsSector =
new TH1F("hRawsOccupancyVsSector", "Occupancy vs sector; Sector; Occupancy",
72, 0, 72);
histRawsOccupancyVsSector->Sumw2();
- Add2RawsList(histRawsOccupancyVsSector, kOccupancyVsSector, !expert, image, !saveCorr);
+ histRawsOccupancyVsSector->SetMarkerStyle(20);
+ histRawsOccupancyVsSector->SetOption("P");
+ histRawsOccupancyVsSector->SetStats(kFALSE);
+ Add2RawsList(histRawsOccupancyVsSector, kRawsOccupancyVsSector, !expert, image, !saveCorr);
TH1F * histRawsNClustersPerEventVsSector =
new TH1F("hRawsNClustersPerEventVsSector", "Nclusters per event vs sector; Sector; Nclusters per event",
72, 0, 72);
histRawsNClustersPerEventVsSector->Sumw2();
- Add2RawsList(histRawsNClustersPerEventVsSector, kNClustersPerEventVsSector, !expert, image, !saveCorr);
+ Add2RawsList(histRawsNClustersPerEventVsSector, kRawsNClustersPerEventVsSector, expert, !image, !saveCorr);
TH1F * histRawsQVsSector =
- new TH1F("hRawsQVsSector", "<Q> vs sector (OROC med: 36-71, long: 72-107); Sector; <Q>",
- 108, 0, 108);
+ new TH1F("hRawsQVsSector", "<Q> vs sector; Sector; <Q>",
+ 72, 0, 72);
histRawsQVsSector->Sumw2();
- Add2RawsList(histRawsQVsSector, kQVsSector, !expert, image, !saveCorr);
+ Add2RawsList(histRawsQVsSector, kRawsQVsSector, expert, !image, !saveCorr);
TH1F * histRawsQmaxVsSector =
- new TH1F("hRawsQmaxVsSector", "<Qmax> vs sector (OROC med: 36-71, long: 72-107); Sector; <Qmax>",
- 108, 0, 108);
+ new TH1F("hRawsQmaxVsSector", "<Qmax> vs sector; Sector; <Qmax>",
+ 72, 0, 72);
histRawsQmaxVsSector->Sumw2();
- Add2RawsList(histRawsQmaxVsSector, kQmaxVsSector, !expert, image, !saveCorr);
+ histRawsQmaxVsSector->SetMarkerStyle(20);
+ histRawsQmaxVsSector->SetOption("P");
+ histRawsQmaxVsSector->SetStats(kFALSE);
+ Add2RawsList(histRawsQmaxVsSector, kRawsQmaxVsSector, !expert, image, !saveCorr);
+
+ // Get histogram information from data QA to build copy
+ const TH1F* hOccHelp = fTPCdataQA[0]->GetHistOccupancyVsEvent();
+ TH1F * histRawsOccupancyVsEvent =
+ CreateEventsHistCopy(hOccHelp, "hRawsOccupancyVsEvent");
+ Add2RawsList(histRawsOccupancyVsEvent, kRawsOccupancyVsEvent, expert, !image, !saveCorr);
+
+ // Get histogram information from data QA to build copy
+ const TH1F* hNclHelp = fTPCdataQA[0]->GetHistNclustersVsEvent();
+ TH1F * histRawsNclustersVsEvent =
+ CreateEventsHistCopy(hNclHelp, "hRawsNclustersVsEvent");
+ Add2RawsList(histRawsNclustersVsEvent, kRawsNclustersVsEvent, expert, !image, !saveCorr);
}
//____________________________________________________________________________
{
// make QA data from ESDs
- // Check id histograms already created for this Event Specie
- if ( ! GetESDsData(KClusters) )
- InitESDs() ;
-
const Int_t nESDTracks = esd->GetNumberOfTracks();
Int_t nTPCtracks = 0;
for(Int_t i = 0; i < nESDTracks; i++) {
// To make QA for the RAW data we use the TPC Calibration framework
// to handle the data and then in the end extract the data
//
- if ( ! GetRawsData(kOccupancy) )
- InitRaws() ;
+ GetRawsData(0); // dummy call to init raw data
rawReader->Reset() ;
- fTPCdataQA[AliRecoParam::AConvert(fEventSpecie)]->ProcessEvent(rawReader);
- }
+ if (! fTPCdataQA[AliRecoParam::AConvert(fEventSpecie)] ) {
+ AliError("Something unexpected here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") ;
+ } else {
+ fTPCdataQA[AliRecoParam::AConvert(fEventSpecie)]->ProcessEvent(rawReader);
+ }
+}
//____________________________________________________________________________
void AliTPCQADataMakerRec::MakeDigits(TTree* digitTree)
{
-
- // Check id histograms already created for this Event Specie
- if ( ! GetDigitsData(kDigitsADC) )
- InitDigits() ;
-
+
TBranch* branch = digitTree->GetBranch("Segment");
AliSimDigits* digArray = 0;
branch->SetAddress(&digArray);
//____________________________________________________________________________
void AliTPCQADataMakerRec::MakeRecPoints(TTree* recTree)
{
- // Check id histograms already created for this Event Specie
- if ( ! GetRecPointsData(kQmaxShort) )
- InitRecPoints() ;
-
- AliTPCClustersRow *clrow = new AliTPCClustersRow();
- clrow->SetClass("AliTPCclusterMI");
- clrow->SetArray(0);
- clrow->GetArray()->ExpandCreateFast(10000);
-
- TBranch* branch = recTree->GetBranch("Segment");
+
+ AliTPCClustersRow* clrow = 0x0;
+ TBranch* branch = recTree->GetBranch("Segment");
branch->SetAddress(&clrow);
+ TClonesArray * clarray = 0x0;
const Int_t nEntries = Int_t(recTree->GetEntries());
for (Int_t i = 0; i < nEntries; i++) {
branch->GetEntry(i);
-
- const Int_t nClusters = clrow->GetArray()->GetEntriesFast();
+
+ clarray = clrow->GetArray();
+
+ if (!clarray) continue;
+
+ const Int_t nClusters = clarray->GetEntriesFast();
for (Int_t icl=0; icl < nClusters; icl++){
AliTPCclusterMI* cluster =
- (AliTPCclusterMI*)clrow->GetArray()->At(icl);
+ (AliTPCclusterMI*)clarray->At(icl);
Float_t Qmax = cluster->GetMax();
Float_t Q = cluster->GetQ();
GetRecPointsData(kRow)->Fill(row);
} // end loop over clusters
} // end loop over tree
-
- delete clrow;
}
//____________________________________________________________________________
path += "/TPC/mapping/Patch";
for(Int_t i = 0; i < 6; i++) {
+
+ if(fMapping[i]!=0) // mapping already loaded
+ continue;
TString path2 = path;
path2 += i;
path2 += ".data";
}
}
+//____________________________________________________________________________
+void AliTPCQADataMakerRec::ResetDetector(AliQAv1::TASKINDEX_t task)
+{
+ // Overwrites general method for RAW data.
+ // The AliTPCdataQA elements that does the internal processing are
+ // in the case they have processed data deleted and new are created
+
+ if ( task != AliQAv1::kRAWS )
+ AliQADataMakerRec::ResetDetector(task);
+
+ for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
+
+ if ( fTPCdataQA[specie] != NULL) { // exist
+
+ if(fTPCdataQA[specie]->GetEventCounter()>0) { // has processed data
+
+ // old configuration
+ Int_t firstTime = fTPCdataQA[specie]->GetFirstTimeBin();
+ Int_t lastTime = fTPCdataQA[specie]->GetLastTimeBin();
+ Int_t minADC = fTPCdataQA[specie]->GetAdcMin();
+ Int_t maxADC = fTPCdataQA[specie]->GetAdcMax();
+
+ //delete old
+ delete fTPCdataQA[specie];
+
+ // create new
+ fTPCdataQA[specie] = new AliTPCdataQA(AliRecoParam::ConvertIndex(specie));
+ // configure new
+ LoadMaps(); // Load Altro maps
+ fTPCdataQA[specie]->SetAltroMapping(fMapping);
+ fTPCdataQA[specie]->SetRangeTime(firstTime, lastTime);
+ fTPCdataQA[specie]->SetRangeAdc(minADC, maxADC);
+ // Here we want to restore the default configuration because
+ // the max events and events are adjusted for the last run
+ fTPCdataQA[specie]->SetMaxEvents(fRawMaxEvents);
+ fTPCdataQA[specie]->SetEventsPerBin(fRawEventsPerBin);
+ }
+ }
+ }
+}
+
+//____________________________________________________________________________
+TH1F* AliTPCQADataMakerRec::CreateEventsHistCopy(const TH1F* hist,
+ const Char_t* copyName)
+{
+ // This method is used to create a copy of the event histograms
+
+ TH1F* histCopy = new TH1F(copyName, hist->GetTitle(),
+ hist->GetXaxis()->GetNbins(),
+ hist->GetXaxis()->GetXmin(),
+ hist->GetXaxis()->GetXmax());
+ histCopy->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
+ histCopy->GetYaxis()->SetTitle(hist->GetYaxis()->GetTitle());
+ histCopy->SetMarkerStyle(20);
+ histCopy->SetOption("P");
+ histCopy->SetStats(kFALSE);
+
+ return histCopy;
+}