]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCdataQA.cxx
Add Missing class declaration
[u/mrichter/AliRoot.git] / TPC / AliTPCdataQA.cxx
index 203d40d274077f546864765b4ca78106c0d2267e..2cefe6129896e7f4fcc1ae3f7d79d3771009d561 100644 (file)
 /* $Id$ */
 
 /*
+  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"
@@ -91,6 +113,7 @@ using namespace std;
 
 //header file
 #include "AliTPCdataQA.h"
+#include "AliLog.h"
 
 ClassImp(AliTPCdataQA)
 
@@ -116,8 +139,14 @@ AliTPCdataQA::AliTPCdataQA() : /*FOLD00*/
   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),
@@ -153,8 +182,14 @@ 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),
@@ -191,8 +226,14 @@ AliTPCdataQA::AliTPCdataQA(const AliTPCdataQA &ped) : /*FOLD00*/
   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),
@@ -239,6 +280,14 @@ AliTPCdataQA::AliTPCdataQA(const AliTPCdataQA &ped) : /*FOLD00*/
     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);
+  }
 }
 
 //_____________________________________________________________________
@@ -265,8 +314,14 @@ AliTPCdataQA::AliTPCdataQA(const TMap *config) : /*FOLD00*/
   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),
@@ -281,6 +336,8 @@ AliTPCdataQA::AliTPCdataQA(const TMap *config) : /*FOLD00*/
   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();
 }
 
 //_____________________________________________________________________
@@ -321,6 +378,8 @@ AliTPCdataQA::~AliTPCdataQA() /*FOLD00*/
   delete fHistQVsTimeSideC;
   delete fHistQMaxVsTimeSideA;
   delete fHistQMaxVsTimeSideC;
+  delete fHistOccupancyVsEvent;
+  delete fHistNclustersVsEvent;
 
   for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
     delete [] fAllBins[iRow];
@@ -330,8 +389,112 @@ AliTPCdataQA::~AliTPCdataQA() /*FOLD00*/
   delete [] fAllSigBins;
   delete [] fAllNSigBins;
 }
+
+//_____________________________________________________________________
+TH1F* AliTPCdataQA::GetHistOccupancyVsEvent()
+{
+  //
+  // 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 *rawStreamV3)
+Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStreamV3 *const rawStreamV3)
 {
   //
   // Event Processing loop - AliTPCRawStreamV3
@@ -341,7 +504,9 @@ Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStreamV3 *rawStreamV3)
   Int_t lastSector = -1;
   
   while ( rawStreamV3->NextDDL() ){
+
     while ( rawStreamV3->NextChannel() ){
+    
       Int_t iSector = rawStreamV3->GetSector(); //  current sector
       Int_t iRow    = rawStreamV3->GetRow();    //  current row
       Int_t iPad    = rawStreamV3->GetPad();    //  current pad
@@ -358,6 +523,7 @@ Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStreamV3 *rawStreamV3)
       }
       
       while ( rawStreamV3->NextBunch() ){
+
         Int_t  startTbin    = (Int_t)rawStreamV3->GetStartTimeBin();
         Int_t  bunchlength  = (Int_t)rawStreamV3->GetBunchLength();
         const UShort_t *sig = rawStreamV3->GetSignals();
@@ -370,29 +536,32 @@ Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStreamV3 *rawStreamV3)
       }
     }
   }
-  
-  if (lastSector>=0&&nSignals>0)
+    
+  if (lastSector>=0&&nSignals>0)  
     FindLocalMaxima(lastSector);
   
   return withInput;
 }
 
 //_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEvent(AliRawReader *rawReader)
+Bool_t AliTPCdataQA::ProcessEvent(AliRawReader *const rawReader)
 {
   //
   //  Event processing loop - AliRawReader
   //
-  AliTPCRawStreamV3 *rawStreamV3 = new AliTPCRawStreamV3(rawReader, (AliAltroMapping**)fMapping);
-  Bool_t res=ProcessEvent(rawStreamV3);
-  delete rawStreamV3;
-  if(res)
+  AliTPCRawStreamV3 rawStreamV3(rawReader, (AliAltroMapping**)fMapping);
+  Bool_t res=ProcessEvent(&rawStreamV3);
+  if(res) {
     fEventCounter++; // only increment event counter if there is TPC data
+
+    if(fEventCounter%fEventsPerBin==0) 
+      UpdateEventHistograms();
+  }
   return res;
 }
 
 //_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEventFast(AliTPCRawStreamFast *rawStreamFast)
+Bool_t AliTPCdataQA::ProcessEventFast(AliTPCRawStreamFast *const rawStreamFast)
 {
   //
   // Event Processing loop - AliTPCRawStream
@@ -434,23 +603,22 @@ Bool_t AliTPCdataQA::ProcessEventFast(AliTPCRawStreamFast *rawStreamFast)
   return withInput;
 }
 //_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEventFast(AliRawReader *rawReader)
+Bool_t AliTPCdataQA::ProcessEventFast(AliRawReader *const rawReader)
 {
   //
   //  Event processing loop - AliRawReader
   //
-  AliTPCRawStreamFast *rawStreamFast = new AliTPCRawStreamFast(rawReader, (AliAltroMapping**)fMapping);
-  Bool_t res=ProcessEventFast(rawStreamFast);
+  AliTPCRawStreamFast rawStreamFast(rawReader, (AliAltroMapping**)fMapping);
+  Bool_t res=ProcessEventFast(&rawStreamFast);
   if(res)
     fEventCounter++; // only increment event counter if there is TPC data
                      // otherwise Analyse (called in QA) fails
 
-  delete rawStreamFast;
   return res;
 }
 
 //_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStream *rawStream)
+Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStream *const rawStream)
 {
   //
   // Event Processing loop - AliTPCRawStream
@@ -494,7 +662,7 @@ Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStream *rawStream)
 
 
 //_____________________________________________________________________
-Bool_t AliTPCdataQA::ProcessEventOld(AliRawReader *rawReader)
+Bool_t AliTPCdataQA::ProcessEventOld(AliRawReader *const rawReader)
 {
   //
   //  Event processing loop - AliRawReader
@@ -513,15 +681,14 @@ Bool_t AliTPCdataQA::ProcessEventOld(AliRawReader *rawReader)
 
 
 //_____________________________________________________________________
-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;
 }
 
@@ -660,6 +827,8 @@ Int_t AliTPCdataQA::Update(const Int_t iSector, /*FOLD00*/
   //
 
   SetExpandDigit(iRow, iPad, iTimeBin, signal);
+
+  fSignalCounter++;
   
   return 1; // signal was accepted
 }
@@ -808,7 +977,7 @@ void AliTPCdataQA::FindLocalMaxima(const Int_t iSector)
     } // end loop over signals
   } // end loop over rows
   
-  //  cout << "Number of local maximas found: " << nLocalMaxima << endl;
+  fClusterCounter += nLocalMaxima;
 }
 
 //_____________________________________________________________________
@@ -818,23 +987,22 @@ void AliTPCdataQA::Analyse()
   //  Calculate calibration constants
   //
   
-  cout << "Analyse called" << endl;
+  AliInfo("Analyse called");
 
   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);  
@@ -850,7 +1018,7 @@ void AliTPCdataQA::Analyse()
 
 
 //_____________________________________________________________________
-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
@@ -980,7 +1148,7 @@ void AliTPCdataQA::SetExpandDigit(const Int_t iRow, Int_t iPad,
 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
@@ -996,37 +1164,37 @@ Float_t AliTPCdataQA::GetQ(const Float_t* adcArray, const Int_t time,
 }
 
 //______________________________________________________________________________
-void AliTPCdataQA::Streamer(TBuffer &R__b)
+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 R__s, R__c;
-   if (R__b.IsReading()) {
-      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
+   UInt_t xRuus, xRuuc;
+   if (xRuub.IsReading()) {
+      Version_t xRuuv = xRuub.ReadVersion(&xRuus, &xRuuc);
       //we use the automatic algorithm for class version > 3
-      if (R__v > 3) {
-       AliTPCdataQA::Class()->ReadBuffer(R__b, this, R__v, R__s,
-                                         R__c);
+      if (xRuuv > 3) {
+       AliTPCdataQA::Class()->ReadBuffer(xRuub, this, xRuuv, xRuus,
+                                         xRuuc);
        return;
       }
-      TH1F::Streamer(R__b);
-      R__b >> fFirstTimeBin;
-      R__b >> fLastTimeBin;
-      R__b >> fAdcMin;
-      R__b >> fAdcMax;
-      R__b >> fNLocalMaxima;
-      R__b >> fMaxCharge;
-      R__b >> fMeanCharge;
-      R__b >> fNoThreshold;
-      R__b >> fNTimeBins;
-      R__b >> fNPads;
-      R__b >> fTimePosition;
-      R__b >> fEventCounter;
-      R__b >> fIsAnalysed;
-      R__b.CheckByteCount(R__s, R__c, AliTPCdataQA::IsA());
+      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(R__b,this);
+     AliTPCdataQA::Class()->WriteBuffer(xRuub,this);
    }
 }