/* $Id$ */
/*
+ July 2011:
+
+ Changes to accomodate updates of general DQM/QA changes to have per trigger
+ histograms (for a given event specie).
+
+ AliTPCdataQA has a new flag for only keeping DQM info event by
+ event!
+ The expert/DA functionality has been kept exactly the same!
+
+
+ June 2010
+
+ This update should solve two problems mainly:
+ * The vs event histograms have been limited to a fixed size for the
+ DQM. The 500k seemed to be a big size but is no longer so, so we
+ need to dynamically expand the range. The non-trivial point is that
+ we also have to do it for the copy owned by AliTPCQADataMakerRec.
+ * The amoreGui now remembers the x-range of the first visualization so
+ the trick of setting the relevant event range as the histogram is
+ filled no longer works.
+
+ The fix is a bit crude but avoids creating a new histogram. Instead
+ the range is expanded (max events and events per bin is doubled) but
+ the number of bins is kept constant! In this way we can change just
+ double the max of the X-axis of the hist and rebin the data. The
+ same can easily be done for the copy owned by AliTPCQADataMakerRec.
+
+ CAUTION:
+ If we change the number of bins we could crash the whole system
+ because ROOT does not create space for extra bins! (but we do not do
+ this). In that way it is a crude solution.
+ The rebinning in the code only works for an even number of bins.
+
+ In addition to the above a bug in the reading of the config file was
+ also found and corrected. fAdcMax was set instead of fEventsPerBin.
+
+ Finally cout was changes to AliInfo.
+
February 2008
The code has been heavily modified so that now the RAW data is
*/
-// stl includes
-#include <iostream>
-
-using namespace std;
-
//Root includes
#include <TH1F.h>
-#include <TH2F.h>
#include <TString.h>
#include <TMath.h>
-#include <TF1.h>
-#include <TRandom.h>
#include <TDirectory.h>
#include <TFile.h>
#include <TError.h>
#include <TMap.h>
+#include <TProfile.h>
//AliRoot includes
#include "AliRawReader.h"
#include "AliRawReaderRoot.h"
#include "AliRawReaderDate.h"
#include "AliTPCRawStream.h"
+#include "AliTPCRawStreamV3.h"
#include "AliTPCCalROC.h"
#include "AliTPCROC.h"
#include "AliMathBase.h"
#include "TTreeStream.h"
-#include "AliTPCRawStreamFast.h"
//date
#include "event.h"
//header file
#include "AliTPCdataQA.h"
+#include "AliLog.h"
+
ClassImp(AliTPCdataQA)
AliTPCdataQA::AliTPCdataQA() : /*FOLD00*/
- TH1F("TPCRAW","TPCRAW",100,0,100),
fFirstTimeBin(60),
fLastTimeBin(1000),
fAdcMin(1),
fOverThreshold10(0),
fOverThreshold20(0),
fOverThreshold30(0),
+ fHistQVsTimeSideA(0),
+ fHistQVsTimeSideC(0),
+ fHistQMaxVsTimeSideA(0),
+ fHistQMaxVsTimeSideC(0),
+ fHistOccupancyVsEvent(0),
+ fHistNclustersVsEvent(0),
fEventCounter(0),
fIsAnalysed(kFALSE),
+ fMaxEvents(500000), // Max events for event histograms
+ fEventsPerBin(1000), // Events per bin for event histograms
+ fSignalCounter(0), // Signal counter
+ fClusterCounter(0), // Cluster counter
fAllBins(0),
fAllSigBins(0),
fAllNSigBins(0),
fRowsMax(0),
fPadsMax(0),
- fTimeBinsMax(0)
+ fTimeBinsMax(0),
+ fIsDQM(kFALSE),
+ fHistOccVsSector(0x0),
+ fHistOcc2dVsSector(0x0),
+ fHistQVsSector(0x0),
+ fHistQmaxVsSector(0x0),
+ fOccVec(0x0),
+ fOccMaxVec(0x0),
+ fOccVecFine(0x0),
+ fOccMaxVecFine(0x0)
{
//
// default constructor
//
}
-
//_____________________________________________________________________
AliTPCdataQA::AliTPCdataQA(const AliTPCdataQA &ped) : /*FOLD00*/
TH1F(ped),
fOverThreshold10(0),
fOverThreshold20(0),
fOverThreshold30(0),
+ fHistQVsTimeSideA(0),
+ fHistQVsTimeSideC(0),
+ fHistQMaxVsTimeSideA(0),
+ fHistQMaxVsTimeSideC(0),
+ fHistOccupancyVsEvent(0),
+ fHistNclustersVsEvent(0),
fEventCounter(ped.GetEventCounter()),
fIsAnalysed(ped.GetIsAnalysed()),
+ fMaxEvents(ped.GetMaxEvents()),
+ fEventsPerBin(ped.GetEventsPerBin()),
+ fSignalCounter(ped.GetSignalCounter()),
+ fClusterCounter(ped.GetClusterCounter()),
fAllBins(0),
fAllSigBins(0),
fAllNSigBins(0),
fRowsMax(0),
fPadsMax(0),
- fTimeBinsMax(0)
+ fTimeBinsMax(0),
+ fIsDQM(ped.GetIsDQM()),
+ fHistOccVsSector(0x0),
+ fHistOcc2dVsSector(0x0),
+ fHistQVsSector(0x0),
+ fHistQmaxVsSector(0x0),
+ fOccVec(0x0),
+ fOccMaxVec(0x0),
+ fOccVecFine(0x0),
+ fOccMaxVecFine(0x0)
{
//
// copy constructor
fOverThreshold20 = new AliTPCCalPad(*ped.GetOverThreshold20());
if(ped.GetOverThreshold30())
fOverThreshold30 = new AliTPCCalPad(*ped.GetOverThreshold30());
+ if(ped.GetHistQVsTimeSideA()) {
+ fHistQVsTimeSideA = new TProfile(*ped.GetHistQVsTimeSideA());
+ fHistQVsTimeSideA->SetDirectory(0);
+ }
+ if(ped.GetHistQVsTimeSideC()) {
+ fHistQVsTimeSideC = new TProfile(*ped.GetHistQVsTimeSideC());
+ fHistQVsTimeSideC->SetDirectory(0);
+ }
+ if(ped.GetHistQMaxVsTimeSideA()) {
+ fHistQMaxVsTimeSideA = new TProfile(*ped.GetHistQMaxVsTimeSideA());
+ fHistQMaxVsTimeSideA->SetDirectory(0);
+ }
+ if(ped.GetHistQMaxVsTimeSideC()) {
+ fHistQMaxVsTimeSideC = new TProfile(*ped.GetHistQMaxVsTimeSideC());
+ fHistQMaxVsTimeSideC->SetDirectory(0);
+ }
+ if(ped.GetHistOccupancyVsEventConst()) {
+ fHistOccupancyVsEvent = new TH1F(*ped.GetHistOccupancyVsEventConst());
+ fHistOccupancyVsEvent->SetDirectory(0);
+ }
+ if(ped.GetHistNclustersVsEventConst()) {
+ fHistNclustersVsEvent = new TH1F(*ped.GetHistNclustersVsEventConst());
+ fHistNclustersVsEvent->SetDirectory(0);
+ }
}
//_____________________________________________________________________
-AliTPCdataQA::AliTPCdataQA(TMap *config) : /*FOLD00*/
+AliTPCdataQA::AliTPCdataQA(const TMap *config) : /*FOLD00*/
TH1F("TPCRAW","TPCRAW",100,0,100),
fFirstTimeBin(60),
fLastTimeBin(1000),
fOverThreshold10(0),
fOverThreshold20(0),
fOverThreshold30(0),
+ fHistQVsTimeSideA(0),
+ fHistQVsTimeSideC(0),
+ fHistQMaxVsTimeSideA(0),
+ fHistQMaxVsTimeSideC(0),
+ fHistOccupancyVsEvent(0),
+ fHistNclustersVsEvent(0),
fEventCounter(0),
fIsAnalysed(kFALSE),
+ fMaxEvents(500000),
+ fEventsPerBin(1000),
+ fSignalCounter(0),
+ fClusterCounter(0),
fAllBins(0),
fAllSigBins(0),
fAllNSigBins(0),
fRowsMax(0),
fPadsMax(0),
- fTimeBinsMax(0)
+ fTimeBinsMax(0),
+ fIsDQM(kFALSE),
+ fHistOccVsSector(0x0),
+ fHistOcc2dVsSector(0x0),
+ fHistQVsSector(0x0),
+ fHistQmaxVsSector(0x0),
+ fOccVec(0x0),
+ fOccMaxVec(0x0),
+ fOccVecFine(0x0),
+ fOccMaxVecFine(0x0)
{
//
// default constructor
if (config->GetValue("LastTimeBin")) fLastTimeBin = ((TObjString*)config->GetValue("LastTimeBin"))->GetString().Atoi();
if (config->GetValue("AdcMin")) fAdcMin = ((TObjString*)config->GetValue("AdcMin"))->GetString().Atoi();
if (config->GetValue("AdcMax")) fAdcMax = ((TObjString*)config->GetValue("AdcMax"))->GetString().Atoi();
+ if (config->GetValue("MaxEvents")) fMaxEvents = ((TObjString*)config->GetValue("MaxEvents"))->GetString().Atoi();
+ if (config->GetValue("EventsPerBin")) fEventsPerBin = ((TObjString*)config->GetValue("EventsPerBin"))->GetString().Atoi();
}
//_____________________________________________________________________
delete fOverThreshold10;
delete fOverThreshold20;
delete fOverThreshold30;
-
+ delete fHistQVsTimeSideA;
+ delete fHistQVsTimeSideC;
+ delete fHistQMaxVsTimeSideA;
+ delete fHistQMaxVsTimeSideC;
+ delete fHistOccupancyVsEvent;
+ delete fHistNclustersVsEvent;
+
+ // DQM
+ delete fHistOccVsSector;
+ delete fHistOcc2dVsSector;
+ delete fHistQVsSector;
+ delete fHistQmaxVsSector;
+ delete fOccVec;
+ delete fOccMaxVec;
+ delete fOccVecFine;
+ delete fOccMaxVecFine;
+
for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
delete [] fAllBins[iRow];
delete [] fAllSigBins[iRow];
}
//_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEventFast(AliTPCRawStreamFast *rawStreamFast)
+TH1F* AliTPCdataQA::GetHistOccupancyVsEvent()
{
//
- // Event Processing loop - AliTPCRawStream
+ // Create Occupancy vs event histogram
+ // (we create this histogram differently then the other histograms
+ // because this we want to be able to access and copy
+ // from AliTPCQAMakerRec before it normally would be created)
+ //
+ if(!fHistOccupancyVsEvent) {
+
+ Int_t nBins = fMaxEvents/fEventsPerBin;
+ fHistOccupancyVsEvent = new TH1F("hOccupancyVsEvent", "Occupancy vs event number (~time); Event number; Occupancy", nBins, 0, nBins*fEventsPerBin);
+ fHistOccupancyVsEvent->SetDirectory(0);
+ }
+
+ return fHistOccupancyVsEvent;
+}
+
+//_____________________________________________________________________
+TH1F* AliTPCdataQA::GetHistNclustersVsEvent()
+{
+ //
+ // Create Nclusters vs event histogram
+ // (we create this histogram differently then the other histograms
+ // because this we want to be able to access and copy
+ // from AliTPCQAMakerRec before it normally would be created)
+ //
+ if(!fHistNclustersVsEvent) {
+
+ Int_t nBins = fMaxEvents/fEventsPerBin;
+ fHistNclustersVsEvent = new TH1F("hNclustersVsEvent", "Nclusters vs event number (~time); Event number; Nclusters per event", nBins, 0, nBins*fEventsPerBin);
+ fHistNclustersVsEvent->SetDirectory(0);
+ }
+
+ return fHistNclustersVsEvent;
+}
+
+//_____________________________________________________________________
+void AliTPCdataQA::UpdateEventHistograms()
+{
+ // Update histograms that display occupancy and
+ // number of clusters as a function of number of
+ // events
+ if (!fHistOccupancyVsEvent)
+ GetHistOccupancyVsEvent();
+ if (!fHistNclustersVsEvent)
+ GetHistNclustersVsEvent();
+
+ if(fEventCounter > fMaxEvents) {
+
+ // we have to expand the histogram to handle the larger number of
+ // events. The way it is done now is to double the range and the
+ // number of events per bin (so the number of histogram bins stays
+ // constant)
+ fEventsPerBin *= 2;
+ fMaxEvents *= 2;
+
+ // Change histogram limits
+ const Int_t nBins = fHistOccupancyVsEvent->GetXaxis()->GetNbins();
+ fHistOccupancyVsEvent->GetXaxis()->Set(nBins, fHistOccupancyVsEvent->GetXaxis()->GetNbins(), fMaxEvents);
+ fHistNclustersVsEvent->GetXaxis()->Set(nBins, fHistNclustersVsEvent->GetXaxis()->GetNbins(), fMaxEvents);
+
+ // Rebin the histogram
+ for(Int_t bin = 1; bin <= nBins; bin+=2) {
+
+ Int_t newBin = TMath::Nint(Float_t(bin+1)/2.0);
+ Float_t newContent = (fHistOccupancyVsEvent->GetBinContent(bin)+
+ fHistOccupancyVsEvent->GetBinContent(bin+1))/2.0;
+ fHistOccupancyVsEvent->SetBinContent(newBin, newContent);
+
+ newContent = (fHistNclustersVsEvent->GetBinContent(bin)+
+ fHistNclustersVsEvent->GetBinContent(bin+1))/2.0;
+ fHistNclustersVsEvent->SetBinContent(newBin, newContent);
+ }
+
+ // Set the remaining bins to 0
+ Int_t lastHalf = nBins/2 +1;
+ for(Int_t bin = lastHalf; bin <= nBins; bin++) {
+
+ fHistOccupancyVsEvent->SetBinContent(bin, 0);
+ fHistNclustersVsEvent->SetBinContent(bin, 0);
+ }
+
+ // In this case we should nut update but wait untill the new
+ // number of events per bin is reached!
+ return;
+ }
+
+ const Int_t bin = TMath::Nint(Float_t(fEventCounter)/fEventsPerBin);
+
+ Float_t averageOccupancy =
+ Float_t(fSignalCounter)/fEventsPerBin/(fLastTimeBin - fFirstTimeBin +1.0)
+ / 570132.0; // 570,132 is number of pads
+ fHistOccupancyVsEvent->SetBinContent(bin, averageOccupancy);
+ fSignalCounter = 0;
+
+ Float_t averageNclusters =
+ Float_t(fClusterCounter)/fEventsPerBin;
+ fHistNclustersVsEvent->SetBinContent(bin, averageNclusters);
+ fClusterCounter = 0;
+}
+
+//_____________________________________________________________________
+Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStreamV3 *const rawStreamV3)
+{
+ //
+ // Event Processing loop - AliTPCRawStreamV3
//
Bool_t withInput = kFALSE;
Int_t nSignals = 0;
Int_t lastSector = -1;
+
+ while ( rawStreamV3->NextDDL() ){
- while ( rawStreamFast->NextDDL() ){
- while ( rawStreamFast->NextChannel() ){
-
- Int_t iSector = rawStreamFast->GetSector(); // current sector
- Int_t iRow = rawStreamFast->GetRow(); // current row
- Int_t iPad = rawStreamFast->GetPad(); // current pad
- // Call local maxima finder if the data is in a new sector
- if(iSector != lastSector) {
-
- if(nSignals>0)
- FindLocalMaxima(lastSector);
-
- CleanArrays();
- lastSector = iSector;
- nSignals = 0;
- }
-
- while ( rawStreamFast->NextBunch() ){
- Int_t startTbin = (Int_t)rawStreamFast->GetStartTimeBin();
- Int_t endTbin = (Int_t)rawStreamFast->GetEndTimeBin();
-
- for (Int_t iTimeBin = startTbin; iTimeBin < endTbin; iTimeBin++){
- Float_t signal = rawStreamFast->GetSignals()[iTimeBin-startTbin];
- nSignals += Update(iSector,iRow,iPad,iTimeBin+1,signal);
- withInput = kTRUE;
- }
- }
+ while ( rawStreamV3->NextChannel() ){
+
+ Int_t iSector = rawStreamV3->GetSector(); // current sector
+ Int_t iRow = rawStreamV3->GetRow(); // current row
+ Int_t iPad = rawStreamV3->GetPad(); // current pad
+ Int_t iPatch = rawStreamV3->GetPatchIndex(); // current patch
+ Int_t iBranch = rawStreamV3->GetBranch(); // current branch
+ if (iRow<0 || iPad<0) continue;
+ // Call local maxima finder if the data is in a new sector
+ if(iSector != lastSector) {
+
+ if(nSignals>0)
+ FindLocalMaxima(lastSector);
+
+ CleanArrays();
+ lastSector = iSector;
+ nSignals = 0;
}
+
+ while ( rawStreamV3->NextBunch() ){
+
+ Int_t startTbin = (Int_t)rawStreamV3->GetStartTimeBin();
+ Int_t bunchlength = (Int_t)rawStreamV3->GetBunchLength();
+ const UShort_t *sig = rawStreamV3->GetSignals();
+
+ for (Int_t iTimeBin = 0; iTimeBin<bunchlength; iTimeBin++){
+ Float_t signal=(Float_t)sig[iTimeBin];
+ nSignals += Update(iSector,iRow,iPad,startTbin--,signal, iPatch, iBranch);
+ withInput = kTRUE;
+ }
+ }
+ }
}
+
+ if (lastSector>=0&&nSignals>0)
+ FindLocalMaxima(lastSector);
return withInput;
}
+
//_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEventFast(AliRawReader *rawReader)
+Bool_t AliTPCdataQA::ProcessEvent(AliRawReader *const rawReader)
{
//
// Event processing loop - AliRawReader
//
- AliTPCRawStreamFast *rawStreamFast = new AliTPCRawStreamFast(rawReader, (AliAltroMapping**)fMapping);
- Bool_t res=ProcessEventFast(rawStreamFast);
- if(res)
+ AliTPCRawStreamV3 rawStreamV3(rawReader,(AliAltroMapping**)fMapping);
+ Bool_t res=ProcessEvent(&rawStreamV3);
+ if(res) {
fEventCounter++; // only increment event counter if there is TPC data
- // otherwise Analyse (called in QA) fails
- delete rawStreamFast;
+ if(fEventCounter%fEventsPerBin==0)
+ UpdateEventHistograms();
+ }
return res;
}
//_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStream *rawStream)
+Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStream *const rawStream)
{
//
// Event Processing loop - AliTPCRawStream
Int_t iPad = rawStream->GetPad(); // current pad
Int_t iTimeBin = rawStream->GetTime(); // current time bin
Float_t signal = rawStream->GetSignal(); // current ADC signal
-
+
// Call local maxima finder if the data is in a new sector
if(iSector != lastSector) {
if(nSignals>0)
- FindLocalMaxima(lastSector);
+ FindLocalMaxima(lastSector);
CleanArrays();
lastSector = iSector;
}
}
+ if (lastSector>=0&&nSignals>0)
+ FindLocalMaxima(lastSector);
+
return withInput;
}
//_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEvent(AliRawReader *rawReader)
+Bool_t AliTPCdataQA::ProcessEventOld(AliRawReader *const rawReader)
{
//
// Event processing loop - AliRawReader
//_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEvent(eventHeaderStruct *event)
+Bool_t AliTPCdataQA::ProcessEvent(eventHeaderStruct *const event)
{
//
// process date event
//
- AliRawReader *rawReader = new AliRawReaderDate((void*)event);
- Bool_t result=ProcessEvent(rawReader);
- delete rawReader;
+ AliRawReaderDate rawReader((void*)event);
+ Bool_t result=ProcessEvent(&rawReader);
return result;
}
const Int_t iRow,
const Int_t iPad,
const Int_t iTimeBin,
- Float_t signal)
+ Float_t signal,
+ const Int_t iPatch,
+ const Int_t iBranch)
{
//
// Signal filling method
// NB! This has to be done first even if the data is rejected by the time
// cut to make sure that the objects are available in Analyse
//
- if (!fNLocalMaxima) fNLocalMaxima = new AliTPCCalPad("NLocalMaxima","NLocalMaxima");
- if (!fMaxCharge) fMaxCharge = new AliTPCCalPad("MaxCharge","MaxCharge");
- if (!fMeanCharge) fMeanCharge = new AliTPCCalPad("MeanCharge","MeanCharge");
- if (!fNoThreshold) fNoThreshold = new AliTPCCalPad("NoThreshold","NoThreshold");
- if (!fNTimeBins) fNTimeBins = new AliTPCCalPad("NTimeBins","NTimeBins");
- if (!fNPads) fNPads = new AliTPCCalPad("NPads","NPads");
- if (!fTimePosition) fTimePosition = new AliTPCCalPad("TimePosition","TimePosition");
- if (!fOverThreshold10) fOverThreshold10 = new AliTPCCalPad("OverThreshold10","OverThreshold10");
- if (!fOverThreshold20) fOverThreshold20 = new AliTPCCalPad("OverThreshold20","OverThreshold20");
- if (!fOverThreshold30) fOverThreshold30 = new AliTPCCalPad("OverThreshold30","OverThreshold30");
+ if(!fIsDQM) {
+
+ if (!fNLocalMaxima) fNLocalMaxima = new AliTPCCalPad("NLocalMaxima","NLocalMaxima");
+ if (!fMaxCharge) fMaxCharge = new AliTPCCalPad("MaxCharge","MaxCharge");
+ if (!fMeanCharge) fMeanCharge = new AliTPCCalPad("MeanCharge","MeanCharge");
+ if (!fNoThreshold) fNoThreshold = new AliTPCCalPad("NoThreshold","NoThreshold");
+ if (!fNTimeBins) fNTimeBins = new AliTPCCalPad("NTimeBins","NTimeBins");
+ if (!fNPads) fNPads = new AliTPCCalPad("NPads","NPads");
+ if (!fTimePosition) fTimePosition = new AliTPCCalPad("TimePosition","TimePosition");
+ if (!fOverThreshold10) fOverThreshold10 = new AliTPCCalPad("OverThreshold10","OverThreshold10");
+ if (!fOverThreshold20) fOverThreshold20 = new AliTPCCalPad("OverThreshold20","OverThreshold20");
+ if (!fOverThreshold30) fOverThreshold30 = new AliTPCCalPad("OverThreshold30","OverThreshold30");
+ if (!fHistQVsTimeSideA) {
+ fHistQVsTimeSideA = new TProfile("hQVsTimeSideA", "Q vs time (side A); Time [Timebin]; Q [ADC ch]", 100, 0, 1000);
+ fHistQVsTimeSideA->SetDirectory(0);
+ }
+ if (!fHistQVsTimeSideC) {
+ fHistQVsTimeSideC = new TProfile("hQVsTimeSideC", "Q vs time (side C); Time [Timebin]; Q [ADC ch]", 100, 0, 1000);
+ fHistQVsTimeSideC->SetDirectory(0);
+ }
+ if (!fHistQMaxVsTimeSideA) {
+ fHistQMaxVsTimeSideA = new TProfile("hQMaxVsTimeSideA", "Q_{MAX} vs time (side A); Time [Timebin]; Q_{MAX} [ADC ch]", 100, 0, 1000);
+ fHistQMaxVsTimeSideA->SetDirectory(0);
+ }
+ if (!fHistQMaxVsTimeSideC) {
+ fHistQMaxVsTimeSideC = new TProfile("hQMaxVsTimeSideC", "Q_{MAX} vs time (side C); Time [Timebin]; Q_{MAX} [ADC ch]", 100, 0, 1000);
+ fHistQMaxVsTimeSideC->SetDirectory(0);
+ }
+ } else { // DQM histograms and array
+
+ if (!fHistOccVsSector) {
+ fHistOccVsSector = new TProfile("hOccVsSector", "Occupancy vs sector; Sector; Occupancy", 72, 0, 72);
+ fHistOccVsSector->SetDirectory(0);
+
+ fHistOcc2dVsSector = new TProfile2D("hOcc2dVsSector", "Occupancy vs sector and patch; Sector; Patch", 72, 0, 36, 6, 0, 6);
+ fHistOcc2dVsSector->SetDirectory(0);
+
+ fHistQVsSector = new TProfile("hQVsSector", "Q vs sector; Sector; Q [ADC ch]", 72, 0, 72);
+ fHistQVsSector->SetDirectory(0);
+
+ fHistQmaxVsSector = new TProfile("hQmaxVsSector", "Qmax vs sector; Sector; Qmax [ADC ch]", 72, 0, 72);
+ fHistQmaxVsSector->SetDirectory(0);
+
+ fOccVec = new TArrayD(72);
+ for(Int_t i = 0; i < 72; i++)
+ fOccVec->GetArray()[i] = 0;
+
+ fOccMaxVec = new TArrayD(72);
+ const Double_t nTimeBins = fLastTimeBin - fFirstTimeBin +1;
+ for(Int_t i = 0; i < 72; i++)
+
+ if(i<36) // IROCs (5504 pads)
+ fOccMaxVec->GetArray()[i] = nTimeBins*5504;
+ else // OROCs (9984 pads)
+ fOccMaxVec->GetArray()[i] = nTimeBins*9984;
+
+ // 12 branches for each full sector
+ const Int_t nBranches = 36*12;
+ fOccVecFine = new TArrayD(nBranches);
+ for(Int_t i = 0; i < nBranches; i++)
+ fOccVecFine->GetArray()[i] = 0;
+
+ // Pads per patch same for all sectors
+ Int_t nPads0[6] = {1152, 1536, 1152, 1280, 1280, 1280};
+ Int_t nPads1[6] = {1152, 1664, 1152, 1280, 1280, 1280};
+
+ fOccMaxVecFine = new TArrayD(nBranches);
+ for(Int_t i = 0; i < nBranches; i++) {
+
+ const Int_t fullSector = Int_t(i/12);
+ Int_t branch = i - fullSector*12;
+ R__ASSERT(branch>=0 && branch<12);
+
+ const Int_t patch = Int_t(branch/2);
+ branch -= patch*2;
+
+ R__ASSERT(branch>=0 && branch<2);
+ if(branch == 0)
+ fOccMaxVecFine->GetArray()[i] = nTimeBins*nPads0[patch];
+ else // OROCs (9984 pads)
+ fOccMaxVecFine->GetArray()[i] = nTimeBins*nPads1[patch];
+ }
+ }
+ }
// Make the arrays for expanding the data
if (!fAllBins)
// If Analyse has been previously called we need now to denormalize the data
// as more data is coming
//
- if(fIsAnalysed == kTRUE) {
+ if(fIsAnalysed == kTRUE && !fIsDQM) {
const Int_t nTimeBins = fLastTimeBin - fFirstTimeBin +1;
const Float_t denormalization = Float_t(fEventCounter * nTimeBins);
signal -= ped;
}
- // In fNoThreshold we fill all data to estimate the ZS volume
- Float_t count = fNoThreshold->GetCalROC(iSector)->GetValue(iRow, iPad);
- fNoThreshold->GetCalROC(iSector)->SetValue(iRow, iPad,count+1);
-
+ if(fIsDQM) {
+
+ fOccVec->GetArray()[iSector] += 1.0;
+ // To change before committing
+ if(iPatch>=0 && iBranch>=0 && iPatch<=5 && iBranch <= 1)
+ fOccVecFine->GetArray()[(iSector%36)*12+iPatch*2+iBranch] += 1.0;
+ } else {
+ // In fNoThreshold we fill all data to estimate the ZS volume
+ Float_t count = fNoThreshold->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fNoThreshold->GetCalROC(iSector)->SetValue(iRow, iPad,count+1);
+ }
+
// Require at least 3 ADC channels
if (signal < 3.0)
return 0;
//
SetExpandDigit(iRow, iPad, iTimeBin, signal);
+
+ fSignalCounter++;
return 1; // signal was accepted
}
Int_t iPad, iTimeBin;
GetPadAndTimeBin(bin, iPad, iTimeBin);
- Float_t count = fNLocalMaxima->GetCalROC(iSector)->GetValue(iRow, iPad);
- fNLocalMaxima->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
-
- count = fTimePosition->GetCalROC(iSector)->GetValue(iRow, iPad);
- fTimePosition->GetCalROC(iSector)->SetValue(iRow, iPad, count+iTimeBin);
-
- Float_t charge = fMaxCharge->GetCalROC(iSector)->GetValue(iRow, iPad);
- fMaxCharge->GetCalROC(iSector)->SetValue(iRow, iPad, charge + qMax);
+ if(!fIsDQM) {
+ Float_t count = fNLocalMaxima->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fNLocalMaxima->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
+
+ count = fTimePosition->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fTimePosition->GetCalROC(iSector)->SetValue(iRow, iPad, count+iTimeBin);
- if(qMax>=10) {
- count = fOverThreshold10->GetCalROC(iSector)->GetValue(iRow, iPad);
- fOverThreshold10->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
- }
- if(qMax>=20) {
- count = fOverThreshold20->GetCalROC(iSector)->GetValue(iRow, iPad);
- fOverThreshold20->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
- }
- if(qMax>=30) {
- count = fOverThreshold30->GetCalROC(iSector)->GetValue(iRow, iPad);
- fOverThreshold30->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
+ Float_t charge = fMaxCharge->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fMaxCharge->GetCalROC(iSector)->SetValue(iRow, iPad, charge + qMax);
+
+ if(qMax>=10) {
+ count = fOverThreshold10->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fOverThreshold10->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
+ }
+ if(qMax>=20) {
+ count = fOverThreshold20->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fOverThreshold20->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
+ }
+ if(qMax>=30) {
+ count = fOverThreshold30->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fOverThreshold30->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
+ }
}
//
}
}
- charge = fMeanCharge->GetCalROC(iSector)->GetValue(iRow, iPad);
- fMeanCharge->GetCalROC(iSector)->SetValue(iRow, iPad, charge + qTot);
-
- count = fNTimeBins->GetCalROC(iSector)->GetValue(iRow, iPad);
- fNTimeBins->GetCalROC(iSector)->SetValue(iRow, iPad, count + maxT-minT+1);
-
- count = fNPads->GetCalROC(iSector)->GetValue(iRow, iPad);
- fNPads->GetCalROC(iSector)->SetValue(iRow, iPad, count + maxP-minP+1);
+ if(fIsDQM) {
+ fHistQVsSector->Fill(iSector, qTot);
+ fHistQmaxVsSector->Fill(iSector, qMax);
+ } else {
+ Float_t charge = fMeanCharge->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fMeanCharge->GetCalROC(iSector)->SetValue(iRow, iPad, charge + qTot);
+
+ Float_t count = fNTimeBins->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fNTimeBins->GetCalROC(iSector)->SetValue(iRow, iPad, count + maxT-minT+1);
+
+ count = fNPads->GetCalROC(iSector)->GetValue(iRow, iPad);
+ fNPads->GetCalROC(iSector)->SetValue(iRow, iPad, count + maxP-minP+1);
+ if((iSector%36)<18) { // A side
+ fHistQVsTimeSideA->Fill(iTimeBin, qTot);
+ fHistQMaxVsTimeSideA->Fill(iTimeBin, qMax);
+ } else {
+ fHistQVsTimeSideC->Fill(iTimeBin, qTot);
+ fHistQMaxVsTimeSideC->Fill(iTimeBin, qMax);
+ }
+ }
} // end loop over signals
} // end loop over rows
- // cout << "Number of local maximas found: " << nLocalMaxima << endl;
+ fClusterCounter += nLocalMaxima;
}
//_____________________________________________________________________
// Calculate calibration constants
//
- cout << "Analyse called" << endl;
+ AliInfo("Analyse called");
+
+ if(fIsDQM == kTRUE) {
+
+ AliInfo("DQM flas is set -> No 2d information to analyze");
+ return;
+ }
if(fIsAnalysed == kTRUE) {
- cout << "No new data since Analyse was called last time" << endl;
+ AliInfo("No new data since Analyse was called last time");
return;
}
if(fEventCounter==0) {
- cout << "EventCounter == 0, Cannot analyse" << endl;
+ AliInfo("EventCounter == 0, Cannot analyse");
return;
}
Int_t nTimeBins = fLastTimeBin - fFirstTimeBin +1;
- cout << "EventCounter: " << fEventCounter << endl
- << "TimeBins: " << nTimeBins << endl;
+ AliInfo(Form("EventCounter: %d , TimeBins: %d", fEventCounter, nTimeBins));
Float_t normalization = 1.0 / Float_t(fEventCounter * nTimeBins);
fNoThreshold->Multiply(normalization);
//_____________________________________________________________________
-void AliTPCdataQA::MakeTree(const char *fname){
+void AliTPCdataQA::MakeTree(const char *fname) const {
//
// Export result to the tree -located in the file
// This file can be analyzed using AliTPCCalibViewer
//
for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
- //
- Int_t maxBin = (fTimeBinsMax+4)*(fPadsMax+4);
- memset(fAllBins[iRow],0,sizeof(Float_t)*maxBin);
+
+ // To speed up the performance by a factor 2 on cosmic data (and
+ // presumably pp data as well) where the ocupancy is low, the
+ // memset is only called if there is more than 1000 signals for a
+ // row (of the order 1% occupancy)
+ if(fAllNSigBins[iRow]<1000) {
+
+ Float_t* allBins = fAllBins[iRow];
+ Int_t* sigBins = fAllSigBins[iRow];
+ const Int_t nSignals = fAllNSigBins[iRow];
+ for(Int_t i = 0; i < nSignals; i++)
+ allBins[sigBins[i]]=0;
+ } else {
+
+ Int_t maxBin = (fTimeBinsMax+4)*(fPadsMax+4);
+ memset(fAllBins[iRow],0,sizeof(Float_t)*maxBin);
+ }
+
fAllNSigBins[iRow]=0;
}
}
fAllNSigBins[iRow]++;
}
+//______________________________________________________________________________
Float_t AliTPCdataQA::GetQ(const Float_t* adcArray, const Int_t time,
const Int_t pad, const Int_t maxTimeBins,
Int_t& timeMin, Int_t& timeMax,
- Int_t& padMin, Int_t& padMax)
+ Int_t& padMin, Int_t& padMax) const
{
//
// This methods return the charge in the bin time+pad*maxTimeBins
}
return charge;
}
+
+//______________________________________________________________________________
+void AliTPCdataQA::Streamer(TBuffer &xRuub)
+{
+ // Automatic schema evolution was first used from revision 4
+ // Code based on:
+ // http://root.cern.ch/root/roottalk/roottalk02/3207.html
+
+ UInt_t xRuus, xRuuc;
+ if (xRuub.IsReading()) {
+ Version_t xRuuv = xRuub.ReadVersion(&xRuus, &xRuuc);
+ //we use the automatic algorithm for class version > 3
+ if (xRuuv > 3) {
+ AliTPCdataQA::Class()->ReadBuffer(xRuub, this, xRuuv, xRuus,
+ xRuuc);
+ return;
+ }
+ TH1F::Streamer(xRuub);
+ xRuub >> fFirstTimeBin;
+ xRuub >> fLastTimeBin;
+ xRuub >> fAdcMin;
+ xRuub >> fAdcMax;
+ xRuub >> fNLocalMaxima;
+ xRuub >> fMaxCharge;
+ xRuub >> fMeanCharge;
+ xRuub >> fNoThreshold;
+ xRuub >> fNTimeBins;
+ xRuub >> fNPads;
+ xRuub >> fTimePosition;
+ xRuub >> fEventCounter;
+ xRuub >> fIsAnalysed;
+ xRuub.CheckByteCount(xRuus, xRuuc, AliTPCdataQA::IsA());
+ } else {
+ AliTPCdataQA::Class()->WriteBuffer(xRuub,this);
+ }
+}
+
+//____________________________________________________________________________________________
+void AliTPCdataQA::FillOccupancyProfile()
+{
+ // This has to be filled at the end of the loop over data
+ if(!fIsDQM)
+ AliInfo("Method only meaningful for DQM");
+
+ for(Int_t i = 0; i < 72; i++) {
+
+ fOccVec->GetArray()[i] /= fOccMaxVec->GetArray()[i];
+ fHistOccVsSector->Fill(i, fOccVec->GetArray()[i]);
+ }
+
+ const Int_t nBranches = 36*12;
+ for(Int_t i = 0; i < nBranches; i++) {
+
+ fOccVecFine->GetArray()[i] /= fOccMaxVecFine->GetArray()[i];
+
+ const Int_t fullSector = Int_t(i/12);
+
+ Int_t branch = i - fullSector*12;
+ const Int_t patch = Int_t(branch/2);
+
+ branch -= patch*2;
+
+ fHistOcc2dVsSector->Fill(fullSector+0.5*branch+0.1, patch+0.5, fOccVecFine->GetArray()[i]);
+ }
+}
+
+//____________________________________________________________________________________________
+void AliTPCdataQA::ResetProfiles()
+{
+ if(!fIsDQM)
+ AliInfo("Method only meaningful for DQM");
+
+ if(fHistQVsSector)
+ fHistQVsSector->Reset();
+ if(fHistQmaxVsSector)
+ fHistQmaxVsSector->Reset();
+ if(fHistOccVsSector)
+ fHistOccVsSector->Reset();
+ if(fHistOcc2dVsSector)
+ fHistOcc2dVsSector->Reset();
+
+ if(fOccVec)
+ for(Int_t i = 0; i < 72; i++)
+ fOccVec->GetArray()[i] = 0.0;
+ if(fOccVecFine)
+ for(Int_t i = 0; i < 36*12; i++)
+ fOccVecFine->GetArray()[i] = 0.0;
+}