]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Add a more fine grained HV treatment during reconstruction to handle the voltage...
authormkrzewic <mkrzewic@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 25 Feb 2013 13:33:07 +0000 (13:33 +0000)
committermkrzewic <mkrzewic@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 25 Feb 2013 13:33:07 +0000 (13:33 +0000)
TPC/AliTPCCalibViewer.h
TPC/AliTPCCalibViewerGUItime.cxx
TPC/AliTPCParam.cxx
TPC/AliTPCParam.h
TPC/AliTPCcalibDB.cxx
TPC/AliTPCcalibDB.h
TPC/AliTPCcalibSummary.cxx
TPC/AliTPCtrackerMI.cxx

index 7c413aeccc7c4ee6f471bfaed88435233c833bda..bbb774029dbf3e2abd6e6257302965ddf35764ff 100644 (file)
 class TFile;
 class TLegend;
 class TGraph;
+class TH1;
+class TH1F;
 #include <TTree.h>
 #include <TMatrixDfwd.h>
+#include <TVectorDfwd.h>
+#include <TVectorFfwd.h>
 
 class AliTPCCalPad;
 class AliTPCCalROC;
index ac6117038b1696488385c5ba2e85a2c55925e338..9ff9b906568b50ef6431142cb2b1ed2ace34d707 100644 (file)
@@ -861,11 +861,11 @@ void AliTPCCalibViewerGUItime::AdjustYRange()
   //
   TIter nextGraphicObject(fTrashBox);
   TObject *o=0x0;
-  Float_t min=0,max=0;
+  Float_t min=1,max=0;
   while ( (o=nextGraphicObject()) ){
     if (o->IsA()==TGraph::Class()){
       TGraph *gr=(TGraph*)o;
-      if (min==max) {
+      if (min>max) {
         min=TMath::MinElement(gr->GetN(),gr->GetY());
         max=TMath::MaxElement(gr->GetN(),gr->GetY());
       } else {
index 1da830d564cca73bccfbf368e0d6e88820e7a8f7..37a82d86ae02f9622d47945f51732de53bb5d7e2 100644 (file)
@@ -116,7 +116,11 @@ AliTPCParam::AliTPCParam()
             fADCDynRange(0.),
             fTotalNormFac(0.),
             fNoiseNormFac(0.),
-       fNominalVoltage(),
+            fNominalVoltage(),
+            fMaxVoltageDeviation(40.),
+            fMaxDipVoltage(2.),
+            fMaxHVfractionBad(.4),
+            fVoltageDipScanPeriod(1.),
             fNResponseMax(0),
             fResponseThreshold(0.),
             fCurrentMax(0),
index 2831239d7c74394c9da64a91e7e59f7a7a7be701..4984b5ec38c94a8e9a5e372c41e56c58b2fca68b 100644 (file)
@@ -194,7 +194,14 @@ public:
   void  SetMaxTBin(Int_t maxtbin)  {  fMaxTBin = maxtbin;}
   void  SetADCSat(Int_t adcsat)    {  fADCSat  = adcsat;}
   void  SetADCDynRange(Float_t adcdynrange) {fADCDynRange = adcdynrange;}
-  void  SetNominalVoltage(Float_t v, UInt_t i) {if (i<72) fNominalVoltage[i]=v;}
+  //
+  // High voltage parameters
+  //
+  void  SetNominalVoltage(Float_t v, UInt_t i)  {if (i<72) fNominalVoltage[i]=v;}
+  void  SetMaxVoltageDeviation(Float_t voltage) { fMaxVoltageDeviation=voltage; }
+  void  SetMaxDipVoltage(Float_t voltage)       { fMaxDipVoltage=voltage;       }
+  void  SetMaxFractionHVbad(Float_t frac )      { fMaxHVfractionBad=frac;       }
+  void  SetVoltageDipScanPeriod(Float_t period) { fVoltageDipScanPeriod=period; }
   //
   //set response  parameters  
   //
@@ -319,7 +326,15 @@ public:
   Float_t  GetADCDynRange() const {return fADCDynRange;}
   Float_t  GetTotalNormFac() const {return fTotalNormFac;}
   Float_t  GetNoiseNormFac() const {return fNoiseNormFac;}
+  //
+  // High voltage parameters
+  //
   Float_t  GetNominalVoltage(UInt_t i) const {return (i<72)?fNominalVoltage[i]:0;} //0-35:IROC, 36-71:OROC
+  Float_t  GetMaxVoltageDeviation()    const { return fMaxVoltageDeviation;      }
+  Float_t  GetMaxDipVoltage()          const { return fMaxDipVoltage;            }
+  Float_t  GetMaxFractionHVbad()       const { return fMaxHVfractionBad;         }
+  Float_t  GetVoltageDipScanPeriod()   const { return fVoltageDipScanPeriod;     }
+  
   //
   // get response data
   //  
@@ -441,8 +456,15 @@ protected :
   Int_t   fADCSat;          //saturation value of ADC (10 bits)
   Float_t fADCDynRange;     //input dynamic range (mV)
   Float_t fTotalNormFac;    //full normalisation factor - calculated
-  Float_t fNoiseNormFac;    //normalisation factor to transform noise in electron to ADC channel   
+  Float_t fNoiseNormFac;    //normalisation factor to transform noise in electron to ADC channel
+  //---------------------------------------------------------------------
+  // High voltage parameters
+  //---------------------------------------------------------------------
   Float_t fNominalVoltage[72];  //nominal voltage in [V] per chamber
+  Float_t fMaxVoltageDeviation; // maximum voltage deviation from nominal voltage before a chamber is masked
+  Float_t fMaxDipVoltage;       // maximum voltage deviation from median before a dip event is marked
+  Float_t fMaxHVfractionBad;    // maximum fraction of bad HV entries (deviation from Median) before a chamber is marked bad
+  Float_t fVoltageDipScanPeriod; // scanning period to detect a high volrage dip: event time stamp +- fVoltageDipScanPeriod [sec]
   
   //---------------------------------------------------------------------
   // ALICE TPC response data 
@@ -467,7 +489,7 @@ private:
 
   void CleanGeoMatrices();
 
-  ClassDef(AliTPCParam,4)  //parameter  object for set:TPC
+  ClassDef(AliTPCParam,5)  //parameter  object for set:TPC
 };
 
  
index c65476e77dd48446e487c09cc6fea4d21f97efa9..00dfa85d6df5874f98dbd38aab515dbec6b5c3b4 100644 (file)
@@ -127,7 +127,10 @@ class AliTPCCalDet;
 #include "AliTPCCorrection.h"
 #include "AliTPCComposedCorrection.h"
 #include "AliTPCPreprocessorOnline.h"
-
+#include "AliTimeStamp.h"
+#include "AliTriggerRunScalers.h"
+#include "AliTriggerScalers.h"
+#include "AliTriggerScalersRecord.h"
 
 ClassImp(AliTPCcalibDB)
 
@@ -191,6 +194,8 @@ AliTPCcalibDB::AliTPCcalibDB():
   fIonTailArray(0),
   fPulserData(0),
   fCEData(0),
+  fHVsensors(),
+  fGrRunState(0x0),
   fTemperature(0),
   fMapping(0),
   fParam(0),
@@ -215,6 +220,12 @@ AliTPCcalibDB::AliTPCcalibDB():
   //  
   //
   fgInstance=this;
+  for (Int_t i=0;i<72;++i){
+    fChamberHVStatus[i]=kTRUE;
+    fChamberHVmedian[i]=-1;
+    fCurrentNominalVoltage[i]=0.;
+    fChamberHVgoodFraction[i]=0.;
+  }
   Update();    // temporary
   fTimeGainSplinesArray.SetOwner(); //own the keys
   fGRPArray.SetOwner(); //own the keys
@@ -246,6 +257,8 @@ AliTPCcalibDB::AliTPCcalibDB(const AliTPCcalibDB& ):
   fIonTailArray(0),
   fPulserData(0),
   fCEData(0),
+  fHVsensors(),
+  fGrRunState(0x0),
   fTemperature(0),
   fMapping(0),
   fParam(0),
@@ -268,7 +281,13 @@ AliTPCcalibDB::AliTPCcalibDB(const AliTPCcalibDB& ):
   //
   // Copy constructor invalid -- singleton implementation
   //
-   Error("copy constructor","invalid -- singleton implementation");
+  Error("copy constructor","invalid -- singleton implementation");
+  for (Int_t i=0;i<72;++i){
+    fChamberHVStatus[i]=kTRUE;
+    fChamberHVmedian[i]=-1;
+    fCurrentNominalVoltage[i]=0.;
+    fChamberHVgoodFraction[i]=0.;
+  }
   fTimeGainSplinesArray.SetOwner(); //own the keys
   fGRPArray.SetOwner(); //own the keys
   fGRPMaps.SetOwner(); //own the keys
@@ -298,6 +317,7 @@ AliTPCcalibDB::~AliTPCcalibDB()
   //
   
   delete fActiveChannelMap;
+  delete fGrRunState;
 }
 AliTPCCalPad* AliTPCcalibDB::GetDistortionMap(Int_t i) const {
   //
@@ -522,6 +542,10 @@ void AliTPCcalibDB::Update(){
     fTransform->SetCurrentRun(AliCDBManager::Instance()->GetRun());
   }
 
+  // Chamber HV data
+  // needs to be called before InitDeadMap
+  UpdateChamberHighVoltageData();
+  
   // Create Dead Channel Map
   InitDeadMap();
 
@@ -596,7 +620,7 @@ void AliTPCcalibDB::CreateObjectList(const Char_t *filename, TObjArray *calibObj
       if ( !sObjType || ! sObjFileName ) continue;
       TString sType(sObjType->GetString());
       TString sFileName(sObjFileName->GetString());
-      printf("%s\t%s\n",sType.Data(),sFileName.Data());
+//       printf("%s\t%s\n",sType.Data(),sFileName.Data());
       
       TFile *fIn = TFile::Open(sFileName);
       if ( !fIn ){
@@ -657,17 +681,17 @@ void AliTPCcalibDB::CreateObjectList(const Char_t *filename, TObjArray *calibObj
 Int_t AliTPCcalibDB::InitDeadMap() {
   // Initialize DeadChannel Map 
   // Source of information:
-  // -  HV < HVnominal -delta
+  // -  HV (see UpdateChamberHighVoltageData())
   // -  Altro disabled channels. Noisy channels.
   // -  DDL list
 
   // check necessary information
-  Int_t run=AliCDBManager::Instance()->GetRun();
+  const Int_t run=GetRun();
   if (run<0){
     AliError("run not set in CDB manager. Cannot create active channel map");
     return 0;
   }
-  AliDCSSensorArray* voltageArray = AliTPCcalibDB::Instance()->GetVoltageSensors(run);
+  AliDCSSensorArray* voltageArray = GetVoltageSensors(run);
   AliTPCCalPad*          altroMap = GetALTROMasked();
   TMap*                    mapddl = GetDDLMap();
 
@@ -676,76 +700,6 @@ Int_t AliTPCcalibDB::InitDeadMap() {
     return 0;
   }
   
-  if (!fActiveChannelMap) fActiveChannelMap=new AliTPCCalPad("ActiveChannelMap","ActiveChannelMap");
-  
-  //=============================================================
-  //get map of bad ROCs from VOLTAGE deviations
-  //
-  Bool_t badVoltage[AliTPCCalPad::kNsec]={kFALSE};
-  Double_t maxVdiff=100.;
-
-  if (voltageArray){
-    //1. get median of median of all chambers
-    Double_t chamberMedian[AliTPCCalPad::kNsec]={0.};
-    for (Int_t iROC=0;iROC<AliTPCCalPad::kNsec;++iROC){
-      TString sensorName="";
-      Char_t sideName='A';
-      if ((iROC/18)%2==1) sideName='C';
-      if (iROC<36) sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,iROC%18);
-      else         sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,iROC%18);
-
-      AliDCSSensor *sensor = voltageArray->GetSensor(sensorName);
-      if (!sensor) continue;
-
-      chamberMedian[iROC]=0;
-      TGraph *gr=sensor->GetGraph();
-      AliSplineFit *fit=sensor->GetFit();
-      if ( gr && gr->GetN()>0 ){
-        chamberMedian[iROC]=TMath::Median(gr->GetN(),gr->GetY());
-      } else if (fit && fit->GetKnots()>0) {
-        chamberMedian[iROC]=TMath::Median(fit->GetKnots(), fit->GetY0());
-      }
-    }
-    Double_t medianIROC=TMath::Median( 36, chamberMedian );
-    Double_t medianOROC=TMath::Median( 36, chamberMedian+36 );
-
-    //2. check if 90% of the knots (points) are out of a given threshold
-    for (Int_t iROC=0;iROC<AliTPCCalPad::kNsec;++iROC){
-      badVoltage[iROC]=kFALSE;
-      TString sensorName="";
-      Char_t sideName='A';
-      Double_t median=medianIROC;
-      if ((iROC/18)%2==1) sideName='C';
-      if (iROC<36) sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,iROC%18);
-      else           {sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,iROC%18); median=medianOROC; }
-
-      AliDCSSensor *sensor = voltageArray->GetSensor(sensorName);
-      if (!sensor) continue;
-
-      chamberMedian[iROC]=0;
-      TGraph *gr=sensor->GetGraph();
-      AliSplineFit *fit=sensor->GetFit();
-      Int_t nmax=1;
-      Int_t nout=0;
-      if ( gr && gr->GetN()>0 ){
-        nmax=gr->GetN();
-        for (Int_t i=0; i<gr->GetN(); ++i)
-          if ( TMath::Abs( gr->GetY()[i]-median ) > maxVdiff ) ++nout;
-      } else if (fit && fit->GetKnots()>0) {
-        nmax=fit->GetKnots();
-        for (Int_t i=0; i<fit->GetKnots(); ++i)
-          if ( TMath::Abs( fit->GetY0()[i]-median ) > maxVdiff ) ++nout;
-      }
-      if ( (Double_t)nout/(Double_t)nmax > 0.9 ) badVoltage[iROC]=kTRUE;
-      //     printf("%d, %d, %d, %f\n",iROC, nout, nmax, median);
-    }
-
-  } else {
-    AliError("Voltage Array missing. ActiveChannelMap can only be created with parts of the information.");
-  }
-  // Voltage map is done
-  //=============================================================
-
   //=============================================================
   // Setup DDL map
 
@@ -766,6 +720,8 @@ Int_t AliTPCcalibDB::InitDeadMap() {
   // Setup active chnnel map
   //
 
+  if (!fActiveChannelMap) fActiveChannelMap=new AliTPCCalPad("ActiveChannelMap","ActiveChannelMap");
+
   AliTPCmapper map(gSystem->ExpandPathName("$ALICE_ROOT/TPC/mapping/"));
 
   if (!altroMap) AliError("ALTRO dead channel map missing. ActiveChannelMap can only be created with parts of the information.");
@@ -778,7 +734,8 @@ Int_t AliTPCcalibDB::InitDeadMap() {
     }
     
     // check for bad voltage
-    if (badVoltage[iROC]){
+    // see UpdateChamberHighVoltageData()
+    if (!fChamberHVStatus[iROC]){
       roc->Multiply(0.);
       continue;
     }
@@ -1517,6 +1474,197 @@ Float_t AliTPCcalibDB::GetDCSSensorMeanValue(AliDCSSensorArray *arr, const char
   return val;
 }
 
+Bool_t AliTPCcalibDB::IsDataTakingActive(time_t timeStamp)
+{
+  if (!fGrRunState) return kFALSE;
+  Double_t time=Double_t(timeStamp);
+  Int_t currentPoint=0;
+  Bool_t currentVal=fGrRunState->GetY()[currentPoint]>0.5;
+  Bool_t retVal=currentVal;
+  Double_t currentTime=fGrRunState->GetX()[currentPoint];
+  
+  while (time>currentTime){
+    retVal=currentVal;
+    if (currentPoint==fGrRunState->GetN()) break;
+    currentVal=fGrRunState->GetY()[currentPoint]>0.5;
+    currentTime=fGrRunState->GetX()[currentPoint];
+    ++currentPoint;
+  }
+
+  return retVal;
+}
+
+void AliTPCcalibDB::UpdateChamberHighVoltageData()
+{
+  //
+  // set chamber high voltage data
+  // 1. Robust median (sampling the hv graphs over time)
+  // 2. Current nominal voltages (nominal voltage corrected for common HV offset)
+  // 3. Fraction of good HV values over time (deviation from robust median)
+  // 4. HV status, based on the above
+  //
+
+  // start and end time of the run
+  const Int_t run=GetRun();
+  if (run<0) return;
+  const Int_t startTimeGRP = GetGRP(run)->GetTimeStart();
+  const Int_t stopTimeGRP  = GetGRP(run)->GetTimeEnd();
+
+  //
+  // check active state by analysing the scalers
+  //
+  // initialise graph with active running
+  AliCDBEntry *entry = GetCDBEntry("GRP/CTP/Scalers");
+  entry->SetOwner(kTRUE);
+  AliTriggerRunScalers *sca = (AliTriggerRunScalers*)entry->GetObject();
+  Int_t nchannels = sca->GetNumClasses(); // number of scaler channels (i.e. trigger classes)
+  Int_t npoints = sca->GetScalersRecords()->GetEntries(); // number of samples
+
+  delete fGrRunState;
+  fGrRunState=new TGraph;
+  fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(startTimeGRP)-.001,0);
+  fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(startTimeGRP),1);
+  ULong64_t lastSum=0;
+  Double_t timeLast=0.;
+  Bool_t active=kTRUE;
+  for (int i=0; i<npoints; i++) {
+    AliTriggerScalersRecord *rec = (AliTriggerScalersRecord *) sca->GetScalersRecord(i);
+    Double_t time = ((AliTimeStamp*) rec->GetTimeStamp())->GetSeconds();
+    ULong64_t sum=0;
+    for (int j=0; j<nchannels; j++) sum += ((AliTriggerScalers*) rec->GetTriggerScalers()->At(j))->GetL2CA();
+    if (TMath::Abs(time-timeLast)<.001 && sum==lastSum ) continue;
+    if (active && sum==lastSum){
+      fGrRunState->SetPoint(fGrRunState->GetN(),timeLast-.01,1);
+      fGrRunState->SetPoint(fGrRunState->GetN(),timeLast,0);
+      active=kFALSE;
+    } else if (!active && sum>lastSum ){
+      fGrRunState->SetPoint(fGrRunState->GetN(),timeLast-.01,0);
+      fGrRunState->SetPoint(fGrRunState->GetN(),timeLast,1);
+      active=kTRUE;
+    }
+    lastSum=sum;
+    timeLast=time;
+  }
+  fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(stopTimeGRP),active);
+  fGrRunState->SetPoint(fGrRunState->GetN(),Double_t(stopTimeGRP)+.001,0);
+  
+  
+  
+  // reset all values
+  for (Int_t iROC=0;iROC<72;++iROC) {
+    fChamberHVmedian[iROC]       = -1;
+    fChamberHVgoodFraction[iROC] = 0.;
+    fCurrentNominalVoltage[iROC] = -999.;
+    fChamberHVStatus[iROC]       = kFALSE;
+  }
+  
+  AliDCSSensorArray* voltageArray = GetVoltageSensors(run);
+  if (!voltageArray) {
+    AliError("Voltage Array missing. Cannot calculate HV information!");
+    return;
+  }
+
+  // max HV diffs before a chamber is masked
+  const Float_t maxVdiff      = fParam->GetMaxVoltageDeviation();
+  const Float_t maxDipVoltage = fParam->GetMaxDipVoltage();
+  const Float_t maxFracHVbad  = fParam->GetMaxFractionHVbad();
+
+  const Int_t samplingPeriod=1;
+
+  // array with sampled voltages
+  const Int_t maxSamples=(stopTimeGRP-startTimeGRP)/samplingPeriod + 10*samplingPeriod;
+  Float_t *vSampled = new Float_t[maxSamples];
+
+  // deviation of the median from the nominal voltage
+  Double_t chamberMedianDeviation[72]={0.};
+
+  for (Int_t iROC=0; iROC<72; ++iROC){
+    chamberMedianDeviation[iROC]=0.;
+    TString sensorName="";
+    Char_t sideName='A';
+    if ((iROC/18)%2==1) sideName='C';
+    if (iROC<36) sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,iROC%18);
+    else        sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,iROC%18);
+
+    AliDCSSensor *sensor = voltageArray->GetSensor(sensorName);
+
+    fHVsensors[iROC]=sensor;
+    if (!sensor) continue;
+
+    Int_t nPointsSampled=0;
+    
+    TGraph *gr=sensor->GetGraph();
+    if ( gr && gr->GetN()>1 ){
+      //1. sample voltage over time
+      //   get a robust median
+      //   buffer sampled voltages
+      
+      // current sampling time
+      Int_t time=startTimeGRP;
+      
+      // input graph sampling point
+      const Int_t nGraph=gr->GetN();
+      Int_t pointGraph=0;
+      
+      //initialise graph information
+      Int_t timeGraph=TMath::Nint(gr->GetX()[pointGraph+1]*3600+sensor->GetStartTime());
+      Double_t sampledHV=gr->GetY()[pointGraph++];
+
+      while (time<stopTimeGRP){
+        while (timeGraph<=time && pointGraph+1<nGraph){
+          timeGraph=TMath::Nint(gr->GetX()[pointGraph+1]*3600+sensor->GetStartTime());
+          sampledHV=gr->GetY()[pointGraph++];
+        }
+        time+=samplingPeriod;
+        if (!IsDataTakingActive(time-samplingPeriod)) continue;
+        vSampled[nPointsSampled++]=sampledHV;
+      }
+
+      if (nPointsSampled<1) continue;
+      
+      fChamberHVmedian[iROC]=TMath::Median(nPointsSampled,vSampled);
+      chamberMedianDeviation[iROC]=fChamberHVmedian[iROC]-fParam->GetNominalVoltage(iROC);
+
+      //2. calculate good HV fraction
+      Int_t ngood=0;
+      for (Int_t ipoint=0; ipoint<nPointsSampled; ++ipoint) {
+        if (TMath::Abs(vSampled[ipoint]-fChamberHVmedian[iROC])<maxDipVoltage) ++ngood;
+      }
+
+      fChamberHVgoodFraction[iROC]=Float_t(ngood)/Float_t(nPointsSampled);
+    } else {
+      AliError(Form("No Graph or too few points found for HV sensor of ROC %d",iROC));
+    }
+  }
+
+  delete [] vSampled;
+  vSampled=0x0;
+  
+  // get median deviation from all chambers (detect e.g. -50V)
+  const Double_t medianIROC=TMath::Median( 36, chamberMedianDeviation );
+  const Double_t medianOROC=TMath::Median( 36, chamberMedianDeviation+36 );
+  
+  // Define current default voltages
+  for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
+    const Float_t averageDeviation=(iROC<36)?medianIROC:medianOROC;
+    fCurrentNominalVoltage[iROC]=fParam->GetNominalVoltage(iROC)+averageDeviation;
+  }
+
+  //
+  // Check HV status
+  //
+  for (Int_t iROC=0;iROC<72/*AliTPCCalPad::kNsec*/;++iROC){
+    fChamberHVStatus[iROC]=kTRUE;
+
+    //a. Deviation of median from current nominal voltage
+    //   allow larger than nominal voltages
+    if (fCurrentNominalVoltage[iROC]-fChamberHVmedian[iROC] >  maxVdiff) fChamberHVStatus[iROC]=kFALSE;
+
+    //b. Fraction of bad hv values
+    if ( 1-fChamberHVgoodFraction[iROC] > maxFracHVbad ) fChamberHVStatus[iROC]=kFALSE;
+  }
+}
+
 Float_t AliTPCcalibDB::GetChamberHighVoltage(Int_t run, Int_t sector, Int_t timeStamp, Int_t sigDigits, Bool_t current) {
   //
   // return the chamber HV for given run and time: 0-35 IROC, 36-72 OROC
index 31fcbc1f4485ef501b2d62a894f33222804a9a70..9c4f983965aca9f1d9f9187e612d181214e18dae 100644 (file)
@@ -138,7 +138,16 @@ class AliTPCcalibDB : public TObject
   static Float_t GetGGoffsetVoltage(Int_t run, Int_t sector, Int_t timeStamp=-1, Int_t sigDigits=0);
   static Float_t GetGGnegVoltage(Int_t run, Int_t sector, Int_t timeStamp=-1, Int_t sigDigits=0);
   static Float_t GetGGposVoltage(Int_t run, Int_t sector, Int_t timeStamp=-1, Int_t sigDigits=0);
+  //
+  Bool_t  GetChamberHVStatus(UInt_t roc)                  const { return (roc<72)?fChamberHVStatus[roc]:kFALSE;   }
+  Float_t GetChamberHighVoltageMedian(UInt_t roc)         const { return (roc<72)?fChamberHVmedian[roc]:0.;       }
+  Float_t GetChamberCurrentNominalHighVoltage(UInt_t roc) const { return (roc<72)?fCurrentNominalVoltage[roc]:0.; }
+  Float_t GetChamberGoodHighVoltageFraction(UInt_t roc)   const { return (roc<72)?fChamberHVgoodFraction[roc]:0.; }
+  AliDCSSensor* GetChamberHVSensor(UInt_t roc)            const { return (roc<72)?fHVsensors[roc]:0x0;            }
+  Bool_t  IsDataTakingActive(time_t timeStamp);
+  //
   //Goofie Values
+  //
   static Float_t GetValueGoofie(Int_t timeStamp, Int_t run, Int_t type);
   //
   static Bool_t  GetTemperatureFit(Int_t timeStamp, Int_t run, Int_t side,TVectorD& fit);
@@ -150,10 +159,12 @@ class AliTPCcalibDB : public TObject
   AliDCSSensorArray *     GetGoofieSensors(Int_t run);
   AliDCSSensorArray *     GetVoltageSensors(Int_t run);
   AliTPCCalibVdrift *     GetVdrift(Int_t run);
-  TObjArray *                                                  GetTimeGainSplinesRun(Int_t run);
+  TObjArray *             GetTimeGainSplinesRun(Int_t run);
   TObjArray*              GetTimeVdriftSplineRun(Int_t run);
   static Float_t GetGain(Int_t sector, Int_t row, Int_t pad);
   //
+  // Drift velocity information
+  //
   Double_t      GetVDriftCorrectionTime(Int_t timeStamp, Int_t run, Int_t side, Int_t mode);
   Double_t      GetTime0CorrectionTime(Int_t timeStamp, Int_t run, Int_t side, Int_t mode);
   Double_t      GetVDriftCorrectionGy(Int_t timeStamp, Int_t run, Int_t side, Int_t mode);
@@ -178,6 +189,7 @@ class AliTPCcalibDB : public TObject
 protected:
   
   AliCDBEntry* GetCDBEntry(const char* cdbPath);   
+  void         UpdateChamberHighVoltageData();
   Int_t        InitDeadMap();
 
   Int_t        fRun;         // current run number
@@ -203,6 +215,15 @@ protected:
   TObjArray *fPulserData;         // Calibration Pulser data
   TObjArray *fCEData;             // CE data
   //
+  // Chamber HV info
+  //
+  Bool_t  fChamberHVStatus[72];       // Status of the Chamber, HV wise (on/off)
+  Float_t fChamberHVmedian[72];       // median chamber high voltage
+  Float_t fCurrentNominalVoltage[72]; // current nominal voltages
+  Float_t fChamberHVgoodFraction[72]; // fraction of time the chamber has a good HV (wrt. robust median)
+  AliDCSSensor *fHVsensors[72];       // HV sensors
+  TGraph *fGrRunState;                // store information if run is active or paused
+  //
   //
   //
   AliTPCSensorTempArray* fTemperature; // Temperature calibration entry
index d4f02f21a5c7efe760799d4de9841d7975bae491..6e4cd18467e43703f640b9a400a105e2a2fc4acc 100644 (file)
@@ -315,10 +315,38 @@ void AliTPCcalibSummary::ProcessRun(Int_t irun, Int_t startTime, Int_t endTime){
       vecGoofie.ResizeTo(19);
     }
     //
-    TVectorD voltagesIROC(36);
-    TVectorD voltagesOROC(36); 
-      for(Int_t j=0; j<36; j++) voltagesIROC[j] = fCalibDB->GetChamberHighVoltage(irun, j,itime); 
-    for(Int_t j=36; j<72; j++) voltagesOROC[j-36] = fCalibDB->GetChamberHighVoltage(irun, j,itime);
+    static TVectorF voltagesIROC(36);
+    static TVectorF voltagesIROCMedian(36);
+    static TVectorF voltagesIROCNominal(36);
+    static TVectorF voltagesIROCCurrentNominal(36);
+    static TVectorF voltagesIROCStatus(36);
+    static TVectorF voltagesIROCGoodFraction(36);
+    //
+    static TVectorF voltagesOROC(36);
+    static TVectorF voltagesOROCMedian(36);
+    static TVectorF voltagesOROCNominal(36);
+    static TVectorF voltagesOROCCurrentNominal(36);
+    static TVectorF voltagesOROCStatus(36);
+    static TVectorF voltagesOROCGoodFraction(36);
+    
+    for(Int_t j=0; j<36; j++){
+      voltagesIROC[j]               = fCalibDB->GetChamberHighVoltage(irun, j,itime);
+      voltagesIROCMedian[j]         = fCalibDB->GetChamberHighVoltageMedian(j);
+      voltagesIROCNominal[j]        = fCalibDB->GetParameters()->GetNominalVoltage(j);
+      voltagesIROCCurrentNominal[j] = fCalibDB->GetChamberCurrentNominalHighVoltage(j);
+      voltagesIROCStatus[j]         = fCalibDB->GetChamberHVStatus(j);
+      voltagesIROCGoodFraction[j]   = fCalibDB->GetChamberGoodHighVoltageFraction(j);
+    }
+    
+    for(Int_t j=36; j<72; j++) {
+      voltagesOROC[j-36]               = fCalibDB->GetChamberHighVoltage(irun, j,itime);
+      voltagesOROCMedian[j-36]         = fCalibDB->GetChamberHighVoltageMedian(j);
+      voltagesOROCNominal[j-36]        = fCalibDB->GetParameters()->GetNominalVoltage(j);
+      voltagesOROCCurrentNominal[j-36] = fCalibDB->GetChamberCurrentNominalHighVoltage(j);
+      voltagesOROCStatus[j-36]         = fCalibDB->GetChamberHVStatus(j);
+      voltagesOROCGoodFraction[j-36]   = fCalibDB->GetChamberGoodHighVoltageFraction(j);
+    }
+    
     Double_t voltIROC = TMath::Median(36, voltagesIROC.GetMatrixArray());
     Double_t voltOROC = TMath::Median(36, voltagesOROC.GetMatrixArray());
     //
@@ -333,6 +361,8 @@ void AliTPCcalibSummary::ProcessRun(Int_t irun, Int_t startTime, Int_t endTime){
     //drift velocity
     Float_t dvCorr=-5;
     if (fitVdrift) dvCorr=fitVdrift->Eval(itime);
+    //data taking active
+    Bool_t dataTakingActive=fCalibDB->IsDataTakingActive((time_t)itime);
     
     //tempMap->GetLinearFitter(0,0,itime);
     (*fPcstream)<<"dcs"<<
@@ -340,11 +370,23 @@ void AliTPCcalibSummary::ProcessRun(Int_t irun, Int_t startTime, Int_t endTime){
       "time="<<itime<<
       "startTimeGRP="<<startTimeGRP<<
       "stopTimeGRP="<<stopTimeGRP<<
+      "dataTakingActive="<<dataTakingActive<<
       //run type
       "runType.="<<&runType<<
       // voltage setting
-      "VIROC.="<<&voltagesIROC<<
-      "VOROC.="<<&voltagesOROC<<
+      "VIROC.="               << &voltagesIROC<<
+      "VIROCMedian.="         << &voltagesIROCMedian<<
+      "VIROCNominal.="        << &voltagesIROCNominal <<
+      "VIROCCurrentNominal.=" << &voltagesIROCCurrentNominal <<
+      "VIROCGoodHVFraction.=" << &voltagesIROCGoodFraction <<
+      "VIROCStatus.="         << &voltagesIROCStatus <<
+      //
+      "VOROC.="               << &voltagesOROC<<
+      "VOROCMedian.="         << &voltagesOROCMedian<<
+      "VOROCNominal.="        << &voltagesOROCNominal <<
+      "VOROCCurrentNominal.=" << &voltagesOROCCurrentNominal <<
+      "VOROCGoodHVFraction.=" << &voltagesOROCGoodFraction <<
+      "VOROCStatus.="         << &voltagesOROCStatus <<
       "medianVIROC="<<voltIROC<<
       "medianVOROC="<<voltOROC<<
       "coverIA=" << coverIA <<
@@ -570,8 +612,8 @@ void AliTPCcalibSummary::ProcessDriftCE(Int_t run,Int_t timeStamp){
   static TVectorD vdriftCE(74);
   static TVectorD tcdriftCE(74);
   static TVectorD tddriftCE(74);
-  static Double_t ltime0A;
-  static Double_t ltime0C;
+  static Double_t ltime0A=0.;
+  static Double_t ltime0C=0.;
   //
   //
   //
@@ -618,9 +660,9 @@ void AliTPCcalibSummary::ProcessDriftAll(Int_t run,Int_t timeStamp){
   static Double_t vdriftP=0;
   static Double_t dcea=0, dcec=0, dcem=0,  dla=0,dlc=0,dlm=0, dlaon=0,dlcon=0,dlmon=0, dp=0;
   static Double_t dits=0;
-  static Double_t ltime0A;
-  static Double_t ltime0C;
-  static Double_t ctime0;
+  static Double_t ltime0A=0.;
+  static Double_t ltime0C=0.;
+  static Double_t ctime0=0.;
   static Double_t vdrift1=0;
   vdrift1= fCalibDB->GetVDriftCorrectionTime(timeStamp,run,0,1);
   vdriftP = fDButil->GetVDriftTPC(dp, run, timeStamp, 86400, 3600,0);
@@ -758,6 +800,13 @@ void AliTPCcalibSummary::ProcessGain(Int_t irun, Int_t timeStamp){
   static TVectorD vGainGraphOROCmedErr(36);
   static TVectorD vGainGraphOROClongErr(36);
   
+  vGainGraphIROC.Zero();
+  vGainGraphOROCmed.Zero();
+  vGainGraphOROClong.Zero();
+  vGainGraphIROCErr.Zero();
+  vGainGraphOROCmedErr.Zero();
+  vGainGraphOROClongErr.Zero();
+  
   TGraphErrors grDummy;
   TObjArray * gainSplines = fCalibDB->GetTimeGainSplinesRun(irun);
   if (gainSplines) {
index b2ad8d6b8f805dc9b728f5665535db954f6371f2..fc0fae852749231655fbb5897dcfc29ba5c0ae41 100644 (file)
 #include <TObjArray.h>
 #include <TTree.h>
 #include <TGraphErrors.h>
+#include <TTimeStamp.h>
 #include "AliLog.h"
 #include "AliComplexCluster.h"
 #include "AliESDEvent.h"
@@ -7794,52 +7795,54 @@ void AliTPCtrackerMI::AddCovarianceAdd(AliTPCseed * seed){
 }
 
 //_____________________________________________________________________________
-Bool_t  AliTPCtrackerMI::IsTPCHVDipEvent(AliESDEvent const *esdEvent) {
-//
-// check events affected by TPC HV dip
-//
-if(!esdEvent) return kFALSE;
-
-// Init TPC OCDB
-if(!AliTPCcalibDB::Instance()) return kFALSE;
-AliTPCcalibDB::Instance()->SetRun(esdEvent->GetRunNumber());
-
-// Get HV TPC chamber sensors and calculate the median
-AliDCSSensorArray *voltageArray= AliTPCcalibDB::Instance()->GetVoltageSensors(esdEvent->GetRunNumber());
-if(!voltageArray) return kFALSE;
-
-TString sensorName="";
-Double_t kTPCHVdip = 2.0; // allow for 2V dip as compared to median from given sensor
+Bool_t  AliTPCtrackerMI::IsTPCHVDipEvent(AliESDEvent const *esdEvent)
+{
+  //
+  // check events affected by TPC HV dip
+  //
+  if(!esdEvent) return kFALSE;
 
+  // Init TPC OCDB
+  AliTPCcalibDB *db=AliTPCcalibDB::Instance();
+  if(!db) return kFALSE;
+  db->SetRun(esdEvent->GetRunNumber());
 
+  // maximum allowed voltage before an event is identified as a dip event
+  // and scanning period
+  const Double_t kTPCHVdip          = db->GetParameters()->GetMaxDipVoltage(); 
+  const Double_t dipEventScanPeriod = db->GetParameters()->GetVoltageDipScanPeriod();
+  const Double_t tevSec             = esdEvent->GetTimeStamp();
+  
   for(Int_t sector=0; sector<72; sector++)
   {
-    Char_t sideName='A';
-    if ((sector/18)%2==1) sideName='C';
-    if (sector<36){
-      //IROC
-      sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
-    } else {
-      //OROC
-      sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
-    }
+    // don't use excluded chambers, since the state is not defined at all
+    if (!db->GetChamberHVStatus(sector)) continue;
+    
+    // get hv sensor of the chamber
+    AliDCSSensor *sensor = db->GetChamberHVSensor(sector);
+    if (!sensor) continue;
+    TGraph *grSensor=sensor->GetGraph();
+    if (!grSensor) continue;
+    if (grSensor->GetN()<1) continue;
     
-    AliDCSSensor* sensor = voltageArray->GetSensor(sensorName.Data());
-    if(!sensor) continue;
-    TGraph *graph = sensor->GetGraph();
-    if(!graph) continue;
-    Double_t median = TMath::Median(graph->GetN(), graph->GetY());
-    if(median == 0) continue;
-
-    //printf("chamber %d, sensor %s, HV %f, median %f\n", sector, sensorName.Data(), sensor->GetValue(esdEvent->GetTimeStamp()), median);
+    // get median
+    const Double_t median = db->GetChamberHighVoltageMedian(sector);
+    if(median < 1.) continue;
     
-    if(TMath::Abs(sensor->GetValue(esdEvent->GetTimeStamp())-median)>kTPCHVdip) {
-      return kTRUE; 
+    for (Int_t ipoint=0; ipoint<grSensor->GetN()-1; ++ipoint){
+      Double_t nextTime=grSensor->GetX()[ipoint+1]*3600+sensor->GetStartTime();
+      if (tevSec-dipEventScanPeriod>nextTime) continue;
+      const Float_t deltaV=TMath::Abs(grSensor->GetY()[ipoint]-median);
+      if (deltaV>kTPCHVdip) {
+        AliDebug(3,Form("HV dip detected in ROC '%02d' with dV '%.2f' at time stamp '%.0f'",sector,deltaV,tevSec));
+        return kTRUE;
+      }
+      if (nextTime>tevSec+dipEventScanPeriod) break;
     }
-  } 
-  return kFALSE; 
-} 
+  }
+  
+  return kFALSE;
+}
 
 //________________________________________
 void AliTPCtrackerMI::MarkSeedFree(TObject *sd)