]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/Base/AliTPCcalibDB.cxx
ATO-78 a.) adding aliases used for gain correction fitting \n b)Kr and QA prefix...
[u/mrichter/AliRoot.git] / TPC / Base / AliTPCcalibDB.cxx
index 8aed5e324a5f7edc6c2f5c25d11ff520d1dbcc72..edc5fbd28388761da5df22fba7db906a5a6fe9eb 100644 (file)
@@ -88,6 +88,7 @@
 #include <AliSplineFit.h>
 #include <AliCTPTimeParams.h>
 
+#include "TGraphErrors.h"
 #include "AliTPCcalibDB.h"
 #include "AliTPCdataQA.h"
 #include "AliTPCcalibDButil.h"
@@ -317,7 +318,8 @@ AliTPCcalibDB::~AliTPCcalibDB()
   //
   // destructor
   //
-  
+
+  //delete fIonTailArray; 
   delete fActiveChannelMap;
   delete fGrRunState;
 }
@@ -490,14 +492,15 @@ void AliTPCcalibDB::Update(){
     fPulserData=(TObjArray*)(entry->GetObject());
   }
   
-   //Calibration ION tail data
- //  entry          = GetCDBEntry("TPC/Calib/IonTail");
-//   if (entry){
-//     entry->SetOwner(kTRUE);
-//     fIonTailArray=(TObjArray*)(entry->GetObject());
-//   }
-
-
+  //Calibration ION tail data
+  entry          = GetCDBEntry("TPC/Calib/IonTail");
+  if (entry){
+    //delete fIonTailArray; fIonTailArray=NULL;
+    entry->SetOwner(kTRUE);
+     fIonTailArray=(TObjArray*)(entry->GetObject());
+     fIonTailArray->SetOwner(); //own the keys
+  }
+  
   //CE data
   entry          = GetCDBEntry("TPC/Calib/CE");
   if (entry){
@@ -600,7 +603,119 @@ void AliTPCcalibDB::UpdateNonRec(){
 
 }
 
+Bool_t AliTPCcalibDB::GetTailcancelationGraphs(Int_t sector, TGraphErrors ** graphRes, Float_t * indexAmpGraphs){
+// 
+//   Read OCDB entry object of Iontail (TObjArray of TGraphErrors of TRFs)
+//   Naming of the TRF objects is: "gr_<chamber_type>_<voltage>_<laser_track_angle>_<distance_to_COG>" --> "gr_iroc_1240_1_1" 
+//   
+  
+  //Int_t run = fTransform->GetCurrentRunNumber();
+  //SetRun(run);
+  //Float_t rocVoltage = GetChamberHighVoltage(run,sector, -1);      // Get the voltage from OCDB with a getter (old function)
+//   Float_t rocVoltage=GetChamberHighVoltageMedian(sector);                      // Get the voltage from OCDB, new function from Jens
+  Int_t nominalVoltage = (sector<36) ? 1240 : 1470 ;     // nominal voltage of 2012 when the TRF functions were produced
 
+  Float_t rocVoltage = nominalVoltage;
+
+  if ( rocVoltage < nominalVoltage/2. || rocVoltage > nominalVoltage*2. )
+  {
+    AliInfo(Form("rocVoltage out of range: roc: %.2f, nominal: %i", rocVoltage, nominalVoltage));
+    return kFALSE;
+  }
+
+  Int_t tempVoltage = 0;                                 
+  Int_t trackAngle  = 4;                                 // (1=first, 2=second, 3=third, 4=first+second, 5=all tracks) note: 3rd is distorted by low freq
+  TString rocType   = (sector<36) ? "iroc" : "oroc";     
+  const Int_t ngraph=fIonTailArray->GetLast();
+  
+  // create array of voltages in order to select the proper TRF with closest voltage  
+  Int_t voltages[ngraph];     // array of voltages
+  for (Int_t i=0; i<ngraph; i++){
+    voltages[i]=0;
+  }
+    
+  // loop over response functions in the TObjarray
+  Int_t nvoltages=0;
+  for (Int_t i=0;i<=ngraph;i++){
+    
+    // read the TRF object name in order to select proper TRF for the given sector
+    TString objname(fIonTailArray->At(i)->GetName());
+    if (!objname.Contains(rocType)) continue;
+
+    TObjArray *objArr = objname.Tokenize("_");
+    
+    // select the roc type (IROC or OROC) and the trackAngle
+    if ( atoi(static_cast<TObjString*>(objArr->At(3))->GetName())==trackAngle )
+    { 
+      // Create the voltage array for proper voltage value selection
+      voltages[nvoltages]=atoi(static_cast<TObjString*>(objArr->At(2))->GetName());
+      nvoltages++;
+    }
+    delete objArr;
+  }
+    
+  // find closest voltage value to ROC voltage (among the TRF' voltage array --> to select proper t.r.f.)
+  Int_t ampIndex     = 0;
+  Int_t diffVoltage  = TMath::Abs(rocVoltage - voltages[0]);
+  for (Int_t k=0;k<ngraph;k++) {
+    if (diffVoltage >= TMath::Abs(rocVoltage-voltages[k]) && voltages[k]!=0)
+      {
+        diffVoltage    = TMath::Abs(rocVoltage-voltages[k]);
+        ampIndex   = k;
+      }     
+  }
+  tempVoltage = voltages[ampIndex];    // use closest voltage to current voltage
+  //if (run<140000) tempVoltage = nominalVoltage;    // for 2010 data
+  
+  // assign TGraphErrors   
+  Int_t igraph=0;
+  for (Int_t i=0; i<=ngraph; i++){
+   
+    // read TRFs for TObjArray and select the roc type (IROC or OROC) and the trackAngle
+    TGraphErrors * trfObj = static_cast<TGraphErrors*>(fIonTailArray->At(i));
+    TString objname(trfObj->GetName());
+    if (!objname.Contains(rocType)) continue; //choose ROC type
+    
+    TObjArray *objArr1 = objname.Tokenize("_");
+     
+    // TRF eleminations
+    TObjString* angleString = static_cast<TObjString*>(objArr1->At(3));
+    TObjString* voltageString = static_cast<TObjString*>(objArr1->At(2));
+    //choose angle and voltage
+    if ((atoi(angleString->GetName())==trackAngle) && (atoi(voltageString->GetName())==tempVoltage) )
+    {
+      // Apply Voltage scaling
+      Int_t voltage       = atoi(voltageString->GetName());
+      Double_t voltageScaled = 1;
+      if (rocVoltage>0)  voltageScaled = Double_t(voltage)/Double_t(rocVoltage); // for jens how it can happen that we have clusters at 0 HV ?
+      const Int_t nScaled          = TMath::Nint(voltageScaled*trfObj->GetN())-1; 
+      Double_t x;
+      Double_t y;
+      
+      delete graphRes[igraph];
+      graphRes[igraph]       = new TGraphErrors(nScaled);
+      
+      for (Int_t j=0; j<nScaled; j++){
+        x = TMath::Nint(j*(voltageScaled));
+        y = (j<trfObj->GetN()) ? (1./voltageScaled)*trfObj->GetY()[j] : 0.;
+        graphRes[igraph]->SetPoint(j,x,y);
+      }
+
+      // fill arrays for proper position and amplitude selections
+      TObjString* distanceToCenterOfGravity = static_cast<TObjString*>(objArr1->At(4));
+      indexAmpGraphs[igraph] = (distanceToCenterOfGravity->GetString().Atof())/10.;
+      // smooth voltage scaled graph 
+      for (Int_t m=1; m<nScaled;m++){
+        if (graphRes[igraph]->GetY()[m]==0) graphRes[igraph]->GetY()[m] = graphRes[igraph]->GetY()[m-1];
+      }
+      igraph++;
+    }
+  delete objArr1;
+  }
+  return kTRUE;
+}
 
 void AliTPCcalibDB::CreateObjectList(const Char_t *filename, TObjArray *calibObjects)
 {
@@ -1656,6 +1771,13 @@ void AliTPCcalibDB::UpdateChamberHighVoltageData()
       }
 
       fChamberHVgoodFraction[iROC]=Float_t(ngood)/Float_t(nPointsSampled);
+    } else if (!gr && !sensor->GetFit() ){
+      // This is an exception handling.
+      // It was observed that for some rund in the 2010 data taking no HV info is available
+      //    for some sectors. However they were active. So take care about this
+      fChamberHVmedian[iROC]       = fParam->GetNominalVoltage(iROC);
+      fChamberHVgoodFraction[iROC] = 1.;
+      AliWarning(Form("ROC %d detected without HV Splines and HV graph. Will set median HV to nominal voltage",iROC));
     } else {
       AliError(Form("No Graph or too few points found for HV sensor of ROC %d",iROC));
     }
@@ -2041,6 +2163,10 @@ Bool_t AliTPCcalibDB::CreateGUITree(const char* filename){
   UpdateNonRec();  // load all infromation now
 
   AliTPCPreprocessorOnline prep;
+  if (GetActiveChannelMap()) prep.AddComponent(new AliTPCCalPad(*GetActiveChannelMap()));
+
+  // gain map
+  if (GetDedxGainFactor()) prep.AddComponent(new AliTPCCalPad(*GetDedxGainFactor()));
   //noise and pedestals
   if (GetPedestals()) prep.AddComponent(new AliTPCCalPad(*(GetPedestals())));
   if (GetPadNoise() ) prep.AddComponent(new AliTPCCalPad(*(GetPadNoise())));
@@ -2272,9 +2398,9 @@ Double_t AliTPCcalibDB::GetVDriftCorrectionDeltaZ(Int_t /*timeStamp*/, Int_t run
   
   // Arguments:
   // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
-  // timestamp - timestamp
+  // timestamp - not used
   // run       - run number
-  // side      - the drift velocity gy correction per side (CE and Laser tracks)
+  // side      - common for boith sides
   //
   if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
   UpdateRunInformations(run,kFALSE);
@@ -2411,7 +2537,7 @@ AliTPCCorrection * AliTPCcalibDB::GetTPCComposedCorrectionDelta() const{
   return (AliTPCCorrection *)fComposedCorrectionArray->At(4);  //
 }
 
-Double_t AliTPCcalibDB::GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int_t sector, Int_t deltaCache){
+Double_t AliTPCcalibDB::GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int_t sector, Int_t deltaCache, Int_t mode){
   //
   // Correction for  changes of gain caused by change of the HV and by relative change of the gas density
   // Function is slow some kind of caching needed
@@ -2419,16 +2545,33 @@ Double_t AliTPCcalibDB::GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int
   //
   // Input paremeters:
   //  deltaCache - maximal time differnce above which the cache is recaclulated
-  // 
-  static TVectorD gGainCorrection(72);
-  static Int_t gTimeStamp=0;
+  //  mode       - mode==0 by default return combined correction 
+  //                       actual HV and Pt correction has to be present in the run calibration otherwise it is ignored.
+  //                       (retrun value differnt than 1 only in case calibration present in the OCDB entry CalibTimeGain
+  //               mode==1 return combined correction ( important for calibration pass)
+  //                       (in case thereis  no calibration in  CalibTimeGain, default value from the AliTPCParam (Parameters) is used
+  //                       this mode is used in the CPass0
+  //               mode==2 return HV correction
+  //               mode==3 return P/T correction
+  //  Usage in the simulation/reconstruction
+  //  MC:     Qcorr  = Qorig*GetGainCorrectionHVandPT   ( in AliTPC.cxx ) 
+  //  Rec:    dEdx   = dEdx/GetGainCorrectionHVandPT    ( in aliTPCseed.cxx )
+  //
+  static Float_t gGainCorrection[72];
+  static Float_t gGainCorrectionPT[72];
+  static Float_t gGainCorrectionHV[72];
+  static Int_t    gTimeStamp=-99999999;
+  static Bool_t   hasTimeDependent=kFALSE; 
   if ( TMath::Abs(timeStamp-gTimeStamp)> deltaCache){    
     //
     TGraphErrors * graphGHV = 0;
     TGraphErrors * graphGPT = 0;
     TObjArray *timeGainSplines = GetTimeGainSplinesRun(run);
-    graphGHV  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesHV");
-    graphGPT  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesPT");
+    if (timeGainSplines){
+      graphGHV  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesHV");
+      graphGPT  = (TGraphErrors*) timeGainSplines->FindObject("GainSlopesPT");
+      if (graphGHV) hasTimeDependent=kTRUE;
+    }
     if (!graphGHV) graphGHV = fParam->GetGainSlopesHV();
     if (!graphGPT) graphGPT = fParam->GetGainSlopesPT();
     //
@@ -2438,9 +2581,18 @@ Double_t AliTPCcalibDB::GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int
       Double_t deltaGPT=0;
       if (graphGHV) deltaGHV = graphGHV->GetY()[isec]*deltaHV;
       if (graphGPT) deltaGPT = graphGPT->GetY()[isec]*GetPTRelative(timeStamp,run,0);
-      gGainCorrection[isec]=deltaGHV+deltaGPT;
+      gGainCorrection[isec]=(1.+deltaGHV)*(1.+deltaGPT);
+      gGainCorrectionPT[isec]=1+deltaGPT;
+      gGainCorrectionHV[isec]=1+deltaGHV;
     }    
     gTimeStamp=timeStamp;
   }
-  return gGainCorrection[sector];
+  if (mode==0){
+    if (hasTimeDependent) return gGainCorrection[sector];
+    if (!hasTimeDependent) return 1;
+  }
+  if (mode==1) return gGainCorrection[sector];
+  if (mode==2) return gGainCorrectionPT[sector];
+  if (mode==3) return gGainCorrectionHV[sector];
+  return 1;
 }