]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
authorhristov <Peter.Hristov@cern.ch>
Mon, 10 Feb 2014 09:38:00 +0000 (10:38 +0100)
committerhristov <Peter.Hristov@cern.ch>
Mon, 10 Feb 2014 09:38:00 +0000 (10:38 +0100)
143 files changed:
ANALYSIS/macros/QAtrain_duo.C
OCDB/GRP/GRP/Data/Run0_999999999_v0_s0.root [new file with mode: 0644]
PWGPP/AliTaskCDBconnect.h
PWGPP/CalibMacros/CPass0/AddTaskTPCCalib.C
PWGPP/CalibMacros/CPass0/recCPass0.C
PWGPP/CalibMacros/CPass1/AddTaskTPCCalib.C
PWGPP/CalibMacros/CPass1/recCPass1.C
PWGPP/CalibMacros/CPass1/runCPass1.sh
PWGPP/TPC/macros/CalibSummary.C [new file with mode: 0644]
PWGPP/TPC/macros/ConfigOCDB.C
PWGPP/TPC/macros/filterPIDSelected.C [new file with mode: 0644]
STAT/CMakeLists.txt
STAT/Macros/TStatToolkitTest.C [new file with mode: 0644]
STAT/TStatToolkit.cxx
STAT/TStatToolkit.h
STEER/CDB/AliDCSSensor.cxx
STEER/CDB/AliDCSSensor.h
STEER/CDB/AliDCSSensorArray.cxx
STEER/CDB/AliDCSSensorArray.h
STEER/ESD/AliESDfriend.cxx
STEER/ESD/AliESDfriend.h
STEER/ESD/AliTrackerBase.cxx
STEER/ESD/AliTrackerBase.h
STEER/STEERBase/AliExternalTrackParam.cxx
STEER/STEERBase/AliTPCPIDResponse.cxx
STEER/STEERBase/AliTPCPIDResponse.h
STEER/STEERBase/AliTPCdEdxInfo.cxx
STEER/STEERBase/AliTPCdEdxInfo.h
TPC/Base/AliTPCComposedCorrection.cxx
TPC/Base/AliTPCComposedCorrection.h
TPC/Base/AliTPCCorrection.cxx
TPC/Base/AliTPCCorrection.h
TPC/Base/AliTPCCorrectionLookupTable.cxx [new file with mode: 0644]
TPC/Base/AliTPCCorrectionLookupTable.h [new file with mode: 0644]
TPC/Base/AliTPCParam.cxx
TPC/Base/AliTPCParam.h
TPC/Base/AliTPCSpaceCharge3D.cxx
TPC/Base/AliTPCSpaceCharge3D.h
TPC/Base/AliTPCTransform.cxx
TPC/Base/AliTPCcalibDB.cxx
TPC/Base/AliTPCcalibDB.h
TPC/CMakelibTPCbase.pkg
TPC/CMakelibTPCupgrade.pkg [new file with mode: 0644]
TPC/Calib/AliTPCPreprocessorOffline.cxx
TPC/Calib/AliTPCPreprocessorOffline.h
TPC/Calib/AliTPCcalibCalib.cxx
TPC/Calib/AliTPCcalibGainMult.cxx
TPC/Calib/AliTPCcalibGainMult.h
TPC/Calib/AliTPCcalibSummary.cxx
TPC/Calib/AliTPCcalibTimeGain.cxx
TPC/Calib/AliTPCcalibTimeGain.h
TPC/Calib/maps/SC_ArCO2_eps5_50kHz.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps10_50kHz.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps10_50kHz_precal.lookup.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps10_50kHz_precal.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps20_50kHz.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.lookup.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps5_50kHz.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.lookup.root [new file with mode: 0644]
TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root [new file with mode: 0644]
TPC/Rec/AliTPCRecoParam.cxx
TPC/Rec/AliTPCRecoParam.h
TPC/Rec/AliTPCclusterMI.cxx
TPC/Rec/AliTPCclusterMI.h
TPC/Rec/AliTPCclusterer.cxx
TPC/Rec/AliTPCseed.cxx
TPC/Rec/AliTPCseed.h
TPC/Rec/AliTPCtracker.cxx
TPC/Rec/AliTPCtracker.h
TPC/Rec/AliTPCtrackerSector.cxx
TPC/Rec/AliTPCtrackerSector.h
TPC/Sim/AliTPC.cxx
TPC/Sim/AliTPCGen.h [new file with mode: 0644]
TPC/Sim/AliTPCv2.cxx
TPC/Sim/AliTPCv2.h
TPC/Sim/AliTPCv4.cxx
TPC/Sim/AliTPCv4.h
TPC/TPCbaseLinkDef.h
TPC/TPCupgradeLinkDef.h [new file with mode: 0644]
TPC/Upgrade/AliToyMCEvent.cxx
TPC/Upgrade/AliToyMCEvent.h
TPC/Upgrade/AliToyMCEventGenerator.cxx
TPC/Upgrade/AliToyMCEventGenerator.h
TPC/Upgrade/AliToyMCEventGeneratorSimple.cxx
TPC/Upgrade/AliToyMCReconstruction.cxx
TPC/Upgrade/AliToyMCReconstruction.h
TPC/Upgrade/data/GEMMCscan/out_235_235_301_374.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_235_235_326_343.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_235_285_273_342.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_235_285_298_314.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_255_235_292_364.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_255_235_316_333.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_255_285_266_330.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_255_285_289_305.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_275_235_284_354.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_275_235_308_323.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_275_285_256_321.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_275_285_281_295.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_295_235_275_344.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_295_235_298_314.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_295_285_248_311.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_295_285_272_285.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_315_235_267_334.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_315_235_289_305.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_315_285_240_300.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/out_315_285_263_276.root [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/readme [new file with mode: 0644]
TPC/Upgrade/data/GEMMCscan/result_sim.root [new file with mode: 0644]
TPC/Upgrade/data/GEMscan/GEMScansIKF.root [new file with mode: 0644]
TPC/Upgrade/data/GEMscan/S_LP_LP_S_ETscans_NeCO2N2.txt [new file with mode: 0644]
TPC/Upgrade/data/GEMscan/S_LP_LP_S_ETscans_NeCO2N2.xls [new file with mode: 0644]
TPC/Upgrade/data/GEMscan/S_LP_LP_S_GEM1scans_ratio0.65_NeCO2N2.xls [new file with mode: 0644]
TPC/Upgrade/data/GEMscan/S_LP_LP_S_scans_ArCO2.txt [new file with mode: 0644]
TPC/Upgrade/data/GEMscan/S_LP_LP_S_scans_NeCO2N2.txt [new file with mode: 0644]
TPC/Upgrade/macros/AnaDelta.C [new file with mode: 0644]
TPC/Upgrade/macros/AnaEpsScan.C [new file with mode: 0644]
TPC/Upgrade/macros/CheckConsistency_DistCorr.C
TPC/Upgrade/macros/GetComposedResidualDistortion.C [new file with mode: 0644]
TPC/Upgrade/macros/NimStyle.C [new file with mode: 0644]
TPC/Upgrade/macros/createSCprecal.C [new file with mode: 0644]
TPC/Upgrade/macros/fastToyMCMI.C [new file with mode: 0644]
TPC/Upgrade/macros/fastToyMCMI.sh [new file with mode: 0755]
TPC/Upgrade/macros/finalPlots.C
TPC/Upgrade/macros/fitResolution.C [new file with mode: 0644]
TPC/Upgrade/macros/loadlibs.C
TPC/Upgrade/macros/makeCurrentCorrection.C [new file with mode: 0644]
TPC/Upgrade/macros/makeCurrentCorrection.sh [new file with mode: 0755]
TPC/Upgrade/macros/makeResidualSpaceChargeOCDB.C [new file with mode: 0644]
TPC/Upgrade/macros/runSimRec
TPC/Upgrade/macros/runSimRec.C
TPC/Upgrade/macros/spaceChargeFluctuation.C
TPC/Upgrade/macros/spaceChargeFluctuation.sh
TPC/Upgrade/macros/toyMCRecPlots.C
TPC/fastSimul/AliTPCclusterFast.cxx
TPC/fastSimul/README.txt
TPC/fastSimul/simul.C
TPC/fastSimul/simul.sh
TPC/macros/CalibratedEdxRegion.C [new file with mode: 0644]
TPC/macros/data2011/makeBBFit.C [new file with mode: 0644]
TPC/macros/data2011/ocdbScan.C [new file with mode: 0644]
TPC/stressTest/README
TPC/stressTest/stressTest.sh

index e97092b61040e6fd9b2dc8e3953312f5e504858d..113a231d1350a65ff59d9ace38da800662c5136c 100644 (file)
@@ -44,7 +44,7 @@ Int_t runNumbers[5] = {158626};
 
 Bool_t doCDBconnect   = 1;
 Bool_t doEventStat    = 1;
-Bool_t doCentrality   = 0;
+Bool_t doCentrality   = 1;
 Bool_t doQAsym        = 1;
 Bool_t doVZERO        = 1;   // there is a 2nd file
 Bool_t doVZEROPbPb    = 1; 
@@ -148,6 +148,7 @@ void LoadLibraries()
   gSystem->Load("libTENDER");
   gSystem->Load("libPWGPP.so");
   gSystem->Load("libAliHLTTrigger.so");
+  gSystem->Load("libPWGTools"); 
 
   if (doEMCAL || doPHOS || doCALO) {
      gSystem->Load("libEMCALUtils");
diff --git a/OCDB/GRP/GRP/Data/Run0_999999999_v0_s0.root b/OCDB/GRP/GRP/Data/Run0_999999999_v0_s0.root
new file mode 100644 (file)
index 0000000..48fa9a0
Binary files /dev/null and b/OCDB/GRP/GRP/Data/Run0_999999999_v0_s0.root differ
index eac818df63d46d21eac841763f017f61efafcf12..ed66f85ad6283ae0b9be6271ec09c1dd10e8c5f2 100644 (file)
@@ -21,6 +21,7 @@ private:
 
   AliTaskCDBconnect(const AliTaskCDBconnect &other);
   AliTaskCDBconnect& operator=(const AliTaskCDBconnect &other);
+
   void                      InitGRP();
   //
 public:
index 92a790b8e11c18c0d5154f87be5dd227d397eb66..2093a56bc754af6193eee165ad6d69714cf020eb 100644 (file)
@@ -338,8 +338,23 @@ void ConfigOCDB(Int_t run){
   if (!array){
     printf("TPC reco param not available");
   }
+  
+  //get the beam type from OCDB to decide which type of reco param we need -
+  //high or low flux
+  entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
+  AliGRPObject* grpData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
+  TString beamType = grpData->GetBeamType();
+  if (beamType==AliGRPObject::GetInvalidString()) {
+    AliError("GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
+    beamType = "UNKNOWN";
+  }
   // 0 - Low Flux (pp), 1- High Flux (Pb-Pb)
-  AliTPCRecoParam * tpcRecoParam = (AliTPCRecoParam*)array->At(1);
+  Int_t fluxType=0;
+  if (beamType.Contains("p-p")) {fluxType=0;}
+  if (beamType.Contains("A-A")) {fluxType=1;}
+  AliTPCRecoParam * tpcRecoParam = (AliTPCRecoParam*)array->At(fluxType);
+  printf("beam type: %s, using fluxType=%i\n",beamType.Data(),fluxType);
+  tpcRecoParam->Print();
 
   transform->SetCurrentRecoParam(tpcRecoParam);
   tpcRecoParam->SetUseGainCorrectionTime(0);
@@ -359,6 +374,8 @@ void ConfigOCDB(Int_t run){
   tpcRecoParam->SetUseMultiplicityCorrectionDedx(kFALSE);
   tpcRecoParam->SetUseAlignmentTime(kFALSE);
   tpcRecoParam->SetUseComposedCorrection(kTRUE);
+  //
+  tpcRecoParam->SetCorrectionHVandPTMode(1);
 
   AliTPCcalibDB::Instance()->SetRun(run); 
 }
index a0f44972fea3e1b7fcb386034fbf81fd66ea4c27..c5fdb6e4f6b7e4abc32e84275623f03b11b52052 100644 (file)
 
 void recCPass0(const char *filename="raw.root",Int_t nevents=-1, const char *ocdb="raw://", const char* options="?Trigger=kCalibBarrel")
 {
+
+  if (gSystem->Getenv("ALIROOT_FORCE_COREDUMP"))
+  {
+    printf("ALIROOT_FORCE_COREDUMP set\n");
+    gSystem->ResetSignal(kSigFloatingException);
+    gSystem->ResetSignal(kSigSegmentationViolation);
+  }
+
   // Load some system libs for Grid and monitoring
   // Set the CDB storage location
   AliCDBManager * man = AliCDBManager::Instance();
index 6d664c081bf1b8e521dedd8ec0b4b128c7d4c796..8e907801956ff45f762163963b563f5d842596a7 100644 (file)
@@ -341,8 +341,23 @@ void ConfigOCDB(Int_t run){
   if (!array){
     printf("TPC reco param not available");
   }
+  
+  //get the beam type from OCDB to decide which type of reco param we need -
+  //high or low flux
+  entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
+  AliGRPObject* grpData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
+  TString beamType = grpData->GetBeamType();
+  if (beamType==AliGRPObject::GetInvalidString()) {
+    AliError("GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
+    beamType = "UNKNOWN";
+  }
   // 0 - Low Flux (pp), 1- High Flux (Pb-Pb)
-  AliTPCRecoParam * tpcRecoParam = (AliTPCRecoParam*)array->At(1);
+  Int_t fluxType=0;
+  if (beamType.Contains("p-p")) {fluxType=0;}
+  if (beamType.Contains("A-A")) {fluxType=1;}
+  AliTPCRecoParam * tpcRecoParam = (AliTPCRecoParam*)array->At(fluxType);
+  printf("beam type: %s, using fluxType=%i\n",beamType.Data(),fluxType);
+  tpcRecoParam->Print();
 
   transform->SetCurrentRecoParam(tpcRecoParam);
   // in CPass1 use a default setting
index cf9a229b27079111465f405dc3a8b8f133666b9c..8c9c4132399743bc5f3ea1bdb0cc4605da92363d 100644 (file)
 
 void recCPass1(const char *filename="raw.root",Int_t nevents=-1, const char *ocdb="raw://", const char* options="?Trigger=kCalibBarrel")
 {
+  if (gSystem->Getenv("ALIROOT_FORCE_COREDUMP"))
+  {
+    printf("ALIROOT_FORCE_COREDUMP set\n");
+    gSystem->ResetSignal(kSigFloatingException);
+    gSystem->ResetSignal(kSigSegmentationViolation);
+  }
+
   // Load some system libs for Grid and monitoring
   // Set the CDB storage location
   AliCDBManager * man = AliCDBManager::Instance();
index 590ba71320bb2a3ff1db99712e9cd5d71c04af85..f5cdd9a65d7f940e38debde54f6f54e82017170a 100755 (executable)
@@ -140,8 +140,6 @@ if [ $exitcode -ne 0 ]; then
     exit $exitcode
 fi
 
-mv AliESDs.root ../AliESDs_Barrel.root
-mv AliESDfriends.root ../AliESDfriends_Barrel.root
 mv syswatch.log ../syswatch_rec_Barrel.log
 
 echo "* Running AliRoot to make calibration..."
@@ -155,7 +153,6 @@ if [ $exitcode -ne 0 ]; then
     exit $exitcode
 fi
 
-mv AliESDfriends_v1.root ../
 mv syswatch.log ../syswatch_calib.log
 
 if [ -f QAtrain_duo.C ]; then
@@ -176,7 +173,10 @@ if [ -f QAtrain_duo.C ]; then
     done
 fi
 
-for file in QAresults_barrel.root EventStat_temp_barrel.root AODtpITS.root; do
+mv AliESDs.root ../AliESDs_Barrel.root
+mv AliESDfriends.root ../AliESDfriends_Barrel.root
+
+for file in AliESDfriends_v1.root QAresults_barrel.root EventStat_temp_barrel.root AODtpITS.root; do
     if [ -f "$file" ]; then
         mv "$file" ../
     fi
diff --git a/PWGPP/TPC/macros/CalibSummary.C b/PWGPP/TPC/macros/CalibSummary.C
new file mode 100644 (file)
index 0000000..934cd80
--- /dev/null
@@ -0,0 +1,16 @@
+// Macro to extract calibration summary information
+// ConfigOCDB.C  macro has to be present in working directory
+//
+void CalibSummary(Int_t irun, const char* ocdbStorage){
+  //
+  //
+  //
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libTPCcalib");  
+  gROOT->LoadMacro("$ALICE_ROOT/PWGPP/TPC/macros/ConfigOCDB.C");
+  ConfigOCDB(irun,ocdbStorage);  
+  AliTPCcalibSummary *calibSummary = new AliTPCcalibSummary;
+  calibSummary->ProcessRun(irun);
+  delete calibSummary;
+}
+  
index e614598b35ccee80de12715c33ea7ac92284e76c..3c76c086c0784472a43223d2a9032e8a94746b25 100644 (file)
@@ -28,6 +28,12 @@ void ConfigOCDB(Int_t run, const char *ocdb="raw://") {
       printf("Problem with magnetic field setup\n"); 
     }
   }
+  if ( !TGeoGlobalMagField::Instance()->GetField()){
+    AliMagF::BMap_t smag = AliMagF::k5kG;
+    Double_t bzfac = 1;
+    AliMagF* magF= new AliMagF("Maps","Maps", bzfac, 1., smag);
+    TGeoGlobalMagField::Instance()->SetField(magF);
+  }
 
   // geometry
   printf("Loading geometry...\n");
@@ -35,5 +41,10 @@ void ConfigOCDB(Int_t run, const char *ocdb="raw://") {
   if( !AliGeomManager::ApplyAlignObjsFromCDB("GRP ITS TPC") ) {
     printf("Problem with align objects\n"); 
   }
-
+  
+  if (gSystem->AccessPathName("localOCDBaccessConfig.C", kFileExists)==0) {        
+    printf("loading localOCDBaccessConfig.C\n");
+    gROOT->LoadMacro("localOCDBaccessConfig.C");
+    localOCDBaccessConfig();
+  }
 }
diff --git a/PWGPP/TPC/macros/filterPIDSelected.C b/PWGPP/TPC/macros/filterPIDSelected.C
new file mode 100644 (file)
index 0000000..8c54362
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+  Macro to make additional filter of the V0 to select clean sample of identified particles.
+  As an input the   
+
+  .x $HOME/rootlogon.C   
+  .L $ALICE_ROOT/PWGPP/TPC/macros/filterPIDSelected.C+
+
+ */
+
+
+
+
+
+#include "TFile.h"
+#include "TTree.h"
+#include "TVectorD.h"
+#include "TMatrixD.h"
+#include "TH2.h"
+#include "TF1.h"
+#include "TTreeStream.h"
+#include "AliMathBase.h"
+#include "TSystem.h"
+#include "TChain.h"
+#include "TDatabasePDG.h"
+#include "TRandom.h"
+#include "AliTPCcalibBase.h"
+#include "TCanvas.h"
+#include "TLegend.h"
+//
+#include "AliESDv0.h"
+#include "AliESDtrack.h"
+#include "TMath.h"
+#include "AliXRDPROOFtoolkit.h"
+#include "TStatToolkit.h"
+#include "TCut.h"
+
+TTree * tree  = 0;
+TTreeSRedirector *pcstream = 0; //new TTreeSRedirector("trend.root");
+//
+
+
+void filterPIDSelected( const char * chfinput="highptAll.list"){
+  //
+  // Code to select identified V0 for the PID 
+  // As an input chain of filter trees is used
+  // Parameter:
+  //   finput - name of the list file or the name of file itself
+  // Oputput:
+  //   file - V0Selected.root
+  //
+  //
+  TTree * chain  = 0;  
+  if (TString(chfinput).Contains(".list")) {
+    chain = AliXRDPROOFtoolkit::MakeChainRandom(chfinput,"V0s",0,1000);
+  }else{
+    TFile * finput= TFile::Open(chfinput);
+    if (!finput) finput= TFile::Open(TString::Format("%s#FilterEvents_Trees.root",finput));
+    chain=(TTree*)finput->Get("V0s");
+  }  
+  chain->SetCacheSize(1000000000);
+  //
+  TDatabasePDG pdg;
+  Double_t massLambda = pdg.GetParticle("Lambda0")->Mass();
+  Double_t massK0 = pdg.GetParticle("K0")->Mass();
+  Double_t massPion = pdg.GetParticle("pi+")->Mass();
+  Double_t massProton = pdg.GetParticle("proton")->Mass();
+  //
+  //
+  chain->SetAlias("massPion",Form("(%f+0)",massPion));
+  chain->SetAlias("massProton",Form("(%f+0)",massProton));
+  chain->SetAlias("massK0",Form("(%f+0)",massK0));
+  chain->SetAlias("massLambda",Form("(%f+0)",massLambda));
+  // delta of mass
+  chain->SetAlias("K0Delta","(v0.GetEffMass(2,2)-massK0)");
+  chain->SetAlias("LDelta","(v0.GetEffMass(4,2)-massLambda)");
+  chain->SetAlias("ALDelta","(v0.GetEffMass(2,4)-massLambda)");
+  chain->SetAlias("EDelta","(v0.GetEffMass(0,0))");
+  // pull of the mass
+  chain->SetAlias("K0Pull","(v0.GetEffMass(2,2)-massK0)/v0.GetKFInfo(2,2,1)");
+  chain->SetAlias("LPull","(v0.GetEffMass(4,2)-massLambda)/v0.GetKFInfo(4,2,1)");
+  chain->SetAlias("ALPull","(v0.GetEffMass(2,4)-massLambda)/v0.GetKFInfo(2,4,1)");
+  chain->SetAlias("EPull","EDelta/v0.GetKFInfo(0,0,1)");
+  // effective pull of the mass - (empirical values form fits)
+  chain->SetAlias("K0PullEff","K0Delta/sqrt((3.63321e-03)**2+(5.68795e-04*v0.Pt())**2)");
+  chain->SetAlias("LPullEff","LDelta/sqrt((1.5e-03)**2+(1.8e-04*v0.Pt())**2)");
+  chain->SetAlias("ALPullEff","ALDelta/sqrt((1.5e-03)**2+(1.8e-04*v0.Pt())**2)");
+  chain->SetAlias("EPullEff","v0.GetEffMass(0,0)/sqrt((5e-03)**2+(1.e-04*v0.Pt())**2)");
+  //
+  //
+  chain->SetAlias("dEdx0DProton","AliMathBase::BetheBlochAleph(track0.fIp.P()/massProton)");
+  chain->SetAlias("dEdx1DProton","AliMathBase::BetheBlochAleph(track1.fIp.P()/massProton)");
+  chain->SetAlias("dEdx0DPion","AliMathBase::BetheBlochAleph(track0.fIp.P()/massPion)");
+  chain->SetAlias("dEdx1DPion","AliMathBase::BetheBlochAleph(track1.fIp.P()/massPion)");
+  //
+  // V0 - cuts -PID, 
+  //   
+  chain->SetAlias("cutDist","sqrt((track0.fIp.fP[0]-track1.fIp.fP[0])**2+(track0.fIp.fP[1]-track1.fIp.fP[1])**2)>3");
+  chain->SetAlias("cutLong","track0.GetTPCClusterInfo(3,1,0)-5*abs(track0.fP[4])>130&&track1.GetTPCClusterInfo(3,1,0)>130-5*abs(track0.fP[4])");
+  chain->SetAlias("cutPID","track0.fTPCsignal>0&&track1.fTPCsignal>0");
+  chain->SetAlias("cutResol","sqrt(track0.fC[14]/track0.fP[4])<0.15&&sqrt(track1.fC[14]/track1.fP[4])<0.15");
+  chain->SetAlias("cutV0","cutPID&&cutDist&&cutLong&&cutResol");       
+  //
+  //  
+  chain->SetAlias("K0Selected",      "abs(K0Pull)<3. &&abs(K0PullEff)<3.  && abs(LPull)>3  && abs(ALPull)>3  &&v0.PtArmV0()>0.11"); 
+  chain->SetAlias("LambdaSelected",  "abs(LPull)<3.  &&abs(LPullEff)<3.   && abs(K0Pull)>3 && abs(EPull)>3 && abs(EDelta)>0.05");  
+  chain->SetAlias("ALambdaSelected", "abs(ALPull)<3. &&abs(ALPullEff)<3   && abs(K0Pull)>3 && abs(EPull)>3 &&abs(EDelta)>0.05");
+  //
+  chain->SetAlias("GammaSelected", "abs(EPull)<3     && abs(K0Pull)>3 && abs(LPull)>3 && abs(ALPull)>3");
+  //
+  //
+  TFile *fselected = TFile::Open("V0Selected.root","recreate");
+  TTree * treeK0     =   chain->CopyTree("type==8&&cutV0&&K0Selected");
+  TTree * treeLambda =   chain->CopyTree("type==4&&cutV0&&LambdaSelected");
+  TTree * treeALambda =   chain->CopyTree("type==2&&cutV0&&ALambdaSelected");
+  TTree * treeGamma =   chain->CopyTree("type==1&&cutV0&&GammaSelected");
+  //
+  TTree * trees[4]={treeK0,treeLambda, treeGamma,treeALambda};
+  TList * aliases = chain->GetListOfAliases();
+  Int_t nalias= aliases->GetEntries();
+
+  for (Int_t i=0; i<4; i++){
+    for (Int_t ialias=0; ialias<nalias; ialias++){
+      TNamed *alias = (TNamed*)aliases->At(ialias);
+      trees[i]->SetAlias(alias->GetName(),alias->GetTitle());
+    }
+  }  
+  treeK0->Write("treeK0");
+  treeLambda->Write("treeLambda");
+  treeALambda->Write("treeALambda");
+  treeGamma->Write("treeGamma");
+  fselected->Close();
+  //
+}
+
+
+void FitPIDNCLSelected(){
+  //
+  // fit the probability to find the cluster
+  //
+  Int_t kmarkers[5]={20,21,25,24,22};
+  Int_t kcolors[5]={1,2,4,5,7};
+  const char *chname[5]={"Proton","Pion","Electron"};
+
+  TFile f("V0Selected.root");
+  TTree * treeLambda = (TTree*)f.Get("treeLambda"); 
+  TTree * treeK0 = (TTree*)f.Get("treeK0"); 
+  TTree * treeGamma = (TTree*)f.Get("treeGamma"); 
+  //
+  //
+  TH2 *his3D=0;
+  TObjArray  fitArray(3); 
+  TH1D * hisNcldEdx[3]={0,0,0};
+  TCut cutOut="abs(track0.fP[4])<2";
+  treeLambda->Draw("(1-track0.GetTPCClusterInfo(2,0)):sqrt(1+track0.fP[3]**2)*AliMathBase::BetheBlochAleph(track0.fIp.P()/massProton)>>hisNclProton(50,1,2.)",cutOut,"prof");
+  hisNcldEdx[0]=(TH1D*)treeLambda->GetHistogram()->Clone();
+  treeK0->Draw("(1-track0.GetTPCClusterInfo(2,0)):sqrt(1+track0.fP[3]**2)*AliMathBase::BetheBlochAleph(track0.fIp.P()/massPion)>>hisNclPion(50,1,2.)",cutOut,"prof");
+  hisNcldEdx[1]=(TH1D*)treeK0->GetHistogram()->Clone();
+  treeGamma->Draw("(1-track0.GetTPCClusterInfo(2,0)):sqrt(1+track0.fP[3]**2)*AliMathBase::BetheBlochAleph(track0.fIp.P()/0.0005)>>hisNclPion(50,1,2.5)",cutOut,"prof");
+  hisNcldEdx[2]=(TH1D*)treeGamma->GetHistogram()->Clone();
+
+  TF1 fnclQ("fnclQ","[0]+[1]*exp(-[2]*abs(x))");
+  fnclQ.SetParameters(0.02,5,3);
+  hisNcldEdx[0]->Fit(&fnclQ);
+  hisNcldEdx[1]->Fit(&fnclQ);
+  //hisNcldEdx[2]->Fit(&fnclQ);
+
+  TCanvas * canvas = new TCanvas("canvasNCL0","canvasNCL0",600,500);
+  TLegend *legend = new TLegend(0.5,0.6,0.89,0.89,"Cluster finder eff.");
+  legend->SetBorderSize(0);
+  for (Int_t i=0; i<3; i++){
+    hisNcldEdx[i]->SetMinimum(0);
+    hisNcldEdx[i]->SetMaximum(0.3);
+    hisNcldEdx[i]->SetMarkerColor(kcolors[i]);
+    hisNcldEdx[i]->SetMarkerStyle(kmarkers[i]);
+    hisNcldEdx[i]->GetXaxis()->SetTitle("Q ~ #sqrt{1+tan(#theta)^2}dE/dx");
+    hisNcldEdx[i]->GetYaxis()->SetTitle("p_{cl}");
+    if (i==0)hisNcldEdx[i]->Draw("");
+    hisNcldEdx[i]->Draw("same");
+    legend->AddEntry(hisNcldEdx[i],chname[i]);
+  }
+  legend->Draw();
+  
+}
index c1ef924418cee786a4906e33ce825ddafaac25d9..8fbb981da73c1e37b5249b9f17b31837ca954533 100644 (file)
@@ -2,7 +2,7 @@
 #
 # Author: Johny Jose m(johny.jose@cern.ch)
 #         Port of previous Makefile build to cmake
-
+#
 cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
 
 file(GLOB PACKAGES CMake*.pkg)
diff --git a/STAT/Macros/TStatToolkitTest.C b/STAT/Macros/TStatToolkitTest.C
new file mode 100644 (file)
index 0000000..d167948
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+  .L $ALICE_ROOT/STAT/Macros/TStatToolkitTest.C+
+
+*/
+
+#include "TH1.h"
+#include "TF1.h"
+#include "TMath.h"
+#include "TRandom.h"
+#include "TVectorD.h"
+#include "TStatToolkit.h"
+#include "TTreeStream.h"
+#include "TLegend.h"
+#include "TGraphErrors.h"
+#include "TCut.h"
+#include "TCanvas.h"
+
+TObjArray arrayFit(3);
+Int_t kMarkers[10]={25,24,20,21};
+Int_t kColors[10]={1,2,4,3};
+const char * names[10] = {"LTM","LThisto","LTMhisto1"};
+const char * distNames[10] = {"Gauss","Gauss+flat","Gauss(m)+0.2*Gauss(m+5#sigma)","Gauss(m)+0.3*Gauss(m+3#sigma)"};
+
+
+void TestLTM(Int_t nevents=10000){
+  //
+  // Goal test and benchamerk numerical stability and precission of the LTM method
+  // Binned data and not binned data: 
+  // Here we assume that binwidth<sigma
+  // Distribution types examples used in test:
+  //
+  //   0 - gaussian
+  //   1 - gauss+uniform background
+  //   2 - gauss+second gaus 5 sigma away 
+  //   
+  Int_t npointsMax=1000;
+  TTreeSRedirector * pcstream = new TTreeSRedirector("TStatToolkit_LTMtest.root","recreate");
+  //
+  TVectorD values(npointsMax);
+  TVectorD vecLTM(6);
+  TVectorD meanLTM(6);
+  TVectorD sigmaLTM(6);
+  TVectorD meanLTMHisto(6);
+  TVectorD sigmaLTMHisto(6);
+  TVectorD meanLTMHisto1(6);
+  TVectorD sigmaLTMHisto1(6);
+  TVectorD paramLTM(10);
+  //
+  for (Int_t iltm=0; iltm<6; iltm++) vecLTM[iltm]=0.99999*(0.5+iltm/10.);
+  TF1 fg("fg","gaus");
+  for (Int_t ievent = 0; ievent<nevents; ievent++){
+    if (ievent%1000==0) printf("%d\n",ievent);
+    Int_t distType=Int_t(gRandom->Rndm()*4);
+    Int_t npoints= 50+(npointsMax-50)*gRandom->Rndm();
+    Double_t mean  = 0.5+(gRandom->Rndm()-0.5)*0.2;
+    Double_t sigma = mean*0.2*(1+2*gRandom->Rndm());
+    TH1F histo("histo","histo",100,-0.5,1.5);
+    //
+    for (Int_t ipoint=0; ipoint<npoints; ipoint++){
+      Double_t value=0;
+      if (distType==0) value=gRandom->Gaus(mean,sigma); // gauss
+      if (distType==1) {
+       if (gRandom->Rndm()>0.2) {                     //  gauss + background
+         value=gRandom->Gaus(mean,sigma);
+       }else{
+         value=mean+(gRandom->Rndm()-0.5)*2;
+       }
+      }
+      if (distType==2) {
+       if (gRandom->Rndm()>0.2) {                     //  gauss + second gaus 5 sigma away
+         value=gRandom->Gaus(mean,sigma);
+       }else{
+         value=gRandom->Gaus(mean+5*sigma,sigma);
+       }
+      }
+      if (distType==3) {
+       if (gRandom->Rndm()>0.3) {                     //  gauss + second gaus 4 sigma away
+         value=gRandom->Gaus(mean,sigma);
+       }else{
+         value=gRandom->Gaus(mean+5*sigma,sigma);
+       }
+      }
+      values[ipoint]=value;
+      histo.Fill(value);
+    }
+    //
+    histo.Fit(&fg,"QN","QN");
+    Double_t meanG = fg.GetParameter(1);
+    Double_t rmsG = fg.GetParameter(2);
+    Double_t meanA  = TMath::Mean(npoints,values.GetMatrixArray());
+    Double_t rmsA   = TMath::Mean(npoints,values.GetMatrixArray());
+    Double_t meanH  = histo.GetMean();
+    Double_t rmsH  = histo.GetRMS();
+    //
+    for (Int_t iltm=0; iltm<6; iltm++){
+      //    
+      Double_t meanV,sigmaV=0;
+      TStatToolkit::EvaluateUni(npoints,values.GetMatrixArray(), meanV,sigmaV, vecLTM[iltm]*npoints);
+      meanLTM[iltm]=meanV;
+      sigmaLTM[iltm]=sigmaV;
+      //
+      TStatToolkit::LTM(&histo, &paramLTM,  vecLTM[iltm]);
+      meanLTMHisto1[iltm]=paramLTM[1];
+      sigmaLTMHisto1[iltm]=paramLTM[2];
+      //
+      TStatToolkit::LTMHisto(&histo, paramLTM,  vecLTM[iltm]);
+      meanLTMHisto[iltm]=paramLTM[1];
+      sigmaLTMHisto[iltm]=paramLTM[2];
+    }
+    (*pcstream)<<"ltm"<<
+      //Input
+      "npoints="<<npoints<<
+      "distType="<<distType<<
+      "mean="<<mean<<
+      "sigma="<<sigma<<
+      // "Standart" statistic output
+      "meanA="<<meanA<<
+      "rmsA="<<rmsA<<
+      "meanH="<<meanH<<
+      "rmsH="<<rmsH<<
+      "meanG="<<meanG<<
+      "rmsG="<<rmsG<<
+      // "LTM" output
+      "vecLTM.="<<&vecLTM<<
+      "meanLTM.="<<&meanLTM<<
+      "meanLTMHisto.="<<&meanLTMHisto<<
+      "meanLTMHisto1.="<<&meanLTMHisto1<<
+      //
+      "sigmaLTM.="<<&sigmaLTM<<
+      "sigmaLTMHisto.="<<&sigmaLTMHisto<<
+      "sigmaLTMHisto1.="<<&sigmaLTMHisto1<<      
+      "\n";
+  }
+  delete pcstream;
+  //
+  //
+  //
+  TFile *fltm = TFile::Open("TStatToolkit_LTMtest.root","update");
+  TTree * tree = (TTree*)fltm->Get("ltm");
+  tree->SetMarkerSize(0.5);
+  tree->SetMarkerStyle(25);
+  //
+  // 1. Get numerical error estimate of the LTM method for gaussian distribution  
+  //
+  TH2 * hisLTMTrunc[10]={0};  
+  TH1 * hisResol[10]={0};
+  TGraphErrors * grSigma[10]={0};
+  TCanvas *canvasLTM= new TCanvas("canvasLTM","canvasLTM",800,700);
+  canvasLTM->Divide(2,2);
+  for (Int_t itype=0; itype<4; itype++){
+    canvasLTM->cd(itype+1);
+    TCut cutType=TString::Format("distType==0%d",itype).Data();
+    tree->Draw("sqrt(npoints-2)*(meanLTM.fElements-mean)/sigma:vecLTM.fElements>>hisLTM(6,0.45,1.05,100,-10,10)",cutType+"npoints>50&&sigma>0.1","colzgof");
+    hisLTMTrunc[0]= (TH2*)(tree->GetHistogram()->Clone());
+    tree->Draw("sqrt(npoints-2)*(meanLTMHisto.fElements-mean)/sigma:vecLTM.fElements>>hisLTMHisto(6,0.45,1.05,100,-10,10)",cutType+"npoints>50&&sigma>0.1","colzgoff");
+    hisLTMTrunc[1]= (TH2*)tree->GetHistogram()->Clone();
+    tree->Draw("sqrt(npoints-2)*(meanLTMHisto1.fElements-mean)/sigma:vecLTM.fElements>>hisLTMHist1(6,0.45,1.05,100,-10,10)",cutType+"npoints>50&&sigma>0.1","colzgoff");
+    hisLTMTrunc[2]= (TH2*)tree->GetHistogram()->Clone();
+    TLegend * legend = new TLegend(0.5,0.7,0.9,0.9,distNames[itype]);
+    legend->SetBorderSize(0);
+    for (Int_t ihis=0; ihis<3; ihis++){
+      // MakeStat1D(TH2 * his, Int_t deltaBin, Double_t fraction, Int_t returnType, Int_t markerStyle, Int_t markerColor);
+      grSigma[ihis]=TStatToolkit::MakeStat1D( hisLTMTrunc[ihis],0,0.99,5,kMarkers[ihis],kColors[ihis]);
+      grSigma[ihis]->GetXaxis()->SetTitle("LTM fraction");
+      grSigma[ihis]->GetYaxis()->SetTitle("#sigma_{meas}/sigma_{gauss}");
+      if (ihis==0)grSigma[ihis]->Draw("alp");
+      if (ihis>0)grSigma[ihis]->Draw("lp");
+      legend->AddEntry(grSigma[ihis],names[ihis],"p");
+    }
+    legend->Draw();
+  }
+  canvasLTM->SaveAs("robustStatLTM_Performance.pdf");
+
+
+}
index 12763524c09c76ffb827121bd7595a7837cf2332..ec1ea5bbe500bf3ea0f9b3c648bc0d3595f65bf9 100644 (file)
@@ -19,8 +19,8 @@
 // 
 // Subset of  matheamtical functions  not included in the TMath
 //
-
-///////////////////////////////////////////////////////////////////////////
+//
+/////////////////////////////////////////////////////////////////////////
 #include "TMath.h"
 #include "Riostream.h"
 #include "TH1F.h"
@@ -38,7 +38,6 @@
 #include "TCanvas.h"
 #include "TLatex.h"
 #include "TCut.h"
-
 //
 // includes neccessary for test functions
 //
@@ -263,25 +262,37 @@ void TStatToolkit::TruncatedMean(const TH1 * his, TVectorD *param, Float_t down,
   if (verbose)  printf("Mean\t%f\t Sigma2\t%f\n", mean,sigma2);
 }
 
-void TStatToolkit::LTM(TH1F * his, TVectorD *param , Float_t fraction,  Bool_t verbose){
+void TStatToolkit::LTM(TH1 * his, TVectorD *param , Float_t fraction,  Bool_t verbose){
   //
-  // LTM
+  // LTM : Trimmed mean on histogram - Modified version for binned data
   //
+  // Robust statistic to estimate properties of the distribution
+  // See http://en.wikipedia.org/w/index.php?title=Trimmed_estimator&oldid=582847999
+  //
+  // New faster version is under preparation
+  //
+  if (!param) return;
+  (*param)[0]=0;
+  (*param)[1]=0;
+  (*param)[2]=0;  
   Int_t nbins    = his->GetNbinsX();
   Int_t nentries = (Int_t)his->GetEntries();
+  if (nentries<=0) return;
   Double_t *data  = new Double_t[nentries];
   Int_t npoints=0;
   for (Int_t ibin=1;ibin<nbins; ibin++){
-    Float_t entriesI = his->GetBinContent(ibin);
-    Float_t xcenter= his->GetBinCenter(ibin);
+    Double_t entriesI = his->GetBinContent(ibin);
+    //Double_t xcenter= his->GetBinCenter(ibin);
+    Double_t x0 =  his->GetXaxis()->GetBinLowEdge(ibin);
+    Double_t w  =  his->GetXaxis()->GetBinWidth(ibin);
     for (Int_t ic=0; ic<entriesI; ic++){
       if (npoints<nentries){
-       data[npoints]= xcenter;
+       data[npoints]= x0+w*Double_t((ic+0.5)/entriesI);
        npoints++;
       }
     }
   }
-  Double_t mean, sigma;
+  Double_t mean, sigma;  
   Int_t npoints2=TMath::Min(Int_t(fraction*Float_t(npoints)),npoints-1);
   npoints2=TMath::Max(Int_t(0.5*Float_t(npoints)),npoints2);
   TStatToolkit::EvaluateUni(npoints, data, mean,sigma,npoints2);
@@ -293,6 +304,149 @@ void TStatToolkit::LTM(TH1F * his, TVectorD *param , Float_t fraction,  Bool_t v
   }
 }
 
+
+void TStatToolkit::MedianFilter(TH1 * his1D, Int_t nmedian){
+  //
+  // Algorithm to filter  histogram
+  // author:  marian.ivanov@cern.ch
+  // Details of algorithm:
+  // http://en.wikipedia.org/w/index.php?title=Median_filter&oldid=582191524
+  // Input parameters:
+  //    his1D - input histogam - to be modiefied by Medianfilter
+  //    nmendian - number of bins in median filter
+  //
+  Int_t nbins    = his1D->GetNbinsX();
+  TVectorD vectorH(nbins);
+  for (Int_t ibin=0; ibin<nbins; ibin++) vectorH[ibin]=his1D->GetBinContent(ibin+1);
+  for (Int_t ibin=0; ibin<nbins; ibin++) {
+    Int_t index0=ibin-nmedian;
+    Int_t index1=ibin+nmedian;
+    if (index0<0) {index1+=-index0; index0=0;}
+    if (index1>=nbins) {index0-=index1-nbins+1; index1=nbins-1;}    
+    Double_t value= TMath::Median(index1-index0,&(vectorH.GetMatrixArray()[index0]));
+    his1D->SetBinContent(ibin+1, value);
+  }  
+}
+
+Bool_t TStatToolkit::LTMHisto(TH1 *his1D, TVectorD &params , Float_t fraction){
+  //
+  // LTM : Trimmed mean on histogram - Modified version for binned data
+  // 
+  // Robust statistic to estimate properties of the distribution
+  // To handle binning error special treatment
+  // for definition of unbinned data see:
+  //     http://en.wikipedia.org/w/index.php?title=Trimmed_estimator&oldid=582847999
+  //
+  // Function parameters:
+  //     his1D   - input histogram
+  //     params  - vector with parameters
+  //             - 0 - area
+  //             - 1 - mean
+  //             - 2 - rms 
+  //             - 3 - error estimate of mean
+  //             - 4 - error estimate of RMS
+  //             - 5 - first accepted bin position
+  //             - 6 - last accepted  bin position
+  //
+  Int_t nbins    = his1D->GetNbinsX();
+  Int_t nentries = (Int_t)his1D->GetEntries();
+  const Double_t kEpsilon=0.0000000001;
+
+  if (nentries<=0) return 0;
+  if (fraction>1) fraction=0;
+  if (fraction<0) return 0;
+  TVectorD vectorX(nbins);
+  TVectorD vectorMean(nbins);
+  TVectorD vectorRMS(nbins);
+  Double_t sumCont=0;
+  for (Int_t ibin0=1; ibin0<=nbins; ibin0++) sumCont+=his1D->GetBinContent(ibin0);
+  //
+  Double_t minRMS=his1D->GetRMS()*10000;
+  Int_t maxBin=0;
+  //
+  for (Int_t ibin0=1; ibin0<nbins; ibin0++){
+    Double_t sum0=0, sum1=0, sum2=0;
+    Int_t ibin1=ibin0;
+    for ( ibin1=ibin0; ibin1<nbins; ibin1++){
+      Double_t cont=his1D->GetBinContent(ibin1);
+      Double_t x= his1D->GetBinCenter(ibin1);
+      sum0+=cont;
+      sum1+=cont*x;
+      sum2+=cont*x*x;
+      if ( (ibin0!=ibin1) && sum0>=fraction*sumCont) break;
+    }
+    vectorX[ibin0]=his1D->GetBinCenter(ibin0);
+    if (sum0<fraction*sumCont) continue;
+    //
+    // substract fractions of bin0 and bin1 to keep sum0=fration*sumCont
+    //
+    Double_t diff = sum0-fraction*sumCont;
+    Double_t mean = sum1/sum0;
+    //
+    Double_t x0=his1D->GetBinCenter(ibin0);
+    Double_t x1=his1D->GetBinCenter(ibin1);
+    Double_t y0=his1D->GetBinContent(ibin0);
+    Double_t y1=his1D->GetBinContent(ibin1);
+    //
+    Double_t d = y0+y1-diff;    //enties to keep 
+    Double_t w0=0,w1=0;
+    if (y0<=kEpsilon&&y1>kEpsilon){
+      w1=d/y1;
+    } 
+    if (y1<=kEpsilon&&y0>kEpsilon){
+      w0=d/y0;
+    }
+    if (y0>kEpsilon && y1>kEpsilon && x1>x0  ){
+      w0 = (d*(x1-mean))/((x1-x0)*y0);
+      w1 = (d-y0*w0)/y1;
+      //
+      if (w0>1) {w1+=(w0-1)*y0/y1; w0=1;}
+      if (w1>1) {w0+=(w1-1)*y1/y0; w1=1;}
+    }  
+    if ( (x1>x0) &&TMath::Abs(y0*w0+y1*w1-d)>kEpsilon*sum0){
+      printf(" TStatToolkit::LTMHisto error\n");
+    }
+    sum0-=y0+y1;
+    sum1-=y0*x0;
+    sum1-=y1*x1;
+    sum2-=y0*x0*x0;
+    sum2-=y1*x1*x1;
+    //
+    Double_t xx0=his1D->GetXaxis()->GetBinUpEdge(ibin0)-0.5*w0*his1D->GetBinWidth(ibin0);
+    Double_t xx1=his1D->GetXaxis()->GetBinLowEdge(ibin1)+0.5*w1*his1D->GetBinWidth(ibin1);
+    sum0+=y0*w0+y1*w1;
+    sum1+=y0*w0*xx0;
+    sum1+=y1*w1*xx1;
+    sum2+=y0*w0*xx0*xx0;
+    sum2+=y1*w1*xx1*xx1;
+
+    //
+    // choose the bin with smallest rms
+    //
+    if (sum0>0){
+      vectorMean[ibin0]=sum1/sum0;
+      vectorRMS[ibin0]=TMath::Sqrt(TMath::Abs(sum2/sum0-vectorMean[ibin0]*vectorMean[ibin0]));
+      if (vectorRMS[ibin0]<minRMS){
+       minRMS=vectorRMS[ibin0];
+       params[0]=sum0;
+       params[1]=vectorMean[ibin0];
+       params[2]=vectorRMS[ibin0];
+       params[3]=vectorRMS[ibin0]/TMath::Sqrt(sumCont*fraction);
+       params[4]=0; // what is the formula for error of RMS???
+       params[5]=ibin0;
+       params[6]=ibin1;
+       params[7]=his1D->GetBinCenter(ibin0);
+       params[8]=his1D->GetBinCenter(ibin1);
+       maxBin=ibin0;
+      }
+    }else{
+      break;
+    }
+  }
+  return kTRUE;
+}
+
+
 Double_t  TStatToolkit::FitGaus(TH1* his, TVectorD *param, TMatrixD */*matrix*/, Float_t xmin, Float_t xmax, Bool_t verbose){
   //
   //  Fit histogram with gaussian function
@@ -583,7 +737,7 @@ void TStatToolkit::TestGausFit(Int_t nhistos){
   // ROOT gauss fit
   //  nhistos - number of histograms to be used for test
   //
-  TTreeSRedirector *pcstream = new TTreeSRedirector("fitdebug.root");
+  TTreeSRedirector *pcstream = new TTreeSRedirector("fitdebug.root","recreate");
   
   Float_t  *xTrue = new Float_t[nhistos];
   Float_t  *sTrue = new Float_t[nhistos];
@@ -609,7 +763,7 @@ void TStatToolkit::TestGausFit(Int_t nhistos){
     h1f[i]->FillRandom("myg");
   }
   
-  TStopwatch s;
+  TStopwatch s; 
   s.Start();
   //standard gaus fit
   for (Int_t i=0; i<nhistos; i++){
@@ -686,7 +840,7 @@ TGraph2D * TStatToolkit::MakeStat2D(TH3 * his, Int_t delta0, Int_t delta1, Int_t
       if (type==0) stat = projection->GetMean();
       if (type==1) stat = projection->GetRMS();
       if (type==2 || type==3){
-       TVectorD vec(3);
+       TVectorD vec(10);
        TStatToolkit::LTM((TH1F*)projection,&vec,0.7);
        if (type==2) stat= vec[1];
        if (type==3) stat= vec[0];      
@@ -703,45 +857,77 @@ TGraph2D * TStatToolkit::MakeStat2D(TH3 * his, Int_t delta0, Int_t delta1, Int_t
   return graph;
 }
 
-TGraph * TStatToolkit::MakeStat1D(TH3 * his, Int_t delta1, Int_t type){
-  //
-  //
-  //
-  // delta - number of bins to integrate
-  // type - 0 - mean value
-
+TGraphErrors * TStatToolkit::MakeStat1D(TH2 * his, Int_t deltaBin, Double_t fraction, Int_t returnType, Int_t markerStyle, Int_t markerColor){
+  //
+  // function to retrieve the "mean and RMS estimate" of 2D histograms
+  //     
+  // Robust statistic to estimate properties of the distribution
+  // See http://en.wikipedia.org/wiki/Trimmed_estimator
+  //
+  // deltaBin - number of bins to integrate (bin+-deltaBin)
+  // fraction - fraction of values for the LTM and for the gauss fit
+  // returnType - 
+  //        0 - mean value
+  //        1 - RMS
+  //        2 - LTM mean
+  //        3 - LTM sigma
+  //        4 - Gaus fit mean  - on LTM range
+  //        5 - Gaus fit sigma - on LTM  range
+  // 
   TAxis * xaxis  = his->GetXaxis();
-  TAxis * yaxis  = his->GetYaxis();
-  //  TAxis * zaxis  = his->GetZaxis();
   Int_t   nbinx  = xaxis->GetNbins();
-  Int_t   nbiny  = yaxis->GetNbins();
   char name[1000];
   Int_t icount=0;
-  TGraph  *graph = new TGraph(nbinx);
+  //
+  TVectorD vecX(nbinx);
+  TVectorD vecXErr(nbinx);
+  TVectorD vecY(nbinx);
+  TVectorD vecYErr(nbinx);
+  //
   TF1 f1("f1","gaus");
-  for (Int_t ix=0; ix<nbinx;ix++){
-    Float_t xcenter = xaxis->GetBinCenter(ix); 
-    //    Float_t ycenter = yaxis->GetBinCenter(iy); 
+  TVectorD vecLTM(10);
+
+  for (Int_t jx=1; jx<=nbinx;jx++){
+    Int_t ix=jx-1;
+    Float_t xcenter = xaxis->GetBinCenter(jx); 
     snprintf(name,1000,"%s_%d",his->GetName(), ix);
-    TH1 *projection = his->ProjectionZ(name,ix-delta1,ix+delta1,0,nbiny);
-    Float_t stat= 0;
-    if (type==0) stat = projection->GetMean();
-    if (type==1) stat = projection->GetRMS();
-    if (type==2 || type==3){
-      TVectorD vec(3);
-       TStatToolkit::LTM((TH1F*)projection,&vec,0.7);
-       if (type==2) stat= vec[1];
-       if (type==3) stat= vec[0];      
+    TH1 *projection = his->ProjectionY(name,TMath::Max(jx-deltaBin,1),TMath::Min(jx+deltaBin,nbinx));
+    Double_t stat= 0;
+    Double_t err =0;
+    TStatToolkit::LTMHisto((TH1F*)projection,vecLTM,fraction);  
+    //
+    if (returnType==0) {
+      stat = projection->GetMean();
+      err  = projection->GetMeanError();
     }
-    if (type==4|| type==5){
-      projection->Fit(&f1);
-      if (type==4) stat= f1.GetParameter(1);
-      if (type==5) stat= f1.GetParameter(2);
+    if (returnType==1) {
+      stat = projection->GetRMS();
+      err = projection->GetRMSError();
     }
-      //printf("%d\t%f\t%f\t%f\n", icount,xcenter, ycenter, stat);
-    graph->SetPoint(icount,xcenter, stat);
+    if (returnType==2 || returnType==3){
+      if (returnType==2) {stat= vecLTM[1];  err =projection->GetRMSError();}
+       if (returnType==3) {stat= vecLTM[2];     err =projection->GetRMSError();}
+    }
+    if (returnType==4|| returnType==5){
+      projection->Fit(&f1,"QN","QN", vecLTM[7], vecLTM[8]);
+      if (returnType==4) {
+       stat= f1.GetParameter(1);
+       err=f1.GetParError(1);
+      }
+      if (returnType==5) {
+       stat= f1.GetParameter(2);
+       err=f1.GetParError(2);
+      }
+    }
+    vecX[icount]=xcenter;
+    vecY[icount]=stat;
+    vecYErr[icount]=err;
     icount++;
+    delete projection;
   }
+  TGraphErrors  *graph = new TGraphErrors(icount,vecX.GetMatrixArray(), vecY.GetMatrixArray(),0, vecYErr.GetMatrixArray());
+  graph->SetMarkerStyle(markerStyle);
+  graph->SetMarkerColor(markerColor);
   return graph;
 }
 
index 06499d4f2ea93d7614ea63f3c02f1af17a32b9ae..a6c9205a15dead0b5b6ec90809ee9a02404a8987 100644 (file)
@@ -15,6 +15,7 @@
 
 class TH1F;
 class TH1;
+class TH2;
 class TH3;
 class TString;
 class TTree;
@@ -39,13 +40,16 @@ class TStatToolkit : public TObject
   // HISTOGRAMS TOOLS
   //
   static  void TruncatedMean(const TH1 * his, TVectorD *param, Float_t down=0, Float_t up=1.0, Bool_t verbose=kFALSE);
-  static void LTM(TH1F * his, TVectorD *param=0 , Float_t fraction=1,  Bool_t verbose=kFALSE);
+  static void MedianFilter(TH1 * his1D, Int_t nmedian);
+  static Bool_t  LTMHisto(TH1 * his, TVectorD &param , Float_t fraction=1);
+  //
+  static void LTM(TH1 * his, TVectorD *param=0 , Float_t fraction=1,  Bool_t verbose=kFALSE);
   static Double_t  FitGaus(TH1* his, TVectorD *param=0, TMatrixD *matrix=0, Float_t xmin=0, Float_t xmax=0,  Bool_t verbose=kFALSE);
   static Double_t  FitGaus(Float_t *arr, Int_t nBins, Float_t xMin, Float_t xMax, TVectorD *param=0, TMatrixD *matrix=0, Bool_t verbose=kFALSE);
   static Float_t  GetCOG(const Short_t *arr, Int_t nBins, Float_t xMin, Float_t xMax, Float_t *rms=0, Float_t *sum=0);
 
   static TGraph2D *  MakeStat2D(TH3 * his, Int_t delta0, Int_t delta1, Int_t type);
-  static TGraph *  MakeStat1D(TH3 * his, Int_t delta1, Int_t type);
+  static TGraphErrors *  MakeStat1D(TH2 * his, Int_t deltaBin, Double_t fraction, Int_t returnType, Int_t markerStyle, Int_t markerColor);
   //
   // Graph tools
   //
index aed5f6dfc447ec06e7f69104d50218cd361f4435..ebfedf74b65a6e9832184fa00a14a4ffcd7445d2 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "AliDCSSensor.h"
 #include "TDatime.h"
+#include "TCanvas.h"
 ClassImp(AliDCSSensor)
 
 const Double_t kSecInHour = 3600.; // seconds in one hour
@@ -78,10 +79,44 @@ AliDCSSensor& AliDCSSensor::operator=(const AliDCSSensor& source){
   return *this;
 }
 
+
+void AliDCSSensor::Print(const Option_t* option) const{
+  //
+  // print function
+  //  
+  TString opt = option; opt.ToLower();
+  printf("%s:%s\n",GetTitle(), GetName());
+  printf("%s\n",fStringID.Data());
+
+}
+
+void AliDCSSensor::Draw(Option_t* option) {
+  //
+  // draw function - to viusalize sensor
+  // Unfortuantelly - it  make a memory leak as function Draw does not return the object pointer
+  //
+  TCanvas * canvas = new TCanvas((fStringID+option).Data(), (fStringID+option).Data()); 
+  if (fGraph){
+    // transform points to time in s
+    Int_t npoints = fGraph->GetN();
+    for (Int_t i=0; i<npoints; i++){
+      fGraph->GetX()[i]=fGraph->GetX()[i]*3600+fStartTime;
+    }
+    fGraph->Draw("alp");
+    return;
+  }
+  canvas->cd();
+  TGraph * graph = MakeGraph(100);  // memory leak - we can not modify the content - const method
+  graph->Draw(option);              // 
+  //
+}
+
+
+
 //_____________________________________________________________________________
 Double_t AliDCSSensor::GetValue(UInt_t timeSec)
 {
- //
+ // 
  // Get DCS value for actual sensor
  //  timeSec given as offset from start-of-map measured in seconds
  //  *NOTE* In the current TPC setup, start-of-map is defined as the 
index 04849618caef64f996a53eb353a69e6e80151c15..5ba32dba6b811b98ea05fed50deb2bb5b9e5fe74 100644 (file)
@@ -35,11 +35,13 @@ public:
   AliDCSSensor(const AliDCSSensor& source);
   virtual ~AliDCSSensor(){}
   AliDCSSensor& operator=(const AliDCSSensor& source);
+  virtual void Print(const Option_t* option="") const;
+  virtual void Draw(Option_t* option="") ;
   
   Int_t       GetId()     const {return fId;     }
   Int_t       GetIdDCS()  const {return fIdDCS;     }
   const TString& GetStringID() const {return fStringID; }
-  
+
   Double_t    GetX()              const {return fX;      }
   Double_t    GetY()              const {return fY;      }
   Double_t    GetZ()              const {return fZ;      }
index 325050d5f021677c87f9e24bdbc50e8dccc0d023..12ada81e4a2d9222bd5d5d909083b9e4de5b9448 100644 (file)
@@ -189,6 +189,20 @@ AliDCSSensorArray &AliDCSSensorArray::operator=(const AliDCSSensorArray &c)
   return *this;
 }
 
+void AliDCSSensorArray::Print(const Option_t* option) const{
+  //
+  // print function overwriten
+  //
+  TString opt = option; opt.ToLower();
+  printf("%s:%s\n",GetTitle(), GetName());
+  if (!fSensors) return;
+  Int_t nsensors=fSensors->GetEntries();
+  for (Int_t i=0; i<nsensors; i++){
+    printf("Sensor Nr%d\n",i);
+    if (fSensors->At(i)) fSensors->At(i)->Print(option);
+  }
+}
+
 //____________________________________________________________________________
 
 void AliDCSSensorArray::SetGraph(TMap *map)
index dafc394162440a75d75bed7252bc613fc787a389..939aec3b8610f5bc0817bd314f9b1289d0bcd6a6 100644 (file)
@@ -32,6 +32,8 @@ class AliDCSSensorArray : public TNamed {
   AliDCSSensorArray(const AliDCSSensorArray &c);
   virtual ~AliDCSSensorArray();
   AliDCSSensorArray &operator=(const AliDCSSensorArray &c);
+  virtual void Print(const Option_t* option="") const;
+
   void SetStartTime (const TTimeStamp& start) { fStartTime = start; }
   void SetEndTime   (const TTimeStamp& end) { fEndTime = end; }
   TTimeStamp GetStartTime () const { return fStartTime; }
@@ -75,9 +77,9 @@ class AliDCSSensorArray : public TNamed {
 
   Int_t GetFirstIdDCS() const;
   Int_t GetLastIdDCS()  const;
+  const TClonesArray * GetArray(){return fSensors;}
 
-
- protected:
+ protected: 
   Int_t  fMinGraph;              // minimum #points of graph to be fitted
   Int_t  fMinPoints;             // minimum number of points per knot in fit
   Int_t  fIter;                  // number of iterations for spline fit
index 41280b36032d364bfb42e556befc360106f7600a..2f0477fe594909cb54dbb3f932d631da580c17d8 100644 (file)
@@ -28,23 +28,34 @@ ClassImp(AliESDfriend)
 
 AliESDfriend::AliESDfriend(): TObject(), fTracks("AliESDfriendTrack",1),
   fESDVZEROfriend(NULL),
-  fESDTZEROfriend(NULL)
-
+  fESDTZEROfriend(NULL),
+  fNclustersTPC(),
+  fNclustersTPCused()
 {
  //
  // Default constructor
  //
+  for (Int_t i=0;i<72;i++)
+  {
+    fNclustersTPC[i]=0;
+    fNclustersTPCused[i]=0;
+  }
 }
 
 AliESDfriend::AliESDfriend(const AliESDfriend &f) :
   TObject(f),
   fTracks(f.fTracks),
   fESDVZEROfriend(f.fESDVZEROfriend ? new AliESDVZEROfriend(*f.fESDVZEROfriend) : NULL),
-  fESDTZEROfriend(f.fESDTZEROfriend ? new AliESDTZEROfriend(*f.fESDTZEROfriend) : NULL)
+  fESDTZEROfriend(f.fESDTZEROfriend ? new AliESDTZEROfriend(*f.fESDTZEROfriend) : NULL),
+  fNclustersTPC(),
+  fNclustersTPCused()
 {
  //
  // Copy constructor
  //
+ memcpy(fNclustersTPC,f.fNclustersTPC,sizeof(fNclustersTPC));
+ memcpy(fNclustersTPCused,f.fNclustersTPCused,sizeof(fNclustersTPCused));
+
 }
 
 AliESDfriend& AliESDfriend::operator=(const AliESDfriend& esd)
@@ -61,6 +72,8 @@ AliESDfriend& AliESDfriend::operator=(const AliESDfriend& esd)
     delete fESDTZEROfriend;
     fESDTZEROfriend = new AliESDTZEROfriend(*esd.fESDTZEROfriend);
  
+    memcpy(fNclustersTPC,esd.fNclustersTPC,sizeof(fNclustersTPC));
+    memcpy(fNclustersTPCused,esd.fNclustersTPCused,sizeof(fNclustersTPCused));
  
  
     return *this;
index 498ce5f25b86e22178945b7be7d918d9b4a83cf0..2d3fdcb98dfb17d0d8b4d61d114cea0db0f4ef61 100644 (file)
@@ -49,12 +49,21 @@ public:
   void SetSkipBit(Bool_t skip){SetBit(23,skip);}
   Bool_t TestSkipBit() {return TestBit(23);}
 
+  //TPC cluster occupancy
+  Int_t GetNclustersTPC(UInt_t sector) const {return (sector<72)?fNclustersTPC[sector]:0;}
+  Int_t GetNclustersTPCused(UInt_t sector) const {return (sector<72)?fNclustersTPCused[sector]:0;}
+  void SetNclustersTPC(UInt_t sector, Int_t occupancy) {if (sector<72) fNclustersTPC[sector]=occupancy;}
+  void SetNclustersTPCused(UInt_t sector, Int_t occupancy) {if (sector<72) fNclustersTPCused[sector]=occupancy;}
+
 protected:
   TClonesArray fTracks;    // ESD friend tracks
   AliESDVZEROfriend *fESDVZEROfriend; // VZERO object containing complete raw data
   AliESDTZEROfriend *fESDTZEROfriend; // TZERO calibration object
+  
+  Int_t fNclustersTPC[72]; //cluster occupancy per sector per sector
+  Int_t fNclustersTPCused[72]; //number of clusters used in tracking per sector
 
-  ClassDef(AliESDfriend,3) // ESD friend
+  ClassDef(AliESDfriend,4) // ESD friend
 };
 
 #endif
index c7811aae037bf822badecfa2ffda8027028dc580..b19efbdf31362d62a3939d94675c5b4ebb7f7e33 100644 (file)
@@ -268,7 +268,7 @@ Double_t AliTrackerBase::MeanMaterialBudget(const Double_t *start, const Double_
 
 Bool_t 
 AliTrackerBase::PropagateTrackTo(AliExternalTrackParam *track, Double_t xToGo, 
-                                Double_t mass, Double_t maxStep, Bool_t rotateTo, Double_t maxSnp, Int_t sign, Bool_t addTimeStep){
+                                Double_t mass, Double_t maxStep, Bool_t rotateTo, Double_t maxSnp, Int_t sign, Bool_t addTimeStep, Bool_t correctMaterialBudget){
   //----------------------------------------------------------------
   //
   // Propagates the track to the plane X=xk (cm) using the magnetic field map 
@@ -291,33 +291,38 @@ AliTrackerBase::PropagateTrackTo(AliExternalTrackParam *track, Double_t xToGo,
     track->GetXYZ(xyz0);   //starting global position
 
     Double_t bz=GetBz(xyz0); // getting the local Bz
-
     if (!track->GetXYZAt(x,bz,xyz1)) return kFALSE;   // no prolongation
     xyz1[2]+=kEpsilon; // waiting for bug correction in geo
-
+    
     if (maxSnp>0 && TMath::Abs(track->GetSnpAt(x,bz)) >= maxSnp) return kFALSE;
     if (!track->PropagateTo(x,bz))  return kFALSE;
 
-    MeanMaterialBudget(xyz0,xyz1,param);       
-    Double_t xrho=param[0]*param[4], xx0=param[1];
-    if (sign) {if (sign<0) xrho = -xrho;}  // sign is imposed
-    else { // determine automatically the sign from direction
-      if (dir>0) xrho = -xrho; // outward should be negative
+    if (correctMaterialBudget){
+      MeanMaterialBudget(xyz0,xyz1,param);
+      Double_t xrho=param[0]*param[4], xx0=param[1];
+      if (sign) {if (sign<0) xrho = -xrho;}  // sign is imposed
+      else { // determine automatically the sign from direction
+        if (dir>0) xrho = -xrho; // outward should be negative
+      }
+      //
+      if (!track->CorrectForMeanMaterial(xx0,xrho,mass)) return kFALSE;
     }
-    //
-    if (!track->CorrectForMeanMaterial(xx0,xrho,mass)) return kFALSE;
+    
     if (rotateTo){
       track->GetXYZ(xyz1);   // global position
       Double_t alphan = TMath::ATan2(xyz1[1], xyz1[0]); 
       if (maxSnp>0) {
        if (TMath::Abs(track->GetSnp()) >= maxSnp) return kFALSE;
+        
        //
        Double_t ca=TMath::Cos(alphan-track->GetAlpha()), sa=TMath::Sin(alphan-track->GetAlpha());
        Double_t sf=track->GetSnp(), cf=TMath::Sqrt((1.-sf)*(1.+sf));
        Double_t sinNew =  sf*ca - cf*sa;
-       if (TMath::Abs(sinNew) >= maxSnp) return kFALSE;
+        if (TMath::Abs(sinNew) >= maxSnp) return kFALSE;
+        
       }
       if (!track->AliExternalTrackParam::Rotate(alphan)) return kFALSE;
+      
     }
     xpos = track->GetX();
     if (addTimeStep && track->IsStartedTimeIntegral()) {
@@ -334,6 +339,78 @@ AliTrackerBase::PropagateTrackTo(AliExternalTrackParam *track, Double_t xToGo,
   return kTRUE;
 }
 
+Int_t AliTrackerBase::PropagateTrackTo2(AliExternalTrackParam *track, Double_t xToGo,
+                                        Double_t mass, Double_t maxStep, Bool_t rotateTo, Double_t maxSnp, Int_t sign, Bool_t addTimeStep, Bool_t correctMaterialBudget){
+  //----------------------------------------------------------------
+  //
+  // Propagates the track to the plane X=xk (cm) using the magnetic field map
+  // and correcting for the crossed material.
+  //
+  // mass     - mass used in propagation - used for energy loss correction
+  // maxStep  - maximal step for propagation
+  //
+  //  Origin: Marian Ivanov,  Marian.Ivanov@cern.ch
+  //
+  //----------------------------------------------------------------
+  const Double_t kEpsilon = 0.00001;
+  Double_t xpos     = track->GetX();
+  Int_t dir         = (xpos<xToGo) ? 1:-1;
+  //
+  while ( (xToGo-xpos)*dir > kEpsilon){
+    Double_t step = dir*TMath::Min(TMath::Abs(xToGo-xpos), maxStep);
+    Double_t x    = xpos+step;
+    Double_t xyz0[3],xyz1[3],param[7];
+    track->GetXYZ(xyz0);   //starting global position
+    
+    Double_t bz=GetBz(xyz0); // getting the local Bz
+    if (!track->GetXYZAt(x,bz,xyz1)) return -1;   // no prolongation
+    xyz1[2]+=kEpsilon; // waiting for bug correction in geo
+    
+    if (maxSnp>0 && TMath::Abs(track->GetSnpAt(x,bz)) >= maxSnp) return -2;
+    if (!track->PropagateTo(x,bz))  return -3;
+    
+    if (correctMaterialBudget){
+      MeanMaterialBudget(xyz0,xyz1,param);
+      Double_t xrho=param[0]*param[4], xx0=param[1];
+      if (sign) {if (sign<0) xrho = -xrho;}  // sign is imposed
+      else { // determine automatically the sign from direction
+        if (dir>0) xrho = -xrho; // outward should be negative
+      }
+      //
+      if (!track->CorrectForMeanMaterial(xx0,xrho,mass)) return -4;
+    }
+    
+    if (rotateTo){
+      track->GetXYZ(xyz1);   // global position
+      Double_t alphan = TMath::ATan2(xyz1[1], xyz1[0]);
+      if (maxSnp>0) {
+        if (TMath::Abs(track->GetSnp()) >= maxSnp) return -5;
+        
+        //
+        Double_t ca=TMath::Cos(alphan-track->GetAlpha()), sa=TMath::Sin(alphan-track->GetAlpha());
+        Double_t sf=track->GetSnp(), cf=TMath::Sqrt((1.-sf)*(1.+sf));
+        Double_t sinNew =  sf*ca - cf*sa;
+        if (TMath::Abs(sinNew) >= maxSnp) return -6;
+        
+      }
+      if (!track->AliExternalTrackParam::Rotate(alphan)) return -7;
+      
+    }
+    xpos = track->GetX();
+    if (addTimeStep && track->IsStartedTimeIntegral()) {
+      if (!rotateTo) track->GetXYZ(xyz1); // if rotateTo==kTRUE, then xyz1 is already extracted
+      Double_t dX=xyz0[0]-xyz1[0],dY=xyz0[1]-xyz1[1],dZ=xyz0[2]-xyz1[2];
+      Double_t d=TMath::Sqrt(dX*dX + dY*dY + dZ*dZ);
+      if (sign) {if (sign>0) d = -d;}  // step sign is imposed, positive means inward direction
+      else { // determine automatically the sign from direction
+        if (dir<0) d = -d;
+      }
+      track->AddTimeStep(d);
+    }
+  }
+  return 1;
+}
+
 Bool_t 
 AliTrackerBase::PropagateTrackToBxByBz(AliExternalTrackParam *track,
                                       Double_t xToGo,Double_t mass, Double_t maxStep, Bool_t rotateTo, Double_t maxSnp,Int_t sign, Bool_t addTimeStep){
@@ -487,13 +564,18 @@ Double_t AliTrackerBase::MakeTgl(Double_t x1,Double_t y1,
   // Initial approximation of the tangent of the track dip angle
   //-----------------------------------------------------------------
   //
+  const Double_t kEpsilon =0.00001;
   x2-=x1;
   y2-=y1;
   z2-=z1;
   Double_t d  =  TMath::Sqrt(x2*x2+y2*y2);  // distance  straight line
   if (TMath::Abs(d*c*0.5)>1) return 0;
   Double_t   angle2    = TMath::ASin(d*c*0.5); 
-  angle2  = z2*TMath::Abs(c/(angle2*2.));
+  if (TMath::Abs(angle2)>kEpsilon)  {
+    angle2  = z2*TMath::Abs(c/(angle2*2.));
+  }else{
+    angle2=z2/d;
+  }
   return angle2;
 }
 
index 5217b99c0dfb26ac33b596132b9f5b9cbe5117c2..ff62e2edff0a8a93350adfc1850a780e7b747eff 100644 (file)
@@ -46,7 +46,9 @@ public:
   Double_t *mparam);
   static
   Bool_t PropagateTrackTo(AliExternalTrackParam *track, Double_t x, Double_t m,
-                         Double_t maxStep, Bool_t rotateTo=kTRUE, Double_t maxSnp=0.8, Int_t sign=0, Bool_t addTimeStep=kFALSE);  
+                          Double_t maxStep, Bool_t rotateTo=kTRUE, Double_t maxSnp=0.8, Int_t sign=0, Bool_t addTimeStep=kFALSE, Bool_t correctMaterialBudget=kTRUE);
+  static Int_t PropagateTrackTo2(AliExternalTrackParam *track, Double_t x, Double_t m,
+                          Double_t maxStep, Bool_t rotateTo=kTRUE, Double_t maxSnp=0.8, Int_t sign=0, Bool_t addTimeStep=kFALSE, Bool_t correctMaterialBudget=kTRUE);
   static Bool_t PropagateTrackToBxByBz(AliExternalTrackParam *track, Double_t x, 
                                       Double_t m,Double_t maxStep, Bool_t rotateTo=kTRUE, Double_t maxSnp=0.8,Int_t sign=0, Bool_t addTimeStep=kFALSE);  
   //
index 800ac0fa8ace064be5dc5dabe3ff1a6ae6c40dec..e9e8af953868a9e2af66c3e68de22a2c199b725a 100644 (file)
@@ -507,6 +507,7 @@ Bool_t AliExternalTrackParam::CorrectForMeanMaterial
   // "anglecorr" - switch for the angular correction
   // "Bethe" - function calculating the energy loss (GeV/(g/cm^2)) 
   //------------------------------------------------------------------
+
   Double_t bg=GetP()/mass;
   if (mass<0) {
     if (mass<-990) {
@@ -557,6 +558,7 @@ Bool_t AliExternalTrackParam::CorrectForMeanMaterialZA
     bg = -2*bg;
   }
   Double_t dEdx=BetheBlochGeant(bg,density,jp1,jp2,exEnergy,zOverA);
+
   if (mass<0) dEdx *= 4;
   return CorrectForMeanMaterialdEdx(xOverX0,xTimesRho,mass,dEdx,anglecorr);
 }
@@ -1810,6 +1812,7 @@ AliExternalTrackParam::GetZAt(Double_t x, Double_t b, Double_t &z) const {
   //---------------------------------------------------------------------
   Double_t dx=x-fX;
   if(TMath::Abs(dx)<=kAlmost0) {z=fP[1]; return kTRUE;}
+
   Double_t crv=GetC(b);
   Double_t x2r = crv*dx;
   Double_t f1=fP[2], f2=f1 + x2r;
@@ -1843,9 +1846,11 @@ AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r) const {
   //---------------------------------------------------------------------
   Double_t dx=x-fX;
   if(TMath::Abs(dx)<=kAlmost0) return GetXYZ(r);
+
   Double_t crv=GetC(b);
   Double_t x2r = crv*dx;
   Double_t f1=fP[2], f2=f1 + dx*crv;
+
   if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
   if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
   
@@ -1866,6 +1871,7 @@ AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r) const {
     double rot = 2*TMath::ASin(0.5*chord*crv); // angular difference seen from the circle center
     r[2] = fP[1] + rot/crv*fP[3];
   }
+
   return Local2GlobalPosition(r,fAlpha);
 }
 
@@ -2299,6 +2305,7 @@ void AliExternalTrackParam::CheckCovariance() {
   // This function forces the diagonal elements of the covariance matrix to be positive.
   // In case the diagonal element is bigger than the maximal allowed value, it is set to
   // the limit and the off-diagonal elements that correspond to it are set to zero.
+
   fC[0] = TMath::Abs(fC[0]);
   if (fC[0]>kC0max) {
     double scl = TMath::Sqrt(kC0max/fC[0]);
@@ -2513,7 +2520,6 @@ Bool_t AliExternalTrackParam::GetXatLabR(Double_t r,Double_t &x, Double_t bz, In
   //
   return kTRUE;
 }
-
 //_________________________________________________________
 Bool_t AliExternalTrackParam::GetXYZatR(Double_t xr,Double_t bz, Double_t *xyz, Double_t* alpSect) const
 {
@@ -2651,4 +2657,3 @@ Bool_t AliExternalTrackParam::GetXYZatR(Double_t xr,Double_t bz, Double_t *xyz,
   return kTRUE;  
   //
 }
-
index 547c4a9c346d1c9fa7496b8bbe34e3641e4920a8..16f334a5bc9f1df3bcdd9e03110978cfdc54b098 100644 (file)
 #include "AliVTrack.h"
 #include "AliTPCPIDResponse.h"
 #include "AliTPCdEdxInfo.h"
+#include "TFile.h"
+#include "TSpline.h"
 
 ClassImp(AliTPCPIDResponse);
 
+
+AliTPCPIDResponse *AliTPCPIDResponse::fgInstance =0;
+
 const char* AliTPCPIDResponse::fgkGainScenarioName[fgkNumberOfGainScenarios+1]=
 {
   "", //default - no name
@@ -94,6 +99,7 @@ AliTPCPIDResponse::AliTPCPIDResponse():
 
   
   ResetMultiplicityCorrectionFunctions();
+  fgInstance=this;
 }
 /*TODO remove?
 //_________________________________________________________________________
@@ -148,6 +154,7 @@ AliTPCPIDResponse::~AliTPCPIDResponse()
   
   delete fCorrFuncSigmaMultiplicity;
   fCorrFuncSigmaMultiplicity = 0x0;
+  if (fgInstance==this) fgInstance=0;
 }
 
 
@@ -1551,3 +1558,30 @@ Bool_t AliTPCPIDResponse::TrackApex(const AliVTrack* track, Float_t magField, Do
   position[2]=0.;
   return kTRUE;
 }
+
+Double_t AliTPCPIDResponse::EvaldEdxSpline(Double_t bg,Int_t entry){
+  //
+  // Evaluate the dEdx response for given entry
+  //
+  TSpline * spline = (TSpline*)fSplineArray.At(entry);
+  if (spline) return spline->Eval(bg);
+  return 0;
+}
+
+
+Bool_t   AliTPCPIDResponse::RegisterSpline(const char * name, Int_t index){
+  //
+  // register spline to be used for drawing comparisons
+  // 
+  TFile * fTPCBB = TFile::Open("$ALICE_ROOT/OADB/COMMON/PID/data/TPCPIDResponse.root");
+  TObjArray  *arrayTPCPID= (TObjArray*)  fTPCBB->Get("TPCPIDResponse");
+  if (fSplineArray.GetEntriesFast()<index) fSplineArray.Expand(index*2);
+  TSpline3 *spline=0;
+  if (arrayTPCPID){
+    spline = (TSpline3*)arrayTPCPID->FindObject(name);
+    if (spline) fSplineArray.AddAt(spline->Clone(),index);    
+  }
+  delete arrayTPCPID;
+  delete fTPCBB;
+  return (spline!=0);
+}
index e981afba31ac64f74519a12fc446567c3070bfe2..333ed2ddf8420531cfbf548606bf30bedf58f525 100644 (file)
@@ -216,6 +216,10 @@ public:
   Float_t  GetRes0(ETPCgainScenario s)  const { return fRes0[s];  }
   Float_t  GetResN2(ETPCgainScenario s) const { return fResN2[s]; }
 
+  Bool_t   RegisterSpline(const char * name, Int_t index);
+  Double_t EvaldEdxSpline(Double_t bg,Int_t entry);
+  static   Double_t SEvaldEdx(Double_t bg,Int_t entry){ return (fgInstance!=0)? fgInstance->EvaldEdxSpline(bg,entry):0;};
+
 protected:
   Double_t GetExpectedSignal(const AliVTrack* track,
                              AliPID::EParticleType species,
@@ -233,6 +237,15 @@ protected:
                             Bool_t correctEta,
                             Bool_t correctMultiplicity) const;
   
+  Double_t GetMultiplicityCorrection(const AliVTrack *track, const Double_t dEdxExpected, const Int_t multiplicity) const;
+  
+  Double_t GetMultiplicitySigmaCorrection(const Double_t dEdxExpected, const Int_t multiplicity) const;
+  
+  Double_t GetSigmaPar1(const AliVTrack *track, AliPID::EParticleType species,
+                        Double_t dEdx, const TSpline3* responseFunction) const;
+  //
+  // function for numberical debugging 0 registed splines can be used in the TFormula and tree visualizations
+  //
 private:
   Float_t fMIP;          // dEdx for MIP
   Float_t fRes0[fgkNumberOfGainScenarios];  // relative dEdx resolution  rel sigma = fRes0*sqrt(1+fResN2/npoint)
@@ -270,9 +283,14 @@ private:
   TF1* fCorrFuncMultiplicityTanTheta; //! Function to correct the additional tanTheta dependence of the multiplicity dependence of the TPC dEdx
   TF1* fCorrFuncSigmaMultiplicity; //! Function to correct for the multiplicity dependence of the TPC dEdx resolution
 
+  //
+  //
+  static AliTPCPIDResponse*   fgInstance;     //! Instance of this class (singleton implementation)
+  TObjArray                   fSplineArray;   //array of registered splines
   ClassDef(AliTPCPIDResponse,6)   // TPC PID class
 };
 
+
 #endif
 
 
index 28a53c6357ca05b764f207589bee3045833e2ccf..964a07f711ab911ec46bb0f9d628ab9eac740cde 100644 (file)
@@ -1,4 +1,6 @@
 #include "AliTPCdEdxInfo.h"
+#include "TObjArray.h"
+#include "TGraphErrors.h"
 
 //##################################################################
 //
 //
 //##################################################################
 
-
+TObjArray * AliTPCdEdxInfo::fArraySectorCalibration=0;
 
 ClassImp(AliTPCdEdxInfo)
 
 AliTPCdEdxInfo::AliTPCdEdxInfo():
   TObject(),
   fTPCsignalRegion(),
+  fTPCsignalRegionQmax(),
   fTPCsignalNRegion(),
   fTPCsignalNRowRegion()
 {
   // Default constructor
   for (Int_t i=0;i<3; i++){
     fTPCsignalRegion[i]=0;
+    fTPCsignalRegionQmax[i]=0;
     fTPCsignalNRegion[i]=0;
     fTPCsignalNRowRegion[i]=0;
   }
   fTPCsignalRegion[3]=0;
+  fTPCsignalRegionQmax[3]=0;
+  
 }
 
-AliTPCdEdxInfo::AliTPCdEdxInfo(const AliTPCdEdxInfo& source):   
-    TObject(),          
-    fTPCsignalRegion(),         
-    fTPCsignalNRegion(),        
-    fTPCsignalNRowRegion()      
-{       
-    //          
-    // copy constructor         
-    //          
-    Double32_t signal[4]; Char_t ncl[3]; Char_t nrows[3];       
-    source.GetTPCSignalRegionInfo(signal, ncl, nrows);          
-    for (Int_t i=0;i<3; i++){   
-       fTPCsignalRegion[i]=signal[i];   
-       fTPCsignalNRegion[i]=ncl[i];     
-       fTPCsignalNRowRegion[i]=nrows[i];        
-    }   
-    fTPCsignalRegion[3]=signal[3];      
-
+//_______________________________________________________________________________________________
+AliTPCdEdxInfo::AliTPCdEdxInfo(const AliTPCdEdxInfo& source):
+    TObject(),
+    fTPCsignalRegion(),
+    fTPCsignalRegionQmax(),
+    fTPCsignalNRegion(),
+    fTPCsignalNRowRegion()
+{
+    //
+    // copy constructor
+    //
+    for (Int_t i=0;i<3; i++){
+      fTPCsignalRegion[i]     = source.fTPCsignalRegion[i];
+      fTPCsignalRegionQmax[i] = source.fTPCsignalRegionQmax[i];
+      fTPCsignalNRegion[i]    = source.fTPCsignalNRegion[i];
+      fTPCsignalNRowRegion[i] = source.fTPCsignalNRowRegion[i];
+    }
+    fTPCsignalRegion[3]       = source.fTPCsignalRegion[3];
+    fTPCsignalRegionQmax[3]   = source.fTPCsignalRegionQmax[3];
+    
 }
 
-AliTPCdEdxInfo& AliTPCdEdxInfo::operator=(const AliTPCdEdxInfo& source)         
-{       
-    //          
-    // assignment operator      
+//_______________________________________________________________________________________________
+AliTPCdEdxInfo& AliTPCdEdxInfo::operator=(const AliTPCdEdxInfo& source)
+{
+    //
+    // assignment operator
     //
 
   if (&source == this) return *this;
   TObject::operator=(source);
 
-  Double32_t signal[4]; Char_t ncl[3]; Char_t nrows[3];         
-  source.GetTPCSignalRegionInfo(signal, ncl, nrows);    
-  for (Int_t i=0;i<3; i++){     
-    fTPCsignalRegion[i]=signal[i];      
-    fTPCsignalNRegion[i]=ncl[i];        
-    fTPCsignalNRowRegion[i]=nrows[i];   
-  }     
-  fTPCsignalRegion[3]=signal[3];
-
+  for (Int_t i=0;i<3; i++){
+    fTPCsignalRegion[i]     = source.fTPCsignalRegion[i];
+    fTPCsignalRegionQmax[i] = source.fTPCsignalRegionQmax[i];
+    fTPCsignalNRegion[i]    = source.fTPCsignalNRegion[i];
+    fTPCsignalNRowRegion[i] = source.fTPCsignalNRowRegion[i];
+  }
+  fTPCsignalRegion[3]       = source.fTPCsignalRegion[3];
+  fTPCsignalRegionQmax[3]   = source.fTPCsignalRegionQmax[3];
+  
   return *this;
 
 }
 
-void  AliTPCdEdxInfo::GetTPCSignalRegionInfo(Double32_t signal[4], Char_t ncl[3], Char_t nrows[3]) const {
+//_______________________________________________________________________________________________
+void  AliTPCdEdxInfo::GetTPCSignalRegionInfo(Double_t signal[4], Char_t ncl[3], Char_t nrows[3]) const {
   //
   // Get the TPC dEdx variables per region
   //
@@ -87,8 +96,20 @@ void  AliTPCdEdxInfo::GetTPCSignalRegionInfo(Double32_t signal[4], Char_t ncl[3]
   return; 
 }
 
+//_______________________________________________________________________________________________
+void  AliTPCdEdxInfo::GetTPCSignals(Double_t signal[4]) const {
+  //
+  // Set the TPC dEdx variables per region
+  //
+  // Double32_t  fTPCsignalRegionQmax[4]; // TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used)
+  //
+  for (Int_t i=0;i<4; i++){
+    signal[i]=fTPCsignalRegion[i];
+  }
+}
 
-void  AliTPCdEdxInfo::SetTPCSignalRegionInfo(Double32_t signal[4], Char_t ncl[3], Char_t nrows[3]){
+//_______________________________________________________________________________________________
+void  AliTPCdEdxInfo::SetTPCSignalRegionInfo(Double_t signal[4], Char_t ncl[3], Char_t nrows[3]){
   //
   // Set the TPC dEdx variables per region
   //
@@ -104,3 +125,107 @@ void  AliTPCdEdxInfo::SetTPCSignalRegionInfo(Double32_t signal[4], Char_t ncl[3]
   fTPCsignalRegion[3]=signal[3];
   return;
 }
+
+//_______________________________________________________________________________________________
+void  AliTPCdEdxInfo::SetTPCSignals(Double_t signal[4]){
+  //
+  // Set the TPC dEdx variables per region
+  //
+  // Double32_t  fTPCsignalRegionQmax[4]; // TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used)
+  //
+  for (Int_t i=0;i<4; i++){
+    fTPCsignalRegion[i]=signal[i];
+  }
+}
+
+//_______________________________________________________________________________________________
+void  AliTPCdEdxInfo::GetTPCSignalRegionInfoQmax(Double_t signal[4], Char_t ncl[3], Char_t nrows[3]) const {
+  //
+  // Get the TPC dEdx variables per region
+  //
+  // Double32_t  fTPCsignalRegionQmax[4]; // TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used)
+  // Char_t      fTPCsignalNRegion[3]; // number of clusters above threshold used in the dEdx calculation
+  // Char_t      fTPCsignalNRowRegion[3]; // number of crosed rows used in the dEdx calculation - signal below threshold included
+  //
+  for (Int_t i=0; i<3; i++){
+    signal[i]=fTPCsignalRegionQmax[i];
+    ncl[i]=fTPCsignalNRegion[i];
+    nrows[i]=fTPCsignalNRowRegion[i];
+  }
+  signal[3]=fTPCsignalRegionQmax[3];
+  return;
+}
+
+//_______________________________________________________________________________________________
+void  AliTPCdEdxInfo::GetTPCSignalsQmax(Double_t signal[4]) const {
+  //
+  // Set the TPC dEdx variables per region
+  //
+  // Double32_t  fTPCsignalRegionQmax[4]; // TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used)
+  //
+  for (Int_t i=0;i<4; i++){
+    signal[i]=fTPCsignalRegionQmax[i];
+  }
+}
+
+//_______________________________________________________________________________________________
+void  AliTPCdEdxInfo::SetTPCSignalRegionInfoQmax(Double_t signal[4], Char_t ncl[3], Char_t nrows[3]){
+  //
+  // Set the TPC dEdx variables per region
+  //
+  // Double32_t  fTPCsignalRegionQmax[4]; // TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used)
+  // Char_t      fTPCsignalNRegion[3]; // number of clusters above threshold used in the dEdx calculation
+  // Char_t      fTPCsignalNRowRegion[3]; // number of crosed rows used in the dEdx calculation - signal below threshold included
+  //
+  for (Int_t i=0;i<3; i++){
+    fTPCsignalRegionQmax[i]=signal[i];
+    fTPCsignalNRegion[i]=ncl[i];
+    fTPCsignalNRowRegion[i]=nrows[i];
+  }
+  fTPCsignalRegionQmax[3]=signal[3];
+  return;
+}
+
+//_______________________________________________________________________________________________
+void  AliTPCdEdxInfo::SetTPCSignalsQmax(Double_t signal[4]){
+  //
+  // Set the TPC dEdx variables per region
+  //
+  // Double32_t  fTPCsignalRegionQmax[4]; // TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used)
+  //
+  for (Int_t i=0;i<4; i++){
+    fTPCsignalRegionQmax[i]=signal[i];
+  }
+}
+
+
+Double_t AliTPCdEdxInfo::GetWeightedMean(Int_t qType, Int_t wType, Double_t w0, Double_t w1, Double_t w2){
+  //
+  // Get weighted mean of the dEdx information
+  //
+  Double_t *info = (qType==0)? fTPCsignalRegion :  fTPCsignalRegionQmax;
+  Char_t *ninfo = (wType==0)? fTPCsignalNRegion:  fTPCsignalNRowRegion;
+  Double_t weight[3]={w0,w1,w2};
+  Double_t sum=0;
+  Double_t sumw=0;
+  for (Int_t i=0; i<3; i++){
+    sum+= info[i]*Double_t(ninfo[i])*weight[i];
+    sumw+= ninfo[i]*weight[i];
+  }
+  Double_t result = (sumw>0) ? sum/sumw:0;
+  return result;
+}
+
+
+
+void  AliTPCdEdxInfo::RegisterSectorCalibration(TGraphErrors* gainSector, Int_t regionID, Int_t calibID){
+  //
+  // Register sector calibration
+  //
+  // create if arrray does not exist
+  if (!fArraySectorCalibration) fArraySectorCalibration= new TObjArray((calibID+1)*3*10); // boook space for calibration pointer
+  // resize if not enough booked
+  if (fArraySectorCalibration->GetSize()<(calibID+1)*3) fArraySectorCalibration->Expand((calibID+1)*3);
+  //
+  fArraySectorCalibration->AddAt(gainSector, 3*calibID+regionID);
+}
index c50c6c6eafdfcccba9815e3452aa87fda3a28e80..f204bdb0021d4e6047eda377b4e6aaa39dc7f95c 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef AliTPCdEdxInfo_H
 #define AliTPCdEdxInfo_H
 
+class TGraphErrors;
+class TObjArray;
 #include <TObject.h>
 
 class AliTPCdEdxInfo : public TObject 
@@ -9,22 +11,46 @@ public:
   AliTPCdEdxInfo();
   AliTPCdEdxInfo(const AliTPCdEdxInfo& source);
   AliTPCdEdxInfo& operator=(const AliTPCdEdxInfo& source);
+  Double_t GetWeightedMean(Int_t qType, Int_t wType, Double_t w0, Double_t w1, Double_t w2); 
   //
-  void     GetTPCSignalRegionInfo(Double32_t signal[4], Char_t ncl[3], Char_t nrows[3]) const;
-  void     SetTPCSignalRegionInfo(Double32_t signal[4], Char_t ncl[3], Char_t nrows[3]);
+  // qTot info
+  void     GetTPCSignalRegionInfo(Double_t signal[4], Char_t ncl[3], Char_t nrows[3]) const;
+  void     GetTPCSignals(Double_t signal[4]) const;
+
+  void     SetTPCSignalRegionInfo(Double_t signal[4], Char_t ncl[3], Char_t nrows[3]);
+  void     SetTPCSignals(Double_t signal[4]);
+  
+  
+  // qMax info
+  void     GetTPCSignalRegionInfoQmax(Double_t signal[4], Char_t ncl[3], Char_t nrows[3]) const;
+  void     GetTPCSignalsQmax(Double_t signal[4]) const;
+
+  void     SetTPCSignalRegionInfoQmax(Double_t signal[4], Char_t ncl[3], Char_t nrows[3]);
+  void     SetTPCSignalsQmax(Double_t signal[4]);
+  
+  Double_t GetSignalTot(Int_t index){ return fTPCsignalRegion[index];}
+  Double_t GetSignalMax(Int_t index){ return fTPCsignalRegionQmax[index];}
   //
-  Double32_t GetTPCsignalShortPad()  const {return fTPCsignalRegion[0];}
-  Double32_t GetTPCsignalMediumPad() const {return fTPCsignalRegion[1];}
-  Double32_t GetTPCsignalLongPad()   const {return fTPCsignalRegion[2];}
+  Double_t GetTPCsignalShortPad()      const {return fTPCsignalRegion[0];}
+  Double_t GetTPCsignalMediumPad()     const {return fTPCsignalRegion[1];}
+  Double_t GetTPCsignalLongPad()       const {return fTPCsignalRegion[2];}
+  Double_t GetTPCsignalOROC()          const {return fTPCsignalRegion[3];}
   
-private:
+  Double_t GetTPCsignalShortPadQmax()  const {return fTPCsignalRegionQmax[0];}
+  Double_t GetTPCsignalMediumPadQmax() const {return fTPCsignalRegionQmax[1];}
+  Double_t GetTPCsignalLongPadQmax()   const {return fTPCsignalRegionQmax[2];}
+  Double_t GetTPCsignalOROCQmax()      const {return fTPCsignalRegionQmax[3];}
+  static void     RegisterSectorCalibration(TGraphErrors* gainSector, Int_t regionID, Int_t calibID);
+private: 
 
-  Double32_t  fTPCsignalRegion[4]; //[0.,0.,10] TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used)  
+  Double32_t  fTPCsignalRegion[4]; //[0.,0.,10] TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used)  - for qTot
+  Double32_t  fTPCsignalRegionQmax[4]; //[0.,0.,10] TPC dEdx signal in 4 different regions - 0 - IROC, 1- OROC medium, 2 - OROC long, 3- OROC all, (default truncation used) - for qMax
   Char_t      fTPCsignalNRegion[3]; // number of clusters above threshold used in the dEdx calculation
   Char_t      fTPCsignalNRowRegion[3]; // number of crosed rows used in the dEdx calculation - signal below threshold included
-
+  //
+  static TObjArray *fArraySectorCalibration;
   
-  ClassDef(AliTPCdEdxInfo,2)
+  ClassDef(AliTPCdEdxInfo,3)
 };
 
 #endif
index e14f0e0f3dae22c337ebfc5ff05422ac38b1a321..00804e6c24841eab850143e2920c14e76d6f0a00 100644 (file)
 //    the corrected position (x+dx1) resulting in dx2, the third one          //
 //    is then called at position (x+dx1+dx2) and so forth. dx=dx1+dx2+...     //
 //    is returned.                                                            //
+// 3. kQueueResidual: like kQueue with the exception that in case of          //
+//    a positive weight the 'Distortion' is called and in case of a negative  //
+//    weight the 'Correction' is called, where the absolute of the weight     //
+//    will be applied to the correction
 // For the inverse of the correction this is taken into account by reversing  //
 // the order the corrections are applied in the kQueue case (no issue for     //
 // kParallel).                                                                //
@@ -57,6 +61,7 @@
 #include <TCollection.h>
 #include <TTimeStamp.h>
 #include <TIterator.h>
+#include <TMath.h>
 #include "AliLog.h"
 
 #include "AliTPCComposedCorrection.h"
@@ -157,6 +162,12 @@ void AliTPCComposedCorrection::GetCorrection(const Float_t x[],const Short_t roc
     }
     for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
     break;
+  case kQueueResidual:
+    //TODO: for the moment assume inverse of distortion
+    //      check if this is what is desired
+    GetDistortion(x,roc,dx);
+    for (Int_t j=0;j<3;++j) dx[j]*=-1.;
+    break;
   }
   delete i;
 }
@@ -171,6 +182,12 @@ void AliTPCComposedCorrection::GetDistortion(const Float_t x[],const Short_t roc
     AliInfo("No Corrections-models were set: can not calculate distortions");
     return;
   }
+  
+  if (fMode==kQueueResidual && !fWeights) {
+    AliInfo("kQueueResidual mode was selected but no weights were given. Switching to kQueue instead.");
+    fMode=kQueue;
+  }
+  
   TIterator *i=fCorrections->MakeReverseIterator();
   AliTPCCorrection *c;
   Int_t weightIndex=0;
@@ -196,6 +213,17 @@ void AliTPCComposedCorrection::GetDistortion(const Float_t x[],const Short_t roc
     }
     for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
     break;
+  case kQueueResidual:
+    Float_t xi2[3];
+    for (Int_t j=0;j<3;++j) xi2[j]=x[j];
+    while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
+      Double_t w=(*fWeights)[weightIndex++];
+      if (w>0) c->GetDistortion(xi2,roc,dx);
+      else c->GetCorrection(xi2,roc,dx);
+      for (Int_t j=0;j<3;++j) xi2[j]+=TMath::Abs(w)*dx[j];
+    }
+    for (Int_t j=0;j<3;++j) dx[j]=xi2[j]-x[j];
+    break;
   }
   delete i;
 }
index fe6ecbde82491bc87af6bdaba96ff7f818aefb0e..4e6c0a8d697f777826f6ec5e38aebf282260ff77 100644 (file)
@@ -34,7 +34,7 @@ class TTimeStamp;
 
 class AliTPCComposedCorrection : public AliTPCCorrection {
 public:
-  enum CompositionType {kParallel,kQueue};
+  enum CompositionType {kParallel,kQueue, kQueueResidual};
 
   AliTPCComposedCorrection();
   AliTPCComposedCorrection(TCollection *corrections,CompositionType mode);
index b5da6e37026944356e0997a98c18b7509afef5af..2ba1b2a3ca48714d82c30775a204e5b3c7a76db1 100644 (file)
 
 #include "AliTPCRecoParam.h"
 #include "TLinearFitter.h"
-
+#include <AliSysInfo.h>
 
 ClassImp(AliTPCCorrection)
 
-
 TObjArray *AliTPCCorrection::fgVisualCorrection=0;
 // instance of correction for visualization
 
@@ -146,7 +146,7 @@ const Double_t AliTPCCorrection::fgke0 = 8.854187817e-12;                 // vac
  
 
 AliTPCCorrection::AliTPCCorrection() 
-  : TNamed("correction_unity","unity"),fILow(0),fJLow(0),fKLow(0), fT1(1), fT2(1)
+  : TNamed("correction_unity","unity"),fILow(0),fJLow(0),fKLow(0), fT1(1), fT2(1), fIsLocal(kFALSE)
 {
   //
   // default constructor
@@ -158,7 +158,7 @@ AliTPCCorrection::AliTPCCorrection()
 }
 
 AliTPCCorrection::AliTPCCorrection(const char *name,const char *title)
-: TNamed(name,title),fILow(0),fJLow(0),fKLow(0), fT1(1), fT2(1)
+  : TNamed(name,title),fILow(0),fJLow(0),fKLow(0), fT1(1), fT2(1), fIsLocal(kFALSE)
 {
   //
   // default constructor, that set the name and title
@@ -288,15 +288,52 @@ void AliTPCCorrection::GetCorrectionDz(const Float_t x[],const Short_t roc,Float
   // Output parameter:
   //   dx[] - array {dx'/dz,  dy'/dz ,  dz'/dz }
 
+  //   if (fIsLocal){  //standard implemenation provides the correction/distortion integrated over full drift length
+  //    
+  //
+  //     GetCorrection(xyz,roc,dxyz);  
+  //   }
   static TLinearFitter fitx(2,"pol1"); 
   static TLinearFitter fity(2,"pol1");
   static TLinearFitter fitz(2,"pol1");
   fitx.ClearPoints();
   fity.ClearPoints();
   fitz.ClearPoints();
+  Int_t zmin=-2;
+  Int_t zmax=0;
+  //adjust limits around CE to stay on one side
+  if ((roc%36)<18) {
+    //A-Side
+    if ((x[2]+zmin*delta)<0){
+      zmin=0;
+      zmax=2;
+      if ((x[2]-delta)>0){
+        zmin=-1;
+        zmax=1;
+      }
+    }
+  } else {
+    //C-Side
+    zmin=0;
+    zmax=2;
+    if ((x[2]+zmax*delta)>0){
+      zmin=-2;
+      zmax=0;
+      if ((x[2]+delta)<0){
+        zmin=-1;
+        zmax=1;
+      }
+    }
+  }
+
   for (Int_t xdelta=-1; xdelta<=1; xdelta++)
     for (Int_t ydelta=-1; ydelta<=1; ydelta++){
-      for (Int_t zdelta=-1; zdelta<=1; zdelta++){
+//       for (Int_t zdelta=-1; zdelta<=1; zdelta++){
+//   for (Int_t xdelta=-2; xdelta<=0; xdelta++)
+//     for (Int_t ydelta=-2; ydelta<=0; ydelta++){
+      for (Int_t zdelta=zmin; zdelta<=zmax; zdelta++){
+        //TODO: what happens if x[2] is on the A-Side, but x[2]+zdelta*delta
+        //      will be on the C-Side?
        Float_t xyz[3]={x[0]+xdelta*delta, x[1]+ydelta*delta, x[2]+zdelta*delta};
        Float_t dxyz[3];
        GetCorrection(xyz,roc,dxyz);
@@ -314,9 +351,76 @@ void AliTPCCorrection::GetCorrectionDz(const Float_t x[],const Short_t roc,Float
   dx[2] = fitz.GetParameter(1);
 }
 
+void AliTPCCorrection::GetDistortionDz(const Float_t x[],const Short_t roc,Float_t dx[], Float_t delta) {
+  // author: marian.ivanov@cern.ch
+  //
+  // In this (virtual)function calculates the dx'/dz,  dy'/dz  and dz'/dz at given point (x,y,z)
+  // Generic implementation. Better precision can be acchieved knowing the internal structure
+  // of underlying trasnformation. Derived classes can reimplement it.
+  // To calculate distortion is fitted in small neighberhood:
+  // (x+-delta,y+-delta,z+-delta) where delta is an argument
+  //
+  // Input parameters:
+  //   x[]   - space point corrdinate
+  //   roc   - readout chamber identifier (important e.g to do not miss the side of detector)
+  //   delta - define the size of neighberhood
+  // Output parameter:
+  //   dx[] - array {dx'/dz,  dy'/dz ,  dz'/dz }
+  
+  static TLinearFitter fitx(2,"pol1");
+  static TLinearFitter fity(2,"pol1");
+  static TLinearFitter fitz(2,"pol1");
+  fitx.ClearPoints();
+  fity.ClearPoints();
+  fitz.ClearPoints();
+
+  Int_t zmin=-1;
+  Int_t zmax=1;
+  //adjust limits around CE to stay on one side
+  if ((roc%36)<18) {
+    //A-Side
+    if ((x[2]+zmin*delta)<0){
+      zmin=0;
+      zmax=2;
+    }
+  } else {
+    //C-Side
+    if ((x[2]+zmax*delta)>0){
+      zmin=-2;
+      zmax=0;
+    }
+  }
+  
+  //TODO: in principle one shuld check that x[2]+zdelta*delta does not get 'out of' bounds,
+  //      so close to the CE it doesn't change the sign, since then the corrections will be wrong ...
+  for (Int_t xdelta=-1; xdelta<=1; xdelta++)
+    for (Int_t ydelta=-1; ydelta<=1; ydelta++){
+      for (Int_t zdelta=zmin; zdelta<=zmax; zdelta++){
+        //TODO: what happens if x[2] is on the A-Side, but x[2]+zdelta*delta
+        //      will be on the C-Side?
+        //TODO: For the C-Side, does this have the correct sign?
+        Float_t xyz[3]={x[0]+xdelta*delta, x[1]+ydelta*delta, x[2]+zdelta*delta};
+        Float_t dxyz[3];
+        GetDistortion(xyz,roc,dxyz);
+        Double_t adelta=zdelta*delta;
+        fitx.AddPoint(&adelta, dxyz[0]);
+        fity.AddPoint(&adelta, dxyz[1]);
+        fitz.AddPoint(&adelta, dxyz[2]);
+      }
+    }
+    fitx.Eval();
+    fity.Eval();
+    fitz.Eval();
+    dx[0] = fitx.GetParameter(1);
+    dx[1] = fity.GetParameter(1);
+    dx[2] = fitz.GetParameter(1);
+}
+
 void AliTPCCorrection::GetCorrectionIntegralDz(const Float_t x[],const Short_t roc,Float_t dx[], Float_t delta){
   //
-  // Integrate 3D distortion along drift lines
+  // Integrate 3D distortion along drift lines starting from the roc plane
+  //   to the expected z position of the point, this assumes that dz is small
+  //   and the error propagating to z' instead of the correct z is negligible
   // To define the drift lines virtual function  AliTPCCorrection::GetCorrectionDz is used
   //
   // Input parameters:
@@ -326,6 +430,56 @@ void AliTPCCorrection::GetCorrectionIntegralDz(const Float_t x[],const Short_t r
   // Output parameter:
   //   dx[] - array { integral(dx'/dz),  integral(dy'/dz) ,  integral(dz'/dz) }
 
+  Float_t zroc= ((roc%36)<18) ? fgkTPCZ0:-fgkTPCZ0;
+  Double_t zdrift = TMath::Abs(x[2]-zroc);
+  Int_t    nsteps = Int_t(zdrift/delta)+1;
+  //
+  //
+  Float_t xyz[3]={x[0],x[1],zroc};
+  Float_t dxyz[3]={x[0],x[1],x[2]};
+  Short_t side=(roc/18)%2;
+  Float_t sign=1-2*side;
+  Double_t sumdz=0;
+  for (Int_t i=0;i<nsteps; i++){
+    //propagate backwards, therefore opposite signs
+    Float_t deltaZ=delta*(-sign);
+//     if (xyz[2]+deltaZ>fgkTPCZ0) deltaZ=TMath::Abs(xyz[2]-fgkTPCZ0);
+//     if (xyz[2]-deltaZ<-fgkTPCZ0) deltaZ=TMath::Abs(xyz[2]-fgkTPCZ0);
+    // protect again integrating through the CE
+    if (side==0){
+      if (xyz[2]+deltaZ<0) deltaZ=-xyz[2]+1e-20;
+    } else {
+      if (xyz[2]+deltaZ>0) deltaZ=xyz[2]-+1e-20;
+    }
+    // since at larger drift (smaller z) the corrections are larger (absolute, but negative)
+    //  the slopes will be positive.
+    // but since we chose deltaZ opposite sign the singn of the corretion should be fine
+    
+    Float_t xyz2[3]={xyz[0],xyz[1],xyz[2]+deltaZ/2.};
+    GetCorrectionDz(xyz2,roc,dxyz,delta/2.);
+    xyz[0]+=deltaZ*dxyz[0];
+    xyz[1]+=deltaZ*dxyz[1];
+    xyz[2]+=deltaZ;           //
+    sumdz+=deltaZ*dxyz[2];
+  }
+  //
+  dx[0]=xyz[0]-x[0];
+  dx[1]=xyz[1]-x[1];
+  dx[2]=      sumdz; //TODO: is sumdz correct?
+}
+
+void AliTPCCorrection::GetDistortionIntegralDz(const Float_t x[],const Short_t roc,Float_t dx[], Float_t delta){
+  //
+  // Integrate 3D distortion along drift lines
+  // To define the drift lines virtual function  AliTPCCorrection::GetCorrectionDz is used
+  //
+  // Input parameters:
+  //   x[]   - space point corrdinate
+  //   roc   - readout chamber identifier (important e.g to do not miss the side of detector)
+  //   delta - define the size of neighberhood
+  // Output parameter:
+  //   dx[] - array { integral(dx'/dz),  integral(dy'/dz) ,  integral(dz'/dz) }
+  
   Float_t zroc= ((roc%36)<18) ? fgkTPCZ0:-fgkTPCZ0;
   Double_t zdrift = TMath::Abs(x[2]-zroc);
   Int_t    nsteps = Int_t(zdrift/delta)+1;
@@ -337,24 +491,28 @@ void AliTPCCorrection::GetCorrectionIntegralDz(const Float_t x[],const Short_t r
   Double_t sumdz=0;
   for (Int_t i=0;i<nsteps; i++){
     Float_t deltaZ=delta;
-    if (xyz[2]+deltaZ>fgkTPCZ0) deltaZ=TMath::Abs(xyz[2]-fgkTPCZ0);
-    if (xyz[2]-deltaZ<-fgkTPCZ0) deltaZ=TMath::Abs(xyz[2]-fgkTPCZ0);
+    if (xyz[2]+deltaZ>fgkTPCZ0) deltaZ=TMath::Abs(xyz[2]-zroc);
+    if (xyz[2]-deltaZ<-fgkTPCZ0) deltaZ=TMath::Abs(xyz[2]-zroc);
+    // since at larger drift (smaller z) the distortions are larger
+    //  the slopes will be negative.
+    // and since we are moving towards the read-out plane the deltaZ for
+    //   weighting the dK/dz should have the opposite sign
     deltaZ*=sign;
-    GetCorrectionDz(xyz,roc,dxyz,delta);
-    xyz[0]+=deltaZ*dxyz[0];        
-    xyz[1]+=deltaZ*dxyz[1];
-    xyz[2]+=deltaZ;           //
-    sumdz+=deltaZ*dxyz[2];
+    Float_t xyz2[3]={xyz[0],xyz[1],xyz[2]+deltaZ/2.};
+    GetDistortionDz(xyz2,roc,dxyz,delta/2.);
+    xyz[0]+=-deltaZ*dxyz[0];
+    xyz[1]+=-deltaZ*dxyz[1];
+    xyz[2]+=deltaZ;           //TODO: Should this also be corrected for the dxyz[2]
+    sumdz+=-deltaZ*dxyz[2];
   }
   //
-  dx[0]=x[0]-xyz[0];
-  dx[1]=x[1]-xyz[1];
-  dx[2]=    dxyz[2];
+  dx[0]=xyz[0]-x[0];
+  dx[1]=xyz[1]-x[1];
+  dx[2]=      sumdz;  //TODO: is sumdz correct?
   
 }
 
 
-
 void AliTPCCorrection::Init() {
   //
   // Initialization funtion (not used at the moment)
@@ -1233,8 +1391,10 @@ void AliTPCCorrection::PoissonRelaxation3D( TMatrixD**arrayofArrayV, TMatrixD**a
   TMatrixD* arrayofSumChargeDensities[1000] ;    // Create temporary arrays to store low resolution charge arrays
 
   for ( Int_t i = 0 ; i < phislices ; i++ ) { arrayofSumChargeDensities[i] = new TMatrixD(rows,columns) ; }
+  AliSysInfo::AddStamp("3DInit", 10,0,0);
 
   for ( Int_t count = 0 ; count < loops ; count++ ) {      // START the master loop and do the binary expansion
+    AliSysInfo::AddStamp("3Diter", 20,count,0);
    
     Float_t  tempgridSizeR   =  gridSizeR  * ione ;
     Float_t  tempratioPhi    =  ratioPhi * ione * ione ; // Used tobe divided by ( m_one * m_one ) when m_one was != 1
@@ -1314,19 +1474,54 @@ void AliTPCCorrection::PoissonRelaxation3D( TMatrixD**arrayofArrayV, TMatrixD**a
        TMatrixD& arrayVP   =  *arrayofArrayV[mplus] ;
        TMatrixD& arrayVM   =  *arrayofArrayV[mminus] ;
        TMatrixD& sumChargeDensity =  *arrayofSumChargeDensities[m] ;
+       Double_t *arrayVfast = arrayV.GetMatrixArray();
+       Double_t *arrayVPfast = arrayVP.GetMatrixArray();
+       Double_t *arrayVMfast = arrayVM.GetMatrixArray();
+       Double_t *sumChargeDensityFast=sumChargeDensity.GetMatrixArray();
 
-       for ( Int_t i = ione ; i < rows-1 ; i+=ione )  {
-         for ( Int_t j = jone ; j < columns-1 ; j+=jone ) {
-
-            arrayV(i,j) = (   coef2[i]          *   arrayV(i-ione,j)
-                           + tempratioZ        * ( arrayV(i,j-jone)  +  arrayV(i,j+jone) )
-                           - overRelaxcoef5[i] *   arrayV(i,j) 
-                           + coef1[i]          *   arrayV(i+ione,j)  
-                           + coef3[i]          * ( signplus*arrayVP(i,j)       +  signminus*arrayVM(i,j) )
-                           + sumChargeDensity(i,j) 
-                         ) * overRelaxcoef4[i] ;     
-           // Note: over-relax the solution at each step.  This speeds up the convergance.
-
+       if (0){
+         // slow implementation
+         for ( Int_t i = ione ; i < rows-1 ; i+=ione )  {
+           for ( Int_t j = jone ; j < columns-1 ; j+=jone ) {
+             
+             arrayV(i,j) = (   coef2[i]          *   arrayV(i-ione,j)
+                               + tempratioZ        * ( arrayV(i,j-jone)  +  arrayV(i,j+jone) )
+                               - overRelaxcoef5[i] *   arrayV(i,j) 
+                               + coef1[i]          *   arrayV(i+ione,j)  
+                               + coef3[i]          * ( signplus*arrayVP(i,j)       +  signminus*arrayVM(i,j) )
+                               + sumChargeDensity(i,j) 
+                               ) * overRelaxcoef4[i] ;     
+             // Note: over-relax the solution at each step.  This speeds up the convergance.         
+           }
+         }
+       }else{
+         for ( Int_t i = ione ; i < rows-1 ; i+=ione )  {
+           Double_t *arrayVfastI = &(arrayVfast[i*columns]);
+           Double_t *arrayVPfastI = &(arrayVPfast[i*columns]);
+           Double_t *arrayVMfastI = &(arrayVMfast[i*columns]);
+           Double_t *sumChargeDensityFastI=&(sumChargeDensityFast[i*columns]);
+           for ( Int_t j = jone ; j < columns-1 ; j+=jone ) {
+             Double_t resSlow,resFast;
+//           resSlow  = (   coef2[i]          *   arrayV(i-ione,j)
+//                             + tempratioZ        * ( arrayV(i,j-jone)  +  arrayV(i,j+jone) )
+//                             - overRelaxcoef5[i] *   arrayV(i,j) 
+//                             + coef1[i]          *   arrayV(i+ione,j)  
+//                             + coef3[i]          * ( signplus*arrayVP(i,j)       +  signminus*arrayVM(i,j) )
+//                             + sumChargeDensity(i,j) 
+//                             ) * overRelaxcoef4[i] ;     
+             resFast   = (   coef2[i]          *   arrayVfastI[j-columns*ione]
+                             + tempratioZ        * ( arrayVfastI[j-jone]  +  arrayVfastI[j+jone] )
+                             - overRelaxcoef5[i] *   arrayVfastI[j] 
+                             + coef1[i]          * arrayVfastI[j+columns*ione]    
+                             + coef3[i]          * ( signplus* arrayVPfastI[j]      +  signminus*arrayVMfastI[j])
+                             + sumChargeDensityFastI[j] 
+                             ) * overRelaxcoef4[i] ;     
+//           if (resSlow!=resFast){
+//             printf("problem\t%d\t%d\t%f\t%f\t%f\n",i,j,resFast,resSlow,resFast-resSlow);
+//           }
+             arrayVfastI[j]=resFast;
+             // Note: over-relax the solution at each step.  This speeds up the convergance.         
+           }
          }
        }
 
@@ -1362,6 +1557,7 @@ void AliTPCCorrection::PoissonRelaxation3D( TMatrixD**arrayofArrayV, TMatrixD**a
   
   //Differentiate V(r) and solve for E(r) using special equations for the first and last row
   //Integrate E(r)/E(z) from point of origin to pad plane
+  AliSysInfo::AddStamp("CalcField", 100,0,0);
 
   for ( Int_t m = 0 ; m < phislices ; m++ ) {
     TMatrixD& arrayV    =  *arrayofArrayV[m] ;
@@ -1393,6 +1589,7 @@ void AliTPCCorrection::PoissonRelaxation3D( TMatrixD**arrayofArrayV, TMatrixD**a
     // if ( m == 0 ) { TCanvas*  c1 =  new TCanvas("erOverEz","erOverEz",50,50,840,600) ;  c1 -> cd() ;
     // eroverEz.Draw("surf") ; } // JT test
   }
+  AliSysInfo::AddStamp("IntegrateEr", 120,0,0);
   
   //Differentiate V(r) and solve for E(phi) 
   //Integrate E(phi)/E(z) from point of origin to pad plane
@@ -1442,6 +1639,7 @@ void AliTPCCorrection::PoissonRelaxation3D( TMatrixD**arrayofArrayV, TMatrixD**a
     // if ( m == 5 ) { TCanvas* c2 =  new TCanvas("arrayE","arrayE",50,50,840,600) ;  c2 -> cd() ;
     // arrayE.Draw("surf") ; } // JT test
   }
+  AliSysInfo::AddStamp("IntegrateEphi", 130,0,0);
   
 
   // Differentiate V(r) and solve for E(z) using special equations for the first and last row
@@ -1475,6 +1673,7 @@ void AliTPCCorrection::PoissonRelaxation3D( TMatrixD**arrayofArrayV, TMatrixD**a
        if ( j == columns-1 ) deltaEz(i,j) =  0.0 ;
       }
     }
+
     // if ( m == 0 ) { TCanvas*  c1 =  new TCanvas("erOverEz","erOverEz",50,50,840,600) ;  c1 -> cd() ;
     // eroverEz.Draw("surf") ; } // JT test
     
@@ -1494,8 +1693,8 @@ void AliTPCCorrection::PoissonRelaxation3D( TMatrixD**arrayofArrayV, TMatrixD**a
       }
     }
 
-  } // end loop over phi
-  
+  } // end loop over phi  
+  AliSysInfo::AddStamp("IntegrateEz", 140,0,0);
  
 
   for ( Int_t k = 0 ; k < phislices ; k++ )
@@ -2892,7 +3091,7 @@ Double_t AliTPCCorrection::GetCorrSector(Double_t sector, Double_t r, Double_t k
   Double_t gx = r*TMath::Cos(phi);
   Double_t gy = r*TMath::Sin(phi);
   Double_t gz = r*kZ;
-  Int_t nsector=(gz>0) ? 0:18; 
+  Int_t nsector=(gz>=0) ? 0:18; 
   //
   //
   //
@@ -2917,9 +3116,9 @@ Double_t AliTPCCorrection::GetCorrXYZ(Double_t gx, Double_t gy, Double_t gz, Int
   AliTPCCorrection *corr = (AliTPCCorrection*)fgVisualCorrection->At(corrType);
   if (!corr) return 0;
   Double_t phi0= TMath::ATan2(gy,gx);
-  Int_t nsector=(gz>0) ? 0:18; 
+  Int_t nsector=(gz>=0) ? 0:18; 
   Float_t distPoint[3]={gx,gy,gz};
-  corr->DistortPoint(distPoint, nsector);
+  corr->CorrectPoint(distPoint, nsector);
   Double_t r0=TMath::Sqrt(gx*gx+gy*gy);
   Double_t r1=TMath::Sqrt(distPoint[0]*distPoint[0]+distPoint[1]*distPoint[1]);
   Double_t phi1=TMath::ATan2(distPoint[1],distPoint[0]);
@@ -2937,14 +3136,14 @@ Double_t AliTPCCorrection::GetCorrXYZDz(Double_t gx, Double_t gy, Double_t gz, I
   AliTPCCorrection *corr = (AliTPCCorrection*)fgVisualCorrection->At(corrType);
   if (!corr) return 0;
   Double_t phi0= TMath::ATan2(gy,gx);
-  Int_t nsector=(gz>0) ? 0:18; 
+  Int_t nsector=(gz>=0) ? 0:18; 
   Float_t distPoint[3]={gx,gy,gz};
   Float_t dxyz[3]={gx,gy,gz};
   //
   corr->GetCorrectionDz(distPoint, nsector,dxyz,delta);
-  distPoint[0]-=dxyz[0];
-  distPoint[1]-=dxyz[1];
-  distPoint[2]-=dxyz[2];
+  distPoint[0]+=dxyz[0];
+  distPoint[1]+=dxyz[1];
+  distPoint[2]+=dxyz[2];
   Double_t r0=TMath::Sqrt(gx*gx+gy*gy);
   Double_t r1=TMath::Sqrt(distPoint[0]*distPoint[0]+distPoint[1]*distPoint[1]);
   Double_t phi1=TMath::ATan2(distPoint[1],distPoint[0]);
@@ -2962,14 +3161,14 @@ Double_t AliTPCCorrection::GetCorrXYZIntegrateZ(Double_t gx, Double_t gy, Double
   AliTPCCorrection *corr = (AliTPCCorrection*)fgVisualCorrection->At(corrType);
   if (!corr) return 0;
   Double_t phi0= TMath::ATan2(gy,gx);
-  Int_t nsector=(gz>0) ? 0:18; 
+  Int_t nsector=(gz>=0) ? 0:18; 
   Float_t distPoint[3]={gx,gy,gz};
   Float_t dxyz[3]={gx,gy,gz};
   //
   corr->GetCorrectionIntegralDz(distPoint, nsector,dxyz,delta);
-  distPoint[0]-=dxyz[0];
-  distPoint[1]-=dxyz[1];
-  distPoint[2]-=dxyz[2];
+  distPoint[0]+=dxyz[0];
+  distPoint[1]+=dxyz[1];
+  distPoint[2]+=dxyz[2];
   Double_t r0=TMath::Sqrt(gx*gx+gy*gy);
   Double_t r1=TMath::Sqrt(distPoint[0]*distPoint[0]+distPoint[1]*distPoint[1]);
   Double_t phi1=TMath::ATan2(distPoint[1],distPoint[0]);
@@ -2980,6 +3179,75 @@ Double_t AliTPCCorrection::GetCorrXYZIntegrateZ(Double_t gx, Double_t gy, Double
 }
 
 
+Double_t AliTPCCorrection::GetDistXYZ(Double_t gx, Double_t gy, Double_t gz, Int_t axisType, Int_t corrType){
+  //
+  // return correction at given x,y,z
+  //
+  if (!fgVisualCorrection) return 0;
+  AliTPCCorrection *corr = (AliTPCCorrection*)fgVisualCorrection->At(corrType);
+  if (!corr) return 0;
+  Double_t phi0= TMath::ATan2(gy,gx);
+  Int_t nsector=(gz>=0) ? 0:18;
+  Float_t distPoint[3]={gx,gy,gz};
+  corr->DistortPoint(distPoint, nsector);
+  Double_t r0=TMath::Sqrt(gx*gx+gy*gy);
+  Double_t r1=TMath::Sqrt(distPoint[0]*distPoint[0]+distPoint[1]*distPoint[1]);
+  Double_t phi1=TMath::ATan2(distPoint[1],distPoint[0]);
+  if (axisType==0) return r1-r0;
+  if (axisType==1) return (phi1-phi0)*r0;
+  if (axisType==2) return distPoint[2]-gz;
+  return phi1-phi0;
+}
+
+Double_t AliTPCCorrection::GetDistXYZDz(Double_t gx, Double_t gy, Double_t gz, Int_t axisType, Int_t corrType,Double_t delta){
+  //
+  // return correction at given x,y,z
+  //
+  if (!fgVisualCorrection) return 0;
+  AliTPCCorrection *corr = (AliTPCCorrection*)fgVisualCorrection->At(corrType);
+  if (!corr) return 0;
+  Double_t phi0= TMath::ATan2(gy,gx);
+  Int_t nsector=(gz>=0) ? 0:18;
+  Float_t distPoint[3]={gx,gy,gz};
+  Float_t dxyz[3]={gx,gy,gz};
+  //
+  corr->GetDistortionDz(distPoint, nsector,dxyz,delta);
+  distPoint[0]+=dxyz[0];
+  distPoint[1]+=dxyz[1];
+  distPoint[2]+=dxyz[2];
+  Double_t r0=TMath::Sqrt(gx*gx+gy*gy);
+  Double_t r1=TMath::Sqrt(distPoint[0]*distPoint[0]+distPoint[1]*distPoint[1]);
+  Double_t phi1=TMath::ATan2(distPoint[1],distPoint[0]);
+  if (axisType==0) return r1-r0;
+  if (axisType==1) return (phi1-phi0)*r0;
+  if (axisType==2) return distPoint[2]-gz;
+  return phi1-phi0;
+}
+
+Double_t AliTPCCorrection::GetDistXYZIntegrateZ(Double_t gx, Double_t gy, Double_t gz, Int_t axisType, Int_t corrType,Double_t delta){
+  //
+  // return correction at given x,y,z
+  //
+  if (!fgVisualCorrection) return 0;
+  AliTPCCorrection *corr = (AliTPCCorrection*)fgVisualCorrection->At(corrType);
+  if (!corr) return 0;
+  Double_t phi0= TMath::ATan2(gy,gx);
+  Int_t nsector=(gz>=0) ? 0:18;
+  Float_t distPoint[3]={gx,gy,gz};
+  Float_t dxyz[3]={gx,gy,gz};
+  //
+  corr->GetDistortionIntegralDz(distPoint, nsector,dxyz,delta);
+  distPoint[0]+=dxyz[0];
+  distPoint[1]+=dxyz[1];
+  distPoint[2]+=dxyz[2];
+  Double_t r0=TMath::Sqrt(gx*gx+gy*gy);
+  Double_t r1=TMath::Sqrt(distPoint[0]*distPoint[0]+distPoint[1]*distPoint[1]);
+  Double_t phi1=TMath::ATan2(distPoint[1],distPoint[0]);
+  if (axisType==0) return r1-r0;
+  if (axisType==1) return (phi1-phi0)*r0;
+  if (axisType==2) return distPoint[2]-gz;
+  return phi1-phi0;
+}
 
 
 
index d1d55dd92f45b6ce3a47c647af488e28a09fc996..348a2d8a951cadb3a7745080ae79dc1741c72c13 100644 (file)
@@ -40,17 +40,24 @@ public:
 
   virtual void GetCorrectionDz(const Float_t x[],const Short_t roc,Float_t dx[], Float_t delta);
   virtual void GetCorrectionIntegralDz(const Float_t x[],const Short_t roc,Float_t dx[], Float_t delta);
-
+  
   // functions to distort a space point
           void DistortPoint (      Float_t x[],const Short_t roc);
           void DistortPointLocal(Float_t x[],const Short_t roc);
           void DistortPoint (const Float_t x[],const Short_t roc,Float_t xp[]);
   virtual void GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]);
 
+  virtual void GetDistortionDz(const Float_t x[],const Short_t roc,Float_t dx[], Float_t delta);
+  virtual void GetDistortionIntegralDz(const Float_t x[],const Short_t roc,Float_t dx[], Float_t delta);
+  
   // initialization and update functions
   virtual void Init();
   virtual void Update(const TTimeStamp &timeStamp);
 
+  // map scaling
+  virtual void    SetCorrScaleFactor(Float_t /*val*/) { ; }
+  virtual Float_t GetCorrScaleFactor() const { return 1.; }
+  
   // convenience functions
   virtual void Print(Option_t* option="") const;
  
@@ -84,6 +91,11 @@ public:
   //
   static Double_t GetCorrXYZDz(Double_t gx, Double_t gy, Double_t gz, Int_t axisType, Int_t corrType=0,Double_t delta=5);
   static Double_t GetCorrXYZIntegrateZ(Double_t gx, Double_t gy, Double_t gz, Int_t axisType, Int_t corrType=0, Double_t delta=5);
+
+  static Double_t GetDistXYZ(Double_t gx, Double_t gy, Double_t gz, Int_t axisType, Int_t corrType=0);
+  //
+  static Double_t GetDistXYZDz(Double_t gx, Double_t gy, Double_t gz, Int_t axisType, Int_t corrType=0,Double_t delta=5);
+  static Double_t GetDistXYZIntegrateZ(Double_t gx, Double_t gy, Double_t gz, Int_t axisType, Int_t corrType=0, Double_t delta=5);
   
 
 protected:
@@ -158,10 +170,12 @@ protected:
                            const Int_t rows, const Int_t columns,  const Int_t phislices, 
                            const Float_t deltaphi, const Int_t iterations, const Int_t summetry,
                            const Bool_t rocDisplacement = kTRUE); 
-    
+  void   SetIsLocal(Bool_t isLocal){fIsLocal=isLocal;}
+  Bool_t IsLocal() const  { return fIsLocal;}
 protected:
   Double_t fT1;         // tensor term of wt - T1
   Double_t fT2;         // tensor term of wt - T2
+  Bool_t fIsLocal;      // switch to indicate that the distortion is a local vector drphi/dz, dr/dz
   static TObjArray *fgVisualCorrection;  // array of orrection for visualization
 private:
   AliTPCCorrection(const AliTPCCorrection &);               // not implemented
@@ -169,7 +183,7 @@ private:
 
   void InitLookUpfulcrums();   // to initialize the grid of the look up table
 
-  ClassDef(AliTPCCorrection,4);
+  ClassDef(AliTPCCorrection,5);
 };
 
 #endif
diff --git a/TPC/Base/AliTPCCorrectionLookupTable.cxx b/TPC/Base/AliTPCCorrectionLookupTable.cxx
new file mode 100644 (file)
index 0000000..c47108d
--- /dev/null
@@ -0,0 +1,843 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+#include <TMath.h>
+#include <TMatrixF.h>
+#include <TStopwatch.h>
+#include <TString.h>
+#include <TFile.h>
+#include <TObjArray.h>
+#include <TSystem.h>
+#include <THashList.h>
+#include <TVector2.h>
+#include <TLinearFitter.h>
+
+#include <AliLog.h>
+#include <AliTPCROC.h>
+
+#include "AliTPCCorrection.h"
+
+#include "AliTPCCorrectionLookupTable.h"
+
+ClassImp(AliTPCCorrectionLookupTable)
+
+//_________________________________________________________________________________________
+AliTPCCorrectionLookupTable::AliTPCCorrectionLookupTable()
+: AliTPCCorrection()
+, fNR(0)
+, fNPhi(0)
+, fNZ(0)
+, fCorrScaleFactor(-1)
+, fFillCorrection(kTRUE)
+, fLimitsR()
+, fLimitsPhi()
+, fLimitsZ()
+, fLookUpDxDist(0x0)
+, fLookUpDyDist(0x0)
+, fLookUpDzDist(0x0)
+, fLookUpDxCorr(0x0)
+, fLookUpDyCorr(0x0)
+, fLookUpDzCorr(0x0)
+{
+  //
+  //
+  //
+}
+//_________________________________________________________________________________________
+AliTPCCorrectionLookupTable::~AliTPCCorrectionLookupTable()
+{
+  //
+  // dtor
+  //
+
+  ResetTables();
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
+  //
+  // Get interpolated Distortion
+  //
+
+  GetInterpolation(x,roc,dx,fLookUpDxDist,fLookUpDyDist,fLookUpDzDist);
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
+  //
+  // Get interplolated correction
+  //
+  GetInterpolation(x,roc,dx,fLookUpDxCorr,fLookUpDyCorr,fLookUpDzCorr);
+
+  if (fCorrScaleFactor>0) {
+    dx[0]*=fCorrScaleFactor;
+    dx[1]*=fCorrScaleFactor;
+    dx[2]*=fCorrScaleFactor;
+  }
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::GetInterpolation(const Float_t x[],const Short_t roc,Float_t dx[],
+                                                   TMatrixF **mDx, TMatrixF **mDy, TMatrixF **mDz)
+{
+  //
+  // Calculates the correction/distotring from a lookup table
+  // type: 0 = correction
+  //       1 = distortion
+  //
+
+//   Float_t typeSign=-1;
+//   if (type==1) typeSign=1;
+  
+  Int_t   order     = 1 ;    // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2
+  
+  Double_t r, phi, z ;
+  Int_t    sign;
+  
+  r      =  TMath::Sqrt( x[0]*x[0] + x[1]*x[1] ) ;
+  phi    =  TMath::ATan2(x[1],x[0]) ;
+  if ( phi < 0 ) phi += TMath::TwoPi() ;                   // Table uses phi from 0 to 2*Pi
+  z      =  x[2] ;                                         // Create temporary copy of x[2]
+  
+  if ( (roc%36) < 18 ) {
+    sign =  1;       // (TPC A side)
+  } else {
+    sign = -1;       // (TPC C side)
+  }
+  
+  if ( sign==1  && z <  fgkZOffSet ) z =  fgkZOffSet;    // Protect against discontinuity at CE
+  if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet;    // Protect against discontinuity at CE
+
+
+  if ( (sign==1 && z<0) || (sign==-1 && z>0) ) // just a consistency check
+    AliError("ROC number does not correspond to z coordinate! Calculation of distortions is most likely wrong!");
+  
+  // Get the Er and Ephi field integrals plus the integral over Z
+    dx[0] = Interpolate3DTable(order, r, z, phi,
+                               fNR, fNZ, fNPhi,
+                               fLimitsR.GetMatrixArray(),
+                               fLimitsZ.GetMatrixArray(),
+                               fLimitsPhi.GetMatrixArray(),
+                               mDx  );
+    dx[1] = Interpolate3DTable(order, r, z, phi,
+                               fNR, fNZ, fNPhi,
+                               fLimitsR.GetMatrixArray(),
+                               fLimitsZ.GetMatrixArray(),
+                               fLimitsPhi.GetMatrixArray(),
+                               mDy);
+    dx[2] = Interpolate3DTable(order, r, z, phi,
+                               fNR, fNZ, fNPhi,
+                               fLimitsR.GetMatrixArray(),
+                               fLimitsZ.GetMatrixArray(),
+                               fLimitsPhi.GetMatrixArray(),
+                               mDz   );
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::CreateLookupTable(AliTPCCorrection &tpcCorr, Float_t stepSize/*=5.*/)
+{
+  //
+  // create lookup table for all phi,r,z bins
+  //
+
+  if (fNR==0) {
+    AliError("Limits are not set yet. Please use one of the Set..Limits functions first");
+    return;
+  }
+
+  TStopwatch s;
+  
+  ResetTables();
+  InitTables();
+  
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    CreateLookupTablePhiBin(tpcCorr,iPhi,stepSize);
+  }
+
+  s.Stop();
+  AliInfo(Form("Required time for lookup table creation: %.2f (%.2f) sec. real (cpu)",s.RealTime(),s.CpuTime()));
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::CreateLookupTableSinglePhi(AliTPCCorrection &tpcCorr, Int_t iPhi, Float_t stepSize)
+{
+  //
+  // Lookup table for only one phi bin. Can be used for parallel processing
+  //
+  
+  if (fNR==0) {
+    AliError("Limits are not set yet. Please use one of the Set..Limits functions first");
+    return;
+  }
+
+  TStopwatch s;
+  
+  ResetTables();
+  InitTableArrays();
+  InitTablesPhiBin(iPhi);
+  CreateLookupTablePhiBin(tpcCorr,iPhi,stepSize);
+
+  s.Stop();
+  AliInfo(Form("Required time for lookup table creation: %.2f (%.2f) sec. real (cpu)",s.RealTime(),s.CpuTime()));
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::CreateLookupTablePhiBin(AliTPCCorrection &tpcCorr, Int_t iPhi, Float_t stepSize)
+{
+  //
+  //
+  //
+
+  if (iPhi<0||iPhi>=fNPhi) return;
+  
+  const Float_t delta=stepSize; // 5cm
+  Float_t x[3]={0.,0.,0.};
+  Float_t dx[3]={0.,0.,0.};
+
+  Double_t phi=fLimitsPhi(iPhi);
+  //
+  TMatrixF &mDxDist   = *fLookUpDxDist[iPhi];
+  TMatrixF &mDyDist   = *fLookUpDyDist[iPhi];
+  TMatrixF &mDzDist   = *fLookUpDzDist[iPhi];
+  //
+  TMatrixF &mDxCorr   = *fLookUpDxCorr[iPhi];
+  TMatrixF &mDyCorr   = *fLookUpDyCorr[iPhi];
+  TMatrixF &mDzCorr   = *fLookUpDzCorr[iPhi];
+  
+  for (Int_t ir=0; ir<fNR; ++ir){
+    Double_t r=fLimitsR(ir);
+    x[0]=r * TMath::Cos(phi);
+    x[1]=r * TMath::Sin(phi);
+    
+    for (Int_t iz=0; iz<fNZ; ++iz){
+      Double_t z=fLimitsZ(iz);
+      x[2]=z;
+      //TODO: change hardcoded value for r>133.?
+      Int_t roc=TMath::Nint(phi*TMath::RadToDeg()/20.)%18;
+      if (r>133.) roc+=36;
+      if (z<0)    roc+=18;
+      
+      if (delta>0)
+        tpcCorr.GetDistortionIntegralDz(x,roc,dx,delta);
+      else
+        tpcCorr.GetDistortion(x,roc,dx);
+      mDxDist(ir,iz)=dx[0];
+      mDyDist(ir,iz)=dx[1];
+      mDzDist(ir,iz)=dx[2];
+
+      if (fFillCorrection) {
+        if (delta>0)
+          tpcCorr.GetCorrectionIntegralDz(x,roc,dx,delta);
+        else
+          tpcCorr.GetCorrection(x,roc,dx);
+        mDxCorr(ir,iz)=dx[0];
+        mDyCorr(ir,iz)=dx[1];
+        mDzCorr(ir,iz)=dx[2];
+      }
+    }
+  }
+  
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::InitTables()
+{
+  //
+  // Init all tables
+  //
+
+  InitTableArrays();
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    InitTablesPhiBin(iPhi);
+  }
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::CreateLookupTableFromResidualDistortion(THn &resDist)
+{
+  //
+  // create lookup table from residual distortions stored in a 3d histogram
+  // assume dimensions are r, phi, z
+  //
+  if (fNR==0) {
+    AliError("Limits are not set yet. Please use one of the Set..Limits functions first");
+    return;
+  }
+  
+  ResetTables();
+  InitTables();
+
+  Double_t x[3]={0.,0.,0.};
+  
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    const Double_t phi=fLimitsPhi(iPhi);
+    x[1]=phi;
+    //
+    TMatrixF &mDxDist   = *fLookUpDxDist[iPhi];
+    TMatrixF &mDyDist   = *fLookUpDyDist[iPhi];
+    TMatrixF &mDzDist   = *fLookUpDzDist[iPhi];
+    //
+    TMatrixF &mDxCorr   = *fLookUpDxCorr[iPhi];
+    TMatrixF &mDyCorr   = *fLookUpDyCorr[iPhi];
+    TMatrixF &mDzCorr   = *fLookUpDzCorr[iPhi];
+    
+    for (Int_t ir=0; ir<fNR; ++ir){
+      const Double_t r=fLimitsR(ir);
+      x[0]=r;
+      
+      for (Int_t iz=0; iz<fNZ; ++iz){
+        const Double_t z=fLimitsZ(iz);
+        x[2]=z;
+
+        const Double_t drphi = resDist.GetBinContent(resDist.GetBin(x));
+        Double_t dx[3]={0.,drphi,0.};
+        
+        // transform rphi distortions (local y, so dy') to a global distortion
+        // assume no radial distortion (dx' = 0)
+        // assume no residual distortion in z for the moment
+        Double_t cs=TMath::Cos(phi), sn=TMath::Sin(phi), lx=dx[0];
+        dx[0]=lx*cs - dx[1]*sn; dx[1]=lx*sn + dx[1]*cs;
+
+        mDxDist(ir,iz)=dx[0];
+        mDyDist(ir,iz)=dx[1];
+        mDzDist(ir,iz)=dx[2];
+
+        mDxCorr(ir,iz)=-dx[0];
+        mDyCorr(ir,iz)=-dx[1];
+        mDzCorr(ir,iz)=-dx[2];
+      }
+    }
+  }
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::CreateResidual(AliTPCCorrection *distortion, AliTPCCorrection* correction)
+{
+  //
+  // create lookup table from residual distortions calculated from distorted - correction
+  //
+  
+  ResetTables();
+  InitTables();
+  
+  Float_t x[3]={0.,0.,0.};
+  
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    const Double_t phi=fLimitsPhi(iPhi);
+    //
+    TMatrixF &mDxDist   = *fLookUpDxDist[iPhi];
+    TMatrixF &mDyDist   = *fLookUpDyDist[iPhi];
+    TMatrixF &mDzDist   = *fLookUpDzDist[iPhi];
+    //
+    TMatrixF &mDxCorr   = *fLookUpDxCorr[iPhi];
+    TMatrixF &mDyCorr   = *fLookUpDyCorr[iPhi];
+    TMatrixF &mDzCorr   = *fLookUpDzCorr[iPhi];
+    
+    for (Int_t ir=0; ir<fNR; ++ir){
+      const Double_t r=fLimitsR(ir);
+      x[0]=r * TMath::Cos(phi);
+      x[1]=r * TMath::Sin(phi);
+      
+      for (Int_t iz=0; iz<fNZ; ++iz){
+        const Double_t z=fLimitsZ(iz);
+        x[2]=z;
+
+        //original point
+        Float_t xdc[3]={x[0], x[1], x[2]};
+        
+        Int_t roc=TMath::Nint(phi*TMath::RadToDeg()/20.)%18;
+        if (r>133.) roc+=36;
+        if (z<0)    roc+=18;
+
+        //get residual distortion
+        distortion->DistortPoint(xdc, roc);
+        correction->CorrectPoint(xdc, roc);
+        Float_t dx[3]={xdc[0]-x[0], xdc[1]-x[1], xdc[2]-x[2]};
+        
+        mDxDist(ir,iz)=dx[0];
+        mDyDist(ir,iz)=dx[1];
+        mDzDist(ir,iz)=dx[2];
+        
+        mDxCorr(ir,iz)=-dx[0];
+        mDyCorr(ir,iz)=-dx[1];
+        mDzCorr(ir,iz)=-dx[2];
+      }
+    }
+  }
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::InitTablesPhiBin(Int_t iPhi)
+{
+  //
+  //
+  //
+
+  // check if already initialised
+  if (iPhi<0||iPhi>=fNPhi) return;
+  if (fLookUpDxCorr[iPhi]) return;
+  
+  fLookUpDxCorr[iPhi] = new TMatrixF(fNR,fNZ);
+  fLookUpDyCorr[iPhi] = new TMatrixF(fNR,fNZ);
+  fLookUpDzCorr[iPhi] = new TMatrixF(fNR,fNZ);
+  
+  fLookUpDxDist[iPhi] = new TMatrixF(fNR,fNZ);
+  fLookUpDyDist[iPhi] = new TMatrixF(fNR,fNZ);
+  fLookUpDzDist[iPhi] = new TMatrixF(fNR,fNZ);
+  
+}
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::InitTableArrays()
+{
+  //
+  //
+  //
+
+  // needs to be before the table creation to set the limits
+  SetupDefaultLimits();
+  
+  fLookUpDxCorr = new TMatrixF*[fNPhi];
+  fLookUpDyCorr = new TMatrixF*[fNPhi];
+  fLookUpDzCorr = new TMatrixF*[fNPhi];
+  
+  fLookUpDxDist = new TMatrixF*[fNPhi];
+  fLookUpDyDist = new TMatrixF*[fNPhi];
+  fLookUpDzDist = new TMatrixF*[fNPhi];
+
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    fLookUpDxCorr[iPhi] = 0x0;
+    fLookUpDyCorr[iPhi] = 0x0;
+    fLookUpDzCorr[iPhi] = 0x0;
+    
+    fLookUpDxDist[iPhi] = 0x0;
+    fLookUpDyDist[iPhi] = 0x0;
+    fLookUpDzDist[iPhi] = 0x0;
+  }
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::ResetTables()
+{
+  //
+  // Reset the lookup tables
+  //
+
+  if (!fLookUpDxCorr) return;
+  
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    delete fLookUpDxCorr[iPhi];
+    delete fLookUpDyCorr[iPhi];
+    delete fLookUpDzCorr[iPhi];
+
+    delete fLookUpDxDist[iPhi];
+    delete fLookUpDyDist[iPhi];
+    delete fLookUpDzDist[iPhi];
+  }
+
+  delete [] fLookUpDxCorr;
+  delete [] fLookUpDyCorr;
+  delete [] fLookUpDzCorr;
+  
+  delete [] fLookUpDxDist;
+  delete [] fLookUpDyDist;
+  delete [] fLookUpDzDist;
+  
+  fLookUpDxCorr   = 0x0;
+  fLookUpDyCorr = 0x0;
+  fLookUpDzCorr    = 0x0;
+  
+  fLookUpDxDist   = 0x0;
+  fLookUpDyDist = 0x0;
+  fLookUpDzDist    = 0x0;
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::SetupDefaultLimits()
+{
+  //
+  // Set default limits for tables
+  //
+
+  fNR   = kNR;
+  fNPhi = kNPhi;
+  fNZ   = kNZ;
+  fLimitsR.  ResizeTo(fNR);
+  fLimitsPhi.ResizeTo(fNPhi);
+  fLimitsZ.  ResizeTo(fNZ);
+  fLimitsR.  SetElements(fgkRList);
+  fLimitsPhi.SetElements(fgkPhiList);
+  fLimitsZ.  SetElements(fgkZList);
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::ResetLimits()
+{
+  fNR   = 0;
+  fNPhi = 0;
+  fNZ   = 0;
+
+  fLimitsR.  ResizeTo(1);
+  fLimitsPhi.ResizeTo(1);
+  fLimitsZ.  ResizeTo(1);
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::MergePhiTables(const char* files)
+{
+  //
+  // merge all lookup tables stored in 'files' with this one
+  // assume that each lookup table in each file has only one phi bin
+  //
+
+  ResetTables();
+  ResetLimits(); // use limits from the first file assuming they are all the same
+  
+  TString sfiles=gSystem->GetFromPipe(Form("ls %s",files));
+  TObjArray *arrFiles=sfiles.Tokenize("\n");
+
+  for (Int_t i=0; i<arrFiles->GetEntriesFast();++i){
+    TFile f(arrFiles->At(i)->GetName());
+    if (!f.IsOpen() || f.IsZombie()) continue;
+    AliTPCCorrectionLookupTable *lt=dynamic_cast<AliTPCCorrectionLookupTable*>(f.Get(f.GetListOfKeys()->First()->GetName()));
+    if (!lt) {
+      AliError(Form("first object in file '%s' is not of type AliTPCCorrectionLookupTable!",f.GetName()));
+      continue;
+    }
+
+    if (!fNR) {
+      fNR        = lt->fNR;
+      fNPhi      = lt->fNPhi;
+      fNZ        = lt->fNZ;
+      fLimitsR   = lt->fLimitsR;
+      fLimitsZ   = lt->fLimitsZ;
+      fLimitsPhi = lt->fLimitsPhi;
+      InitTableArrays();
+    } else {
+      if (fNR!=lt->fNR || fNPhi!=lt->fNPhi || fNZ!=lt->fNZ ){
+        AliError(Form("Current limits don't macht the ones in file '%s'",f.GetName()));
+        continue;
+      }
+    }
+
+    for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi) {
+      if (!lt->fLookUpDxCorr[iPhi]) continue;
+
+      AliInfo(Form("Adding phi bin '%d' from file '%s'",iPhi,f.GetName()));
+
+      InitTablesPhiBin(iPhi);
+
+      *fLookUpDxDist[iPhi] = *lt->fLookUpDxDist[iPhi];
+      *fLookUpDyDist[iPhi] = *lt->fLookUpDyDist[iPhi];
+      *fLookUpDzDist[iPhi] = *lt->fLookUpDzDist[iPhi];
+      //
+      *fLookUpDxCorr[iPhi] = *lt->fLookUpDxCorr[iPhi];
+      *fLookUpDyCorr[iPhi] = *lt->fLookUpDyCorr[iPhi];
+      *fLookUpDzCorr[iPhi] = *lt->fLookUpDzCorr[iPhi];
+      break;
+    }
+  }
+
+  //check of all phi bins are initialised
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi) {
+    if (!fLookUpDxCorr[iPhi]) {
+      AliFatal(Form("Phi bin '%d' not initialised from files!",iPhi));
+    }
+  }
+  
+  delete arrFiles;
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::BuildExactInverse()
+{
+  //
+  // this method build the exact inverse of the standard distortion map
+  // for the the distortion man first needs to be calculated
+  // then the correction map will be overwritten
+  //
+
+  Float_t x[3]    = {0.,0.,0.};
+  Float_t x2[3]   = {0.,0.,0.};
+  Float_t xref[3] = {0.,0.,0.};
+  Float_t xd[3]   = {0.,0.,0.};
+  Float_t dx[3]   = {0.,0.,0.};
+
+  // reset correction matrices
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    TMatrixF &mDxCorr   = *fLookUpDxCorr[iPhi];
+    TMatrixF &mDyCorr   = *fLookUpDyCorr[iPhi];
+    TMatrixF &mDzCorr   = *fLookUpDzCorr[iPhi];
+    
+    for (Int_t ir=0; ir<fNR; ++ir){
+      for (Int_t iz=0; iz<fNZ; ++iz){
+        mDxCorr(ir,iz) = -1000.;
+        mDyCorr(ir,iz) = -1000.;
+        mDzCorr(ir,iz) = -1000.;
+      }
+    }
+  }
+  
+  // get interplolated corrections on standard grid
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    Double_t phi=fLimitsPhi(iPhi);
+    TMatrixF &mDxDist   = *fLookUpDxDist[iPhi];
+    TMatrixF &mDyDist   = *fLookUpDyDist[iPhi];
+    TMatrixF &mDzDist   = *fLookUpDzDist[iPhi];
+    
+    for (Int_t ir=0; ir<fNR; ++ir){
+      Double_t r=fLimitsR(ir);
+      x[0]=r * TMath::Cos(phi);
+      x[1]=r * TMath::Sin(phi);
+
+      for (Int_t iz=0; iz<fNZ; ++iz){
+        Double_t z=fLimitsZ(iz);
+        x[2]=z;
+        
+        //TODO: change hardcoded value for r>133.?
+        Int_t roc=TMath::Nint(phi*TMath::RadToDeg()/20.)%18;
+        if (r>133.) roc+=36;
+        if (z<0)    roc+=18;
+
+        dx[0] = mDxDist(ir,iz);
+        dx[1] = mDyDist(ir,iz);
+        dx[2] = mDzDist(ir,iz);
+
+        xd[0] = x[0]+dx[0];
+        xd[1] = x[1]+dx[1];
+        xd[2] = x[2]+dx[2];
+
+        const Double_t phid = TVector2::Phi_0_2pi(TMath::ATan2(xd[1],xd[0]));
+        const Double_t rd   = TMath::Sqrt(xd[0]*xd[0] + xd[1]*xd[1]);
+        const Double_t zd   = xd[2];
+
+        Int_t ilow = 0, jlow = 0, klow = 0 ;
+        
+        Search( fLimitsR.GetNrows(),   fLimitsR.GetMatrixArray(),   rd,   ilow   ) ;
+        Search( fLimitsZ.GetNrows(),   fLimitsZ.GetMatrixArray(),   zd,   jlow   ) ;
+        Search( fLimitsPhi.GetNrows(), fLimitsPhi.GetMatrixArray(), phid, klow   ) ;
+        
+        if ( ilow < 0 ) ilow = 0 ;   // check if out of range
+        if ( jlow < 0 ) jlow = 0 ;
+        if ( klow < 0 ) klow = 0 ;
+        if ( ilow >= fLimitsR.GetNrows())   ilow = fLimitsR.GetNrows() - 1;
+        if ( jlow >= fLimitsZ.GetNrows())   jlow = fLimitsZ.GetNrows() - 1;
+        if ( klow >= fLimitsPhi.GetNrows()) klow = fLimitsPhi.GetNrows() - 1;
+
+        const Double_t phiRef = fLimitsPhi[klow];
+        const Double_t rRef   = fLimitsR[ilow];
+        const Double_t zRef   = fLimitsZ[jlow];
+        
+        TMatrixF &mDxCorr   = *fLookUpDxCorr[klow];
+        if ( mDxCorr(ilow, jlow) > -1000. ) continue;
+        TMatrixF &mDyCorr   = *fLookUpDyCorr[klow];
+        TMatrixF &mDzCorr   = *fLookUpDzCorr[klow];
+        
+        xref[0]= rRef * TMath::Cos(phiRef);
+        xref[1]= rRef * TMath::Sin(phiRef);
+        xref[2]= zRef;
+        
+        FindClosestPosition(ir,iz,iPhi, xref, x2);
+
+        GetDistortion(x2,roc,dx);
+
+        mDxCorr(ilow, jlow) = -dx[0];
+        mDyCorr(ilow, jlow) = -dx[1];
+        mDzCorr(ilow, jlow) = -dx[2];
+
+//         printf("%3d %3d %3d\n",iPhi, ir, iz);
+//         printf("%3d %3d %3d\n",klow, ilow, jlow);
+//         printf("x2:   %.5f %.5f %.5f\n", x2[0], x2[1], x2[2]);
+//         printf("x2d:  %.5f %.5f %.5f\n", x2[0]+dx[0], x2[1]+dx[1], x2[2]+dx[2]);
+//         printf("xref: %.5f %.5f %.5f\n", xref[0], xref[1], xref[2]);
+//         printf("xrd:  %.5f %.5f %.5f\n", x2[0]+dx[0]-xref[0], x2[1]+dx[1]-xref[1], x2[2]+dx[2]-xref[2]);
+//         printf("phid: %.5f %.5f %.5f\n", phid,rd,zd);
+//         printf("phir: %.5f %.5f %.5f\n", phiRef,rRef,zRef);
+//         printf("\n");
+      }
+    }
+  }
+
+  // fill remaining empty bins
+  // The last ein first phi bin entries must be identical, fill those first
+  {
+  TMatrixF &mDxCorr   = *fLookUpDxCorr[0];
+  TMatrixF &mDyCorr   = *fLookUpDyCorr[0];
+  TMatrixF &mDzCorr   = *fLookUpDzCorr[0];
+  
+  TMatrixF &mDxCorr2  = *fLookUpDxCorr[fNPhi-1];
+  TMatrixF &mDyCorr2  = *fLookUpDyCorr[fNPhi-1];
+  TMatrixF &mDzCorr2  = *fLookUpDzCorr[fNPhi-1];
+  
+  for (Int_t ir=0; ir<fNR; ++ir){
+    for (Int_t iz=0; iz<fNZ; ++iz){
+      mDxCorr2(ir,iz) = mDxCorr(ir,iz);
+      mDyCorr2(ir,iz) = mDyCorr(ir,iz);
+      mDzCorr2(ir,iz) = mDzCorr(ir,iz);
+    }
+  }
+  }
+
+  for (Int_t iPhi=0; iPhi<fNPhi; ++iPhi){
+    TMatrixF &mDxCorr   = *fLookUpDxCorr[iPhi];
+    TMatrixF &mDyCorr   = *fLookUpDyCorr[iPhi];
+    TMatrixF &mDzCorr   = *fLookUpDzCorr[iPhi];
+    
+    Double_t phi=fLimitsPhi(iPhi);
+    for (Int_t ir=0; ir<fNR; ++ir){
+      Double_t r=fLimitsR(ir);
+      x[0]=r * TMath::Cos(phi);
+      x[1]=r * TMath::Sin(phi);
+
+      for (Int_t iz=0; iz<fNZ; ++iz){
+        if (mDxCorr(ir,iz) > -999.) continue;
+
+        Double_t z=fLimitsZ(iz);
+        x[2]=z;
+        
+        //TODO: change hardcoded value for r>133.?
+        Int_t roc=TMath::Nint(phi*TMath::RadToDeg()/20.)%18;
+        if (r>133.) roc+=36;
+        if (z<0)    roc+=18;
+        
+        // get last point
+        dx[0] = mDxCorr(ir,iz-1);
+        dx[1] = mDyCorr(ir,iz-1);
+        dx[2] = mDzCorr(ir,iz-1);
+        
+        xd[0] = x[0]+dx[0];
+        xd[1] = x[1]+dx[1];
+        xd[2] = x[2]+dx[2];
+
+        // get distorted point
+        const Double_t phid = TVector2::Phi_0_2pi(TMath::ATan2(xd[1],xd[0]));
+        const Double_t rd   = TMath::Sqrt(xd[0]*xd[0] + xd[1]*xd[1]);
+        const Double_t zd   = xd[2];
+        
+        Int_t ilow = 0, jlow = 0, klow = 0 ;
+        
+        Search( fLimitsR.GetNrows(),   fLimitsR.GetMatrixArray(),   rd,   ilow   ) ;
+        Search( fLimitsZ.GetNrows(),   fLimitsZ.GetMatrixArray(),   zd,   jlow   ) ;
+        Search( fLimitsPhi.GetNrows(), fLimitsPhi.GetMatrixArray(), phid, klow   ) ;
+        
+        if ( ilow < 0 ) ilow = 0 ;   // check if out of range
+        if ( jlow < 0 ) jlow = 0 ;
+        if ( klow < 0 ) klow = 0 ;
+        if ( ilow >= fLimitsR.GetNrows())   ilow = fLimitsR.GetNrows() - 1;
+        if ( jlow >= fLimitsZ.GetNrows())   jlow = fLimitsZ.GetNrows() - 1;
+        if ( klow >= fLimitsPhi.GetNrows()) klow = fLimitsPhi.GetNrows() - 1;
+        
+        FindClosestPosition(ilow,jlow,klow, x, x2);
+        
+        GetDistortion(x2,roc,dx);
+        
+        mDxCorr(ir, iz) = -dx[0];
+        mDyCorr(ir, iz) = -dx[1];
+        mDzCorr(ir, iz) = -dx[2];
+      }
+    }
+  }
+  
+}
+
+//_________________________________________________________________________________________
+void AliTPCCorrectionLookupTable::FindClosestPosition(const Int_t binR, const Int_t binZ, const Int_t binPhi,
+                                                      const Float_t xref[3], Float_t xret[3])
+{
+  //
+  //
+  //
+
+//   static TLinearFitter fitx(2,"pol2");
+//   static TLinearFitter fity(2,"pol2");
+//   static TLinearFitter fitz(2,"pol2");
+  static TLinearFitter fitx(4,"hyp3");
+  static TLinearFitter fity(4,"hyp3");
+  static TLinearFitter fitz(4,"hyp3");
+  fitx.ClearPoints();
+  fity.ClearPoints();
+  fitz.ClearPoints();
+
+  const Int_t nPoints=3;
+  Int_t counter=0;
+  Int_t rMin=binR;
+  Int_t zMin=binZ;
+  Int_t phiMin=binPhi;
+
+  counter=nPoints/2;
+  while (rMin>0 && counter--) --rMin;
+  counter=nPoints/2;
+  while (zMin>0 && counter--) --zMin;
+  counter=nPoints/2;
+  while (phiMin>0 && counter--) --phiMin;
+
+  Int_t rMax   = rMin  +nPoints;
+  Int_t zMax   = zMin  +nPoints;
+  Int_t phiMax = phiMin+nPoints;
+
+  while (rMax>=fNR) {--rMin; --rMax;}
+  while (zMax>=fNZ) {--zMin; --zMax;}
+  while (phiMax>=fNPhi) {--phiMin; --phiMax;}
+  
+  Float_t  x[3]    = {0.,0.,0.};
+  Double_t xd[3]   = {0.,0.,0.};
+  Float_t  dx[3]   = {0.,0.,0.};
+  
+  for (Int_t iPhi=phiMin; iPhi<phiMax; ++iPhi) {
+    TMatrixF &mDxDist   = *fLookUpDxDist[iPhi];
+    TMatrixF &mDyDist   = *fLookUpDyDist[iPhi];
+    TMatrixF &mDzDist   = *fLookUpDzDist[iPhi];
+    
+    Double_t phi=fLimitsPhi(iPhi);
+    for (Int_t ir=rMin; ir<rMax; ++ir){
+      Double_t r=fLimitsR(ir);
+      x[0]=r * TMath::Cos(phi);
+      x[1]=r * TMath::Sin(phi);
+      
+      for (Int_t iz=zMin; iz<zMax; ++iz){
+        Double_t z=fLimitsZ(iz);
+        x[2]=z;
+        
+        dx[0] = mDxDist(ir,iz);
+        dx[1] = mDyDist(ir,iz);
+        dx[2] = mDzDist(ir,iz);
+        
+        xd[0] = x[0]+dx[0];
+        xd[1] = x[1]+dx[1];
+        xd[2] = x[2]+dx[2];
+
+        fitx.AddPoint(xd,   x[0]);
+        fity.AddPoint(xd, x[1]);
+        fitz.AddPoint(xd, x[2]);
+      }
+    }
+  }
+
+  fitx.Eval();
+  fity.Eval();
+  fitz.Eval();
+  xret[0] = fitx.GetParameter(0) + fitx.GetParameter(1)*xref[0]
+                                 + fitx.GetParameter(2)*xref[1]
+                                 + fitx.GetParameter(3)*xref[2];
+  xret[1] = fity.GetParameter(0) + fity.GetParameter(1)*xref[0]
+                                 + fity.GetParameter(2)*xref[1]
+                                 + fity.GetParameter(3)*xref[2];
+  xret[2] = fitz.GetParameter(0) + fitz.GetParameter(1)*xref[0]
+                                 + fitz.GetParameter(2)*xref[1]
+                                 + fitz.GetParameter(3)*xref[2];
+//   xret[0] = fitx.GetParameter(0) + fitx.GetParameter(1)*xref[0] + fitx.GetParameter(2)*xref[0]*xref[0];
+//   xret[1] = fity.GetParameter(0) + fity.GetParameter(1)*xref[1] + fity.GetParameter(2)*xref[1]*xref[1];
+//   xret[2] = fitz.GetParameter(0) + fitz.GetParameter(1)*xref[2] + fitz.GetParameter(2)*xref[2]*xref[2];
+}
+
diff --git a/TPC/Base/AliTPCCorrectionLookupTable.h b/TPC/Base/AliTPCCorrectionLookupTable.h
new file mode 100644 (file)
index 0000000..9c0d65d
--- /dev/null
@@ -0,0 +1,92 @@
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+////////////////////////////////////////////////////////////////////////////
+// AliTPCCorrectionLookupTable class                                              //
+// Authors: Jens Wiechula                                            //
+////////////////////////////////////////////////////////////////////////////
+
+#include "AliTPCCorrection.h"
+#include <TVectorD.h>
+#include <TMatrixFfwd.h>
+#include <THn.h>
+
+class AliTPCCorrectionLookupTable : public AliTPCCorrection {
+
+public:
+  AliTPCCorrectionLookupTable();
+  virtual ~AliTPCCorrectionLookupTable();
+
+  virtual void GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]);
+  virtual void GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]);
+
+  void SetupDefaultLimits();
+  void CreateLookupTable(AliTPCCorrection &tpcCorr, Float_t stepSize=5.);
+  void CreateLookupTableSinglePhi(AliTPCCorrection &tpcCorr, Int_t iPhi, Float_t stepSize=5.);
+
+  void CreateLookupTableFromResidualDistortion(THn &resDist);
+  void CreateResidual(AliTPCCorrection *distortion, AliTPCCorrection* correction);
+  
+  void MergePhiTables(const char* files);
+
+  void   SetFillCorrection(Bool_t fill) { fFillCorrection=fill;   }
+  Bool_t GetFillCorrection() const      { return fFillCorrection; }
+  void BuildExactInverse();
+
+  Int_t GetNR()   const { return fNR;   }
+  Int_t GetNPhi() const { return fNPhi; }
+  Int_t GetNZ()   const { return fNZ;   }
+
+  const TVectorD& GetLimitsR()   const { return fLimitsR; }
+  const TVectorD& GetLimitsPhi() const { return fLimitsPhi; }
+  const TVectorD& GetLimitsZ()   const { return fLimitsZ; }
+  
+  void SetCorrScaleFactor(Float_t    val) { fCorrScaleFactor = val; }
+  Float_t    GetCorrScaleFactor() const { return fCorrScaleFactor; }
+  
+private:
+
+  // sizes of lookup tables
+  // TODO: Remove, since it will be stored in the TVectorD anyhow?
+  Int_t     fNR;                   // number of rows (r) used for lookup table
+  Int_t     fNPhi;                 // number of phi slices used for lookup table
+  Int_t     fNZ;                   // number of columns (z) used for lookup table
+
+  Float_t   fCorrScaleFactor;      // overall scaling factor for the correction
+  
+  Bool_t    fFillCorrection;       // whether to also fill the correction tables
+  //
+  TVectorD  fLimitsR;              // bin limits in row direction
+  TVectorD  fLimitsPhi;            // bin limits in phi direction
+  TVectorD  fLimitsZ;              // bin limits in z direction
+  // for distortion
+  TMatrixF **fLookUpDxDist;        //[fNPhi] Array to store electric field integral (int Er/Ez)
+  TMatrixF **fLookUpDyDist;        //[fNPhi] Array to store electric field integral (int Er/Ez)
+  TMatrixF **fLookUpDzDist;        //[fNPhi] Array to store electric field integral (int Er/Ez)
+
+  // for correction
+  TMatrixF **fLookUpDxCorr;        //[fNPhi] Array to store electric field integral (int Er/Ez)
+  TMatrixF **fLookUpDyCorr;        //[fNPhi] Array to store electric field integral (int Er/Ez)
+  TMatrixF **fLookUpDzCorr;        //[fNPhi] Array to store electric field integral (int Er/Ez)
+
+  void InitTables();
+  void InitTableArrays();
+  void InitTablesPhiBin(Int_t iPhi);
+  
+  void ResetTables();
+  void ResetLimits();
+  
+  void GetInterpolation(const Float_t x[],const Short_t roc,Float_t dx[],
+                        TMatrixF **mR, TMatrixF **mPhi, TMatrixF **mZ);
+
+  void CreateLookupTablePhiBin(AliTPCCorrection &tpcCorr, Int_t iPhi, Float_t stepSize);
+
+  void FindClosestPosition(const Int_t binR, const Int_t binZ, const Int_t binPhi,
+                           const Float_t xref[3], Float_t xret[3]);
+  AliTPCCorrectionLookupTable(const AliTPCCorrectionLookupTable &corr);
+  AliTPCCorrectionLookupTable& operator= (const AliTPCCorrectionLookupTable &corr);
+  
+  ClassDef(AliTPCCorrectionLookupTable,3);  // TPC corrections dumped into a lookup table
+};
+
+
index 37a82d86ae02f9622d47945f51732de53bb5d7e2..67f8ffbbd4630d910026064c5337566971b18b70 100644 (file)
 #include "AliAlignObj.h"
 #include "AliAlignObjParams.h"
 #include "AliLog.h"
+#include "TGraphErrors.h"
+#include "AliTPCcalibDB.h"
+#include "AliMathBase.h"
+
+TObjArray *AliTPCParam::fBBParam = 0;
 
 ClassImp(AliTPCParam)
 
@@ -103,6 +108,15 @@ AliTPCParam::AliTPCParam()
             fOmegaTau(0.),
             fAttCoef(0.),
             fOxyCont(0.),
+             fFpot(0.),
+             fNprim(0.),
+             fNtot(0.),
+             fWmean(0.),
+             fExp(0.),
+             fEend(0.),
+             fBetheBloch(0x0),
+            fGainSlopesHV(0),   // graph with the gain slope as function of HV - per chamber
+            fGainSlopesPT(0),   // graph with the gain slope as function of P/T - per chamber
             fPadCoupling(0.),
             fZeroSup(0),
             fNoise(0.),
@@ -137,6 +151,7 @@ AliTPCParam::AliTPCParam()
 
   SetTitle("75x40_100x60_150x60");
   SetDefault();  
+  if (!fBBParam) fBBParam= new TObjArray(1000);
 }
 
 AliTPCParam::~AliTPCParam()
@@ -399,6 +414,12 @@ void AliTPCParam::SetDefault()
   static const  Float_t  kOmegaTau = 0.145;
   static const  Float_t  kAttCoef = 250.;
   static const  Float_t  kOxyCont = 5.e-6;
+  static const  Float_t  kFpot = 22.77e-9;
+  static const  Float_t  kNprim=14.35;
+  static const  Float_t  kNtot=42.66;
+  static const  Float_t  kWmean = 35.97e-9;
+  static const  Float_t  kExp = 2.2;
+  static const  Float_t  kEend = 10.e-6; 
   //
   //electronic default parameters
   //
@@ -484,6 +505,16 @@ void AliTPCParam::SetDefault()
   SetOmegaTau(kOmegaTau);
   SetAttCoef(kAttCoef);
   SetOxyCont(kOxyCont);
+  SetFpot(kFpot);
+  SetNprim(kNprim);
+  SetNtot(kNtot);
+  SetWmean(kWmean);
+  SetExp(kExp);
+  SetEend(kEend);
+  //
+  SetComposition(0.9,0.,0.1,0.,0.,0.);// Ne-CO2 90/10
+  //
+  SetBetheBloch(GetBetheBlochParamAlice());
   //
   //set electronivc parameters  
   //
@@ -518,6 +549,7 @@ void AliTPCParam::SetDefault()
   SetGateDelay(kGateDelay);
   SetL1Delay(kL1Delay);
   SetNTBinsBeforeL1(kNTBinsBeforeL1);
+  SetNominalGainSlopes();
 }
 
           
@@ -851,3 +883,81 @@ Float_t AliTPCParam::GetChamberCenter(Int_t isec, Float_t * center) const
   }
 }
 
+void AliTPCParam::SetNominalGainSlopes(){
+  //
+  // Setting the nominal TPC gain slopes 
+  // Nominal values were obtained as a mena values foe 2010,2011, and 2012 data
+  // Differntial values can be provided per year
+  //
+  Float_t sector[72]={0};
+  Float_t gainHV[72]={0};
+  Float_t gainPT[72]={0};
+  //
+  for (Int_t isec=0; isec<72; isec++){
+    sector[isec]=isec;
+    gainHV[isec]=0.0115;  // change of the Gain dG/G  per 1 Volt  of voltage change(1/V) - it is roughly the same for IROC and OROC
+    gainPT[isec]=2.2;     // change of the Gains dG/G per P/T change ()
+  }
+  fGainSlopesHV = new TGraphErrors(72,sector,gainHV,0,0);
+  fGainSlopesPT = new TGraphErrors(72,sector,gainPT,0,0);
+  fGainSlopesHV->SetName("GainSlopesHV");
+  fGainSlopesPT->SetName("GainSlopesPT");
+}
+
+
+TVectorD * AliTPCParam::GetBetheBlochParamNa49(){
+  //
+  //  Parameters of the BB for the Aleph parametrization AliMathBase::BetheBlochAleph
+  //  Na49 parameters were used as first set of parameters for ALICE simulation
+  //  (see TPC TDR for details)
+  TVectorD v(5);
+  v(0)=0.76176e-1;
+  v(1)=10.632;
+  v(2)=0.13279e-4;
+  v(3)=1.8631;
+  v(4)=1.9479;
+  return new TVectorD(v);
+}
+
+TVectorD * AliTPCParam::GetBetheBlochParamAlice(){
+  //
+  //
+  //  Parameters of the BB for the Aleph parametrization AliMathBase::BetheBlochAleph
+  //  Na49 parameters were used as first set of parameters for ALICE simulation
+  //  Second set was obtained from ALICE 2009-2013 data taking 
+  //  (see TPC TDR for details)
+  //  
+  TVectorD v(5);
+  v[0] = 0.0851148;
+  v[1] = 9.25771;
+  v[2] = 2.6558e-05;
+  v[3] = 2.32742;
+  v[4] = 1.83039;
+  return new TVectorD(v);
+}
+
+
+Double_t  AliTPCParam::BetheBlochAleph(Double_t bg, Int_t type){
+  //
+  //  GetBetheBloch retur values for the parametrs regieter at poition type 
+  //  Used for visualization and comparison purposes
+  TVectorD * paramBB =0;
+  if (type==0) {
+    AliTPCParam* param = AliTPCcalibDB::Instance()->GetParameters();
+    if (param) paramBB=param->GetBetheBlochParameters();
+  } 
+  if (type>0){
+    paramBB = (TVectorD*)fBBParam->At(type);
+  }
+  if (!paramBB) return 0;
+  //
+  return AliMathBase::BetheBlochAleph(bg,(*paramBB)(0),(*paramBB)(1),(*paramBB)(2),(*paramBB)(3),(*paramBB)(4)); 
+}
+
+
+void AliTPCParam::RegisterBBParam(TVectorD* param, Int_t position){
+  //
+  // 
+  //
+  fBBParam->AddAt(param,position);
+}
index 4984b5ec38c94a8e9a5e372c41e56c58b2fca68b..620b63a4cbdf216ae502198d57e3eae567a5892e 100644 (file)
@@ -13,8 +13,9 @@
 #include "TMath.h"
 
 #include <TGeoMatrix.h>
-
+#include <TVectorD.h>
 class TString;
+class TGraphErrors;
 
 class AliTPCParam : public AliDetectorParam {
   //////////////////////////////////////////////////////
@@ -181,6 +182,29 @@ public:
   void  SetOmegaTau(Float_t OmegaTau){  fOmegaTau=OmegaTau;}
   void  SetAttCoef(Float_t AttCoef){  fAttCoef=AttCoef;}
   void  SetOxyCont(Float_t OxyCont){  fOxyCont=OxyCont;}
+  void  SetGainSlopesHV(TGraphErrors * gainSlopesHV){ fGainSlopesHV=gainSlopesHV;}
+  void  SetGainSlopesPT(TGraphErrors * gainSlopesPT){ fGainSlopesPT=gainSlopesPT;}
+  void  SetNominalGainSlopes();
+  void  SetComposition(Float_t c1, Float_t c2, Float_t c3, Float_t c4, Float_t c5, Float_t c6){fComposition[0]=c1;
+               fComposition[1]=c2;
+               fComposition[2]=c3;
+               fComposition[3]=c4;
+               fComposition[4]=c5;
+               fComposition[5]=c6;}
+  void   SetFpot(Float_t fpot){fFpot=fpot;}
+  void   SetNprim(Float_t prim){fNprim=prim;}
+  void   SetNtot(Float_t ntot){fNtot=ntot;}
+  void   SetWmean(Float_t wmean){fWmean=wmean;}
+  void   SetExp(Float_t exp){fExp=exp;}
+  void   SetEend(Float_t end){fEend=end;}
+  void   SetBetheBloch(TVectorD *v){
+    if (fBetheBloch) delete fBetheBloch;
+    fBetheBloch=0;
+    if (v) fBetheBloch=new TVectorD(*v);
+  }
+  static TVectorD * GetBetheBlochParamNa49();
+  static TVectorD * GetBetheBlochParamAlice();
+  static void RegisterBBParam(TVectorD* param, Int_t position);
   //
   //set electronivc parameters  
   //
@@ -307,7 +331,18 @@ public:
   Float_t  GetDriftV() const {return fDriftV;}
   Float_t  GetOmegaTau() const {return fOmegaTau;}
   Float_t  GetAttCoef() const {return fAttCoef;}
-  Float_t  GetOxyCont() const {return fOxyCont;}
+  Float_t  GetOxyCont() const {return fOxyCont;} 
+  TGraphErrors * GetGainSlopesHV() const { return fGainSlopesHV;}
+  TGraphErrors * GetGainSlopesPT() const { return fGainSlopesPT;}
+  Float_t* GetComposition() {return fComposition;}
+  Float_t  GetFpot()const {return fFpot;}
+  Float_t  GetNprim() const {return fNprim;}
+  Float_t  GetNtot() const {return fNtot;}
+  Float_t  GetWmean()const {return fWmean;}
+  Float_t  GetExp()const {return fExp;}
+  Float_t  GetEend()const {return fEend;}
+  TVectorD* GetBetheBlochParameters(){return fBetheBloch;} 
+  static Double_t BetheBlochAleph(Double_t bb, Int_t type=0);
   //
   //get Electronic parameters
   //
@@ -440,6 +475,17 @@ protected :
   Float_t  fOmegaTau;       //omega tau ExB coeficient
   Float_t  fAttCoef;        //attachment coefitients
   Float_t  fOxyCont;        //oxygen content
+  Float_t  fFpot;            // first ionisation potential
+  Float_t  fNprim;           // number of primary electrons/cm
+  Float_t  fNtot;            //total number of electrons/c (MIP)
+  Float_t  fWmean;           // mean energy for electron/ion pair
+  Float_t  fExp;             // de = f(E) - energy loss parametrization
+  Float_t  fEend;            // upper cutoff for de generation
+  TVectorD*  fBetheBloch;   // Bethe-Bloch parametrization
+  // gas mixture composition
+  Float_t  fComposition[6]; 
+  TGraphErrors * fGainSlopesHV;   // graph with the gain slope as function of HV - per chamber
+  TGraphErrors * fGainSlopesPT;   // graph with the gain slope as function of P/T - per chamber
   //---------------------------------------------------------------------
   //   ALICE TPC  Electronics Parameters
   //--------------------------------------------------------------------
@@ -482,14 +528,15 @@ protected :
   Float_t fL1Delay;         //Delay of L1 arrival for the TPC readout 
   UShort_t fNTBinsBeforeL1; //Number of time bins before L1 arrival which are being read out 
   Float_t fNTBinsL1;        //Overall L1 delay in time bins
-
-private:
+ protected:
+  static TObjArray *fBBParam; // array of the Bethe-Bloch parameters. 
+ private:
   AliTPCParam(const AliTPCParam &);
   AliTPCParam & operator=(const AliTPCParam &);
 
   void CleanGeoMatrices();
 
-  ClassDef(AliTPCParam,5)  //parameter  object for set:TPC
+  ClassDef(AliTPCParam,8)  //parameter  object for set:TPC
 };
 
  
index 0bbe6392c51e06bb7a5dc10219b983d307d2aa4a..4a9947ae6479d378850044633717e1ece287449b 100644 (file)
 //   WriteChargeDistributionToFile. In there, a $\rho(r,z) = (A-B\,z)/r^2$, 
 //   with slightly different magnitude on the A and C side (due to the muon absorber),
 //   is superpositioned with a few leaking wires at arbitrary positions. 
+//
+//
+//   Marian Ivanov change: 26.06.2013
+//   Usage of the realy 3D space charge map as an optional input
+//   SetInputSpaceCharge map.
+//   In case given map is used 2 2D maps are ignored and  scaling functions  $\rho(r,z) = (A-B\,z)/r^2$, 
+//   will not work
+//
+
+
 // End_Html
 //
 // Begin_Macro(source)
@@ -78,6 +88,7 @@
 #include "TMath.h"
 #include "AliTPCROC.h"
 #include "AliTPCSpaceCharge3D.h"
+#include "AliSysInfo.h"
 
 ClassImp(AliTPCSpaceCharge3D)
 
@@ -92,7 +103,10 @@ AliTPCSpaceCharge3D::AliTPCSpaceCharge3D()
     fSCLookUpPOCsFileNameRPhi(""),
     fSCdensityInRZ(0),
     fSCdensityInRPhiA(0), 
-    fSCdensityInRPhiC(0)
+    fSCdensityInRPhiC(0),
+    fSpaceChargeHistogram3D(0),
+    fSpaceChargeHistogramRPhi(0),
+    fSpaceChargeHistogramRZ(0)
 {
   //
   // default constructor
@@ -141,7 +155,9 @@ AliTPCSpaceCharge3D::~AliTPCSpaceCharge3D() {
   delete fSCdensityInRZ;
   delete fSCdensityInRPhiA;
   delete fSCdensityInRPhiC;
-
+  delete fSpaceChargeHistogram3D;
+  delete fSpaceChargeHistogramRPhi;
+  delete fSpaceChargeHistogramRZ;
 }
 
 
@@ -251,7 +267,7 @@ void AliTPCSpaceCharge3D::InitSpaceCharge3DDistortion() {
 
   if (fInitLookUp) {
     AliInfo("Lookup table was already initialized!  Doing it again anyway ...");
-    //    return;
+    return;
   }
   
   // ------------------------------------------------------------------------------------------------------
@@ -1014,8 +1030,8 @@ void AliTPCSpaceCharge3D::InitSpaceCharge3DDistortionCourse() {
 
     // weights (charge density) at POC position on the A and C side (in C/m^3/e0)
     // note: coordinates are in [cm]
-    Double_t weightA = GetSpaceChargeDensity(r0*100,phi0, z0*100);
-    Double_t weightC = GetSpaceChargeDensity(r0*100,phi0,-z0*100);
+    Double_t weightA = GetSpaceChargeDensity(r0*100,phi0, z0*100,0);
+    Double_t weightC = GetSpaceChargeDensity(r0*100,phi0,-z0*100,0);
   
     // Summing up the vector components according to their weight
 
@@ -1081,8 +1097,8 @@ void AliTPCSpaceCharge3D::InitSpaceCharge3DDistortionCourse() {
       
       // weights (charge density) at POC position on the A and C side (in C/m^3/e0)
       // note: coordinates are in [cm]
-      weightA = GetSpaceChargeDensity(r0*100,phi0, z0*100); 
-      weightC = GetSpaceChargeDensity(r0*100,phi0,-z0*100);
+      weightA = GetSpaceChargeDensity(r0*100,phi0, z0*100,0); 
+      weightC = GetSpaceChargeDensity(r0*100,phi0,-z0*100,0);
       
       //     printf("%f %f %f: %e %e\n",r0,phi0,z0,weightA,weightC);
        
@@ -1377,6 +1393,63 @@ void AliTPCSpaceCharge3D::SetSCDataFileName(TString fname) {
   
 }
 
+void     AliTPCSpaceCharge3D::SetInputSpaceCharge(TH3 * hisSpaceCharge3D,  TH2 * hisRPhi, TH2* hisRZ, Double_t norm){
+  //
+  // Use 3D space charge map as an optional input
+  // The layout of the input histogram is assumed to be: (phi,r,z)
+  // Density histogram is expreseed is expected to bin in  C/m^3
+  //
+  // Standard histogram interpolation is used in order to use the density at center of voxel
+  // 
+  //
+  fSpaceChargeHistogram3D = hisSpaceCharge3D;
+  fSpaceChargeHistogramRPhi = hisRPhi;
+  fSpaceChargeHistogramRZ = hisRZ;
+
+  Double_t  r, phi, z ;
+  TMatrixD &scDensityInRZ   =  *fSCdensityInRZ;
+  TMatrixD &scDensityInRPhiA   =  *fSCdensityInRPhiA;
+  TMatrixD &scDensityInRPhiC   =  *fSCdensityInRPhiC;
+  //
+  Double_t rmin=hisSpaceCharge3D->GetYaxis()->GetBinCenter(0);
+  Double_t rmax=hisSpaceCharge3D->GetYaxis()->GetBinUpEdge(hisSpaceCharge3D->GetYaxis()->GetNbins());
+  Double_t zmin=hisSpaceCharge3D->GetZaxis()->GetBinCenter(0);
+  Double_t zmax=hisSpaceCharge3D->GetZaxis()->GetBinCenter(hisSpaceCharge3D->GetZaxis()->GetNbins());
+
+  for ( Int_t k = 0 ; k < kNPhi ; k++ ) {
+    phi = fgkPhiList[k] ;
+    TMatrixF &scDensity   =  *fSCdensityDistribution[k]  ;
+    for ( Int_t j = 0 ; j < kNZ ; j++ ) {
+      z = fgkZList[j] ; 
+      for ( Int_t i = 0 ; i < kNR ; i++ ) { 
+       // Full 3D configuration ...
+       r = fgkRList[i] ;
+       if (r>rmin && r<rmax && z>zmin && z< zmax){               
+         // partial load in (r,z)
+         if (k==0) {
+           if (fSpaceChargeHistogramRZ) scDensityInRZ(i,j) = norm*fSpaceChargeHistogramRZ->Interpolate(r,z) ;
+         }
+         // partial load in (r,phi)
+         if ( (j==0 || j == kNZ/2) && fSpaceChargeHistogramRPhi) {
+           if (z>0) 
+             scDensityInRPhiA(i,k) = norm*fSpaceChargeHistogramRPhi->Interpolate(phi,r);  // A side
+           else 
+             scDensityInRPhiC(i,k) = norm*fSpaceChargeHistogramRPhi->Interpolate(phi+TMath::TwoPi(),r); // C side
+         }
+         
+         if (z>0) 
+           scDensity(i,j) = norm*fSpaceChargeHistogram3D->Interpolate(phi,r,z); 
+         else
+           scDensity(i,j) = norm*fSpaceChargeHistogram3D->Interpolate(phi,r,z);
+       }
+      }
+    }
+  }
+  
+  fInitLookUp = kFALSE;
+
+}
+
 
 Float_t  AliTPCSpaceCharge3D::GetSpaceChargeDensity(Float_t r, Float_t phi, Float_t z, Int_t mode) {
   //
@@ -1602,4 +1675,161 @@ void AliTPCSpaceCharge3D::Print(const Option_t* option) const {
    
   if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitSpaceCharge3DDistortion() ...");
 
+} 
+
+
+
+void AliTPCSpaceCharge3D::InitSpaceCharge3DPoisson(Int_t kRows, Int_t kColumns, Int_t kPhiSlices, Int_t kIterations){
+  //
+  // MI extension  - calculate E field
+  //               - inspired by  AliTPCROCVoltError3D::InitROCVoltError3D()
+  // Initialization of the Lookup table which contains the solutions of the 
+  // Dirichlet boundary problem
+  // Calculation of the single 3D-Poisson solver is done just if needed
+  // (see basic lookup tables in header file)
+  //  
+  Int_t kPhiSlicesPerSector = kPhiSlices/18; 
+  //
+  const Int_t   order       =    1  ;  // Linear interpolation = 1, Quadratic = 2  
+  const Float_t gridSizeR   =  (fgkOFCRadius-fgkIFCRadius) / (kRows-1) ;
+  const Float_t gridSizeZ   =  fgkTPCZ0 / (kColumns-1) ;
+  const Float_t gridSizePhi =  TMath::TwoPi() / ( 18.0 * kPhiSlicesPerSector);
+
+  // temporary arrays to create the boundary conditions
+  TMatrixD *arrayofArrayV[kPhiSlices], *arrayofCharge[kPhiSlices] ; 
+  TMatrixD *arrayofEroverEz[kPhiSlices], *arrayofEphioverEz[kPhiSlices], *arrayofDeltaEz[kPhiSlices] ; 
+
+  for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
+    arrayofArrayV[k]     =   new TMatrixD(kRows,kColumns) ;
+    arrayofCharge[k]     =   new TMatrixD(kRows,kColumns) ;
+    arrayofEroverEz[k]   =   new TMatrixD(kRows,kColumns) ;
+    arrayofEphioverEz[k] =   new TMatrixD(kRows,kColumns) ;
+    arrayofDeltaEz[k]    =   new TMatrixD(kRows,kColumns) ;
+  }
+  
+  // list of point as used in the poisson relation and the interpolation (during sum up)
+  Double_t  rlist[kRows], zedlist[kColumns] , philist[kPhiSlices];
+  for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
+    philist[k] =  gridSizePhi * k;
+    for ( Int_t i = 0 ; i < kRows ; i++ )    {
+      rlist[i] = fgkIFCRadius + i*gridSizeR ;
+      for ( Int_t j = 0 ; j < kColumns ; j++ ) { // Fill Vmatrix with Boundary Conditions
+       zedlist[j]  = j * gridSizeZ ;
+      }
+    }
+  }
+
+  // ==========================================================================
+  // Solve Poisson's equation in 3D cylindrical coordinates by relaxation technique
+  // Allow for different size grid spacing in R and Z directions
+  
+  const Int_t   symmetry = 0;
+  // Set bondaries and solve Poisson's equation --------------------------
+  
+  if ( !fInitLookUp ) {
+    
+    AliInfo(Form("Solving the poisson equation (~ %d sec)",2*10*(int)(kPhiSlices/10)));
+    
+    for ( Int_t side = 0 ; side < 2 ; side++ ) {  // Solve Poisson3D twice; once for +Z and once for -Z
+      AliSysInfo::AddStamp("RunSide", 1,side,0);
+      for ( Int_t k = 0 ; k < kPhiSlices ; k++ )  {
+       TMatrixD &arrayV    =  *arrayofArrayV[k] ;
+       TMatrixD &charge    =  *arrayofCharge[k] ;
+       
+       //Fill arrays with initial conditions.  V on the boundary and Charge in the volume.
+//     for ( Int_t i = 0 ; i < kRows ; i++ ) {
+//       for ( Int_t j = 0 ; j < kColumns ; j++ ) {  // Fill Vmatrix with Boundary Conditions
+//         arrayV(i,j) = 0.0 ; 
+//         charge(i,j) = 0.0 ;
+
+// //      Float_t radius0 = rlist[i] ;
+// //      Float_t phi0    = gridSizePhi * k ;
+           
+//         // To avoid problems at sector boundaries, use an average of +- 1 degree from actual phi location
+// //      if ( j == (kColumns-1) ) {
+// //        arrayV(i,j) = 0.5*  ( GetROCVoltOffset( side, radius0, phi0+0.02 ) + GetROCVoltOffset( side, radius0, phi0-0.02 ) ) ;
+
+// //        if (side==1) // C side
+// //          arrayV(i,j) = -arrayV(i,j); // minus sign on the C side to allow a consistent usage of global z when setting the boundaries
+// //      }
+//       }
+//     }      
+       
+       for ( Int_t i = 1 ; i < kRows-1 ; i++ ) { 
+         for ( Int_t j = 1 ; j < kColumns-1 ; j++ ) {      
+           Float_t radius0 = rlist[i] ;
+           Float_t phi0    = gridSizePhi * k ;
+           Double_t z0 = zedlist[j];
+           if (side==1) z0= -TMath::Abs(zedlist[j]);
+           arrayV(i,j) = 0.0 ; 
+           charge(i,j)  =  fSpaceChargeHistogram3D->Interpolate(phi0,radius0,z0);
+         }
+       }
+      }      
+      AliSysInfo::AddStamp("RunPoisson", 2,side,0);
+      
+      // Solve Poisson's equation in 3D cylindrical coordinates by relaxation technique
+      // Allow for different size grid spacing in R and Z directions
+      
+      //      PoissonRelaxation3D( arrayofArrayV, arrayofCharge, 
+      //                          arrayofEroverEz, arrayofEphioverEz, arrayofDeltaEz,
+      //                          kRows, kColumns, kPhiSlices, gridSizePhi, kIterations, 
+      //                          symmetry , fROCdisplacement) ;
+      PoissonRelaxation3D( arrayofArrayV, arrayofCharge, 
+                          arrayofEroverEz, arrayofEphioverEz, arrayofDeltaEz,
+                          kRows, kColumns, kPhiSlices, gridSizePhi, kIterations, 
+                          symmetry ) ;
+      
+      //Interpolate results onto a custom grid which is used just for these calculations.
+      Double_t  r, phi, z ;
+      for ( Int_t k = 0 ; k < kNPhi ; k++ ) {
+       phi = fgkPhiList[k] ;
+       
+       TMatrixF &erOverEz   =  *fLookUpErOverEz[k]  ;
+       TMatrixF &ephiOverEz =  *fLookUpEphiOverEz[k];
+       TMatrixF &deltaEz    =  *fLookUpDeltaEz[k]   ;
+       
+       for ( Int_t j = 0 ; j < kNZ ; j++ ) {
+
+         z = TMath::Abs(fgkZList[j]) ;  // Symmetric solution in Z that depends only on ABS(Z)
+  
+         if ( side == 0 &&  fgkZList[j] < 0 ) continue; // Skip rest of this loop if on the wrong side
+         if ( side == 1 &&  fgkZList[j] > 0 ) continue; // Skip rest of this loop if on the wrong side
+         
+         for ( Int_t i = 0 ; i < kNR ; i++ ) { 
+           r = fgkRList[i] ;
+
+           // Interpolate basicLookup tables; once for each rod, then sum the results
+           erOverEz(i,j)   = Interpolate3DTable(order, r, z, phi, kRows, kColumns, kPhiSlices, 
+                                                rlist, zedlist, philist, arrayofEroverEz  );
+           ephiOverEz(i,j) = Interpolate3DTable(order, r, z, phi, kRows, kColumns, kPhiSlices,
+                                                rlist, zedlist, philist, arrayofEphioverEz);
+           deltaEz(i,j)    = Interpolate3DTable(order, r, z, phi, kRows, kColumns, kPhiSlices,
+                                                rlist, zedlist, philist, arrayofDeltaEz  );
+
+           if (side == 1)  deltaEz(i,j) = -  deltaEz(i,j); // negative coordinate system on C side
+
+         } // end r loop
+       }// end z loop
+      }// end phi loop
+      AliSysInfo::AddStamp("Interpolate Poisson", 3,side,0);      
+      if ( side == 0 ) AliInfo(" A side done");
+      if ( side == 1 ) AliInfo(" C side done");
+    } // end side loop
+  }
+  
+  // clear the temporary arrays lists
+  for ( Int_t k = 0 ; k < kPhiSlices ; k++ )  {
+    delete arrayofArrayV[k];
+    delete arrayofCharge[k];
+    delete arrayofEroverEz[k];  
+    delete arrayofEphioverEz[k];
+    delete arrayofDeltaEz[k];
+  }
+
+  fInitLookUp = kTRUE;
+
 }
+
index 6abd2fb45970aa31c144486b00e3002406ed266a..a473a3249d96fcbf5304eef43353d9ad86e1bcf4 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "AliTPCCorrection.h"
 class TH3F;
+class TH3;
 
 class AliTPCSpaceCharge3D : public AliTPCCorrection {
 public:
@@ -42,7 +43,9 @@ public:
   void InitSpaceCharge3DDistortionCourse(); // real 3D but not accurate enough
   void ForceInitSpaceCharge3DDistortion() { fInitLookUp=kFALSE; InitSpaceCharge3DDistortion(); }
 
-  Float_t GetSpaceChargeDensity(Float_t r, Float_t phi, Float_t z, Int_t mode=0);
+  void  InitSpaceCharge3DPoisson(Int_t kRows, Int_t kColumns, Int_t kPhiSlices, Int_t kIterations);
+  void ForceInitSpaceCharge3DPoisson(Int_t kRows, Int_t kColumns, Int_t kPhiSlices, Int_t kIterations) { fInitLookUp=kFALSE; InitSpaceCharge3DPoisson(kRows,kColumns,kPhiSlices,kIterations); }
+  Float_t GetSpaceChargeDensity(Float_t r, Float_t phi, Float_t z, Int_t mode);
   TH2F* CreateHistoSCinXY(Float_t z, Int_t nx=100, Int_t ny=100, Int_t mode=0);
   TH2F* CreateHistoSCinZR(Float_t phi, Int_t nz=100, Int_t nr=100, Int_t mode=0);
 
@@ -50,8 +53,15 @@ public:
   void WriteChargeDistributionToFile(const char* fname = "SC-Alice.root");
 
   virtual void Print(const Option_t* option="") const;
+  // MI - Add the "real" 3D histogram as an optional input (26.06.2013)
+  //
+  void    SetInputSpaceCharge(TH3 * hisSpaceCharge3D, TH2 * hisRPhi, TH2* hisRZ, Double_t norm);
+  void    SetInputSpaceCharge3D(TH3 * hisSpaceCharge3D){fSpaceChargeHistogram3D= hisSpaceCharge3D;}
+
+  const TH3 *   GetInputSpaceCharge3D(){return fSpaceChargeHistogram3D;}       // MI add 
+  const TH2 *   GetInputSpaceChargeRPhi(){return fSpaceChargeHistogramRPhi;}       // MI add 
+  const TH2 *   GetInputSpaceChargeRZ(){return fSpaceChargeHistogramRZ;}       // MI add 
 
-protected:
   virtual void GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]);
 
 private:
@@ -86,7 +96,9 @@ private:
   TMatrixD *fSCdensityInRZ;       // (r,z) space charge distribution
   TMatrixD *fSCdensityInRPhiA;     // (r,phi) space charge distribution
   TMatrixD *fSCdensityInRPhiC;     // (r,phi) space charge distribution
+  TH3 *    fSpaceChargeHistogram3D;      // Histogram with the input space charge histogram - used as an optional input 
+  TH2 *    fSpaceChargeHistogramRPhi;      // Histogram with the input space charge histogram - used as an optional input 
+  TH2 *    fSpaceChargeHistogramRZ;      // Histogram with the input space charge histogram - used as an optional input 
   ClassDef(AliTPCSpaceCharge3D,2); 
 };
 
index 8ba3d56bba9b0d5d5e290f7abc4933cac445ac95..08597320337e801107d726bced95e460bfca9c14 100644 (file)
@@ -319,6 +319,7 @@ void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
   static Double_t vdcorrectionTime=1;
   static Double_t vdcorrectionTimeGY=0;
   static Double_t time0corrTime=0;
+  static Double_t deltaZcorrTime=0;
   static Int_t    lastStampT=-1;
   //
   if (lastStampT!=(Int_t)fCurrentTimeStamp){
@@ -334,6 +335,13 @@ void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
                               fCurrentRun,
                               sector%36>=18,
                               fCurrentRecoParam->GetUseDriftCorrectionTime()); 
+      //
+      deltaZcorrTime= AliTPCcalibDB::Instance()->
+       GetVDriftCorrectionDeltaZ(fCurrentTimeStamp, 
+                              fCurrentRun,
+                              sector%36>=18,
+                              0);      
+      
     }
     //
     if(fCurrentRecoParam->GetUseDriftCorrectionGY()>0) {
@@ -407,6 +415,7 @@ void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
   x[2]-= 3.*param->GetZSigma() + time0corrTime;
   // subtract the time offsets
   x[2] = sign*( param->GetZLength(sector) - x[2]);
+  x[2]-=deltaZcorrTime;   // subtrack time dependent z shift (calibrated together with the drift velocity and T0)
 }
 
 void AliTPCTransform::RotatedGlobal2Global(Int_t sector,Double_t *x) const {
index f54cf303bd620dd515f42efb670ef5a6d53ce650..e2eb63b194131bc7bac0bc059727a2936c4c0641 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,7 @@ AliTPCcalibDB::~AliTPCcalibDB()
   //
   // destructor
   //
-  
+  delete fIonTailArray; 
   delete fActiveChannelMap;
   delete fGrRunState;
 }
@@ -490,14 +491,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 +602,117 @@ 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
+
+  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 +1768,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));
     }
@@ -2264,6 +2383,35 @@ Double_t AliTPCcalibDB::GetVDriftCorrectionGy(Int_t timeStamp, Int_t run, Int_t
   return -result/250.; //normalized before
 }
 
+
+Double_t AliTPCcalibDB::GetVDriftCorrectionDeltaZ(Int_t /*timeStamp*/, Int_t run, Int_t /*side*/, Int_t /*mode*/){
+  //
+  // Get deltaZ run/by/run  correction - as fitted together with drift velocity
+  // Value extracted  form the TPC-ITS, mean value is used
+  
+  // Arguments:
+  // mode determines the algorith how to combine the Laser Track, LaserCE or TPC-ITS
+  // timestamp - not used
+  // run       - run number
+  // side      - common for boith sides
+  //
+  if (run<=0 && fTransform) run = fTransform->GetCurrentRunNumber();
+  UpdateRunInformations(run,kFALSE);
+  TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
+  if (!array) return 0;
+  Double_t result=0;
+
+  // use TPC-ITS if present
+  TGraphErrors *gr= (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DELTAZ");
+  if(gr) { 
+    result = TMath::Mean(gr->GetN(), gr->GetY());
+  }
+  return result;
+}
+
+
+
+
 AliTPCCalPad* AliTPCcalibDB::MakeDeadMap(Double_t notInMap, const char* nameMappingFile) {
 //
 //   Read list of active DDLs from OCDB entry
@@ -2382,3 +2530,62 @@ 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, 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
+  // Cache implemented using the static TVectorD
+  //
+  // Input paremeters:
+  //  deltaCache - maximal time differnce above which the cache is recaclulated
+  //  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);
+    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();
+    //
+    for (Int_t isec=0; isec<72; isec++){
+      Double_t deltaHV= GetChamberHighVoltage(run,isec, timeStamp) - fParam->GetNominalVoltage(isec);
+      Double_t deltaGHV=0;
+      Double_t deltaGPT=0;
+      if (graphGHV) deltaGHV = graphGHV->GetY()[isec]*deltaHV;
+      if (graphGPT) deltaGPT = graphGPT->GetY()[isec]*GetPTRelative(timeStamp,run,0);
+      gGainCorrection[isec]=(1.+deltaGHV)*(1.+deltaGPT);
+      gGainCorrectionPT[isec]=1+deltaGPT;
+      gGainCorrectionHV[isec]=1+deltaGHV;
+    }    
+    gTimeStamp=timeStamp;
+  }
+  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;
+}
index bd4901d842b887aa0740616ce96c227af7c30c59..537d2a9be13664bef79d3da40bfddfd66c03761f 100644 (file)
@@ -22,6 +22,7 @@ class AliTPCExB;
 #include "AliSplineFit.h"
 #include "TMap.h"
 
+class TGraphErrors;
 class AliTPCSensorTempArray;
 class AliDCSSensorArray;
 class AliCDBEntry;
@@ -52,6 +53,7 @@ class AliTPCcalibDB : public TObject
   void   Update();  //update entries
   void   UpdateRunInformations(Int_t run, Bool_t force=kFALSE);
   void   UpdateNonRec();
+  Bool_t   GetTailcancelationGraphs(Int_t sector, TGraphErrors ** graphRes, Float_t * indexAmpGraphs);
   //
   Long64_t GetRun() const {return fRun;}
   //
@@ -147,6 +149,7 @@ class AliTPCcalibDB : public TObject
   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;            }
+  Double_t GetGainCorrectionHVandPT(Int_t timeStamp, Int_t run, Int_t sector, Int_t deltaCache, Int_t mode);
   Bool_t  IsDataTakingActive(time_t timeStamp);
   //
   //Goofie Values
@@ -171,6 +174,7 @@ class AliTPCcalibDB : public TObject
   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);
+  Double_t      GetVDriftCorrectionDeltaZ(Int_t timeStamp, Int_t run, Int_t side, Int_t mode);
   //
   AliSplineFit* GetVdriftSplineFit(const char* name, Int_t run);
   AliSplineFit* CreateVdriftSplineFit(const char* graphName, Int_t run);
index aa3424d9ca69f39c82616b23a0c46b37acc3da82..c0684e0be9e1ae363b66b424b89a33841ceefb5c 100644 (file)
@@ -86,6 +86,7 @@ set ( SRCS
     Base/AliTPCROCVoltError3D.cxx 
     Base/AliTPCSpaceCharge.cxx 
     Base/AliTPCSpaceCharge3D.cxx 
+    Base/AliTPCCorrectionLookupTable.cxx
     Base/AliXRDPROOFtoolkit.cxx 
     Base/AliTPCExBEffective.cxx 
     Base/AliTPCExBEffectiveSector.cxx 
diff --git a/TPC/CMakelibTPCupgrade.pkg b/TPC/CMakelibTPCupgrade.pkg
new file mode 100644 (file)
index 0000000..9023703
--- /dev/null
@@ -0,0 +1,43 @@
+# -*- mode: CMake -*-
+
+#--------------------------------------------------------------------------------#
+# Package File for TPCsim                                                        #
+# Author : Johny Jose (johny.jose@cern.ch)                                       #
+# Variables Defined :                                                            #
+#                                                                                #
+# SRCS - C++ source files                                                        #
+# HDRS - C++ header files                                                        #
+# DHDR - ROOT Dictionary Linkdef header file                                     #
+# CSRCS - C source files                                                         #
+# CHDRS - C header files                                                         #
+# EINCLUDE - Include directories                                                 #
+# EDEFINE - Compiler definitions                                                 #
+# ELIBS - Extra libraries to link                                                #
+# ELIBSDIR - Extra library directories                                           #
+# PACKFFLAGS - Fortran compiler flags for package                                #
+# PACKCXXFLAGS - C++ compiler flags for package                                  #
+# PACKCFLAGS - C compiler flags for package                                      #
+# PACKSOFLAGS - Shared library linking flags                                     #
+# PACKLDFLAGS - Module linker flags                                              #
+# PACKBLIBS - Libraries to link (Executables only)                               #
+# EXPORT - Header files to be exported                                           #
+# CINTHDRS - Dictionary header files                                             #
+# CINTAUTOLINK - Set automatic dictionary generation                             #
+# ARLIBS - Archive Libraries and objects for linking (Executables only)          #
+# SHLIBS - Shared Libraries and objects for linking (Executables only)           #
+#--------------------------------------------------------------------------------#
+
+set ( SRCS   
+    Upgrade/AliToyMCTrack.cxx
+    Upgrade/AliToyMCEvent.cxx
+    Upgrade/AliToyMCEventGenerator.cxx
+    Upgrade/AliToyMCEventGeneratorSimple.cxx
+    Upgrade/AliToyMCReconstruction.cxx
+    Upgrade/AliToyMCDrawer.cxx
+)
+
+string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
+
+set ( DHDR  TPCupgradeLinkDef.h)
+
+set ( EINCLUDE  TPC/Base TPC/Rec TPC/Upgrade STEER/STEER STEER/CDB STEER/STEERBase )
index 33016a2415c5f686da89a3cedb186910e3b85caf..b0937d7520938ce76351165c9e590f9df439190d 100644 (file)
@@ -41,7 +41,7 @@
   AliTPCPreprocessorOffline proces;
   proces.CalibTimeGain("TPCMultObjects.root",114000,140040,0);
   TFile oo("OCDB/TPC/Calib/TimeGain/Run114000_121040_v0_s0.root")
 TObjArray * arr = AliCDBEntry->GetObject()
+ TObjArray * arr = AliCDBEntry->GetObject()
   arr->At(4)->Draw("alp")
 
 */
 #include "AliTPCPreprocessorOffline.h"
 #include "AliTPCCorrectionFit.h"
 
+#include "AliTPCClusterParam.h"
+#include "AliTPCRecoParam.h"
+
 using std::endl;
 using std::cout;
+
 ClassImp(AliTPCPreprocessorOffline)
 
 AliTPCPreprocessorOffline::AliTPCPreprocessorOffline():
@@ -253,8 +257,16 @@ void AliTPCPreprocessorOffline::CalibTimeVdrift(const Char_t* file, Int_t ustart
     if (alignmentTime) fVdriftArray->AddLast(alignmentTime);
   }
   //
+  // 5.) Add the RecoParam and ClusterParam - for compatibility checks -different sets of parameters can invalidate calibration 
+  //
+  AliTPCClusterParam *clParam =   AliTPCcalibDB::Instance()->GetClusterParam();
+  TObjArray *recoParams = new TObjArray(4) ;
+  for (Int_t i=0;i<4;i++) recoParams->AddAt(AliTPCcalibDB::Instance()->GetRecoParam(i),i);
+  fVdriftArray->AddLast(clParam);
+  fVdriftArray->AddLast(recoParams);
   //
-  // 5. update of OCDB
+  //
+  // 6. update of OCDB
   //
   //
   UpdateOCDBDrift(ustartRun,uendRun,fOCDBstorage);
@@ -901,6 +913,11 @@ void AliTPCPreprocessorOffline::CalibTimeGain(const Char_t* fileName, Int_t star
   AnalyzeGainMultiplicity();
   AnalyzeGainChamberByChamber();
   //
+  AnalyzeGainDipAngle(0); // short pads
+  AnalyzeGainDipAngle(1); // medium pads
+  AnalyzeGainDipAngle(2); // long pads
+  AnalyzeGainDipAngle(3); // absolute calibration on full track
+  //
   // 3. Make control plots
   //
   MakeQAPlot(1.43);  
@@ -969,7 +986,7 @@ void AliTPCPreprocessorOffline::ReadGainGlobal(const Char_t* fileName){
 Bool_t AliTPCPreprocessorOffline::AnalyzeGain(Int_t startRunNumber, Int_t endRunNumber, Int_t minEntriesGaussFit,  Float_t FPtoMIPratio){
   //
   // Analyze gain - produce the calibration graphs
 //
+ //
 
   // 1.) try to create MIP spline
   if (fGainMIP) 
@@ -1008,6 +1025,21 @@ Bool_t AliTPCPreprocessorOffline::AnalyzeGain(Int_t startRunNumber, Int_t endRun
   // with naming convention and backward compatibility
   fGainArray->AddAt(fGraphMIP,2);
   fGainArray->AddAt(fGraphCosmic,3);
+  //
+  // 3.) Add HV and PT correction parameterization which was used
+  //
+  AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
+  if (param->GetGainSlopesHV())  fGainArray->AddLast(param->GetGainSlopesHV());
+  if (param->GetGainSlopesPT())  fGainArray->AddLast(param->GetGainSlopesPT());
+  //
+  // 4.) Add the RecoParam and ClusterParam - for compatibility checks -deffrent sets of paramters can invalidate calibration 
+  //
+  AliTPCClusterParam *clParam =   AliTPCcalibDB::Instance()->GetClusterParam();
+  TObjArray *recoParams = new TObjArray(4) ;
+  for (Int_t i=0;i<4;i++) recoParams->AddAt(AliTPCcalibDB::Instance()->GetRecoParam(i),i);
+  fGainArray->AddLast(clParam);
+  fGainArray->AddLast(recoParams);
+  //
   cout << "fGraphCosmic: " << fGraphCosmic << " fGraphMIP " << fGraphMIP << endl;
   return kTRUE;
 
@@ -1133,6 +1165,80 @@ Bool_t AliTPCPreprocessorOffline::AnalyzePadRegionGain(){
 }
 
 
+Bool_t AliTPCPreprocessorOffline::AnalyzeGainDipAngle(Int_t padRegion)  {
+  //
+  // Analyze gain as a function of multiplicity and produce calibration graphs
+  // padRegion -- 0: short, 1: medium, 2: long, 3: absolute calibration of full track
+  //
+  if (!fGainMult) return kFALSE;
+  if (!(fGainMult->GetHistTopology())) return kFALSE;
+  //
+  // "dEdxRatioMax","dEdxRatioTot","padType","mult","driftlength"
+  TObjArray arrMax;
+  TObjArray arrTot;
+  //
+  TH2D * histQmax = 0x0;
+  TH2D * histQtot = 0x0;
+  fGainMult->GetHistPadEqual()->GetAxis(4)->SetRangeUser(-0.85,0.85);
+  fGainMult->GetHistTopology()->GetAxis(2)->SetRangeUser(-0.85,0.85);
+  if (padRegion < 3) {
+    fGainMult->GetHistPadEqual()->GetAxis(2)->SetRangeUser(padRegion,padRegion); // short,medium,long
+    histQmax = (TH2D*) fGainMult->GetHistPadEqual()->Projection(0,4);
+    histQtot = (TH2D*) fGainMult->GetHistPadEqual()->Projection(1,4);
+  } else {
+    fGainMult->GetHistTopology()->GetAxis(1)->SetRangeUser(1,1); //Qmax
+    histQmax = (TH2D*) fGainMult->GetHistTopology()->Projection(0,2);
+    histQmax->SetName("fGainMult_GetHistPadEqual_11");
+    fGainMult->GetHistTopology()->GetAxis(1)->SetRangeUser(0,0); //Qtot
+    histQtot = (TH2D*) fGainMult->GetHistTopology()->Projection(0,2);
+    histQtot->SetName("fGainMult_GetHistPadEqual_00");
+  }
+  //  
+  histQmax->FitSlicesY(0,0,-1,0,"QNR",&arrMax);
+  TH1D * corrMax = (TH1D*)arrMax.At(1)->Clone();
+  histQtot->FitSlicesY(0,0,-1,0,"QNR",&arrTot);
+  TH1D * corrTot = (TH1D*)arrTot.At(1)->Clone();
+  corrMax->Scale(1./histQmax->GetMean(2));
+  corrTot->Scale(1./histQtot->GetMean(2));
+  //
+  const char* names[4]={"SHORT","MEDIUM","LONG","ABSOLUTE"};
+  //
+  TGraphErrors * graphMax = new TGraphErrors(corrMax);
+  TGraphErrors * graphTot = new TGraphErrors(corrTot);
+  Double_t meanMax = TMath::Mean(graphMax->GetN(), graphMax->GetY());
+  Double_t meanTot = TMath::Mean(graphTot->GetN(), graphTot->GetY());
+  //
+  for (Int_t ipoint=0; ipoint<graphMax->GetN(); ipoint++) {graphMax->GetY()[ipoint]/=meanMax;}
+  for (Int_t ipoint=0; ipoint<graphTot->GetN(); ipoint++) {graphTot->GetY()[ipoint]/=meanTot;}
+
+  //
+  graphMax->SetNameTitle(Form("TGRAPHERRORS_QMAX_DIPANGLE_%s_BEAM_ALL",names[padRegion]),
+                       Form("TGRAPHERRORS_QMAX_DIPANGLE_%s_BEAM_ALL",names[padRegion]));
+  graphTot->SetNameTitle(Form("TGRAPHERRORS_QTOT_DIPANGLE_%s_BEAM_ALL",names[padRegion]),
+                       Form("TGRAPHERRORS_QTOT_DIPANGLE_%s_BEAM_ALL",names[padRegion]));
+  //
+  fGainArray->AddLast(graphMax);
+  fGainArray->AddLast(graphTot);
+  //
+  // Normalization to 1 (mean of the graph.fY --> 1)
+  //
+  TF1 * funMax= new TF1("","1++abs(x)++abs(x*x)");
+  TF1 * funTot= new TF1("","1++abs(x)++abs(x*x)");
+  graphMax->Fit(funMax,"w","rob=0.9",-0.8,0.8);
+  graphTot->Fit(funTot,"w","rob=0.9",-0.8,0.8);
+  funMax->SetNameTitle(Form("TF1_QMAX_DIPANGLE_%s_BEAM_ALL",names[padRegion]),
+                       Form("TF1_QMAX_DIPANGLE_%s_BEAM_ALL",names[padRegion]));
+  funTot->SetNameTitle(Form("TF1_QTOT_DIPANGLE_%s_BEAM_ALL",names[padRegion]),
+                       Form("TF1_QTOT_DIPANGLE_%s_BEAM_ALL",names[padRegion]));
+
+  //
+  fGainArray->AddLast(funMax);
+  fGainArray->AddLast(funTot);
+  //
+  return kTRUE;
+}
+
+
 Bool_t AliTPCPreprocessorOffline::AnalyzeGainMultiplicity() {
   //
   // Analyze gain as a function of multiplicity and produce calibration graphs
@@ -1146,8 +1252,11 @@ Bool_t AliTPCPreprocessorOffline::AnalyzeGainMultiplicity() {
   //
   TObjArray arrMax;
   TObjArray arrTot;
-  histMultMax->FitSlicesY(0,0,-1,0,"QNR",&arrMax);
-  histMultTot->FitSlicesY(0,0,-1,0,"QNR",&arrTot);
+  TF1 fitGaus("fitGaus","gaus(0)",histMultMax->GetYaxis()->GetXmin(),histMultMax->GetYaxis()->GetXmax());
+  fitGaus.SetParameters(histMultMax->GetEntries()/10., histMultMax->GetMean(2), TMath::Sqrt(TMath::Abs(histMultMax->GetMean(2))));
+  histMultMax->FitSlicesY(&fitGaus,0,-1,1,"QNRB",&arrMax);
+  fitGaus.SetParameters(histMultTot->GetEntries()/10., histMultTot->GetMean(2), TMath::Sqrt(TMath::Abs(histMultTot->GetMean(2))));
+  histMultTot->FitSlicesY(&fitGaus,0,-1,1,"QNRB",&arrTot);
   //
   TH1D * meanMax = (TH1D*)arrMax.At(1);
   TH1D * meanTot = (TH1D*)arrTot.At(1);
@@ -1215,9 +1324,9 @@ Bool_t AliTPCPreprocessorOffline::AnalyzeGainChamberByChamber(){
   // get chamber by chamber gain
   //
   if (!fGainMult) return kFALSE;
-  TGraphErrors *grShort  = fGainMult->GetGainPerChamber(0);
-  TGraphErrors *grMedium = fGainMult->GetGainPerChamber(1);
-  TGraphErrors *grLong   = fGainMult->GetGainPerChamber(2);
+  TGraphErrors *grShort  = fGainMult->GetGainPerChamberRobust(0);
+  TGraphErrors *grMedium = fGainMult->GetGainPerChamberRobust(1);
+  TGraphErrors *grLong   = fGainMult->GetGainPerChamberRobust(2);
   if (grShort==0x0 || grMedium==0x0 || grLong==0x0) {
     delete grShort;
     delete grMedium;
@@ -1728,3 +1837,11 @@ Int_t AliTPCPreprocessorOffline::GetStatus()
 
   return fCalibrationStatus;
 }
+
+/*
+  Short sequence to acces the calbration entry:
+  TFile *f = TFile::Open("CalibObjects.root");
+  AliTPCcalibGainMult      * fGainMult = (AliTPCcalibGainMult      *)f->Get("TPCCalib/calibGainMult");
+  
+*/
index 3766d3ac9ead038fd6869fb747b59f4230369699..2c7de5b588527b9832b8ea1761aa8d5cbfb84874 100644 (file)
@@ -50,6 +50,7 @@ public:
   Bool_t AnalyzeGain(Int_t startRunNumber, Int_t endRunNumber, Int_t minEntriesGaussFit = 500, Float_t FPtoMIPratio = 1.43); 
   Bool_t AnalyzeAttachment(Int_t startRunNumber, Int_t endRunNumber, Int_t minEntriesFit = 2000);
   Bool_t AnalyzePadRegionGain();
+  Bool_t AnalyzeGainDipAngle(Int_t padRegion = 0);
   Bool_t AnalyzeGainMultiplicity();
   Bool_t AnalyzeGainChamberByChamber();
   void SetTimeGainRange(Double_t minGain=2.0, Double_t maxGain = 3.0) 
index 495502e61832c67bd7074341aff661eb5faa797d..3987a4b48a84637b5ebce6a790a2dbaa9ae3a927 100644 (file)
@@ -208,13 +208,20 @@ Bool_t  AliTPCcalibCalib::RefitTrack(AliESDtrack * track, AliTPCseed *seed, Floa
   // First apply calibration
   //
   //  AliTPCPointCorrection * corr =  AliTPCPointCorrection::Instance();
+  TVectorD vec(5, seed->GetParameter());
   for (Int_t irow=0;irow<159;irow++) {
     AliTPCclusterMI *cluster=seed->GetClusterPointer(irow);
     if (!cluster) continue; 
     AliTPCclusterMI cl0(*cluster);
     Double_t x[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
     Int_t i[1]={cluster->GetDetector()};
-
+    AliTPCTrackerPoint * point = seed->GetTrackPoint(irow);
+    Double_t ty=0,tz=0;
+     
+    if (point){
+      ty = TMath::Abs(point->GetAngleY());
+      tz = TMath::Abs(point->GetAngleZ()*TMath::Sqrt(1+ty*ty));      
+    }
     transform->Transform(x,i,0,1);
     //
     // get position correction
@@ -248,7 +255,7 @@ Bool_t  AliTPCcalibCalib::RefitTrack(AliESDtrack * track, AliTPCseed *seed, Floa
 
 
 
-    if (fStreamLevel>2 && streamCounter<20*fStreamLevel ){
+    if (fStreamLevel>2 && gRandom->Rndm()<0.1 ){
       // dump debug info if required
       TTreeSRedirector *cstream = GetDebugStreamer();
       if (cstream){
@@ -263,6 +270,9 @@ Bool_t  AliTPCcalibCalib::RefitTrack(AliESDtrack * track, AliTPCseed *seed, Floa
          "cl.="<<cluster<<
          "cy="<<dy<<
          "cz="<<dz<<
+         "ty="<<ty<<
+         "tz="<<tz<<
+         "vec.="<<&vec<<  //track parameters
          "\n";
       }
     }
@@ -441,6 +451,8 @@ Bool_t  AliTPCcalibCalib::RefitTrack(AliESDtrack * track, AliTPCseed *seed, Floa
        "nclIn="<<nclIn<<
        "nclOut="<<nclOut<<
        "ncl="<<ncl<<
+       "seed.="<<seed<<
+       "track.="<<track<<
        "TrIn0.="<<trackInOld<<
        "TrOut0.="<<trackOutOld<<
        "TrIn1.="<<&trackIn<<
index 51a13f2e2c5c38000f5b6f254f4d392e469afd64..49d444aa73d60ccef379d248968a173db01904c3 100644 (file)
@@ -67,6 +67,7 @@ Send comments etc. to: A.Kalweit@gsi.de, marian.ivanov@cern.ch
 #include "AliTracker.h"
 #include "AliTPCTransform.h"
 #include "AliTPCROC.h"
+#include "TStatToolkit.h"
 
 ClassImp(AliTPCcalibGainMult)
 
@@ -78,12 +79,21 @@ AliTPCcalibGainMult::AliTPCcalibGainMult()
    fLowerTrunc(0),
    fUpperTrunc(0),
    fUseMax(kFALSE),
+   fCutCrossRows(0),
+   fCutEtaWindow(0),
+   fCutRequireITSrefit(0),
+   fCutMaxDcaXY(0),
+   fCutMaxDcaZ(0),
+   fMinMomentumMIP(0),
+   fMaxMomentumMIP(0),
+   fAlephParameters(),
    fHistNTracks(0),
    fHistClusterShape(0),
    fHistQA(0),
    fHistGainSector(0),
    fHistPadEqual(0),
    fHistGainMult(0),
+   fHistTopology(0),
    fPIDMatrix(0),
    fHistdEdxMap(0),
    fHistdEdxMax(0),
@@ -104,12 +114,21 @@ AliTPCcalibGainMult::AliTPCcalibGainMult(const Text_t *name, const Text_t *title
    fLowerTrunc(0),
    fUpperTrunc(0),
    fUseMax(kFALSE),
+   fCutCrossRows(0),
+   fCutEtaWindow(0),
+   fCutRequireITSrefit(0),
+   fCutMaxDcaXY(0),
+   fCutMaxDcaZ(0),
+   fMinMomentumMIP(0),
+   fMaxMomentumMIP(0),
+   fAlephParameters(),
    fHistNTracks(0),
    fHistClusterShape(0),
    fHistQA(0),
    fHistGainSector(0),
    fHistPadEqual(0),
    fHistGainMult(0),
+   fHistTopology(0),
    fPIDMatrix(0),
    fHistdEdxMap(0),
    fHistdEdxMax(0),
@@ -128,12 +147,30 @@ AliTPCcalibGainMult::AliTPCcalibGainMult(const Text_t *name, const Text_t *title
   fUpperTrunc = 0.6;
   fUseMax = kTRUE; // IMPORTANT CHANGE FOR PbPb; standard: kFALSE;
   //
+  // define track cuts and default BB parameters for interpolation around mean
+  //
+  fCutCrossRows = 80;
+  fCutEtaWindow = 0.8;
+  fCutRequireITSrefit = kFALSE;
+  fCutMaxDcaXY = 3.5;
+  fCutMaxDcaZ  = 25.;
+  // default values for MIP window selection
+  fMinMomentumMIP = 0.4;
+  fMaxMomentumMIP = 0.6;
+  fAlephParameters[0] = 0.07657; // the following parameters work for most of the periods and are therefore default
+  fAlephParameters[1] = 10.6654; // but they can be overwritten in the train setup of cpass0
+  fAlephParameters[2] = 2.51466e-14;
+  fAlephParameters[3] = 2.05379;
+  fAlephParameters[4] = 1.84288;
+  //
+  // basic QA histograms - mainly for debugging purposes
+  //
   fHistNTracks = new TH1F("ntracks","Number of Tracks per Event; number of tracks per event; number of tracks",1001,-0.5,1000.5);
   fHistClusterShape = new TH1F("fHistClusterShape","cluster shape; rms meas. / rms exp.;",300,0,3);
   fHistQA = new TH3F("fHistQA","dEdx; momentum p (GeV); TPC signal (a.u.); pad",500,0.1,20.,500,0.,500,6,-0.5,5.5);
   AliTPCcalibBase::BinLogX(fHistQA);
   //
-  //
+  // gain per chamber
   //                          MIP, sect,  pad (short,med,long,full,oroc),   run,      ncl
   Int_t binsGainSec[5]    = { 145,   72,    4,  10000000,   65};
   Double_t xminGainSec[5] = { 10., -0.5, -0.5,      -0.5, -0.5}; 
@@ -147,13 +184,13 @@ AliTPCcalibGainMult::AliTPCcalibGainMult(const Text_t *name, const Text_t *title
     fHistGainSector->GetAxis(iaxis)->SetTitle(axisTitleSec[iaxis]);
   }
   //
+  // pad region equalization
   //
-  //
-  Int_t binsPadEqual[5]    = { 400, 400,    4,   10,   10};
-  Double_t xminPadEqual[5] = { 0.0, 0.0, -0.5,    0, -250}; 
-  Double_t xmaxPadEqual[5] = { 2.0, 2.0,  3.5, 13000, 250};
-  TString axisNamePadEqual[5]   = {"dEdxRatioMax","dEdxRatioTot","padType","mult","driftlength"};
-  TString axisTitlePadEqual[5]  = {"dEdx_padRegion/mean_dEdx Qmax", "dEdx_padRegion/mean_dEdx Qtot","padType","mult","driftlength"};
+  Int_t binsPadEqual[5]    = { 400, 400,    4,    5,   20};
+  Double_t xminPadEqual[5] = { 0.0, 0.0, -0.5,    0,  -1.}; 
+  Double_t xmaxPadEqual[5] = { 2.0, 2.0,  3.5, 13000,  +1};
+  TString axisNamePadEqual[5]   = {"dEdxRatioMax","dEdxRatioTot","padType","mult","dipAngle"};
+  TString axisTitlePadEqual[5]  = {"dEdx_padRegion/mean_dEdx Qmax", "dEdx_padRegion/mean_dEdx Qtot","padType","mult","tan(lambda)"};
   //
   fHistPadEqual = new THnSparseF("fHistPadEqual","0:dEdx_pad/dEdx_mean, 1:pad, 2:mult, 3:drift", 5, binsPadEqual, xminPadEqual, xmaxPadEqual);
   for (Int_t iaxis=0; iaxis<5;iaxis++){
@@ -161,7 +198,7 @@ AliTPCcalibGainMult::AliTPCcalibGainMult(const Text_t *name, const Text_t *title
     fHistPadEqual->GetAxis(iaxis)->SetTitle(axisTitlePadEqual[iaxis]);
   }
   //
-  //
+  // multiplicity dependence
   //                    MIP Qmax, MIP Qtot,  z,  pad, vtx. contribut., ncl
   Int_t binsGainMult[6]    = { 145,  145,   25,    4,  100,  80};
   Double_t xminGainMult[6] = { 10.,  10.,    0, -0.5,    0, -0.5}; 
@@ -174,6 +211,26 @@ AliTPCcalibGainMult::AliTPCcalibGainMult(const Text_t *name, const Text_t *title
     fHistGainMult->GetAxis(iaxis)->SetName(axisNameMult[iaxis]);
     fHistGainMult->GetAxis(iaxis)->SetTitle(axisTitleMult[iaxis]);
   }
+  //
+  // dip-angle (theta or eta) and inclination angle (local phi) dependence -- absolute calibration
+  //
+  //              (0.) weighted dE/dx, (1.) 0:Qtot - 1:Qmax, (2.) tgl, (3.) 1./pT
+  Int_t binsTopology[4]        = {145,                    2,       20,  20};
+  Double_t xminTopology[4]     = { 10,                 -0.5,       -1,   0};
+  Double_t xmaxTopology[4]     = { 300,                  1.5,       +1,   5};
+  TString axisNameTopology[4]  = {"dEdx",        "QtotQmax",    "tgl", "1/pT"};
+  TString axisTitleTopology[4] = {"dEdx",        "QtotQmax",    "tgl", "1/pT"};
+  //
+  fHistTopology = new THnF("fHistTopology", "dEdx,QtotQmax,tgl, 1/pT", 4, binsTopology, xminTopology, xmaxTopology);
+  for (Int_t iaxis=0; iaxis<4;iaxis++){
+    fHistTopology->GetAxis(iaxis)->SetName(axisNameTopology[iaxis]);
+    fHistTopology->GetAxis(iaxis)->SetTitle(axisTitleTopology[iaxis]);
+  }
+  //
+  // MI suggestion for all dEdx histograms we shpuld keep log scale - to have the same relative resolution
+  //
+  // e.g: I want to enable -   AliTPCcalibBase::BinLogX(fHistTopology->GetAxis(0));
+
   //
   //
   //                    dedx maps - bigger granulatity in phi -
@@ -223,6 +280,7 @@ AliTPCcalibGainMult::~AliTPCcalibGainMult(){
   delete fHistGainSector;   //  histogram which shows MIP peak for each of the 3x36 sectors (pad region)
   delete fHistPadEqual;     //  histogram for the equalization of the gain in the different pad regions -> pass0
   delete fHistGainMult;     //  histogram which shows decrease of MIP signal as a function
+  delete fHistTopology;
   //
   delete fHistdEdxMap;
   delete fHistdEdxMax;
@@ -251,11 +309,11 @@ void AliTPCcalibGainMult::Process(AliESDEvent *event) {
   //
   // Criteria for the track selection
   //
-  const Int_t kMinNCL=80;     // minimal number of cluster  - tracks accepted for the dedx calibration
-  const Double_t kMaxEta=0.8; // maximal eta fo the track to be accepted
-  const Double_t kMaxDCAR=10; // maximal DCA R of the track
-  const Double_t kMaxDCAZ=5;  // maximal DCA Z of the track
-  const Double_t kMIPPt=0.45; // MIP pt
+  //  const Int_t kMinNCL=80;     // minimal number of cluster  - tracks accepted for the dedx calibration
+  //const Double_t kMaxEta=0.8; // maximal eta fo the track to be accepted
+  //const Double_t kMaxDCAR=10; // maximal DCA R of the track
+  //const Double_t kMaxDCAZ=5;  // maximal DCA Z of the track
+  //  const Double_t kMIPPt=0.525; // MIP pt
   
   if (!event) {
     Printf("ERROR: ESD not available");
@@ -272,16 +330,16 @@ void AliTPCcalibGainMult::Process(AliESDEvent *event) {
   }
   if (!(esdFriend->TestSkipBit())) fPIDMatrix= new TMatrixD(ntracks,5);
   fHistNTracks->Fill(ntracks);
-  ProcessCosmic(event);  // usually not enogh statistic
+  //  ProcessCosmic(event);  // usually not enogh statistic
 
   if (esdFriend->TestSkipBit()) {
     return;
-  }
+   }
   //
-  ProcessV0s(event);   // 
-  ProcessTOF(event);   //
+  //ProcessV0s(event);   // 
+  //ProcessTOF(event);   //
   //ProcessKinks(event); // not relyable
-  DumpHPT(event);      // 
+  //DumpHPT(event);      // 
   UInt_t runNumber = event->GetRunNumber();
   Int_t nContributors = event->GetNumberOfTracks();
   //
@@ -298,21 +356,31 @@ void AliTPCcalibGainMult::Process(AliESDEvent *event) {
     // calculate necessary track parameters
     Double_t meanP = trackIn->GetP();
     Int_t ncls = track->GetTPCNcls();
-
-    if (ncls < kMinNCL) continue;     
+    Int_t nCrossedRows = track->GetTPCCrossedRows();
+
+    // correction factor of dE/dx in MIP window
+    Float_t corrFactorMip = AliExternalTrackParam::BetheBlochAleph(meanP/0.13957, 
+                                                                  fAlephParameters[0], 
+                                                                  fAlephParameters[1], 
+                                                                  fAlephParameters[2], 
+                                                                  fAlephParameters[3],
+                                                                  fAlephParameters[4]);
+    if (TMath::Abs(corrFactorMip) < 1e-10) continue;
+    
+    if (nCrossedRows < fCutCrossRows) continue;     
     // exclude tracks which do not look like primaries or are simply too short or on wrong sectors
-    if (TMath::Abs(trackIn->Eta()) > kMaxEta) continue;
+    if (TMath::Abs(trackIn->Eta()) > fCutEtaWindow) continue;
 
     UInt_t status = track->GetStatus();
     if ((status&AliESDtrack::kTPCrefit)==0) continue;
-    //if (track->GetNcls(0) < 3) continue; // ITS clusters
+    if ((status&AliESDtrack::kITSrefit)==0 && fCutRequireITSrefit) continue; // ITS cluster
     Float_t dca[2], cov[3];
     track->GetImpactParameters(dca,cov);
     Float_t primVtxDCA = TMath::Sqrt(dca[0]*dca[0]);
-    if (primVtxDCA > kMaxDCAR || primVtxDCA < 0.00001) continue;
-    if (TMath::Abs(dca[1]) > kMaxDCAZ) continue;
-    //
+    if (TMath::Abs(dca[0]) > fCutMaxDcaXY || TMath::Abs(dca[0]) < 0.0000001) continue;  // cut in xy
+    if (((status&AliESDtrack::kITSrefit) == 1 && TMath::Abs(dca[1]) > 3.) || TMath::Abs(dca[1]) > fCutMaxDcaZ ) continue;
     //
+    //  
     // fill Alexander QA histogram
     //
     if (primVtxDCA < 3 && track->GetNcls(0) > 3 && track->GetKinkIndex(0) == 0 && ncls > 100) fHistQA->Fill(meanP, track->GetTPCsignal(), 5);
@@ -333,6 +401,7 @@ void AliTPCcalibGainMult::Process(AliESDEvent *event) {
       if (!trackIn) continue;
       if (!trackOut) continue;
       Double_t meanDrift = 250 - 0.5*TMath::Abs(trackIn->GetZ() + trackOut->GetZ());
+      Double_t dipAngleTgl  = trackIn->GetTgl();
       //
       for (Int_t irow =0; irow<160;irow++)    {
        AliTPCTrackerPoint * point = seed->GetTrackPoint(irow);
@@ -355,8 +424,10 @@ void AliTPCcalibGainMult::Process(AliESDEvent *event) {
       //
       Double_t signalShortTot = seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,0,0,62);
       Double_t signalMedTot   = seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,0,63,126);
-      Double_t signalLongTot  = seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,0,127,159);
-      Double_t signalTot      = seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,0,row0,row1);
+      Double_t signalLongTot  = seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,0,127,159); 
+      //
+      Double_t signalTot      = 0;
+      //
       Double_t signalArrayTot[4] = {signalShortTot, signalMedTot, signalLongTot, signalTot};
       //
       Double_t mipSignalShort = fUseMax ? signalShortMax : signalShortTot;
@@ -371,36 +442,55 @@ void AliTPCcalibGainMult::Process(AliESDEvent *event) {
       fHistQA->Fill(meanP, signal, 3);
       fHistQA->Fill(meanP, mipSignalOroc, 4);
       //
-      // "dEdxRatioMax","dEdxRatioTot","padType","mult","driftlength", "1_pt"
-      Float_t meanMax = (1/3.)*(signalArrayMax[0] + signalArrayMax[1] + signalArrayMax[2]);
-      Float_t meanTot = (1/3.)*(signalArrayTot[0] + signalArrayTot[1] + signalArrayTot[2]); 
-      if (meanMax < 1e-5 || meanTot < 1e-5) continue;
+      // normalize pad regions to their common mean
+      //
+      Float_t meanMax = (63./159)*signalArrayMax[0] + (64./159)*signalArrayMax[1] + (32./159)*signalArrayMax[2];
+      Float_t meanTot = (63./159)*signalArrayTot[0] + (64./159)*signalArrayTot[1] + (32./159)*signalArrayTot[2]; 
+      //MY SUGGESTION COMMENT NEXT LINE
+      //      if (meanMax < 1e-5 || meanTot < 1e-5) continue;      
+      //AND INTRODUCE NEW LINE
+      // 
+      const Double_t kMinAmp=0.001;
+      if (signalArrayMax[0]<=kMinAmp) continue;
+      if (signalArrayMax[1]<=kMinAmp) continue;
+      if (signalArrayMax[2]<=kMinAmp) continue;
+      if (signalArrayTot[0]<=kMinAmp) continue;
+      if (signalArrayTot[1]<=kMinAmp) continue;
+      if (signalArrayTot[2]<=kMinAmp) continue;
+      //
       for(Int_t ipad = 0; ipad < 4; ipad ++) {
-       Double_t vecPadEqual[5] = {signalArrayMax[ipad]/meanMax, signalArrayTot[ipad]/meanTot, ipad, nContributors, meanDrift};
-       if ( TMath::Abs(meanP-kMIPPt)<0.05 ) fHistPadEqual->Fill(vecPadEqual);
+       // "dEdxRatioMax","dEdxRatioTot","padType","mult","driftlength"
+       Double_t vecPadEqual[5] = {signalArrayMax[ipad]/meanMax, signalArrayTot[ipad]/meanTot, ipad, nContributors, dipAngleTgl};
+       if (fMinMomentumMIP > meanP && meanP < fMaxMomentumMIP) fHistPadEqual->Fill(vecPadEqual);
       }
       //
-      //      if (meanP > 0.4 && meanP < 0.55) {
-      if ( TMath::Abs(meanP-kMIPPt)<0.05 ) {
-       Double_t vecMult[6] = {seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,1,row0,row1),
-                              seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,0,row0,row1),
+      //
+      if (meanP < fMaxMomentumMIP && meanP > fMinMomentumMIP) {
+       Double_t vecMult[6] = {seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,1,row0,row1)/corrFactorMip,
+                              seed->CookdEdxAnalytical(fLowerTrunc,fUpperTrunc,0,row0,row1)/corrFactorMip,
                               meanDrift,
                               3,
                               nContributors,
                               ncls};
        //
        fHistGainMult->Fill(vecMult);
-       vecMult[0]=mipSignalShort; vecMult[1]=mipSignalShort; vecMult[3]=0;
+       vecMult[0]=mipSignalShort/corrFactorMip; vecMult[1]=mipSignalShort/corrFactorMip; vecMult[3]=0;
        fHistGainMult->Fill(vecMult);
-       vecMult[0]=mipSignalMed; vecMult[1]=mipSignalMed; vecMult[3]=1;
+       vecMult[0]=mipSignalMed/corrFactorMip; vecMult[1]=mipSignalMed/corrFactorMip; vecMult[3]=1;
        fHistGainMult->Fill(vecMult);
-       vecMult[0]=mipSignalLong; vecMult[1]=mipSignalLong; vecMult[3]=2;
+       vecMult[0]=mipSignalLong/corrFactorMip; vecMult[1]=mipSignalLong/corrFactorMip; vecMult[3]=2;
        fHistGainMult->Fill(vecMult);
        //
+       // topology histogram (absolute)
+       //                        (0.) weighted dE/dx, (1.) 0:Qtot - 1:Qmax, (2.) tgl, (3.) 1./pT
+       Double_t vecTopolTot[4] = {meanTot, 0, dipAngleTgl, TMath::Abs(track->GetSigned1Pt())};
+       Double_t vecTopolMax[4] = {meanMax, 1, dipAngleTgl, TMath::Abs(track->GetSigned1Pt())};
+       fHistTopology->Fill(vecTopolTot);
+       fHistTopology->Fill(vecTopolMax);
       }
       //
       //
-      if ( TMath::Abs(meanP-kMIPPt)>0.05 ) continue;  // only MIP pions
+      if (fMinMomentumMIP < meanP || meanP > fMaxMomentumMIP) continue;  // only MIP pions
       //if (meanP > 0.5 || meanP < 0.4) continue; // only MIP pions
       //
       // for each track, we look at the three different pad regions, split it into tracklets, check if the sector does not change and fill the histogram
@@ -428,7 +518,7 @@ void AliTPCcalibGainMult::Process(AliESDEvent *event) {
       //
       //                        MIP, sect,  pad,   run
       //
-      Double_t vecMip[5] = {mipSignalShort, mipSignalMed, mipSignalLong, signal, mipSignalOroc};
+      Double_t vecMip[5] = {mipSignalShort/corrFactorMip, mipSignalMed/corrFactorMip, mipSignalLong/corrFactorMip, signal/corrFactorMip, mipSignalOroc/corrFactorMip};
       //
       for(Int_t ipad = 0; ipad < 3; ipad++) {
        // AK. -  run Number To be removed - not needed 
@@ -495,7 +585,10 @@ Long64_t AliTPCcalibGainMult::Merge(TCollection *li) {
     if (cal->GetHistGainMult()) {
        if (fHistGainMult->GetEntries()<kMaxEntriesSparse) fHistGainMult->Add(cal->GetHistGainMult());
     } 
-
+    if (cal->GetHistTopology()) {
+       fHistTopology->Add(cal->GetHistTopology());
+    } 
+    //
     if (cal->fHistdEdxMap){
       if (fHistdEdxMap) fHistdEdxMap->Add(cal->fHistdEdxMap);
     }
@@ -1893,6 +1986,34 @@ TGraphErrors* AliTPCcalibGainMult::GetGainPerChamber(Int_t padRegion/*=1*/, Bool
   delete histGainSec;
   return gr;
 }
+TGraphErrors* AliTPCcalibGainMult::GetGainPerChamberRobust(Int_t padRegion/*=1*/, Bool_t /*plotQA=kFALSE*/)
+{
+  //
+  // Extract gain variations per chamger for 'padRegion'
+  // Use Robust mean - LTM with 60 % 0 should be similar to the truncated mean 60 %
+  if (padRegion<0||padRegion>2) return 0x0;
+  const Int_t colors[10]={1,2,4,6};
+  const Int_t markers[10]={21,25,22,20};
+  //
+  if (!fHistGainSector) return NULL;
+  if (!fHistGainSector->GetAxis(2)) return NULL;
+  fHistGainSector->GetAxis(2)->SetRangeUser(padRegion,padRegion);
+  if (padRegion==0) fHistGainSector->GetAxis(1)->SetRangeUser(0.0,35.);
+  if (padRegion>0) fHistGainSector->GetAxis(1)->SetRangeUser(36.,71.);
+  //
+  TH2D * histGainSec = fHistGainSector->Projection(0,1);
+  TGraphErrors * gr = TStatToolkit::MakeStat1D(histGainSec, 0, 0.6,2,markers[padRegion],colors[padRegion]);
+  Double_t median = TMath::Median(gr->GetN(),gr->GetY());
+  if (median>0){
+    for (Int_t i=0; i<gr->GetN();i++) {
+      gr->GetY()[i]/=median;
+      gr->SetPointError(i,gr->GetErrorX(i),gr->GetErrorY(i)/median);
+    }    
+  }
+  const char* names[3]={"SHORT","MEDIUM","LONG"};
+  gr->SetNameTitle(Form("TGRAPHERRORS_MEAN_CHAMBERGAIN_%s_BEAM_ALL",names[padRegion]),Form("TGRAPHERRORS_MEAN_CHAMBERGAIN_%s_BEAM_ALL",names[padRegion]));
+  return gr;
+}
 
 // void AliTPCcalibGainMult::Terminate(){
 //   //
index 1d4fa167c7aa0b4cb65f9df4612db2eb357d8dcf..7896be8fe11747b8be50d42be4cd33f4c33aa6bf 100644 (file)
@@ -9,6 +9,7 @@
 #include "TH3F.h"
 #include "TF1.h"
 #include "THnSparse.h"
+#include "THn.h"
 #include "TMatrixD.h"
 #include "TVectorD.h"
 class TH1F;
@@ -45,18 +46,31 @@ public:
   THnSparseF *      GetHistGainSector() const {return fHistGainSector;};
   THnSparseF *      GetHistPadEqual() const {return fHistPadEqual;};
   THnSparseF *      GetHistGainMult() const {return fHistGainMult;};  
+  THnF       *      GetHistTopology() const {return fHistTopology;};
+  //
   THnSparseF * GetHistdEdxMap() const { return fHistdEdxMap;}      // 4D dedx histogram
   THnSparseF * GetHistdEdxMax() const { return fHistdEdxMax;}      // 4D dedx histogram
   THnSparseF * GetHistdEdxTot() const { return fHistdEdxTot;}      // 4D dedx histogram
   TTree *      GetdEdxTree() const {return fdEdxTree;}         // tree for the later minimization
 
   TGraphErrors* GetGainPerChamber(Int_t padRegion=1, Bool_t plotQA=kFALSE);
+  TGraphErrors* GetGainPerChamberRobust(Int_t padRegion=1, Bool_t plotQA=kFALSE);
   //
   void SetMIPvalue(Float_t mip){fMIP = mip;};
   void SetLowerTrunc(Float_t lowerTrunc){fLowerTrunc = lowerTrunc;};
   void SetUpperTrunc(Float_t upperTrunc){fUpperTrunc = upperTrunc;};
   void SetUseMax(Bool_t useMax){fUseMax = useMax;};
   //
+  void SetCutMinCrossRows(Int_t crossRows){fCutCrossRows = crossRows;};
+  void SetCutMaxEta(Float_t maxEta){fCutEtaWindow = maxEta;};
+  void SetCutRequireITSrefit(Bool_t requireItsRefit = kFALSE){fCutRequireITSrefit = requireItsRefit;};
+  void SetCutMaxDcaXY(Float_t maxXY){fCutMaxDcaXY = maxXY;}; 
+  void SetCutMaxDcaZ(Float_t maxZ){fCutMaxDcaZ = maxZ;}; 
+  //
+  void SetMinMomentumMIP(Float_t minMom = 0.4){fMinMomentumMIP = minMom;};
+  void SetMaxMomentumMIP(Float_t maxMom = 0.6){fMaxMomentumMIP = maxMom;};
+  void SetAlephParameters(Float_t * parameters){for(Int_t j=0;j<5;j++) fAlephParameters[j] = parameters[j];};
+  //
   //
   void     Process(AliESDtrack *track, Int_t runNo=-1){AliTPCcalibBase::Process(track,runNo);};
   void     Process(AliTPCseed *track){return AliTPCcalibBase::Process(track);}
@@ -82,15 +96,31 @@ private:
   //
   Bool_t fUseMax;                 // flag if Qmax or Qtot should be used
   //
+  // track cuts
+  //
+  Int_t   fCutCrossRows;                // minimum number of crossed rows 
+  Float_t fCutEtaWindow;                // maximum eta of tracks
+  Bool_t  fCutRequireITSrefit;          // if ITSrefit should be required (dangerous in cpass0)
+  Float_t fCutMaxDcaXY;                 // max dca_xy (only TPConly resolution is guaranteed!)
+  Float_t fCutMaxDcaZ;                  // max dca_z  (dangerous if vDrift is not calibrated)
+  //
+  // definition of MIP window
+  //
+  Float_t fMinMomentumMIP;              // minimum momentum of MIP region, e.g. 400 MeV
+  Float_t fMaxMomentumMIP;              // maximum momentum of MIP region, e.g. 600 MeV
+  Float_t fAlephParameters[5];          // parameters for equalization in MIP window, parameter set should be =1 at MIP
+  //
   // histograms
   //
   TH1F  *fHistNTracks;            //  histogram showing number of ESD tracks per event
   TH1F  *fHistClusterShape;       //  histogram to check the cluster shape
   TH3F  *fHistQA;                 //  dE/dx histogram showing the final spectrum
   //
+  //
   THnSparseF * fHistGainSector;   //  histogram which shows MIP peak for each of the 3x36 sectors (pad region)
   THnSparseF * fHistPadEqual;     //  histogram for the equalization of the gain in the different pad regions -> pass0
   THnSparseF * fHistGainMult;     //  histogram which shows decrease of MIP signal as a function
+  THnF       * fHistTopology;     //  histogram for topological corrections of signal - dip angle theta and curvature (1/pT)
   TMatrixD *fPIDMatrix;           //! custom PID matrix
   //
   THnSparseF * fHistdEdxMap;      // 4D dedx histogram - per sector/phi
@@ -102,7 +132,7 @@ private:
   AliTPCcalibGainMult(const AliTPCcalibGainMult&); 
   AliTPCcalibGainMult& operator=(const AliTPCcalibGainMult&); 
 
-  ClassDef(AliTPCcalibGainMult, 2); 
+  ClassDef(AliTPCcalibGainMult, 4); 
 };
 
 #endif
index 6e4cd18467e43703f640b9a400a105e2a2fc4acc..06b9ad8f51f0f5987be6a3ab4f6643959f9925fa 100644 (file)
@@ -799,6 +799,33 @@ void AliTPCcalibSummary::ProcessGain(Int_t irun, Int_t timeStamp){
   static TVectorD vGainGraphIROCErr(36);
   static TVectorD vGainGraphOROCmedErr(36);
   static TVectorD vGainGraphOROClongErr(36);
+  //
+  static TVectorD vGainQMaxGraphRegion(3);
+  static TVectorD vGainQTotGraphRegion(3);
+  //
+  static TGraphErrors ggrPadEqualMax(36);
+  static TGraphErrors ggrPadEqualTot(36);
+  //
+  static TGraphErrors ggrDipAngleMaxShort;
+  static TGraphErrors ggrDipAngleMaxMedium;
+  static TGraphErrors ggrDipAngleMaxLong;
+  static TGraphErrors ggrDipAngleMaxAbsolute;
+  //
+  static TGraphErrors ggrDipAngleTotShort;
+  static TGraphErrors ggrDipAngleTotMedium;
+  static TGraphErrors ggrDipAngleTotLong;
+  static TGraphErrors ggrDipAngleTotAbsolute;
+  //
+  static TVectorD vFitDipAngleParMaxShort(3);
+  static TVectorD vFitDipAngleParMaxMedium(3);
+  static TVectorD vFitDipAngleParMaxLong(3);
+  static TVectorD vFitDipAngleParMaxAbsolute(3);
+  //
+  static TVectorD vFitDipAngleParTotShort(3);
+  static TVectorD vFitDipAngleParTotMedium(3);
+  static TVectorD vFitDipAngleParTotLong(3);
+  static TVectorD vFitDipAngleParTotAbsolute(3);
+
   
   vGainGraphIROC.Zero();
   vGainGraphOROCmed.Zero();
@@ -806,7 +833,8 @@ void AliTPCcalibSummary::ProcessGain(Int_t irun, Int_t timeStamp){
   vGainGraphIROCErr.Zero();
   vGainGraphOROCmedErr.Zero();
   vGainGraphOROClongErr.Zero();
-  
+  vGainQMaxGraphRegion.Zero();
+  vGainQTotGraphRegion.Zero();
   TGraphErrors grDummy;
   TObjArray * gainSplines = fCalibDB->GetTimeGainSplinesRun(irun);
   if (gainSplines) {
@@ -814,9 +842,54 @@ void AliTPCcalibSummary::ProcessGain(Int_t irun, Int_t timeStamp){
     TGraphErrors * graphCosmic = (TGraphErrors *) gainSplines->FindObject("TGRAPHERRORS_MEAN_GAIN_COSMIC_ALL");
     TGraphErrors * graphAttach = (TGraphErrors *) gainSplines->FindObject("TGRAPHERRORS_MEAN_ATTACHMENT_BEAM_ALL");
     //
+    TGraphErrors * grPadEqualQMax = (TGraphErrors * ) gainSplines->FindObject("TGRAPHERRORS_MEANQMAX_PADREGIONGAIN_BEAM_ALL");
+    TGraphErrors * grPadEqualQTot = (TGraphErrors * ) gainSplines->FindObject("TGRAPHERRORS_MEANQTOT_PADREGIONGAIN_BEAM_ALL");
+    //
     TGraphErrors * graphGainIROC       = (TGraphErrors *) gainSplines->FindObject("TGRAPHERRORS_MEAN_CHAMBERGAIN_SHORT_BEAM_ALL");
     TGraphErrors * graphGainOROCMedium = (TGraphErrors *) gainSplines->FindObject("TGRAPHERRORS_MEAN_CHAMBERGAIN_MEDIUM_BEAM_ALL");
     TGraphErrors * graphGainOROCLong   = (TGraphErrors *) gainSplines->FindObject("TGRAPHERRORS_MEAN_CHAMBERGAIN_LONG_BEAM_ALL");
+    //
+    //
+    TF1*  funDipAngleMax[4]={0x0,0x0,0x0,0x0};
+    TF1*  funDipAngleTot[4]={0x0,0x0,0x0,0x0};
+    TGraphErrors*  grDipAngleMax[4]={0x0,0x0,0x0,0x0};
+    TGraphErrors*  grDipAngleTot[4]={0x0,0x0,0x0,0x0};
+    const char* names[4]={"SHORT","MEDIUM","LONG","ABSOLUTE"};
+    for (Int_t iPadRegion=0; iPadRegion<4; ++iPadRegion) {
+      funDipAngleMax[iPadRegion]=(TF1*) gainSplines->FindObject(Form("TF1_QMAX_DIPANGLE_%s_BEAM_ALL",names[iPadRegion]));
+      funDipAngleTot[iPadRegion]=(TF1*) gainSplines->FindObject(Form("TF1_QTOT_DIPANGLE_%s_BEAM_ALL",names[iPadRegion]));
+      grDipAngleMax[iPadRegion]= (TGraphErrors*) gainSplines->FindObject(Form("TGRAPHERRORS_QMAX_DIPANGLE_%s_BEAM_ALL",names[iPadRegion]));
+      grDipAngleTot[iPadRegion]= (TGraphErrors*) gainSplines->FindObject(Form("TGRAPHERRORS_QTOT_DIPANGLE_%s_BEAM_ALL",names[iPadRegion]));
+    }
+    //
+    for(Int_t iPar=0; iPar < 3; iPar++) {
+      if (funDipAngleMax[0]) vFitDipAngleParMaxShort(iPar)    = funDipAngleMax[0]->GetParameter(iPar);
+      if (funDipAngleMax[1]) vFitDipAngleParMaxMedium(iPar)   = funDipAngleMax[1]->GetParameter(iPar);
+      if (funDipAngleMax[2]) vFitDipAngleParMaxLong(iPar)     = funDipAngleMax[2]->GetParameter(iPar);
+      if (funDipAngleMax[3]) vFitDipAngleParMaxAbsolute(iPar) = funDipAngleMax[3]->GetParameter(iPar);
+      //
+      if (funDipAngleTot[0]) vFitDipAngleParTotShort(iPar)    = funDipAngleTot[0]->GetParameter(iPar);
+      if (funDipAngleTot[1]) vFitDipAngleParTotMedium(iPar)   = funDipAngleTot[1]->GetParameter(iPar);
+      if (funDipAngleTot[2]) vFitDipAngleParTotLong(iPar)     = funDipAngleTot[2]->GetParameter(iPar);
+      if (funDipAngleTot[3]) vFitDipAngleParTotAbsolute(iPar) = funDipAngleTot[3]->GetParameter(iPar);
+    }
+    //
+    if (grDipAngleMax[0]) ggrDipAngleMaxShort    = * grDipAngleMax[0];
+    if (grDipAngleMax[1]) ggrDipAngleMaxMedium   = * grDipAngleMax[1];
+    if (grDipAngleMax[2]) ggrDipAngleMaxLong     = * grDipAngleMax[2];
+    if (grDipAngleMax[3]) ggrDipAngleMaxAbsolute = * grDipAngleMax[3];
+    //
+    if (grDipAngleTot[0]) ggrDipAngleTotShort    = * grDipAngleTot[0];
+    if (grDipAngleTot[1]) ggrDipAngleTotMedium   = * grDipAngleTot[1];
+    if (grDipAngleTot[2]) ggrDipAngleTotLong     = * grDipAngleTot[2];
+    if (grDipAngleTot[3]) ggrDipAngleTotAbsolute = * grDipAngleTot[3];
+    //
+    //
+    TGraphErrors *grPadEqualMax = (TGraphErrors * ) gainSplines->FindObject("TGRAPHERRORS_MEANQMAX_PADREGIONGAIN_BEAM_ALL");
+    TGraphErrors *grPadEqualTot = (TGraphErrors * ) gainSplines->FindObject("TGRAPHERRORS_MEANQTOT_PADREGIONGAIN_BEAM_ALL");
+    if (grPadEqualMax) ggrPadEqualMax = *grPadEqualMax;
+    if (grPadEqualTot) ggrPadEqualTot = *grPadEqualTot;
+
 
     if (graphGainIROC && graphGainOROCMedium && graphGainOROCLong) {
       Double_t x=0,y=0;
@@ -832,6 +905,10 @@ void AliTPCcalibSummary::ProcessGain(Int_t irun, Int_t timeStamp){
         vGainGraphOROCmedErr(i)  = graphGainOROCMedium->GetEY()[i];
         vGainGraphOROClongErr(i) = graphGainOROCLong->GetEY()[i];
       }
+       for (Int_t i=0; i<3; ++i){
+        vGainQMaxGraphRegion[i]=grPadEqualQMax->GetY()[i];
+        vGainQTotGraphRegion[i]=grPadEqualQTot->GetY()[i];
+       }
     }
     
     if (graphMIP) gainMIP = AliTPCcalibDButil::EvalGraphConst(graphMIP,timeStamp);
@@ -840,14 +917,39 @@ void AliTPCcalibSummary::ProcessGain(Int_t irun, Int_t timeStamp){
     if (graphMIP)  AliTPCcalibDButil::GetNearest(graphMIP, timeStamp, dMIP,dummy);    
   }
     
-  // time dependence of gain
+  // time dependence of gain 
   (*fPcstream)<<"dcs"<<
-    "rocGainIROC.="            << &vGainGraphIROC        <<
+    "grPadEqualMax.=" << &ggrPadEqualMax <<
+    "grPadEqualTot.=" << &ggrPadEqualTot <<
+    "rocGainIROC.="            << &vGainGraphIROC        <<          
     "rocGainOROCMedium.="      << &vGainGraphOROCmed     <<
     "rocGainOROCLong.="        << &vGainGraphOROClong    <<
     "rocGainErrIROC.="         << &vGainGraphIROCErr     <<
     "rocGainErrOROCMedium.="   << &vGainGraphOROCmedErr  <<
     "rocGainErrOROCLong.="     << &vGainGraphOROClongErr <<
+    "vGainQMaxGraphRegion.="   << &vGainQMaxGraphRegion<<
+    "vGainQTotGraphRegion.="   << &vGainQTotGraphRegion<<
+    //
+    "vFitDipAngleParMaxShort.="   << &vFitDipAngleParMaxShort<<
+    "vFitDipAngleParMaxMedium.="  << &vFitDipAngleParMaxMedium<<
+    "vFitDipAngleParMaxLong.="    << &vFitDipAngleParMaxLong<<
+    "vFitDipAngleParMaxAbsolute.="<< &vFitDipAngleParMaxAbsolute<<
+    //
+    "vFitDipAngleParTotShort.="   << &vFitDipAngleParTotShort<<
+    "vFitDipAngleParTotMedium.="  << &vFitDipAngleParTotMedium<<
+    "vFitDipAngleParTotLong.="    << &vFitDipAngleParTotLong<<
+    "vFitDipAngleParTotAbsolute.="<< &vFitDipAngleParTotAbsolute<<    
+    //
+    "grDipAngleMaxShort.="        << &ggrDipAngleMaxShort    <<
+    "grDipAngleMaxMedium.="       << &ggrDipAngleMaxMedium   <<
+    "grDipAngleMaxLong.="         << &ggrDipAngleMaxLong     <<
+    "grDipAngleMaxAbsolute.="     << &ggrDipAngleMaxAbsolute <<
+    //
+    "grDipAngleTotShort.="        << &ggrDipAngleTotShort    <<
+    "grDipAngleTotMedium.="       << &ggrDipAngleTotMedium   <<
+    "grDipAngleTotLong.="         << &ggrDipAngleTotLong     <<
+    "grDipAngleTotAbsolute.="     << &ggrDipAngleTotAbsolute <<
+    //
     "gainMIP="                 << gainMIP                <<
     "attachMIP="               << attachMIP              <<
     "dMIP="                    << dMIP                   <<
index a32e33b815d89c4190f0cc65529812dfcd9a5c95..8c161a493caf3b48c7bcb0cf9d55314a11967be1 100644 (file)
@@ -189,6 +189,14 @@ AliTPCcalibTimeGain::AliTPCcalibTimeGain()
    fHistDeDxTotal(0),
    fIntegrationTimeDeDx(0),
    fMIP(0),
+   fCutCrossRows(0),
+   fCutEtaWindow(0),
+   fCutRequireITSrefit(0),
+   fCutMaxDcaXY(0),
+   fCutMaxDcaZ(0),
+   fMinMomentumMIP(0),
+   fMaxMomentumMIP(0),
+   fAlephParameters(),
    fUseMax(0),
    fLowerTrunc(0),
    fUpperTrunc(0),
@@ -213,6 +221,14 @@ AliTPCcalibTimeGain::AliTPCcalibTimeGain(const Text_t *name, const Text_t *title
    fHistDeDxTotal(0),
    fIntegrationTimeDeDx(0),
    fMIP(0),
+   fCutCrossRows(0),
+   fCutEtaWindow(0),
+   fCutRequireITSrefit(0),
+   fCutMaxDcaXY(0),
+   fCutMaxDcaZ(0),
+   fMinMomentumMIP(0),
+   fMaxMomentumMIP(0),
+   fAlephParameters(),
    fUseMax(0),
    fLowerTrunc(0),
    fUpperTrunc(0),
@@ -247,6 +263,23 @@ AliTPCcalibTimeGain::AliTPCcalibTimeGain(const Text_t *name, const Text_t *title
   fHistDeDxTotal = new TH2F("DeDx","dEdx; momentum p (GeV); TPC signal (a.u.)",250,0.01,100.,1000,0.,8);
   BinLogX(fHistDeDxTotal);
   
+  
+  // default track selection cuts
+  fCutCrossRows = 80;
+  fCutEtaWindow = 0.8;
+  fCutRequireITSrefit = kFALSE;
+  fCutMaxDcaXY = 3.5;
+  fCutMaxDcaZ  = 25.;
+
+  // default values for MIP window selection
+  fMinMomentumMIP = 0.4;
+  fMaxMomentumMIP = 0.6;
+  fAlephParameters[0] = 0.07657; // the following parameters work for most of the periods and are therefore default
+  fAlephParameters[1] = 10.6654; // but they can be overwritten in the train setup of cpass0
+  fAlephParameters[2] = 2.51466e-14;
+  fAlephParameters[3] = 2.05379;
+  fAlephParameters[4] = 1.84288;
+
   // default values for dE/dx
   fMIP = 50.;
   fUseMax = kTRUE;
@@ -395,19 +428,24 @@ void AliTPCcalibTimeGain::ProcessBeamEvent(AliESDEvent *event) {
     // calculate necessary track parameters
     Double_t meanP = trackIn->GetP();
     Double_t meanDrift = 250 - 0.5*TMath::Abs(trackIn->GetZ() + trackOut->GetZ());
-    Int_t nclsDeDx = track->GetTPCNcls();
+    Int_t nCrossedRows = track->GetTPCCrossedRows();
 
+    //
     // exclude tracks which do not look like primaries or are simply too short or on wrong sectors
-    if (nclsDeDx < 60) continue;     
-    //if (TMath::Abs(trackIn->GetTgl()) > 1) continue;
-    //if (TMath::Abs(trackIn->GetSnp()) > 0.6) continue;
-    if (TMath::Abs(trackIn->Eta()) > 1) continue;
+    // fCutCrossRows = 80, fCutEtaWindow = 0.8, fCutRequireITSrefit, fCutMaxDcaXY = 3.5, fCutMaxDcaZ = 25
+    //
+    if (nCrossedRows < fCutCrossRows) continue;     
+    if (TMath::Abs(trackIn->Eta()) > fCutEtaWindow) continue;
+    //
     UInt_t status = track->GetStatus();
     if ((status&AliESDtrack::kTPCrefit)==0) continue;
-    //if (track->GetNcls(0) < 3) continue; // ITS clusters
+    if ((status&AliESDtrack::kITSrefit)==0 && fCutRequireITSrefit) continue; // ITS cluster
+    //
     Float_t dca[2], cov[3];
     track->GetImpactParameters(dca,cov);
-    if (TMath::Abs(dca[0]) > 7 || TMath::Abs(dca[0]) < 0.0000001 || TMath::Abs(dca[1]) > 25 ) continue; // cut in xy
+    if (TMath::Abs(dca[0]) > fCutMaxDcaXY || TMath::Abs(dca[0]) < 0.0000001) continue;  // cut in xy
+    if (((status&AliESDtrack::kITSrefit) == 1 && TMath::Abs(dca[1]) > 3.) || TMath::Abs(dca[1]) > fCutMaxDcaZ ) continue;
+    //
     Double_t eta = trackIn->Eta();
     
     // Get seeds
@@ -419,13 +457,25 @@ void AliTPCcalibTimeGain::ProcessBeamEvent(AliESDEvent *event) {
 
     if (seed) {
       Int_t particleCase = 0;
-      if (meanP < 0.5  && meanP > 0.4)  particleCase = 2; // MIP pions
+      if (meanP < fMaxMomentumMIP && meanP > fMinMomentumMIP)  particleCase = 2; // MIP pions
       if (meanP < 0.57 && meanP > 0.56) particleCase = 3; // protons 1
       if (meanP < 0.66 && meanP > 0.65) particleCase = 4; // protons 2
       //
       if (fLowMemoryConsumption && particleCase == 0) continue;
       //
       Double_t tpcSignal = GetTPCdEdx(seed);
+      //
+      // flattens signal in MIP window
+      //
+      if (particleCase == 2) {
+       Float_t corrFactor = AliExternalTrackParam::BetheBlochAleph(meanP/0.13957, 
+                                                                   fAlephParameters[0], 
+                                                                   fAlephParameters[1], 
+                                                                   fAlephParameters[2], 
+                                                                   fAlephParameters[3],
+                                                                   fAlephParameters[4]);
+       tpcSignal /= corrFactor; 
+      }        
       fHistDeDxTotal->Fill(meanP, tpcSignal);
       //
       //dE/dx, time, type (1-muon cosmic,2-pion beam data, 3&4 protons), momenta, runNumner, eta
@@ -471,7 +521,7 @@ void AliTPCcalibTimeGain::ProcessBeamEvent(AliESDEvent *event) {
       }    
       if (seed) { 
        if (fLowMemoryConsumption) {
-         if (meanP > 0.5 || meanP < 0.4) continue;
+         if (meanP > fMaxMomentumMIP || meanP < fMinMomentumMIP) continue;
          meanP = 0.45; // set all momenta to one in order to save memory
       }
        Double_t tpcSignal = GetTPCdEdx(seed);
index 0dfb3e58636262a3d7ff6bc93597d63786bce308..385417b51ad61e9f172b63e70bf065d84f199bf0 100644 (file)
@@ -59,6 +59,16 @@ public:
   void SetIsCosmic(Bool_t IsCosmic){fIsCosmic = IsCosmic;};
   void SetLowMemoryConsumption(Bool_t LowMemoryConsumption){fLowMemoryConsumption = LowMemoryConsumption;};
   void SetUseCookAnalytical(Bool_t UseCookAnalytical){fUseCookAnalytical = UseCookAnalytical;};
+  //
+  void SetCutMinCrossRows(Int_t crossRows){fCutCrossRows = crossRows;};
+  void SetCutMaxEta(Float_t maxEta){fCutEtaWindow = maxEta;};
+  void SetCutRequireITSrefit(Bool_t requireItsRefit = kFALSE){fCutRequireITSrefit = requireItsRefit;};
+  void SetCutMaxDcaXY(Float_t maxXY){fCutMaxDcaXY = maxXY;}; 
+  void SetCutMaxDcaZ(Float_t maxZ){fCutMaxDcaZ = maxZ;}; 
+  //
+  void SetMinMomentumMIP(Float_t minMom = 0.4){fMinMomentumMIP = minMom;};
+  void SetMaxMomentumMIP(Float_t maxMom = 0.6){fMaxMomentumMIP = maxMom;};
+  void SetAlephParameters(Float_t * parameters){for(Int_t j=0;j<5;j++) fAlephParameters[j] = parameters[j];};
 
   static void SetMergeEntriesCut(Double_t entriesCut){fgMergeEntriesCut = entriesCut;}
 
@@ -77,6 +87,21 @@ private:
   //
   Float_t fMIP;                         // rough MIP position in order to have scaleable histograms
   //
+  // track cuts
+  //
+  Int_t   fCutCrossRows;                // minimum number of crossed rows 
+  Float_t fCutEtaWindow;                // maximum eta of tracks
+  Bool_t  fCutRequireITSrefit;          // if ITSrefit should be required (dangerous in cpass0)
+  Float_t fCutMaxDcaXY;                 // max dca_xy (only TPConly resolution is guaranteed!)
+  Float_t fCutMaxDcaZ;                  // max dca_z  (dangerous if vDrift is not calibrated)
+  //
+  // definition of MIP window
+  //
+  Float_t fMinMomentumMIP;              // minimum momentum of MIP region, e.g. 400 MeV
+  Float_t fMaxMomentumMIP;              // maximum momentum of MIP region, e.g. 600 MeV
+  Float_t fAlephParameters[5];          // parameters for equalization in MIP window, parameter set should be =1 at MIP
+  //
+  //
   Bool_t  fUseMax;                      // true: use max charge for dE/dx calculation, false: use total charge for dE/dx calculation
   Float_t fLowerTrunc;                  // lower truncation of dE/dx ; at most 5%
   Float_t fUpperTrunc;                  // upper truncation of dE/dx ; ca. 70%
@@ -93,7 +118,7 @@ private:
   void     Process(AliESDtrack *track, Int_t runNo=-1){AliTPCcalibBase::Process(track,runNo);};
   void     Process(AliTPCseed *track){return AliTPCcalibBase::Process(track);}
 
-  ClassDef(AliTPCcalibTimeGain, 1); 
+  ClassDef(AliTPCcalibTimeGain, 2);
 };
 
 #endif
diff --git a/TPC/Calib/maps/SC_ArCO2_eps5_50kHz.root b/TPC/Calib/maps/SC_ArCO2_eps5_50kHz.root
new file mode 100644 (file)
index 0000000..911c412
Binary files /dev/null and b/TPC/Calib/maps/SC_ArCO2_eps5_50kHz.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps10_50kHz.root b/TPC/Calib/maps/SC_NeCO2_eps10_50kHz.root
new file mode 100644 (file)
index 0000000..de5fa23
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps10_50kHz.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps10_50kHz_precal.lookup.root b/TPC/Calib/maps/SC_NeCO2_eps10_50kHz_precal.lookup.root
new file mode 100644 (file)
index 0000000..498c4cc
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps10_50kHz_precal.lookup.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps10_50kHz_precal.root b/TPC/Calib/maps/SC_NeCO2_eps10_50kHz_precal.root
new file mode 100644 (file)
index 0000000..3410c1f
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps10_50kHz_precal.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps20_50kHz.root b/TPC/Calib/maps/SC_NeCO2_eps20_50kHz.root
new file mode 100644 (file)
index 0000000..827d5c2
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps20_50kHz.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.lookup.root b/TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.lookup.root
new file mode 100644 (file)
index 0000000..10ebd30
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.lookup.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.root b/TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.root
new file mode 100644 (file)
index 0000000..7e99e4a
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps5_50kHz.root b/TPC/Calib/maps/SC_NeCO2_eps5_50kHz.root
new file mode 100644 (file)
index 0000000..e656575
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps5_50kHz.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.lookup.root b/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.lookup.root
new file mode 100644 (file)
index 0000000..f863bf7
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.lookup.root differ
diff --git a/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root b/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root
new file mode 100644 (file)
index 0000000..bd487d7
Binary files /dev/null and b/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root differ
index ebaa60d7f3b82481d3fe4c34641109e8cb77ec8d..4a57cb7d4b9b48d5ec2c40c9deafc3f59f5d2d38 100644 (file)
@@ -105,6 +105,8 @@ AliTPCRecoParam::AliTPCRecoParam():
   fMinFraction(0.01),           // truncated mean - lower threshold
   fMaxFaction(0.7),            // truncated mean - upper threshold
   fNeighborRowsDedx(2),           // neighbour rows for below threshold dEdx calculation
+  fGainCorrectionHVandPTMode(0), // switch for the usage of GainCorrectionHVandPT (see AliTPCcalibDB::GetGainCorrectionHVandPT   
+  fSkipTimeBins(5),              // number of time bins to be skiiped (corrupted signal druing gating opening)
   fUseTOFCorrection(kTRUE),
   fUseSystematicCorrelation(kTRUE)
 {
index 17ddd5aa86cd78d695836ca3877f7d897e2a6f05..1479a46916cad2b603fed32e8c286c3ca6a90845 100644 (file)
@@ -68,8 +68,11 @@ class AliTPCRecoParam : public AliDetectorRecoParam
   void  SetUseTotCharge(Bool_t flag) {fUseTotCharge = flag;}
   void  SetCtgRange(Double_t ctgRange) {fCtgRange = ctgRange;}
   void  SetUseMultiplicityCorrectionDedx(Bool_t flag) {fUseMultiplicityCorrectionDedx = flag;}
+  
   void  SetUseAlignmentTime(Bool_t flag) {fUseAlignmentTime = flag;}
   void  SetNeighborRowsDedx(Int_t nRows) {fNeighborRowsDedx = nRows;}
+  void SetCorrectionHVandPTMode(Int_t value){ fGainCorrectionHVandPTMode =value;}
+  void SetSkipTimeBins(Double_t value) {fSkipTimeBins=value;}
   //
   Int_t    GetLastSeedRowSec()       const  { return fLastSeedRowSec;} 
   Int_t    GetSeedGapPrim()        const  { return fSeedGapPrim;} 
@@ -115,6 +118,9 @@ class AliTPCRecoParam : public AliDetectorRecoParam
   Int_t GetUseIonTailCorrection() const {return fUseIonTailCorrection;}
 
   Bool_t GetUseMultiplicityCorrectionDedx() const {return fUseMultiplicityCorrectionDedx;}
+  Int_t  GetGainCorrectionHVandPTMode() const  { return   fGainCorrectionHVandPTMode;}
+  Double_t  GetSkipTimeBins() const {return fSkipTimeBins;}
+
   Bool_t GetUseAlignmentTime() const {return fUseAlignmentTime;}
   //
   Bool_t   GetUseTotCharge() const {return fUseTotCharge;}          // switch use total or max charge
@@ -200,6 +206,8 @@ class AliTPCRecoParam : public AliDetectorRecoParam
   Float_t fMinFraction;           // truncated mean - lower threshold
   Float_t fMaxFaction;            // truncated mean - upper threshold
   Int_t   fNeighborRowsDedx;      // number of neighboring rows to identify cluster below thres in dEdx calculation 0 -> switch off
+  Int_t   fGainCorrectionHVandPTMode; // switch for the usage of GainCorrectionHVandPT (see AliTPCcalibDB::GetGainCorrectionHVandPT 
+  Double_t fSkipTimeBins;        // number of time bins to be skiiped (corrupted signal druing gating opening)
 
   Bool_t fUseTOFCorrection;  // switch - kTRUE use TOF correction kFALSE - do not use
   //
@@ -213,7 +221,7 @@ public:
                                       // to be switched off for pass 0 reconstruction
                                       // Use static function, other option will be to use 
                                       // additional specific storage ?
-  ClassDef(AliTPCRecoParam, 17)
+  ClassDef(AliTPCRecoParam, 18)
 };
 
 
index 17f0438c86c795e29bcca9c8f0c4c0b9f3135c9b..90538e154c57262fb5f82f9343d3fb9ec7d9072d 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "AliTPCclusterMI.h"
 #include "AliTPCclusterInfo.h"
+#include "AliTrackPointArray.h"
 #include "AliGeomManager.h"
 #include "AliLog.h"
 
@@ -161,3 +162,46 @@ void AliTPCclusterMI::SetInfo(AliTPCclusterInfo * info) {
   if (fInfo) delete fInfo;
   fInfo = info;
 }
+
+
+AliTPCclusterMI* AliTPCclusterMI::MakeCluster(AliTrackPoint* /*point*/) {
+  //
+  // make AliTPCclusterMI out of AliTrackPoint
+  // (not yet implemented)
+  
+  return NULL;
+}
+
+
+AliTrackPoint* AliTPCclusterMI::MakePoint() {
+  //
+  // make AliTrackPoint out of AliTPCclusterMI
+  //
+
+  AliTrackPoint* point = new AliTrackPoint();
+  Float_t xyz[3]={0.};
+  Float_t cov[6]={0.};
+  GetGlobalXYZ(xyz);
+  GetGlobalCov(cov);
+  // voluem ID to add later ....
+  point->SetXYZ(xyz);
+  point->SetCov(cov);
+
+  return point;
+}
+
+//______________________________________________________________________________
+void AliTPCclusterMI::SetGlobalTrackPoint( const AliCluster &cl, AliTrackPoint &point )
+{
+  //
+  // Set global AliTrackPoint
+  //
+  
+  Float_t xyz[3]={0.};
+  Float_t cov[6]={0.};
+  cl.GetGlobalXYZ(xyz);
+  cl.GetGlobalCov(cov);
+  // voluem ID to add later ....
+  point.SetXYZ(xyz);
+  point.SetCov(cov);
+}
index 47292f6b579f263635ac8dd2f4cf27eaa3de7739..de8423e8363d036729f2cac9562dd0988813d473 100644 (file)
@@ -13,6 +13,8 @@
 #include "AliCluster.h"
 #include "TMath.h"
 #include "AliTPCclusterInfo.h"
+#include <AliTrackPointArray.h>
+
 //_____________________________________________________________________________
 class AliTPCclusterMI : public AliCluster {
 public:
@@ -43,7 +45,11 @@ public:
   Float_t GetPad() const { return fPad;}
   AliTPCclusterInfo * GetInfo() const { return fInfo;}
   void SetInfo(AliTPCclusterInfo * info);
-
+  //
+  AliTPCclusterMI*  MakeCluster(AliTrackPoint* point);
+  AliTrackPoint*    MakePoint();
+  static void     SetGlobalTrackPoint(const AliCluster &cl, AliTrackPoint &point);
+  
 private:
   AliTPCclusterInfo * fInfo;  // pointer to the cluster debug info
   Float_t   fTimeBin;  //time bin coordinate
index 9f72759b21258a43f343ef41e18ec2376658baa9..a8afecdd90b1fe2ce66462665cf5b5d373a93483 100644 (file)
@@ -648,8 +648,8 @@ void AliTPCclusterer::AddCluster(AliTPCclusterMI &c, Float_t * /*matrix*/, Int_t
   if (!fRecoParam->DumpSignal()) {
     cl->SetInfo(0);
   }
-  
-  if (AliTPCReconstructor::StreamLevel()>1) {
+  const Int_t kClusterStream=128; // stream level should be per action - to be added to the AliTPCReconstructor
+  if ( (AliTPCReconstructor::StreamLevel()&kClusterStream)==kClusterStream) {
     Float_t xyz[3];
     cl->GetGlobalXYZ(xyz);
      (*fDebugStreamer)<<"Clusters"<<
index a98574550a124fcbfee0a53906e2dcd497cdacff..0c87dd04753dbb13c6e514b16be0c087681ccc64 100644 (file)
@@ -37,6 +37,7 @@
 #include "AliSplineFit.h"
 #include "AliCDBManager.h"
 #include "AliTPCcalibDButil.h"
+#include <AliCTPTimeParams.h>
 
 
 ClassImp(AliTPCseed)
@@ -84,7 +85,7 @@ AliTPCseed::AliTPCseed():
     fNCDEDX[i] = 0;
     fNCDEDXInclThres[i] = 0;
   }
-  fDEDX[4] = 0;
+  for (Int_t i=0;i<9;i++) fDEDX[i] = 0;
   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
 }
 
@@ -138,7 +139,8 @@ AliTPCseed::AliTPCseed(const AliTPCseed &s, Bool_t clusterOwner):
     fNCDEDX[i] = s.fNCDEDX[i];
     fNCDEDXInclThres[i] = s.fNCDEDXInclThres[i];
   }
-  fDEDX[4] = s.fDEDX[4];
+  for (Int_t i=0;i<9;i++) fDEDX[i] = 0;
+
   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = s.fOverlapLabels[i];
 
 }
@@ -194,7 +196,8 @@ AliTPCseed::AliTPCseed(const AliTPCtrack &t):
     fNCDEDX[i] = 0;
     fNCDEDXInclThres[i] = 0;
   }
-    fDEDX[4] = 0;
+  for (Int_t i=0;i<9;i++) fDEDX[i] = fDEDX[i];
+
   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
 }
 
@@ -241,7 +244,8 @@ AliTPCseed::AliTPCseed(Double_t xr, Double_t alpha, const Double_t xx[5],
     fNCDEDX[i] = 0;
     fNCDEDXInclThres[i] = 0;
   }
-    fDEDX[4] = 0;
+  for (Int_t i=0;i<9;i++) fDEDX[i] = 0;
+
   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
 }
 
@@ -294,7 +298,8 @@ AliTPCseed & AliTPCseed::operator=(const AliTPCseed &param)
       fNCDEDX[i] = param.fNCDEDX[i];
       fNCDEDXInclThres[i] = param.fNCDEDXInclThres[i];
     }
-      fDEDX[4]   = param.fDEDX[4];
+    for (Int_t i=0;i<9;i++) fDEDX[i] = 0;
+
     for(Int_t i = 0;i<AliPID::kSPECIES;++i)fTPCr[i] = param.fTPCr[i];
     
     fSeedType = param.fSeedType;
@@ -608,37 +613,54 @@ Float_t AliTPCseed::CookdEdx(Double_t low, Double_t up,Int_t i1, Int_t i2, Bool_
   //
   //
   TVectorF i1i2;
-  TVectorF  iro;
-  TVectorF oro1;
-  TVectorF oro2;
-  TVectorF foro;
+  TVectorF  irocTot;
+  TVectorF oroc1Tot;
+  TVectorF oroc2Tot;
+  TVectorF forocTot;
+  //
+  TVectorF  irocMax;
+  TVectorF oroc1Max;
+  TVectorF oroc2Max;
+  TVectorF forocMax;
 
   CookdEdxAnalytical(low,up,useTot ,i1  ,i2,   0, 2, 0, &i1i2);
-  CookdEdxAnalytical(low,up,useTot ,0   ,row0, 0, 2, 0, &iro);
-  CookdEdxAnalytical(low,up,useTot ,row0,row1, 0, 2, 0, &oro1);
-  CookdEdxAnalytical(low,up,useTot ,row1,row2, 0, 2, 0, &oro2);
-  CookdEdxAnalytical(low,up,useTot ,row0,row2, 0, 2, 0, &foro); // full OROC truncated mean
+  //
+  CookdEdxAnalytical(low,up,kTRUE ,0   ,row0, 0, 2, 0, &irocTot);
+  CookdEdxAnalytical(low,up,kTRUE ,row0,row1, 0, 2, 0, &oroc1Tot);
+  CookdEdxAnalytical(low,up,kTRUE ,row1,row2, 0, 2, 0, &oroc2Tot);
+  CookdEdxAnalytical(low,up,kTRUE ,row0,row2, 0, 2, 0, &forocTot); // full OROC truncated mean
+  //
+  CookdEdxAnalytical(low,up,kFALSE ,0   ,row0, 0, 2, 0, &irocMax);
+  CookdEdxAnalytical(low,up,kFALSE ,row0,row1, 0, 2, 0, &oroc1Max);
+  CookdEdxAnalytical(low,up,kFALSE ,row1,row2, 0, 2, 0, &oroc2Max);
+  CookdEdxAnalytical(low,up,kFALSE ,row0,row2, 0, 2, 0, &forocMax); // full OROC truncated mean
 
   fDEDX[0]      = i1i2(0);
-  fDEDX[1]      =  iro(0);
-  fDEDX[2]      = oro1(0);
-  fDEDX[3]      = oro2(0);
-  fDEDX[4]      = foro(0); // full OROC truncated mean
+  //
+  fDEDX[1]      =  irocTot(0);
+  fDEDX[2]      = oroc1Tot(0);
+  fDEDX[3]      = oroc2Tot(0);
+  fDEDX[4]      = forocTot(0); // full OROC truncated mean
+  fDEDX[5]      =  irocMax(0);
+  fDEDX[6]      = oroc1Max(0);
+  fDEDX[7]      = oroc2Max(0);
+  fDEDX[8]      = forocMax(0); // full OROC truncated mean
   //
   fSDEDX[0]     = i1i2(1);
-  fSDEDX[1]     =  iro(1);
-  fSDEDX[2]     = oro1(1);
-  fSDEDX[3]     = oro2(1);
+  fSDEDX[1]     =  irocTot(1);
+  fSDEDX[2]     = oroc1Tot(1);
+  fSDEDX[3]     = oroc2Tot(1);
   //
   fNCDEDX[0]    = TMath::Nint(i1i2(2));
-  fNCDEDX[1]    = TMath::Nint( iro(2));
-  fNCDEDX[2]    = TMath::Nint(oro1(2));
-  fNCDEDX[3]    = TMath::Nint(oro2(2));
+
+  fNCDEDX[1]    = TMath::Nint( irocTot(2));
+  fNCDEDX[2]    = TMath::Nint(oroc1Tot(2));
+  fNCDEDX[3]    = TMath::Nint(oroc2Tot(2));
   //
   fNCDEDXInclThres[0]    = TMath::Nint(i1i2(2)+i1i2(9));
-  fNCDEDXInclThres[1]    = TMath::Nint( iro(2)+ iro(9));
-  fNCDEDXInclThres[2]    = TMath::Nint(oro1(2)+oro1(9));
-  fNCDEDXInclThres[3]    = TMath::Nint(oro2(2)+oro2(9));
+  fNCDEDXInclThres[1]    = TMath::Nint( irocTot(2)+ irocTot(9));
+  fNCDEDXInclThres[2]    = TMath::Nint(oroc1Tot(2)+oroc1Tot(9));
+  fNCDEDXInclThres[3]    = TMath::Nint(oroc2Tot(2)+oroc2Tot(9));
   //
   SetdEdx(fDEDX[0]);
   return fDEDX[0];
@@ -968,6 +990,7 @@ Float_t  AliTPCseed::CookdEdxNorm(Double_t low, Double_t up, Int_t type, Int_t i
   //
   if (AliTPCcalibDB::Instance()->GetParameters()){
     gainGG= AliTPCcalibDB::Instance()->GetParameters()->GetGasGain()/20000;  //relative gas gain
+    gainGG *= AliTPCcalibDB::Instance()->GetParameters()->GetNtot()/36.82;//correction for the ionisation
   }
 
   const Float_t ktany = TMath::Tan(TMath::DegToRad()*10);
@@ -1061,9 +1084,10 @@ Float_t  AliTPCseed::CookdEdxNorm(Double_t low, Double_t up, Int_t type, Int_t i
       if (type==1) corrNorm=1.;
     }
     //
+    //
     amp[ncl]=charge;
-    amp[ncl]/=gainGG;
-    amp[ncl]/=gainPad;
+    amp[ncl]/=gainGG;                 // normalized gas gain
+    amp[ncl]/=gainPad;                // 
     amp[ncl]/=corrShape;
     amp[ncl]/=corrPadType;
     amp[ncl]/=corrPos;
@@ -1145,6 +1169,8 @@ Float_t  AliTPCseed::CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, I
 
   AliTPCClusterParam * parcl = AliTPCcalibDB::Instance()->GetClusterParam();
   AliTPCParam * param = AliTPCcalibDB::Instance()->GetParameters();
+  AliTPCTransform * trans = AliTPCcalibDB::Instance()->GetTransform();
+  const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
   if (!parcl)  return 0;
   if (!param) return 0;
   Int_t row0 = param->GetNRowLow();
@@ -1164,7 +1190,18 @@ Float_t  AliTPCseed::CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, I
   //
   if (AliTPCcalibDB::Instance()->GetParameters()){
     gainGG= AliTPCcalibDB::Instance()->GetParameters()->GetGasGain()/20000;  //relative gas gain
+    gainGG *= AliTPCcalibDB::Instance()->GetParameters()->GetNtot()/36.82;//correction for the ionisation
+  }
+  Double_t timeCut=0;
+  if (AliTPCcalibDB::Instance()->IsTrgL0()){
+    // by defualt we assume L1 trigger is used - make a correction in case of  L0
+    AliCTPTimeParams* ctp = AliTPCcalibDB::Instance()->GetCTPTimeParams();
+    Double_t delay = ctp->GetDelayL1L0()*0.000000025;
+    delay/=param->GetTSample();    
+    timeCut=delay;
   }
+  timeCut += recoParam->GetSkipTimeBins();
+
   //
   // extract time-dependent correction for pressure and temperature variations
   //
@@ -1172,19 +1209,19 @@ Float_t  AliTPCseed::CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, I
   Float_t corrTimeGain = 1;
   TObjArray * timeGainSplines = 0x0;
   TGraphErrors * grPadEqual = 0x0;
-  TGraphErrors*  grChamberGain[3]={0x0,0x0,0x0};
+  TGraphErrors*  grChamberGain[4]={0x0,0x0,0x0,0x0};
+  TF1*  funDipAngle[4]={0x0,0x0,0x0,0x0};
   //
-  AliTPCTransform * trans = AliTPCcalibDB::Instance()->GetTransform();
-  const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
   //
-  if (recoParam->GetNeighborRowsDedx() == 0) rowThres = 0;
+  if (recoParam->GetNeighborRowsDedx() == 0) rowThres = 0;     
+  UInt_t time = 1;//
   //
   if (trans) {
       runNumber = trans->GetCurrentRunNumber();
+      time = trans->GetCurrentTimeStamp();
       //AliTPCcalibDB::Instance()->SetRun(runNumber);
       timeGainSplines = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(runNumber);
       if (timeGainSplines && recoParam->GetUseGainCorrectionTime()>0) {
-       UInt_t time = trans->GetCurrentTimeStamp();
        AliSplineFit * fitMIP = (AliSplineFit *) timeGainSplines->At(0);
        AliSplineFit * fitFPcosmic = (AliSplineFit *) timeGainSplines->At(1);
        if (fitMIP) {
@@ -1195,9 +1232,12 @@ Float_t  AliTPCseed::CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, I
        //
        if (type==1) grPadEqual = (TGraphErrors * ) timeGainSplines->FindObject("TGRAPHERRORS_MEANQMAX_PADREGIONGAIN_BEAM_ALL");
        if (type==0) grPadEqual = (TGraphErrors * ) timeGainSplines->FindObject("TGRAPHERRORS_MEANQTOT_PADREGIONGAIN_BEAM_ALL");
-        const char* names[3]={"SHORT","MEDIUM","LONG"};
-        for (Int_t iPadRegion=0; iPadRegion<3; ++iPadRegion)
+        const char* names[4]={"SHORT","MEDIUM","LONG","ABSOLUTE"};
+        for (Int_t iPadRegion=0; iPadRegion<4; ++iPadRegion) {
           grChamberGain[iPadRegion]=(TGraphErrors*)timeGainSplines->FindObject(Form("TGRAPHERRORS_MEAN_CHAMBERGAIN_%s_BEAM_ALL",names[iPadRegion]));
+         if (type==1) funDipAngle[iPadRegion]=(TF1*)timeGainSplines->FindObject(Form("TF1_QMAX_DIPANGLE_%s_BEAM_ALL",names[iPadRegion]));
+         if (type==0) funDipAngle[iPadRegion]=(TF1*)timeGainSplines->FindObject(Form("TF1_QTOT_DIPANGLE_%s_BEAM_ALL",names[iPadRegion]));
+       }
       }
   }
   
@@ -1220,6 +1260,7 @@ Float_t  AliTPCseed::CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, I
       if (isClBefore && isClAfter) nclBelowThr++;
     }
     if (!cluster) continue;
+    if (cluster->GetTimeBin()<timeCut) continue; //reject  clusters at the gating grid opening
     //
     //
     if (TMath::Abs(cluster->GetY())>cluster->GetX()*ktany-kedgey) continue; // edge cluster
@@ -1296,14 +1337,33 @@ Float_t  AliTPCseed::CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, I
     // chamber-by-chamber equalization outside gain map
     //
     Float_t gainChamber = 1;
-    if (grChamberGain[ipad] && recoParam->GetUseGainCorrectionTime()>0) gainChamber = grChamberGain[ipad]->Eval(cluster->GetDetector());
+    if (grChamberGain[ipad] && recoParam->GetUseGainCorrectionTime()>0) {
+      gainChamber = grChamberGain[ipad]->Eval(cluster->GetDetector());
+      if (gainChamber==0) gainChamber=1; // in case old calibation was used before use no correction
+    }
+    //
+    // dip angle correction
+    //
+    Float_t corrDipAngle = 1;
+    Float_t corrDipAngleAbs = 1;
+    //    if (grDipAngle[ipad]) corrDipAngle = grDipAngle[ipad]->Eval(GetTgl());
+    Double_t tgl=GetTgl();
+    if (funDipAngle[ipad]) corrDipAngle = funDipAngle[ipad]->Eval(tgl);
+    if (funDipAngle[3]) corrDipAngleAbs = funDipAngle[3]->Eval(tgl);
+    //
+    // pressure temperature and high voltage correction
+    //
+    Double_t correctionHVandPT = AliTPCcalibDB::Instance()->GetGainCorrectionHVandPT(time, runNumber,cluster->GetDetector(), 5 , recoParam->GetGainCorrectionHVandPTMode());
     //
     amp[ncl]=charge;
-    amp[ncl]/=gainGG;
-    amp[ncl]/=gainPad;
+    amp[ncl]/=gainGG;               // nominal gas gain
+    amp[ncl]/=correctionHVandPT;    // correction for the HV and P/T - time dependent
+    amp[ncl]/=gainPad;              // 
     amp[ncl]/=corrPos;
     amp[ncl]/=gainEqualPadRegion;
     amp[ncl]/=gainChamber;
+    amp[ncl]/=corrDipAngle;
+    amp[ncl]/=corrDipAngleAbs;
     //
     ncl++;
   }
index 06ac521daafd1b7d1da13fb5e33e07b74d4664e5..6ded28396df10829f11911ceb295faac5d1ea8fa 100644 (file)
@@ -51,6 +51,7 @@ class AliTPCseed : public AliTPCtrack {
      virtual Bool_t Update(const AliCluster* c2, Double_t chi2, Int_t i);
      AliTPCTrackerPoint * GetTrackPoint(Int_t i);
      AliTPCclusterMI * GetClusterFast(Int_t irow){ return fClusterPointer[irow];}
+     AliTPCclusterMI * GetClusterFast(Int_t irow) const { return fClusterPointer[irow];}
      void SetClusterPointer(Int_t irow, AliTPCclusterMI* cl) {fClusterPointer[irow]=cl;}
      Double_t GetDensityFirst(Int_t n);
      Double_t GetSigma2C() const {
@@ -178,7 +179,7 @@ class AliTPCseed : public AliTPCtrack {
      Bool_t  fBSigned;        //indicates that clusters of this trackes are signed to be used
      //
      //
-     Float_t fDEDX[5];            // dedx according padrows
+     Float_t fDEDX[9];            // dedx according padrows
      Float_t fSDEDX[4];           // sdedx according padrows
      Int_t   fNCDEDX[4];          // number of clusters for dedx measurment
      Int_t   fNCDEDXInclThres[4]; // number of clusters for dedx measurment including sub-threshold clusters
@@ -192,7 +193,7 @@ class AliTPCseed : public AliTPCtrack {
      Char_t   fCircular;           // indicates curlin track
      AliTPCTrackerPoint  fTrackPoints[160];  //track points - array track points
      Int_t   fPoolID;              //! id in the pool
-     ClassDef(AliTPCseed,6)  
+     ClassDef(AliTPCseed,7)  
 };
 
 
index 79c245ae4fe1d1f22c4d1fab3e6a05a46d573545..47179c9d836dcd648cf39e51c52ce64024831a4b 100644 (file)
@@ -21,7 +21,7 @@
 // 
 //  AliTPC parallel tracker
 //
-//  The track fitting is based on Kalaman filtering approach
+//  The track fitting is based on Kalman filtering approach
 
 //  The track finding steps:
 //      1. Seeding - with and without vertex constraint
@@ -460,7 +460,7 @@ AliTracker(),
   }
 
   if (AliTPCReconstructor::StreamLevel()>0) {
-    fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
+    fDebugStreamer = new TTreeSRedirector("TPCdebug.root","recreate");
   }
   //
   fSeedsPool = new TClonesArray("AliTPCseed",1000);
@@ -1241,7 +1241,6 @@ Int_t  AliTPCtracker::LoadClusters(const TObjArray *arr)
   delete clrow;
   LoadOuterSectors();
   LoadInnerSectors();
-  ApllyTailCancellation();
   return 0;
 }
 
@@ -1310,6 +1309,7 @@ Int_t  AliTPCtracker::LoadClusters()
   static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
   //
   //  TTree * tree = fClustersArray.GetTree();
+  AliInfo("LoadClusters()\n");
 
   TTree * tree = fInput;
   TBranch * br = tree->GetBranch("Segment");
@@ -1353,6 +1353,7 @@ Int_t  AliTPCtracker::LoadClusters()
   clrow->Clear("C");
   LoadOuterSectors();
   LoadInnerSectors();
+  if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
   return 0;
 }
 
@@ -1473,57 +1474,252 @@ void   AliTPCtracker::Transform(AliTPCclusterMI * cluster){
   }
 }
 
-void  AliTPCtracker::ApllyTailCancellation(){
+void  AliTPCtracker::ApplyTailCancellation(){
   //
-  // Correct the cluster charge for the tail from the previous clusters
+  // Correct the cluster charge for the ion tail effect 
   // The TimeResponse function accessed via  AliTPCcalibDB (TPC/Calib/IonTail)
   //
-  //
 
-  for (Int_t secType=0; secType<2; secType++){  //loop inner or outer sector
+  // Retrieve
+  TObjArray *ionTailArr = (TObjArray*)AliTPCcalibDB::Instance()->GetIonTailArray();
+  if (!ionTailArr) {AliFatal("TPC - Missing IonTail OCDB object");}
+  TObject *rocFactorIROC  = ionTailArr->FindObject("factorIROC");
+  TObject *rocFactorOROC  = ionTailArr->FindObject("factorOROC");   
+  Float_t factorIROC      = (atof(rocFactorIROC->GetTitle()));
+  Float_t factorOROC      = (atof(rocFactorOROC->GetTitle()));
+
+  // find the number of clusters for the whole TPC (nclALL)
+  Int_t nclALL=0;
+  for (Int_t isector=0; isector<36; isector++){
+    AliTPCtrackerSector &sector= (isector<18)?fInnerSec[isector%18]:fOuterSec[isector%18];
+    nclALL += sector.GetNClInSector(0);
+    nclALL += sector.GetNClInSector(1);
+  }
+
+  // start looping over all clusters 
+  for (Int_t iside=0; iside<2; iside++){    // loop over sides
     //
     //
-    for (Int_t sec = 0;sec<fkNOS;sec++){        //loop overs sectors
-      //
-      //
-      AliTPCtrackerSector &sector= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
-      //
-      Int_t nrows = sector.GetNRows();      
-      for (Int_t row = 0;row<nrows;row++){      //loop over rows
-       AliTPCtrackerRow&  tpcrow = sector[row];            
-       Int_t ncl = tpcrow.GetN1();
-       //
-       for (Int_t icl0=0; icl0<ncl;icl0++){  // first loop over clusters
-         AliTPCclusterMI *cl0= (tpcrow.GetCluster1(icl0));       
-         if (!icl0) continue;
-         for (Int_t icl1=0; icl1<ncl;icl1++){  // second loop over clusters
-           AliTPCclusterMI *cl1= (tpcrow.GetCluster1(icl1));
-           if (!icl1) continue;
-           if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>2) continue; // no contribution if far away in pad direction
-           if (cl1->GetTimeBin()> cl0->GetTimeBin()) continue;  // no contibution to the tail if later
-           Double_t ionTailMax=0; // 
-           Double_t ionTailTotal=0; // 
-           //ionTail=????'
-           cl0->SetQ(cl0->GetQ()+ionTailTotal);
-           cl0->SetMax(cl0->GetMax()+ionTailMax);
-           if (AliTPCReconstructor::StreamLevel()>5) {
-             TTreeSRedirector &cstream = *fDebugStreamer;
-             cstream<<"IonTail"<<
-               "cl0.="<<cl0<<      // cluster 0 (to be corrected)
-               "cl1.="<<cl1<<      // cluster 1 (previous cluster)
-               "ionTailTotal="<<ionTailTotal<< // ion Tail from cluster 1 contribution to cluster0
-               "ionTailMax="<<ionTailMax<< // ion Tail from cluster 1 contribution to cluster0
-               "\n";
-           }// dump the results to the debug streamer if in debug mode
-         }//end of secon loop over clusters
-       }//end of first loop over cluster
-      }//end of loop over rows
-    }//end of loop over sectors
-  }//end of loop over IROC/OROC
+    for (Int_t secType=0; secType<2; secType++){  //loop over inner or outer sector
+      // cache experimantal tuning factor for the different chamber type 
+      const Float_t ampfactor = (secType==0)?factorIROC:factorOROC;
+      std::cout << " ampfactor = " << ampfactor << std::endl;
+      //
+      for (Int_t sec = 0;sec<fkNOS;sec++){        //loop overs sectors
+        //
+        //
+        // Cache time response functions and their positons to COG of the cluster        
+        TGraphErrors ** graphRes   = new TGraphErrors *[20];
+        Float_t * indexAmpGraphs   = new Float_t[20];      
+        for (Int_t icache=0; icache<20; icache++) 
+        {
+          graphRes[icache]       = NULL;
+          indexAmpGraphs[icache] = 0;
+        }
+        /////////////////////////////  --> position fo sie loop
+        if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(sec+36*secType+18*iside,graphRes,indexAmpGraphs))
+        {
+          continue;
+        }
+        
+        AliTPCtrackerSector &sector= (secType==0)?fInnerSec[sec]:fOuterSec[sec];  
+        Int_t nrows     = sector.GetNRows();                                       // number of rows
+        Int_t nclSector = sector.GetNClInSector(iside);                            // ncl per sector to be used for debugging
+
+        for (Int_t row = 0;row<nrows;row++){           // loop over rows
+
+          AliTPCtrackerRow&  tpcrow = sector[row];     // row object   
+          Int_t ncl = tpcrow.GetN1();                  // number of clusters in the row
+          if (iside>0) ncl=tpcrow.GetN2();
+        
+          // Order clusters in time for the proper correction of ion tail
+          Float_t qTotArray[ncl];                      // arrays to be filled with modified Qtot and Qmax values in order to avoid float->int conversion  
+          Float_t qMaxArray[ncl];
+          Int_t sortedClusterIndex[ncl];
+          Float_t sortedClusterTimeBin[ncl];
+          TObjArray *rowClusterArray = new TObjArray(ncl);  // cache clusters for each row  
+          for (Int_t i=0;i<ncl;i++) 
+          {
+            qTotArray[i]=0;
+            qMaxArray[i]=0;
+            sortedClusterIndex[i]=i;
+            AliTPCclusterMI *rowcl= (iside>0)?(tpcrow.GetCluster2(i)):(tpcrow.GetCluster1(i));
+            if (rowcl) {
+              rowClusterArray->AddAt(rowcl,i);
+            } else {
+              rowClusterArray->RemoveAt(i);
+            }
+            // Fill the timebin info to the array in order to sort wrt tb
+            if (!rowcl) {
+             sortedClusterTimeBin[i]=0.0;
+           } else {
+            sortedClusterTimeBin[i] = rowcl->GetTimeBin();
+           }
+
+          } 
+         TMath::Sort(ncl,sortedClusterTimeBin,sortedClusterIndex,kFALSE);       // sort clusters in time
+     
+          // Main cluster correction loops over clusters
+          for (Int_t icl0=0; icl0<ncl;icl0++){    // first loop over clusters
+
+            AliTPCclusterMI *cl0= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl0]));
+            
+            if (!cl0) continue;
+            Int_t nclPad=0;                       
+            for (Int_t icl1=0; icl1<ncl;icl1++){  // second loop over clusters
+          
+              AliTPCclusterMI *cl1= static_cast<AliTPCclusterMI*>(rowClusterArray->At(sortedClusterIndex[icl1]));
+             if (!cl1) continue;
+             if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>4) continue;           // no contribution if far away in pad direction
+              if (cl0->GetTimeBin()<= cl1->GetTimeBin()) continue;               // no contibution to the tail if later
+              if (TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin())>600) continue; // out of the range of response function
+
+              if (TMath::Abs(cl0->GetPad()-cl1->GetPad())<4) nclPad++;           // count ncl for every pad for debugging
+            
+              // Get the correction values for Qmax and Qtot and find total correction for a given cluster
+              Double_t ionTailMax=0.;  
+              Double_t ionTailTotal=0.;  
+              GetTailValue(ampfactor,ionTailMax,ionTailTotal,graphRes,indexAmpGraphs,cl0,cl1);
+              ionTailMax=TMath::Abs(ionTailMax);
+              ionTailTotal=TMath::Abs(ionTailTotal);
+              qTotArray[icl0]+=ionTailTotal;
+              qMaxArray[icl0]+=ionTailMax;
+
+              // Dump some info for debugging while clusters are being corrected
+              if (AliTPCReconstructor::StreamLevel()==1) {
+                TTreeSRedirector &cstream = *fDebugStreamer;
+                if (gRandom->Rndm() > 0.999){
+                  cstream<<"IonTail"<<
+                      "cl0.="         <<cl0          <<   // cluster 0 (to be corrected)
+                      "cl1.="         <<cl1          <<   // cluster 1 (previous cluster)
+                      "ionTailTotal=" <<ionTailTotal <<   // ion Tail from cluster 1 contribution to cluster0
+                      "ionTailMax="   <<ionTailMax   <<   // ion Tail from cluster 1 contribution to cluster0 
+                      "\n";
+                }
+              }// dump the results to the debug streamer if in debug mode
+            
+            }//end of second loop over clusters
+            
+            // Set corrected values of the corrected cluster          
+            cl0->SetQ(TMath::Nint(Float_t(cl0->GetQ())+Float_t(qTotArray[icl0])));
+            cl0->SetMax(TMath::Nint(Float_t(cl0->GetMax())+qMaxArray[icl0]));
+          
+            // Dump some info for debugging after clusters are corrected 
+            if (AliTPCReconstructor::StreamLevel()==1) {
+              TTreeSRedirector &cstream = *fDebugStreamer;
+              if (gRandom->Rndm() > 0.999){
+              cstream<<"IonTailCorrected"<<
+                  "cl0.="                     << cl0              <<   // cluster 0 with huge Qmax
+                  "ionTailTotalPerCluster="   << qTotArray[icl0]  <<
+                  "ionTailMaxPerCluster="     << qMaxArray[icl0]  <<
+                  "nclALL="                   << nclALL           <<
+                  "nclSector="                << nclSector        <<
+                  "nclRow="                   << ncl              <<
+                  "nclPad="                   << nclPad           <<
+                  "row="                      << row              <<
+                  "sector="                   << sec              <<
+                  "icl0="                     << icl0             <<
+                  "\n";
+              }
+            }// dump the results to the debug streamer if in debug mode
+          
+          }//end of first loop over cluster
+          delete rowClusterArray;
+        }//end of loop over rows
+        for (int i=0; i<20; i++) delete graphRes[i];
+        delete [] graphRes;
+        delete [] indexAmpGraphs;
+      
+      }//end of loop over sectors
+    }//end of loop over IROC/OROC
+  }// end of side loop
 }
+//_____________________________________________________________________________
+void AliTPCtracker::GetTailValue(const Float_t ampfactor,Double_t &ionTailMax, Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1){
 
+  //
+  // Function in order to calculate the amount of the correction to be added for a given cluster, return values are ionTailTaoltal and ionTailMax
+  // 
+
+  const Double_t kMinPRF    = 0.5;                           // minimal PRF width
+  ionTailTotal              = 0.;                            // correction value to be added to Qtot of cl0
+  ionTailMax                = 0.;                            // correction value to be added to Qmax of cl0
+
+  Float_t qTot0             =  cl0->GetQ();                  // cl0 Qtot info
+  Float_t qTot1             =  cl1->GetQ();                  // cl1 Qtot info
+  Int_t sectorPad           =  cl1->GetDetector();           // sector number
+  Int_t padcl0              =  TMath::Nint(cl0->GetPad());   // pad0
+  Int_t padcl1              =  TMath::Nint(cl1->GetPad());   // pad1
+  Float_t padWidth          = (sectorPad < 36)?0.4:0.6;      // pad width in cm
+  const Int_t deltaTimebin  =  TMath::Nint(TMath::Abs(cl1->GetTimeBin()-cl0->GetTimeBin()))+12;  //distance between pads of cl1 and cl0 increased by 12 bins
+  Double_t rmsPad1          = (cl1->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl1->GetSigmaY2())/padWidth);
+  Double_t rmsPad0          = (cl0->GetSigmaY2()==0)?kMinPRF:(TMath::Sqrt(cl0->GetSigmaY2())/padWidth);
+  
+  Double_t sumAmp1=0.;
+  for (Int_t idelta =-2; idelta<=2;idelta++){
+    sumAmp1+=TMath::Exp(-idelta*idelta/(2*rmsPad1));
+  }
 
+  Double_t sumAmp0=0.;
+  for (Int_t idelta =-2; idelta<=2;idelta++){
+    sumAmp0+=TMath::Exp(-idelta*idelta/(2*rmsPad0));
+  }
 
+  // Apply the correction  -->   cl1 corrects cl0 (loop over cl1's pads and find which pads of cl0 are going to be corrected)
+  Int_t padScan=2;      // +-2 pad-timebin window will be scanned
+  for (Int_t ipad1=padcl1-padScan; ipad1<=padcl1+padScan; ipad1++) {
+    //
+    //
+    Float_t  deltaPad1  = TMath::Abs(cl1->GetPad()-(Float_t)ipad1);
+    Double_t amp1       = (TMath::Exp(-(deltaPad1*deltaPad1)/(2*rmsPad1)))/sumAmp1;  // normalized pad response function
+    Float_t qTotPad1    = amp1*qTot1;                                               // used as a factor to multipliy the response function
+      
+    // find closest value of cl1 to COG (among the time response functions' amplitude array --> to select proper t.r.f.)
+    Int_t ampIndex = 0;
+    Float_t diffAmp  = TMath::Abs(deltaPad1-indexAmpGraphs[0]);
+    for (Int_t j=0;j<20;j++) {
+      if (diffAmp > TMath::Abs(deltaPad1-indexAmpGraphs[j]) && indexAmpGraphs[j]!=0)
+        {
+          diffAmp  = TMath::Abs(deltaPad1-indexAmpGraphs[j]);
+          ampIndex = j;
+        }
+    }
+    if (!graphRes[ampIndex]) continue;
+    if (deltaTimebin+2 >= graphRes[ampIndex]->GetN()) continue;
+    if (graphRes[ampIndex]->GetY()[deltaTimebin+2]>=0) continue;
+     
+    for (Int_t ipad0=padcl0-padScan; ipad0<=padcl0+padScan; ipad0++) {
+      //
+      //
+      if (ipad1!=ipad0) continue;                                     // check if ipad1 channel sees ipad0 channel, if not no correction to be applied.
+      
+      Float_t deltaPad0  = TMath::Abs(cl0->GetPad()-(Float_t)ipad0);
+      Double_t amp0      = (TMath::Exp(-(deltaPad0*deltaPad0)/(2*rmsPad0)))/sumAmp0;  // normalized pad resp function
+      Float_t qMaxPad0   = amp0*qTot0;
+           
+      // Add 5 timebin range contribution around the max peak (-+2 tb window)
+      for (Int_t itb=deltaTimebin-2; itb<=deltaTimebin+2; itb++) {
+
+        if (itb<0) continue; 
+        if (itb>=graphRes[ampIndex]->GetN()) continue;
+       
+        // calculate contribution to qTot
+        Float_t tailCorr =  TMath::Abs((qTotPad1*ampfactor)*(graphRes[ampIndex])->GetY()[itb]);
+        if (ipad1!=padcl0) { 
+          ionTailTotal += TMath::Min(qMaxPad0,tailCorr);   // for side pad
+        } else {             
+          ionTailTotal += tailCorr;                        // for center pad
+        }
+        // calculate contribution to qMax
+        if (itb == deltaTimebin && ipad1 == padcl0) ionTailMax += tailCorr;   
+        
+      } // end of tb correction loop which is applied over 5 tb range
+
+    } // end of cl0 loop
+  } // end of cl1 loop
+  
+}
 
 //_____________________________________________________________________________
 Int_t AliTPCtracker::LoadOuterSectors() {
@@ -2845,18 +3041,23 @@ Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
       // fill new dEdx information
       //
       Double32_t signal[4]; 
+      Double32_t signalMax[4]; 
       Char_t ncl[3]; 
       Char_t nrows[3];
       //
       for(Int_t iarr=0;iarr<3;iarr++) {
        signal[iarr] = seed->GetDEDXregion(iarr+1);
+       signalMax[iarr] = seed->GetDEDXregion(iarr+5);
        ncl[iarr] = seed->GetNCDEDX(iarr+1);
        nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
       }
       signal[3] = seed->GetDEDXregion(4);
+      signalMax[3] = seed->GetDEDXregion(8);
+      
       //
       AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
       infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
+      infoTpcPid->SetTPCSignalsQmax(signalMax);
       esd->SetTPCdEdxInfo(infoTpcPid);
       //
       // add seed to the esd track in Calib level
@@ -2880,6 +3081,8 @@ Int_t AliTPCtracker::RefitInward(AliESDEvent *event)
 
   AliCosmicTracker::FindCosmic(event, kTRUE);
 
+  FillClusterOccupancyInfo();
+
   return 0;
 }
 
@@ -3043,19 +3246,7 @@ void AliTPCtracker::ReadSeeds(const AliESDEvent *const event, Int_t direction)
     //  MarkSeedFree( seed );
     //  continue;    
     //}
-    if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 )  {
-      Double_t par0[5],par1[5],alpha,x;
-      esd->GetInnerExternalParameters(alpha,x,par0);
-      esd->GetExternalParameters(x,par1);
-      Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
-      Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
-      Double_t trdchi2=0;
-      if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
-      //reset covariance if suspicious 
-      if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
-       seed->ResetCovariance(10.);
-    }
-
+    
     //
     //
     // rotate to the local coordinate system
@@ -8268,3 +8459,25 @@ TObjArray * AliTPCtracker::MakeSeedsHLT(const AliESDEvent *hltEvent)
   std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;
   return seeds;    
 }
+
+void AliTPCtracker::FillClusterOccupancyInfo()
+{
+  //fill the cluster occupancy info into the ESD friend
+  AliESDfriend* esdFriend = static_cast<AliESDfriend*>(fEvent->FindListObject("AliESDfriend"));
+  if (!esdFriend) return;
+
+  for (Int_t isector=0; isector<18; isector++){
+    AliTPCtrackerSector &iroc = fInnerSec[isector];
+    AliTPCtrackerSector &oroc = fOuterSec[isector];
+    //all clusters
+    esdFriend->SetNclustersTPC(isector,   iroc.GetNClInSector(0));
+    esdFriend->SetNclustersTPC(isector+18,iroc.GetNClInSector(1));
+    esdFriend->SetNclustersTPC(isector+36,oroc.GetNClInSector(0));
+    esdFriend->SetNclustersTPC(isector+54,oroc.GetNClInSector(1));
+    //clusters used in tracking
+    esdFriend->SetNclustersTPCused(isector,    iroc.GetNClUsedInSector(0));
+    esdFriend->SetNclustersTPCused(isector+18, iroc.GetNClUsedInSector(1));
+    esdFriend->SetNclustersTPCused(isector+36, oroc.GetNClUsedInSector(0));
+    esdFriend->SetNclustersTPCused(isector+54, oroc.GetNClUsedInSector(1));
+  }
+}
index bcba87c08f89dfaf47ebedb12611858c29a5de77..6239fbf2c26564ff4f3e30defade3de3fa820029 100644 (file)
@@ -18,6 +18,8 @@
 #include "AliTPCreco.h"
 #include "AliTPCclusterMI.h"
 #include "AliTPCtrackerSector.h"
+#include "AliESDfriend.h"
+
 
 
 class TFile;
@@ -32,7 +34,7 @@ class TTreeSRedirector;
 class AliTrackPoint;
 class AliDCSSensorArray;
 class AliDCSSensor;
-
+class TGraphErrors;
 
 
 class AliTPCtracker : public AliTracker {
@@ -55,7 +57,8 @@ public:
   Int_t LoadOuterSectors();
   virtual void FillClusterArray(TObjArray* array) const;
   void   Transform(AliTPCclusterMI * cluster);
-  void ApllyTailCancellation();
+  void ApplyTailCancellation();
+  void GetTailValue(const Float_t ampfactor,Double_t &ionTailMax,Double_t &ionTailTotal,TGraphErrors **graphRes,Float_t *indexAmpGraphs,AliTPCclusterMI *cl0,AliTPCclusterMI *cl1);
   //
   void FillESD(const TObjArray* arr);
   void DeleteSeeds();
@@ -72,6 +75,7 @@ public:
   Int_t RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &kink);
    Int_t ReadSeeds(const TFile *in);
    TObjArray * GetSeeds() const {return fSeeds;}
+   void SetSeeds(TObjArray * seeds) { fSeeds = seeds;}
    //   
    AliCluster * GetCluster(Int_t index) const {return (AliCluster*)GetClusterMI(index);}
    AliTPCclusterMI *GetClusterMI(Int_t index) const;
@@ -117,6 +121,8 @@ public:
  public:
    void SetUseHLTClusters(Int_t useHLTClusters) {fUseHLTClusters = useHLTClusters;} // set usage from HLT clusters from rec.C options
 
+   inline void SetTPCtrackerSectors(AliTPCtrackerSector *innerSec, AliTPCtrackerSector *outerSec); // set the AliTPCtrackerSector arrays from outside (toy MC)
+
    Float_t OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t &sum2);
    void  SignShared(AliTPCseed * s1, AliTPCseed * s2);
    void  SignShared(TObjArray * arr);
@@ -127,6 +133,12 @@ public:
 
    Bool_t IsTPCHVDipEvent(AliESDEvent const *esdEvent);
 
+   // public for ToyMC usage
+   void MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4], Float_t deltay = -1, Bool_t bconstrain=kTRUE); 
+   void MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4], Float_t deltay = -1, Int_t ddsec=0); 
+   void SumTracks(TObjArray *arr1,TObjArray *&arr2);
+   void SignClusters(const TObjArray * arr, Float_t fnumber=3., Float_t fdensity=2.);  
+
 private:
   Bool_t IsFindable(AliTPCseed & t);
   AliTPCtracker(const AliTPCtracker& r);           //dummy copy constructor
@@ -147,10 +159,7 @@ private:
  
    void ReadSeeds(const AliESDEvent *const event, Int_t direction);  //read seeds from the event
 
-   void MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4], Float_t deltay = -1, Int_t ddsec=0); 
    void MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4], Float_t deltay = -1);
-
-   void MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4], Float_t deltay = -1, Bool_t bconstrain=kTRUE);
   
 
    AliTPCseed *MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2); //reseed
@@ -164,14 +173,14 @@ private:
    //Int_t LoadOuterSectors();
    void DumpClusters(Int_t iter, TObjArray *trackArray);
    void UnsignClusters();
-   void SignClusters(const TObjArray * arr, Float_t fnumber=3., Float_t fdensity=2.);  
+
+   void FillClusterOccupancyInfo();
 
    void ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast);
    void Tracking(TObjArray * arr);
    TObjArray * Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy=-1, Int_t dsec=0);
    TObjArray * Tracking();
    TObjArray * TrackingSpecial();
-   void SumTracks(TObjArray *arr1,TObjArray *&arr2);
    void PrepareForBackProlongation(const TObjArray *const arr, Float_t fac) const;
    void PrepareForProlongation(TObjArray *const arr, Float_t fac) const;
 
@@ -263,7 +272,12 @@ Double_t  AliTPCtracker::GetPadPitchLength(Int_t row) const
   return fPadLength[row];
 }
 
-
+void  AliTPCtracker::SetTPCtrackerSectors(AliTPCtrackerSector *innerSec, AliTPCtrackerSector *outerSec)
+{
+  //
+  fInnerSec = innerSec;
+  fOuterSec = outerSec;
+}
 
 #endif
 
index 8f37233469f9ef95ab8fe933d8d5929eb35b204c..fe5cc0eff0c36eae34cf0c542b21b94430df423c 100644 (file)
@@ -30,6 +30,7 @@
 #include <TClonesArray.h>
 #include "AliLog.h"
 #include "AliComplexCluster.h"
+//#include "AliTPCcluster.h"
 #include "AliTPCclusterMI.h"
 #include "AliTPCClustersRow.h"
 #include "AliTPCParam.h"
@@ -144,7 +145,8 @@ AliTPCclusterMI * AliTPCtrackerRow::FindNearest(Double_t y, Double_t z, Double_t
   for (Int_t i=Find(z-roadz); i<fN; i++) {
       AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
       if (c->GetZ() > z+roadz) break;
-      if ( (c->GetY()-y) >  roady ) continue;
+//       if ( (c->GetY()-y) >  roady ) continue; //JW: Why here not abs???
+      if ( TMath::Abs(c->GetY()-y) >  roady ) continue;
       Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
       if (maxdistance>distance) {
        maxdistance = distance;
@@ -202,6 +204,24 @@ void AliTPCtrackerRow::SetFastCluster(Int_t i, Short_t cl){
   }
 }
 
+Int_t  AliTPCtrackerSector::GetNClInSector(Int_t side) 
+{
+  // return number of all clusters in one sector; side =0 for A side and 1 for C side 
+
+  Int_t nclSector=0;
+  Int_t nrows = GetNRows();
+
+  for (Int_t row=0;row<nrows;row++) {
+    AliTPCtrackerRow&  tpcrow = (*this)[row];
+    Int_t ncl =  (side==0)?(tpcrow.GetN1()):(tpcrow.GetN2());
+    nclSector+=ncl;
+  }
+  
+  return nclSector;
+}
+
+
+
 
 Int_t  AliTPCtrackerSector::GetRowNumber(Double_t x) const 
 {
@@ -330,3 +350,44 @@ void AliTPCtrackerSector::InsertCluster(AliTPCclusterMI *cl, Int_t size, const A
   }
 }
 
+//_________________________________________________________________________
+Int_t  AliTPCtrackerSector::GetNClInSector(Int_t side) const
+{
+  //return number of all clusters in one sector; side =0 for A side and 1 for C side 
+
+  Int_t nclSector=0;
+  Int_t nrows = GetNRows();
+
+  for (Int_t row=0;row<nrows;row++) {
+    AliTPCtrackerRow&  tpcrow = (*this)[row];
+    Int_t ncl =  (side==0)?(tpcrow.GetN1()):(tpcrow.GetN2());
+    nclSector+=ncl;
+  }
+
+  return nclSector;
+}
+
+//_________________________________________________________________________
+Int_t  AliTPCtrackerSector::GetNClUsedInSector(Int_t side) const
+{
+  //return number of clusters used in tracking in one sector; side =0 for A side and 1 for C side 
+
+  Int_t nclSector=0;
+  Int_t nrows = GetNRows();
+
+  for (Int_t row=0;row<nrows;row++) {
+    AliTPCtrackerRow&  tpcrow = (*this)[row];
+    Int_t nclusters = (side==0)?tpcrow.GetN1():tpcrow.GetN2();
+    for (Int_t icluster=0; icluster<nclusters; icluster++)
+    {
+      AliTPCclusterMI* cluster = NULL;
+      if (side==0) { cluster=tpcrow.GetCluster1(icluster); }
+      else         { cluster=tpcrow.GetCluster2(icluster); }
+      if (!cluster) continue;
+      if (cluster->IsUsed(1)) nclSector++;
+    }
+  }
+
+  return nclSector;
+}
+
index 30ee252589a6bd4f4a041ecff99b209515d7d19c..bf87f0cf08f429b3347cb3d01d467cd051d1866f 100644 (file)
@@ -47,8 +47,10 @@ public:
   TClonesArray* GetClusters2() const {return fClusters2;}
   void SetCluster1(Int_t i, const AliTPCclusterMI &cl);
   void SetCluster2(Int_t i, const AliTPCclusterMI &cl);
-  AliTPCclusterMI* GetCluster1(Int_t i) const {return (AliTPCclusterMI*) fClusters1->At(i);}
-  AliTPCclusterMI* GetCluster2(Int_t i) const {return (AliTPCclusterMI*) fClusters2->At(i);}
+
+  AliTPCclusterMI* GetCluster1(Int_t i) const {return (fClusters1)?(AliTPCclusterMI*) fClusters1->At(i):NULL;}
+  AliTPCclusterMI* GetCluster2(Int_t i) const {return (fClusters2)?(AliTPCclusterMI*) fClusters2->At(i):NULL;}  
+  
   Short_t GetFastCluster(Int_t i) const {return fFastCluster[i];}
   void SetFastCluster(Int_t i, Short_t cl);
   Int_t IncrementN1() { return ++fN1;}
@@ -96,6 +98,7 @@ class AliTPCtrackerSector: public TObject {
     Double_t GetAlpha() const {return fAlpha;}
     Double_t GetAlphaShift() const {return fAlphaShift;}     
     //Int_t GetFirst(){return fFirstRow;}
+    Int_t GetNClInSector(Int_t side);
     Int_t GetRowNumber(Double_t  x) const;
     Double_t GetPadPitchWidth()  const {return fPadPitchWidth;}
     Double_t GetPadPitchLength() const {return fPadPitchLength;}
@@ -103,6 +106,9 @@ class AliTPCtrackerSector: public TObject {
     
     void InsertCluster(AliTPCclusterMI *cl, Int_t size, const AliTPCParam *par);
 
+    Int_t GetNClInSector(Int_t side) const;
+    Int_t GetNClUsedInSector(Int_t side) const;
+  
  private:
     AliTPCtrackerSector & operator=(const AliTPCtrackerSector & );
     AliTPCtrackerSector(const AliTPCtrackerSector &/*s*/);           //dummy copy contructor 
index 6fda234242af5d3b0311bc116c808fbaa0bfb5a9..7fa8acbe00b96e3d95a0c4177af003a6b34db71d 100644 (file)
@@ -55,6 +55,8 @@
 #include <TParameter.h>
 
 #include "AliDigits.h"
+#include "AliHeader.h"
+
 #include "AliMagF.h"
 #include "AliRun.h"
 #include "AliRunLoader.h"
@@ -247,9 +249,9 @@ void AliTPC::CreateMaterials()
    Int_t iSXFLD=((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
   Float_t sXMGMX=((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
 
-  Float_t amat[5]; // atomic numbers
-  Float_t zmat[5]; // z
-  Float_t wmat[5]; // proportions
+  Float_t amat[7]; // atomic numbers
+  Float_t zmat[7]; // z
+  Float_t wmat[7]; // proportions
 
   Float_t density;
  
@@ -273,7 +275,7 @@ void AliTPC::CreateMaterials()
   wmat[0]=0.2729;
   wmat[1]=0.7271;
 
-  density=0.001754609;
+  density=1.842e-3;
 
 
   AliMixture(10,"CO2",amat,zmat,density,2,wmat);
@@ -294,52 +296,107 @@ void AliTPC::CreateMaterials()
   AliMixture(11,"Air",amat,zmat,density,2,wmat);
   
   //----------------------------------------------------------------
-  // drift gases 
+  // drift gases 5 mixtures, 5 materials
   //----------------------------------------------------------------
-
   //
   // Drift gases 1 - nonsensitive, 2 - sensitive, 3 - for Kr
   //  Composition by % of volume, values at 20deg and 1 atm.
   //
   //  get the geometry title - defined in Config.C
   //
-
-  TString title(GetTitle());
-  
+  //--------------------------------------------------------------
+  //  predefined gases, composition taken from param file
+  //--------------------------------------------------------------
+  TString names[6]={"Ne","Ar","CO2","N","CF4","CH4"};
+  TString gname;
+  Float_t *comp = fTPCParam->GetComposition();
+  // indices:
+  // 0-Ne, 1-Ar, 2-CO2, 3-N, 4-CF4, 5-CH4
   //
-  amat[0]= 20.18;
-  amat[1]=12.011;
-  amat[2]=15.9994;
-
-
-  zmat[0]= 10.; 
-  zmat[1]=6.;
-  zmat[2]=8.;
-
-  if(title == TString("Ne-CO2") || title == TString("Default")){
-    wmat[0]=0.8038965;
-    wmat[1]= 0.053519;
-    wmat[2]= 0.1425743;
-    density=0.0009393;
-    //
-    AliMixture(12,"Ne-CO2-1",amat,zmat,density,3,wmat);
-    AliMixture(13,"Ne-CO2-2",amat,zmat,density,3,wmat);
-    AliMixture(40,"Ne-CO2-3",amat,zmat,density,3,wmat);
+  // elements' masses
+  // 
+  amat[0]=20.18; //Ne
+  amat[1]=39.95; //Ar
+  amat[2]=12.011; //C
+  amat[3]=15.9994; //O
+  amat[4]=14.007; //N
+  amat[5]=18.998; //F
+  amat[6]=1.; //H
+  //
+  // elements' atomic numbers
+  //
+  // 
+  zmat[0]=10.; //Ne
+  zmat[1]=18.; //Ar
+  zmat[2]=6.;  //C
+  zmat[3]=8.;  //O
+  zmat[4]=7.;  //N
+  zmat[5]=9.;  //F
+  zmat[6]=1.;  //H
+  //
+  // Mol masses
+  //
+  Float_t wmol[6];
+  wmol[0]=20.18; //Ne
+  wmol[1]=39.948; //Ar
+  wmol[2]=44.0098; //CO2
+  wmol[3]=2.*14.0067; //N2
+  wmol[4]=88.0046; //CF4
+  wmol[5]=16.011; //CH4
+  //
+  Float_t wtot=0.; //total mass of the mixture
+  for(Int_t i =0;i<6;i++){
+    wtot += *(comp+i)*wmol[i]; 
   }
-  else if (title == TString("Ne-CO2-N")){
-     amat[3]=14.007;
-     zmat[3]=7.; 
-     wmat[0]=0.756992632;
-     wmat[1]=0.056235789; 
-     wmat[2]=0.128469474; 
-     wmat[3]=0.058395789;
-     density=0.000904929;
-     //
-     AliMixture(12,"Ne-CO2-N-1",amat,zmat,density,4,wmat);
-     AliMixture(13,"Ne-CO2-N-2",amat,zmat,density,4,wmat);
-     AliMixture(40,"Ne-CO2-N-3",amat,zmat,density,4,wmat);
-  
+  wmat[0]=comp[0]*amat[0]/wtot; //Ne
+  wmat[1]=comp[1]*amat[1]/wtot; //Ar
+  wmat[2]=(comp[2]*amat[2]+comp[4]*amat[2]+comp[5]*amat[2])/wtot; //C
+  wmat[3]=comp[2]*amat[3]*2./wtot; //O
+  wmat[4]=comp[3]*amat[4]*2./wtot; //N
+  wmat[5]=comp[4]*amat[5]*4./wtot; //F
+  wmat[6]=comp[5]*amat[6]*4./wtot; //H
+  //
+  // densities (NTP)
+  //
+  Float_t dens[6]={0.839e-3,1.661e-3,1.842e-3,1.251e-3,3.466e-3,0.668e-3};
+ //
+  density=0.;
+  for(Int_t i=0;i<6;i++){
+    density += comp[i]*dens[i];
+  }
+  //
+  // names
+  //
+  Int_t cnt=0;
+  for(Int_t i =0;i<6;i++){
+    if(comp[i]){
+     if(cnt)gname+="-"; 
+      gname+=names[i];
+      cnt++;   
+    } 
   }
+TString gname1,gname2,gname3;
+gname1 = gname + "-1";
+gname2 = gname + "-2";
+gname3 = gname + "-3";
+//
+// take only elements with nonzero weights
+//
+ Float_t amat1[6],zmat1[6],wmat1[6];
+ cnt=0;
+ for(Int_t i=0;i<7;i++){
+   if(wmat[i]){
+     zmat1[cnt]=zmat[i];
+     amat1[cnt]=amat[i];
+     wmat1[cnt]=wmat[i];
+     cnt++;
+   }
+ }
+   
+//
+AliMixture(12,gname1.Data(),amat1,zmat1,density,cnt,wmat1); // nonsensitive
+AliMixture(13,gname2.Data(),amat1,zmat1,density,cnt,wmat1); // sensitive
+AliMixture(40,gname3.Data(),amat1,zmat1,density,cnt,wmat1); //sensitive Kr
 
 
 
@@ -2053,8 +2110,13 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
 
   Float_t gasgain = fTPCParam->GetGasGain();
   gasgain = gasgain/fGainFactor;
+  //  const Int_t timeStamp = 1; //where to get it? runloader->GetHeader()->GetTimeStamp(). https://savannah.cern.ch/bugs/?53025
+  const Int_t timeStamp = fLoader->GetRunLoader()->GetHeader()->GetTimeStamp(); //?
+  Double_t correctionHVandPT = calib->GetGainCorrectionHVandPT(timeStamp, calib->GetRun(), isec, 5 ,tpcrecoparam->GetGainCorrectionHVandPTMode());
+  gasgain*=correctionHVandPT;
+
   Int_t i;
-  Float_t xyz[5]
+  Float_t xyz[5]={0,0,0,0,0};
 
   AliTPChit *tpcHit; // pointer to a sigle TPC hit    
   //MI change
@@ -2168,9 +2230,12 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
       for(Int_t nel=0;nel<qI;nel++){
        // skip if electron lost due to the attachment
        if((gRandom->Rndm(0)) < attProb) continue; // electron lost!
-       
+       // use default hit position
+       xyz[0]=tpcHit->X();
+       xyz[1]=tpcHit->Y();
+       xyz[2]=tpcHit->Z(); 
        //
-       // ExB effect
+       // ExB effect - distort hig if specifiend in the RecoParam
        //
         if (tpcrecoparam->GetUseExBCorrection()) {
          Double_t dxyz0[3],dxyz1[3];
diff --git a/TPC/Sim/AliTPCGen.h b/TPC/Sim/AliTPCGen.h
new file mode 100644 (file)
index 0000000..08eb642
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef ALITPCGEN_H
+#define ALITPCGEN_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+/* $Id$ */
+typedef struct {
+    Float_t fpot;
+    Float_t eend;
+    Float_t eexpo;
+}Gas; // to communicate with gfluct
+#endif
index a66ef5f0e3c866ef58e0f4e65bc53da90697a609..18337b67319adbb4519e0044aa5b02b73c74b23d 100644 (file)
@@ -56,6 +56,9 @@
 
 using std::ifstream;
 using std::ios_base;
+extern "C"{
+  Gas gaspar_;
+};
 ClassImp(AliTPCv2)
  
 //_____________________________________________________________________________
@@ -71,10 +74,14 @@ AliTPCv2::AliTPCv2(const char *name, const char *title) :
 
 
   SetBufferSize(128000);
+  if(!fTPCParam) {AliFatal("TPC parameters not set");
+      return;
+  }
+  gaspar_.fpot=fTPCParam->GetFpot();
+  gaspar_.eend=fTPCParam->GetEend();
+  gaspar_.eexpo=fTPCParam->GetExp();
 
 
-//   if (fTPCParam)
-//      fTPCParam->Write(fTPCParam->GetTitle());
 }
  
 //_____________________________________________________________________________
@@ -2104,7 +2111,7 @@ void AliTPCv2::Init()
   fIDrift=gMC->VolId("TPC_Drift");
   fSecOld=-100; // fake number 
 
-  gMC->SetMaxNStep(-30000); // max. number of steps increased
+  gMC->SetMaxNStep(-120000); // max. number of steps increased
 
   if (fPrimaryIonisation) {
     // for FLUKA
@@ -2134,12 +2141,15 @@ void AliTPCv2::StepManager()
   //
   // parameters used for the energy loss calculations
   //
-  const Float_t kprim = 14.35; // number of primary collisions per 1 cm
-  const Float_t kpoti = 20.77e-9; // first ionization potential for Ne/CO2
-  const Float_t kwIon = 35.97e-9; // energy for the ion-electron pair creation
+  //const Float_t kprim = 14.35; // number of primary collisions per 1 cm
+  //const Float_t kpoti = 20.77e-9; // first ionization potential for Ne/CO2
+  //const Float_t kwIon = 35.97e-9; // energy for the ion-electron pair creation 
   const Float_t kScalewIonG4 = 0.85; // scale factor to tune kwIon for Geant4 
   const Float_t kFanoFactorG4 = 0.7; // parameter for smearing the number of ionizations (nel) using Geant4
   const Int_t   kMaxDistRef =15;     // maximal difference between 2 stored references 
+  Float_t prim = fTPCParam->GetNprim();
+  Float_t poti = fTPCParam->GetFpot();
+  Float_t wIon = fTPCParam->GetWmean();
  
   const Float_t kbig = 1.e10;
 
@@ -2263,23 +2273,23 @@ void AliTPCv2::StepManager()
   if(gMC->TrackStep() > 0) {
     Int_t nel=0;
     if (!fPrimaryIonisation) {
-      nel = (Int_t)(((gMC->Edep())-kpoti)/kwIon) + 1;
+      nel = (Int_t)(((gMC->Edep())-poti)/wIon) + 1;
     }
     else {
       
       /*
       static Double_t deForNextStep = 0.;
       // Geant4 (the meaning of Edep as in Geant3) - wrong
-      //nel = (Int_t)(((gMC->Edep())-kpoti)/kwIon) + 1;
+      //nel = (Int_t)(((gMC->Edep())-poti)/wIon) + 1;
 
       // Geant4 (the meaning of Edep as in Geant3) - NEW
       Double_t eAvailable = gMC->Edep() + deForNextStep;
-      nel = (Int_t)(eAvailable/kwIon);
-      deForNextStep = eAvailable - nel*kwIon;
+      nel = (Int_t)(eAvailable/wIon);
+      deForNextStep = eAvailable - nel*wIon;
       */
 
       //new Geant4-approach
-      Double_t meanIon = gMC->Edep()/(kwIon*kScalewIonG4);
+      Double_t meanIon = gMC->Edep()/(wIon*kScalewIonG4);
       nel = (Int_t) ( kFanoFactorG4*AliMathBase::Gamma(meanIon/kFanoFactorG4)); // smear nel using gamma distr w mean = meanIon and variance = meanIon/kFanoFactorG4
     }
     nel=TMath::Min(nel,300); // 300 electrons corresponds to 10 keV
@@ -2337,18 +2347,18 @@ void AliTPCv2::StepManager()
     Float_t ptot=mom.Rho();
     Float_t betaGamma = ptot/gMC->TrackMass();
 
-    Int_t pid=gMC->TrackPid();
-    if((pid==kElectron || pid==kPositron) && ptot > 0.002)
-      { 
-        pp = kprim*1.58; // electrons above 20 MeV/c are on the plateau!
-      }
-    else
-      {
-
-        betaGamma = TMath::Max(betaGamma,(Float_t)7.e-3); // protection against too small bg
-        pp=kprim*AliMathBase::BetheBlochAleph(betaGamma); 
-   
-    }
+    //Int_t pid=gMC->TrackPid();
+    // if((pid==kElectron || pid==kPositron) && ptot > 0.002)
+    //       { 
+    //         pp = prim*1.58; // electrons above 20 MeV/c are on the plateau!
+    //       }
+    //     else
+    //       {
+    
+    betaGamma = TMath::Max(betaGamma,(Float_t)7.e-3); // protection against too small bg
+    TVectorD *bbpar = fTPCParam->GetBetheBlochParameters(); //get parametrization from OCDB
+    pp=prim*AliMathBase::BetheBlochAleph(betaGamma,(*bbpar)(0),(*bbpar)(1),(*bbpar)(2),(*bbpar)(3),(*bbpar)(4));         
+    //     }
   
     Double_t rnd = gMC->GetRandom()->Rndm();
   
index db4d70424413e302c7ae78beb9bbd1fcc1a2c45f..d19b141d1452db9cd06e39363513c4676a3601f7 100644 (file)
@@ -21,6 +21,7 @@
 #include "AliRun.h"
 #include "AliTPCDigitsArray.h"
 #include "TGeoManager.h"
+#include "AliTPCGen.h"
 class AliTPCv2 : public AliTPC {
 
 public:
index 70284ea48b5a137147f1e39473101ba80a76b143..cc315d67b72b611017ab2e2efce4053cf8451770 100644 (file)
@@ -60,6 +60,10 @@ TPC version for the krypton runs (Marek)
 
 using std::ifstream;
 using std::ios_base;
+
+extern "C"{
+  Gas gaspar1_;
+};
 ClassImp(AliTPCv4)
  
 //_____________________________________________________________________________
@@ -76,9 +80,15 @@ AliTPCv4::AliTPCv4(const char *name, const char *title) :
 
   SetBufferSize(128000);
 
+  if(!fTPCParam) {AliFatal("TPC parameters not set");
+      return;
+  }
+
+
+  gaspar1_.fpot=fTPCParam->GetFpot();
+  gaspar1_.eend=1.e-6;
+  gaspar1_.eexpo=fTPCParam->GetExp();
 
-  if (fTPCParam)
-     fTPCParam->Write(fTPCParam->GetTitle());
 }
  
 //_____________________________________________________________________________
@@ -1987,9 +1997,9 @@ void AliTPCv4::StepManager()
   //
   // parameters used for the energy loss calculations
   //
-  const Float_t kprim = 14.35; // number of primary collisions per 1 cm
-  const Float_t kpoti = 20.77e-9; // first ionization potential for Ne/CO2
-  const Float_t kwIon = 35.97e-9; // energy for the ion-electron pair creation 
+   Float_t prim = fTPCParam->GetNprim();
+  Float_t poti = fTPCParam->GetFpot();
+  Float_t wIon = fTPCParam->GetWmean(); 
  
  
   const Float_t kbig = 1.e10;
@@ -2098,7 +2108,7 @@ void AliTPCv4::StepManager()
 
   if(gMC->TrackStep() > 0){ 
 
-    Int_t nel = (Int_t)(((gMC->Edep())-kpoti)/kwIon) + 1;
+    Int_t nel = (Int_t)(((gMC->Edep())-poti)/wIon) + 1;
     nel=TMath::Min(nel,30); // 30 electrons corresponds to 1 keV
     //
     gMC->TrackPosition(p);
@@ -2133,18 +2143,18 @@ void AliTPCv4::StepManager()
   Float_t betaGamma = ptot/gMC->TrackMass();
   
   Int_t pid=gMC->TrackPid();
-  if((pid==kElectron || pid==kPositron) && ptot > 0.002)
-    { 
-      pp = kprim*1.58; // electrons above 20 MeV/c are on the plateau!
-    }
-  else
-    {
-
-      betaGamma = TMath::Max(betaGamma,(Float_t)7.e-3); // protection against too small bg
-      pp=kprim*AliMathBase::BetheBlochAleph(betaGamma); 
-   
-      if(TMath::Abs(charge) > 1.) pp *= (charge*charge);
-    }
+  //  if((pid==kElectron || pid==kPositron) && ptot > 0.002)
+  //     { 
+  //       pp = prim*1.58; // electrons above 20 MeV/c are on the plateau!
+  //     }
+  //   else
+  //     {
+  
+  betaGamma = TMath::Max(betaGamma,(Float_t)7.e-3); // protection against too small bg
+  TVectorD* bbpar = fTPCParam->GetBetheBlochParameters(); //get parametrization from OCDB
+  pp=prim*AliMathBase::BetheBlochAleph(betaGamma,(*bbpar)(0),(*bbpar)(1),(*bbpar)(2),(*bbpar)(3),(*bbpar)(4));    
+  if(TMath::Abs(charge) > 1.) pp *= (charge*charge);
+  //    }
   
   Double_t rnd = gMC->GetRandom()->Rndm();
   
index 9de4125688bcf4f9b01381df48874072c25084ad..6fc6ef4adbf7e0dce9836879a9daeed181f5f148 100644 (file)
@@ -22,6 +22,7 @@
 #include "AliRun.h"
 #include "AliTPCDigitsArray.h"
 #include "TGeoManager.h"
+#include "AliTPCGen.h"
 class AliTPCv4 : public AliTPC {
 
 public:
index 6b23ff4c2cc3a5082c0b16a4239b0857beeed39d..5b2046a56b035f67db8784c28b94ca04693bee14 100644 (file)
                                                        //  + OROC qudarant (OROC has 4 separate pad planes) alignment 
 #pragma link C++ class AliTPCSpaceCharge+;             // Distortions due to space charge in the TPC - rotational symetric
 #pragma link C++ class AliTPCSpaceCharge3D+;           // Distortions due to space charge in the TPC - 3D calculation
-
+#pragma link C++ class AliTPCCorrectionLookupTable+;   // Lookup table created from distortions
 #pragma link C++ class AliTPCExBEffective+;            // Cover ExB effect of non-explained physical model - not used
                                                        // --- still used in CalibMacros --- move to attic if removed there
 #pragma link C++ class AliTPCExBEffectiveSector+;      // sectorwise above
diff --git a/TPC/TPCupgradeLinkDef.h b/TPC/TPCupgradeLinkDef.h
new file mode 100644 (file)
index 0000000..6c75d9f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef __CINT__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: TPCrecLinkDef.h 61214 2013-03-04 07:12:14Z jthaeder $ */
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class AliToyMCTrack+;
+#pragma link C++ class AliToyMCEvent+;
+#pragma link C++ class AliToyMCEventGenerator+;
+#pragma link C++ class AliToyMCEventGeneratorSimple+;
+#pragma link C++ class AliToyMCReconstruction+;
+#pragma link C++ class AliToyMCDrawer;
+
+#endif
index 3ec158d10d7f33264a25c9a85112cfdc86dd5fe6..6b3705b34f0758b90973e4d596e93b89e7c1350a 100644 (file)
@@ -11,6 +11,8 @@ AliToyMCEvent::AliToyMCEvent()
   ,fX(-1000.)
   ,fY(-1000.)
   ,fZ(-1000.)
+  ,fSCscale(-1.)
+  ,fSCscaleChi2(0)
   ,fTracks("AliToyMCTrack")
 {
   fEventNumber = fgEvCounter;
@@ -26,6 +28,8 @@ AliToyMCEvent::AliToyMCEvent(const AliToyMCEvent &event)
   ,fX(event.fX)
   ,fY(event.fY)
   ,fZ(event.fZ)
+  ,fSCscale(event.fSCscale)
+  ,fSCscaleChi2(event.fSCscaleChi2)
   ,fTracks(event.fTracks)
 {
   //
index dc70ed5a8aed85e146a63ec6e43f21c07f406c4d..c08d5a602574d640f2c4d44887ef4ab4dbdeb548 100644 (file)
@@ -39,22 +39,31 @@ class AliToyMCEvent : public TObject {
 
   void SetEventType(EEventType type) { fEventType=type; }
   EEventType GetEventType() const    { return fEventType; }
+
+  void     SetSCscale(Float_t  val)      { fSCscale = val;      }
+  Float_t  GetSCscale() const            { return fSCscale;     }
+
+  void     SetSCscaleChi2(Float_t  val)  { fSCscaleChi2 = val;  }
+  Float_t  GetSCscaleChi2() const        { return fSCscaleChi2; }
   
  private:
-  static Int_t fgEvCounter;
+  static Int_t fgEvCounter;      // static counter
     
-  UInt_t fEventNumber;
+  UInt_t fEventNumber;           // event number
 
-  EEventType fEventType;
+  EEventType fEventType;         // type of the event
     
-  Float_t fT0;
-  Float_t fX;
-  Float_t fY;
-  Float_t fZ;
+  Float_t fT0;                   // Interaction time of the event
+  Float_t fX;                    // x-vertex position
+  Float_t fY;                    // y-vertex position
+  Float_t fZ;                    // z-vertex position
 
-  TClonesArray fTracks;
+  Float_t fSCscale;              // scaling parameter for space charge correction
+  Float_t fSCscaleChi2;          // chi2 of scaling parameter for space charge correction
+  
+  TClonesArray fTracks;          // array of tracks
 
-  ClassDef(AliToyMCEvent, 1);
+  ClassDef(AliToyMCEvent, 2);    // MC event class
 
 };
 
index a8fef3415db1934e853fc50c71b4ae33eb9b9982..344a39aa4f26dba9fb3e63c78f06fb0efc722c04 100644 (file)
@@ -1,4 +1,5 @@
 #include <iostream>
+#include <fstream>
 
 #include <TDatabasePDG.h>
 #include <TRandom.h>
@@ -7,6 +8,9 @@
 #include <TSpline.h>
 #include <TObjString.h>
 #include <TROOT.h>
+#include <TSystem.h>
+#include <TObjArray.h>
+#include <TLinearFitter.h>
 
 #include <AliLog.h>
 #include <AliTPCROC.h>
@@ -35,6 +39,9 @@ AliToyMCEventGenerator::AliToyMCEventGenerator()
   ,fEvent(0x0)
   ,fCurrentTrack(0)
   ,fTPCCorrection(0x0)
+  ,fTPCCorrectionAv(0x0)
+  ,fSCList(0x0)
+  ,fSCListFile()
   ,fCorrectionFile("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.lookup.root")
   ,fOutputFileName("toyMC.root")
   ,fOutFile(0x0)
@@ -42,6 +49,8 @@ AliToyMCEventGenerator::AliToyMCEventGenerator()
   ,fUseStepCorrection(kFALSE)
   ,fUseMaterialBudget(kFALSE)
   ,fIsLaser(kTRUE)
+  ,fPrereadSCList(kFALSE)
+  ,fCalculateScaling(kTRUE)
 {
   fTPCParam = AliTPCcalibDB::Instance()->GetParameters();
   fTPCParam->ReadGeoMatrices();
@@ -54,6 +63,9 @@ AliToyMCEventGenerator::AliToyMCEventGenerator(const AliToyMCEventGenerator &gen
   ,fEvent(0x0)
   ,fCurrentTrack(0)
   ,fTPCCorrection(gen.fTPCCorrection)
+  ,fTPCCorrectionAv(0x0)
+  ,fSCList(gen.fSCList)
+  ,fSCListFile(gen.fSCListFile)
   ,fCorrectionFile(gen.fCorrectionFile)
   ,fOutputFileName(gen.fOutputFileName)
   ,fOutFile(0x0)
@@ -61,6 +73,8 @@ AliToyMCEventGenerator::AliToyMCEventGenerator(const AliToyMCEventGenerator &gen
   ,fUseStepCorrection(gen.fUseStepCorrection)
   ,fUseMaterialBudget(gen.fUseMaterialBudget)
   ,fIsLaser(gen.fIsLaser)
+  ,fPrereadSCList(gen.fPrereadSCList)
+  ,fCalculateScaling(gen.fCalculateScaling)
 {
   //
   gRandom->SetSeed();
@@ -68,7 +82,8 @@ AliToyMCEventGenerator::AliToyMCEventGenerator(const AliToyMCEventGenerator &gen
 //________________________________________________________________
 AliToyMCEventGenerator::~AliToyMCEventGenerator() 
 {
-  delete fTPCCorrection;
+  if (HasSCList() &&!fPrereadSCList) delete fTPCCorrection;
+  delete fSCList;
 }
 
 //________________________________________________________________
@@ -554,6 +569,9 @@ void AliToyMCEventGenerator::SetSpaceCharge(EEpsilon epsilon, EGasType gasType/*
     case kNeCO2_9010:
       fCorrectionFile.Append("_NeCO2");
       break;
+    case kNeCO2N2_90105:
+      fCorrectionFile.Append("_NeCO2N2");
+      break;
   }
   switch (epsilon) {
     case kEps5:
@@ -565,6 +583,18 @@ void AliToyMCEventGenerator::SetSpaceCharge(EEpsilon epsilon, EGasType gasType/*
     case kEps20:
       fCorrectionFile.Append("_eps20");
       break;
+    case kEps25:
+      fCorrectionFile.Append("_eps25");
+      break;
+    case kEps30:
+      fCorrectionFile.Append("_eps30");
+      break;
+    case kEps35:
+      fCorrectionFile.Append("_eps35");
+      break;
+    case kEps40:
+      fCorrectionFile.Append("_eps40");
+      break;
   }
   switch (collRate) {
     case k50kHz:
@@ -589,25 +619,200 @@ void AliToyMCEventGenerator::InitSpaceCharge()
   // this should be called after the tree was connected
   //
 
+  if (HasSCList()) {
+    InitSpaceChargeList();
+    return;
+  }
+  
   AliInfo(Form("Using space charge map file: '%s'",fCorrectionFile.Data()));
 
-  TString corrName("map");
+  SetCorrectionFromFile(fCorrectionFile, fTPCCorrection);
+
+  if (fOutTree){
+    AliInfo("Attaching space charge map file name to the tree");
+    fOutTree->GetUserInfo()->Add(new TObjString(fCorrectionFile.Data()));
+  }
+}
+
+//________________________________________________________________
+void AliToyMCEventGenerator::InitSpaceChargeList()
+{
+  //
+  // init space charge conditions from a list of files
+  // this should be called after the tree was connected
+  //
+
+  std::ifstream file(fSCListFile.Data());
+  TString list;
+  list.ReadFile(file);
+  
+  TObjArray *arr=list.Tokenize("\n");
+  if (!arr->GetEntriesFast()) {
+    delete arr;
+    AliFatal(Form("No SC file initialised. SC list '%s' seems empty",fSCListFile.Data()));
+    return;
+  }
+
+  // it is assumed that in case of an input list
+  // fCorrectionFile contains the name of the average correction
+  // to be then used in the reconstruction
+  if (fOutTree){
+    if (fCorrectionFile.IsNull()) {
+      AliFatal("List of SC files set, but no average map is specified. Use 'SetSpaceChargeFile' to do so");
+      return;
+    }
+    AliInfo("Attaching average space charge map file name to the tree");
+    fOutTree->GetUserInfo()->Add(new TObjString(fCorrectionFile.Data()));
+  }
+  
+  // check for an average map
+  if (!fCorrectionFile.IsNull()) {
+    SetCorrectionFromFile(fCorrectionFile, fTPCCorrectionAv);
+  }
+  
+  // case of non preread
+  // store the names of the files
+  if (!fPrereadSCList) {
+    if (fSCList) delete fSCList;
+    fSCList=arr;
+    return;
+  }
+
+  // case of preread
+  // load all SC files and set them to the list
+  if (!fSCList) fSCList=new TObjArray;
+  fSCList->SetOwner();
+  fSCList->Delete();
+  
+  for (Int_t ifile=0; ifile<arr->GetEntriesFast(); ++ifile) {
+    TString scname=arr->At(ifile)->GetName();
+    AliTPCCorrection *sc=0x0;
+    SetCorrectionFromFile(scname, sc);
+    if (!sc) continue;
+    fSCList->Add(sc);
+  }
+}
+
+//________________________________________________________________
+void AliToyMCEventGenerator::IterateSC(Int_t ipos)
+{
+  //
+  // In case a list of SC files is set iterate over them
+  //
+
+  if (!HasSCList()) return;
+
+  if (ipos<0) {
+    if (fOutTree) ipos=fOutTree->GetEntries();
+    else ipos=0;
+  }
 
+  TObject *sc=fSCList->At(ipos%fSCList->GetEntriesFast());
+  AliInfo(Form("Event: %d - SC: %s",ipos,sc->GetName()));
+  // case SC files have been preread
+  if (fPrereadSCList) {
+    fTPCCorrection=(AliTPCCorrection*)sc;
+    return;
+  }
+
+  // case no preread was done
+  TString &file=((TObjString*)sc)->String();
+  delete fTPCCorrection;
+  fTPCCorrection=0x0;
+
+  SetCorrectionFromFile(file, fTPCCorrection);
+  
+  if (!fTPCCorrection) {
+    AliFatal(Form("Could not read SC map from SC file '%s'",file.Data()));
+    return;
+  }
+
+}
+
+//________________________________________________________________
+Float_t AliToyMCEventGenerator::GetSCScalingFactor(AliTPCCorrection *corr, AliTPCCorrection *averageCorr, Float_t &chi2)
+{
+  //
+  // calculate the scaling factor
+  // between the fluctuation map and the average map
+  //
+
+  TLinearFitter fitter(2,"pol1");
+  
+  for (Float_t iz=-245; iz<=245; iz+=10) {
+    Short_t roc=(iz>=0)?0:18;
+    for (Float_t ir=86; ir<250; ir+=10) {
+      for (Float_t iphi=0; iphi<TMath::TwoPi(); iphi+=10*TMath::DegToRad()){
+        Float_t x=ir*(Float_t)TMath::Cos(iphi);
+        Float_t y=ir*(Float_t)TMath::Sin(iphi);
+        Float_t x3[3]    = {x,y,iz};
+        Float_t dx3[3]   = {0.,0.,0.};
+        Float_t dx3av[3] = {0.,0.,0.};
+        
+        corr->GetDistortion(x3,roc,dx3);
+        averageCorr->GetDistortion(x3,roc,dx3av);
+
+        Double_t dr   = TMath::Sqrt(dx3[0]*dx3[0]     +  dx3[1]*dx3[1]);
+        Double_t drav = TMath::Sqrt(dx3av[0]*dx3av[0] +  dx3av[1]*dx3av[1]);
+
+        fitter.AddPoint(&drav,dr);
+      }
+    }
+  }
+  
+  fitter.Eval();
+  chi2 = fitter.GetChisquare()/fitter.GetNpoints();
+  return fitter.GetParameter(1);
+}
+
+//________________________________________________________________
+void AliToyMCEventGenerator::SetSCScalingFactor()
+{
+  //
+  // if running with a SC list calculate the scaling factor
+  // between the fluctuation map and the average map
+  //
+
+  if ( !(fCalculateScaling && HasSCList() && fTPCCorrection && fTPCCorrectionAv && fEvent) ) return;
+
+  // loop over several z, r and phi bins and find a factor that minimises
+  // the distortions between the current map and the average map
+
+  Float_t chi2   = 0.;
+  Float_t factor = GetSCScalingFactor(fTPCCorrection, fTPCCorrectionAv, chi2);
+
+  fEvent->SetSCscale(factor);
+  fEvent->SetSCscaleChi2(chi2);
+}
+
+//________________________________________________________________
+void AliToyMCEventGenerator::SetCorrectionFromFile(TString file, AliTPCCorrection* &corr)
+{
+  //
+  // read the correction from file and set it to corr
+  //
+
+  corr=0x0;
+  TString corrName("map");
+  
   // allow for specifying an object name for the AliTPCCorrection in the file name
   // separated by a ':'
-  TObjArray *arr=fCorrectionFile.Tokenize(":");
+  TObjArray *arr=file.Tokenize(":");
   if (arr->GetEntriesFast()>1) {
-    fCorrectionFile=arr->At(0)->GetName();
+    file=arr->At(0)->GetName();
     corrName=arr->At(1)->GetName();
   }
   delete arr;
   
   
-  TFile f(fCorrectionFile.Data());
-  fTPCCorrection=(AliTPCSpaceCharge3D*)f.Get("map");
-
-  if (fOutTree){
-    AliInfo("Attaching space charge map file name to the tree");
-    fOutTree->GetUserInfo()->Add(new TObjString(fCorrectionFile.Data()));
+  TFile f(file.Data());
+  if (!f.IsOpen()||f.IsZombie()) {
+    printf("E-AliToyMCEventGenerator::Could not open SC file '%s'",file.Data());
+    return;
   }
+  
+  corr=(AliTPCSpaceCharge3D*)f.Get(corrName.Data());
+  if (corr) corr->SetName(f.GetName());
 }
+
+
index 73becd496fbf5c890b6f46a74df0b0ef1ce9803d..828db48c70808083b2764ff0f6c39b8b69dc2eca 100644 (file)
@@ -5,10 +5,13 @@
 
 class TFile;
 class TTree;
+class TObjArray;
 
 class AliTPCParam;
 class AliTPCCorrection;
 class AliTrackPointArray;
+class AliTrackPoint;
+class AliTPCclusterMI;
 
 class AliToyMCTrack;
 class AliToyMCEvent;
@@ -16,13 +19,18 @@ class AliToyMCEvent;
 class AliToyMCEventGenerator : public TObject {
  public:
    enum EGasType {
-     kNeCO2_9010=0
-  };
+     kNeCO2_9010=0,
+     kNeCO2N2_90105
+   };
 
   enum EEpsilon {
     kEps5=0,
     kEps10,
-    kEps20
+    kEps20,
+    kEps25,
+    kEps30,
+    kEps35,
+    kEps40
   };
 
   enum ECollRate {
@@ -69,34 +77,55 @@ class AliToyMCEventGenerator : public TObject {
 
   void SetIsLaser(Bool_t use) { fIsLaser=use;    }
   Bool_t GetIsLaser() const   { return fIsLaser; }
+
+  void   SetSCListFile(const char* file) { fSCListFile=file;              }
+  const char* GetSCListFile() const      { return fSCListFile.Data();     }
+  void   SetPrereadSCList(Bool_t b)      { fPrereadSCList=b;              }
+  Bool_t GetPrereadSCList() const        { return fPrereadSCList;         }
+  Bool_t HasSCList() const               { return  !fSCListFile.IsNull(); }
+
+  void SetCalculateScaling(Bool_t  val) { fCalculateScaling = val; }
+  Bool_t  GetCalculateScaling() const { return fCalculateScaling; }
+
+  static Float_t GetSCScalingFactor(AliTPCCorrection *corr, AliTPCCorrection *averageCorr, Float_t &chi2);
+  static void SetCorrectionFromFile(TString file, AliTPCCorrection* &corr);
   
  protected:
-  AliTPCParam *fTPCParam;
-  AliToyMCEvent *fEvent;
+  AliTPCParam *fTPCParam;                //! TPC params
+  AliToyMCEvent *fEvent;                 //! Toy event
   
   Bool_t ConnectOutputFile();
   Bool_t CloseOutputFile();
   void FillTree();
-
+  void IterateSC(Int_t ipos=-1);
+  void SetSCScalingFactor();
+  
   UInt_t fCurrentTrack;                  // unique track id within the current event generation
 
   
  private:
   AliToyMCEventGenerator& operator= (const AliToyMCEventGenerator& );
    
-  AliTPCCorrection *fTPCCorrection;
-
-  TString fCorrectionFile;
-  TString fOutputFileName;
-  TFile   *fOutFile;
-  TTree   *fOutTree;
-
-  Bool_t fUseStepCorrection;
-  Bool_t fUseMaterialBudget;
-  Bool_t fIsLaser;
+  AliTPCCorrection *fTPCCorrection;      //! distortion correction
+  AliTPCCorrection *fTPCCorrectionAv;    //! average distortion correction
+  
+  TObjArray   *fSCList;                  //! list with
+  TString fSCListFile;                   // file with a list of space charge files
+  TString fCorrectionFile;               // name of a sinfle SC file
+  TString fOutputFileName;               // name of the output file
+  TFile   *fOutFile;                     //! output file
+  TTree   *fOutTree;                     //! output tree
+
+  Bool_t fUseStepCorrection;             // use integralDz method?
+  Bool_t fUseMaterialBudget;             // use material budget in tracking?
+  Bool_t fIsLaser;                       // is a laser event?
+  Bool_t fPrereadSCList;                 // preread all SC files from the SC list
+  Bool_t fCalculateScaling;              // calculate scaling factor
+
+  void InitSpaceChargeList();
+  
+  ClassDef(AliToyMCEventGenerator, 2)
   
-  ClassDef(AliToyMCEventGenerator, 1)
-     
 };
 
 #endif
index 7247c74401ee4748c12a9a3a14a9c8b8b00f226c..8123181b39dffb431461a902d0783c3a823ba097 100644 (file)
@@ -1,5 +1,6 @@
 #include <iostream>
 
+#include <TROOT.h>
 #include <TDatabasePDG.h>
 #include <TRandom.h>
 #include <TF1.h>
@@ -80,11 +81,14 @@ AliToyMCEventGeneratorSimple& AliToyMCEventGeneratorSimple::operator = (const Al
 void AliToyMCEventGeneratorSimple::SetParametersToyGen(const Char_t* parfilename/*="files/params.root*/, Double_t vertexMean/*=0*/, Double_t vertexSigma/*=7.*/) {
   fVertexMean = vertexMean;
   fVertexSigma = vertexSigma;
-  fParamFile = new TFile(parfilename, "read");
-  fHPt = (TH1F*) fParamFile->Get("hPt");
-  fHEta = (TH1F*) fParamFile->Get("hEta"); 
-  fHMult = (TH1I*) fParamFile->Get("hMult") ;
+//   fParamFile = new TFile(parfilename, "read");
+  TFile f(parfilename);
+  gROOT->cd();
+  fHPt = (TH1F*) f.Get("hPt");
+  fHEta = (TH1F*) f.Get("hEta");
+  fHMult = (TH1I*) f.Get("hMult") ;
   fHistosSet = kTRUE;
+  f.Close();
  
   
 }
@@ -92,8 +96,11 @@ void AliToyMCEventGeneratorSimple::SetParametersToyGen(const Char_t* parfilename
 AliToyMCEvent* AliToyMCEventGeneratorSimple::Generate(Double_t time)
 {
   //
+  // Generate an event at 'time'
   //
-  //
+
+  // iterate over space charge maps in case they are set
+  IterateSC();
   
   AliToyMCEvent *retEvent = new AliToyMCEvent();
   retEvent->SetT0(time);
@@ -183,6 +190,7 @@ void AliToyMCEventGeneratorSimple::RunSimulation(const Int_t nevents/*=10*/, con
   for (Int_t ievent=0; ievent<nevents; ++ievent){
     printf("Generating event %3d (%.3g)\n",ievent,eventTime);
     fEvent = Generate(eventTime);
+    SetSCScalingFactor();
     FillTree();
     delete fEvent;
     fEvent=0x0;
@@ -371,6 +379,7 @@ void AliToyMCEventGeneratorSimple::RunSimulationBunchTrain(const Int_t nevents/*
     if(equalSpacing)  {
       printf("Generating event %3d (%.3g)\n",nGeneratedEvents,eventTime);
       fEvent = Generate(eventTime);
+      SetSCScalingFactor();
       nGeneratedEvents++;
       FillTree();
       delete fEvent;
@@ -382,6 +391,7 @@ void AliToyMCEventGeneratorSimple::RunSimulationBunchTrain(const Int_t nevents/*
       for(Int_t iColl = 0; iColl<nCollsInCrossing; iColl++){
        printf("Generating event %3d (%.3g)\n",nGeneratedEvents,eventTime);
        fEvent = Generate(eventTime);
+        SetSCScalingFactor();
        nGeneratedEvents++;
        FillTree();
        delete fEvent;
@@ -442,8 +452,8 @@ Int_t AliToyMCEventGeneratorSimple::OpenInputAndGetMaxEvents(const Int_t type, c
 
     fInputIndex = 0;
 
-    return fESDTree->GetEntries();
     gRandom->SetSeed();
+    return fESDTree->GetEntries();
    }
 
  
@@ -509,6 +519,9 @@ AliToyMCEvent* AliToyMCEventGeneratorSimple::GenerateESD2(Double_t time) {
 
   //test that enough tracks will pass cuts (and that there is tracks at all)
   Bool_t testEvent = kTRUE;
+
+  // iterate over space charge maps in case they are set
+  IterateSC();
   while(fESDTree->GetEvent(fInputIndex) && testEvent) {  
     
     Int_t nPassedCuts = 0;
@@ -569,6 +582,9 @@ AliToyMCEvent* AliToyMCEventGeneratorSimple::GenerateLaser(Double_t time)
   //
   // Generate an Event with laser tracks
   //
+
+  // iterate over space charge maps in case they are set
+  IterateSC();
   
   AliToyMCEvent *retEvent = new AliToyMCEvent();
   retEvent->SetEventType(AliToyMCEvent::kLaser);
index ecec86fc4c48e7b13ea4e6743954c65262fa7a34..41fe303f72df39e400f6543fe4267c4625caafcf 100644 (file)
@@ -5,6 +5,7 @@
 #include <TROOT.h>
 #include <TFile.h>
 #include <TPRegexp.h>
+#include <TVectorF.h>
 
 #include <AliExternalTrackParam.h>
 #include <AliTPCcalibDB.h>
@@ -47,6 +48,11 @@ AliToyMCReconstruction::AliToyMCReconstruction() : TObject()
 , fTime0(-1)
 , fCreateT0seed(kFALSE)
 , fLongT0seed(kTRUE)
+, fFillClusterRes(kFALSE)
+, fUseT0list(kFALSE)
+, fUseZ0list(kFALSE)
+, fForceAlpha(kFALSE)
+, fRecoInfo(-1)
 , fStreamer(0x0)
 , fInputFile(0x0)
 , fTree(0x0)
@@ -60,6 +66,7 @@ AliToyMCReconstruction::AliToyMCReconstruction() : TObject()
 , fAllClusters("AliTPCclusterMI",10000)
 , fMapTrackEvent(10000)
 , fMapTrackTrackInEvent(10000)
+, fHnDelta(0x0)
 , fIsAC(kFALSE)
 {
   //
@@ -89,6 +96,9 @@ void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
   ConnectInputFile(file, nmaxEv);
   if (!fTree) return;
 
+  Int_t maxev=fTree->GetEntries();
+  if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
+  
   InitStreamer(".debug");
   
   gROOT->cd();
@@ -116,10 +126,26 @@ void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
   AliExternalTrackParam trackITS2;
   
   AliExternalTrackParam *dummy;
-  
-  Int_t maxev=fTree->GetEntries();
-  if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
 
+  // prepare list of T0s
+  TVectorF t0list(maxev);
+  TVectorF z0list(maxev);
+  if (fUseT0list || fUseZ0list) {
+    for (Int_t iev=0; iev<maxev; ++iev){
+      fTree->GetEvent(iev);
+      const Float_t t0=fEvent->GetT0();
+      const Float_t z0=fEvent->GetZ();
+      t0list[iev]=t0;
+      z0list[iev]=z0;
+    }
+  }
+  
+  // array with cluster residuals
+  TClonesArray *arrClustRes=0x0;
+  if (fFillClusterRes){
+    arrClustRes=new TClonesArray("AliTPCclusterMI",160);
+  }
+  
   const Double_t lastLayerITS = 43.0; // same as in AliToyMCEventGenerator::MakeITSClusters (hard coded)
   const Double_t iFCRadius =  83.5; //radius constants found in AliTPCCorrection.cxx
   const Double_t betweeTPCITS = (lastLayerITS+iFCRadius)/2.; // its track propgated to inner TPC wall
@@ -127,36 +153,68 @@ void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
   const Double_t kMaxSnp = 0.85;
   const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
   
+  Double_t lastT0=0;
+
+  // residuals
+  // binning r, phi, z, delta
+  const Int_t nbins=4;
+  Int_t bins[nbins]    = {16, 18*5, 50, 80};
+  Double_t xmin[nbins] = {86. , 0.,           -250., -2.};
+  Double_t xmax[nbins] = {250., 2*TMath::Pi(), 250.,  2.};
+  fHnDelta = new THnF("hn", "hn", nbins, bins, xmin, xmax);
+
+  // fill streamer?
+  Bool_t fillStreamer=(fStreamer!=0x0);
+  if (fRecoInfo>-1 && ((fRecoInfo&kFillNoTrackInfo)==kFillNoTrackInfo)) fillStreamer=kFALSE;
   
   for (Int_t iev=0; iev<maxev; ++iev){
     printf("==============  Processing Event %6d =================\n",iev);
     fTree->GetEvent(iev);
+    
+    Float_t z0=fEvent->GetZ();
+    Float_t t0=fEvent->GetT0();
+
+    // set SC scaling factor
+    fTPCCorrection->SetCorrScaleFactor(fEvent->GetSCscale());
+    
     for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
 //       printf(" > ======  Processing Track %6d ========  \n",itr);
       const AliToyMCTrack *tr=fEvent->GetTrack(itr);
       tOrig = *tr;
-      // ideal track propagated to ITS reference points
-      tOrigITS  = *tr;
-      tOrigITS1 = *tr;
-      tOrigITS2 = *tr;
+
       // propagate original track to ITS comparison points
-      AliTrackerBase::PropagateTrackTo(&tOrigITS, lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
-      AliTrackerBase::PropagateTrackTo(&tOrigITS1,betweeTPCITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
-      AliTrackerBase::PropagateTrackTo(&tOrigITS2,iFCRadius,   kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+      if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS  ) {
+        tOrigITS  = *tr;
+        AliTrackerBase::PropagateTrackTo(&tOrigITS, lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+        tRealITS  = resetParam;
+      }
+      if (fRecoInfo<0 || (fRecoInfo&kFillITS1)==kFillITS1 ) {
+        tOrigITS1 = *tr;
+        AliTrackerBase::PropagateTrackTo(&tOrigITS1,betweeTPCITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+        tRealITS1 = resetParam;
+      }
+      if (fRecoInfo<0 || (fRecoInfo&kFillITS2)==kFillITS2 ) {
+        tOrigITS2 = *tr;
+        AliTrackerBase::PropagateTrackTo(&tOrigITS2,iFCRadius,   kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+        tRealITS2 = resetParam;
+      }
 
       // realistic ITS track propagated to reference points
-      tRealITS  = resetParam;
-      tRealITS1 = resetParam;
-      tRealITS2 = resetParam;
       dummy = GetTrackRefit(tr,kITS);
       if (dummy){
-        tRealITS = *dummy;
-        tRealITS1 = *dummy;
-        tRealITS2 = *dummy;
         // propagate realistic track to ITS comparison points
-        AliTrackerBase::PropagateTrackTo(&tRealITS, lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
-        AliTrackerBase::PropagateTrackTo(&tRealITS1,betweeTPCITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
-        AliTrackerBase::PropagateTrackTo(&tRealITS2,iFCRadius,   kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+        if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS  ) {
+          tRealITS = *dummy;
+          AliTrackerBase::PropagateTrackTo(&tRealITS, lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+        }
+        if (fRecoInfo<0 || (fRecoInfo&kFillITS1)==kFillITS1 ) {
+          tRealITS1 = *dummy;
+          AliTrackerBase::PropagateTrackTo(&tRealITS1,betweeTPCITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+        }
+        if (fRecoInfo<0 || (fRecoInfo&kFillITS2)==kFillITS2 ) {
+          tRealITS2 = *dummy;
+          AliTrackerBase::PropagateTrackTo(&tRealITS2,iFCRadius,   kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+        }
         //
         delete dummy;
         dummy=0x0;
@@ -168,13 +226,11 @@ void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
       t0seed    = resetParam;
       seed      = resetParam;
       track     = resetParam;
-      trackITS  = resetParam;
-      trackITS1 = resetParam;
-      trackITS2 = resetParam;
       
-      Float_t z0=fEvent->GetZ();
-      Float_t t0=fEvent->GetT0();
-
+      if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS  ) trackITS  = resetParam;
+      if (fRecoInfo<0 || (fRecoInfo&kFillITS1)==kFillITS1 ) trackITS1 = resetParam;
+      if (fRecoInfo<0 || (fRecoInfo&kFillITS2)==kFillITS2 ) trackITS2 = resetParam;
+      
       Float_t vDrift=GetVDrift();
       Float_t zLength=GetZLength(0);
 
@@ -194,30 +250,32 @@ void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
           t0seed = *dummy;
           delete dummy;
         }
-        
-        // crate real seed using the time 0 from the first seed
-        // set fCreateT0seed now to false to get the seed in z coordinates
+
+        // set the T0 from the seed
+        // in case the match with the real T0 infor is requested, find the
+        //    closes T0 from the list of T0s
         fTime0 = t0seed.GetZ()-zLength/vDrift;
+        if (fUseT0list || fUseZ0list) {
+          fTime0 = FindClosestT0(t0list, z0list, t0seed);
+        }
+        // create real seed using the time 0 from the first seed
+        // set fCreateT0seed now to false to get the seed in z coordinates
         fCreateT0seed = kFALSE;
 //         printf("seed (%.2g)\n",fTime0);
         dummy  = GetSeedFromTrack(tr);
         if (dummy) {
           seed = *dummy;
           delete dummy;
+          dummy=0x0;
 
           // create fitted track
           if (fDoTrackFit){
 //             printf("track\n");
-            dummy = GetFittedTrackFromSeed(tr, &seed);
+            dummy = GetFittedTrackFromSeed(tr, &seed, arrClustRes);
             track = *dummy;
+            dummy=0x0;
             delete dummy;
           }
-
-          // Copy original track and fitted track
-          // for extrapolation to ITS last layer
-          trackITS  = track;
-          trackITS1 = track;
-          trackITS2 = track;
           
           // propagate seed to 0
           AliTrackerBase::PropagateTrackTo(&seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
@@ -227,29 +285,39 @@ void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
           //
           
           // rotate fitted track to the frame of the original track and propagate to same reference
-          AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
-          trackITS.Rotate(tOrigITS.GetAlpha());
-          AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
+          if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS  ){
+            trackITS  = track;
+            AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+            trackITS.Rotate(tOrigITS.GetAlpha());
+            AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
+          }
 
           // rotate fitted track to the frame of the original track and propagate to same reference
-          AliTrackerBase::PropagateTrackTo(&trackITS1,betweeTPCITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
-          trackITS1.Rotate(tOrigITS1.GetAlpha());
-          AliTrackerBase::PropagateTrackTo(&trackITS1,betweeTPCITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
+          if (fRecoInfo<0 || (fRecoInfo&kFillITS1)==kFillITS1 ){
+            trackITS1 = track;
+            AliTrackerBase::PropagateTrackTo(&trackITS1,betweeTPCITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+            trackITS1.Rotate(tOrigITS1.GetAlpha());
+            AliTrackerBase::PropagateTrackTo(&trackITS1,betweeTPCITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
+          }
 
           // rotate fitted track to the frame of the original track and propagate to same reference
-          AliTrackerBase::PropagateTrackTo(&trackITS2,iFCRadius,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
-          trackITS2.Rotate(tOrigITS2.GetAlpha());
-          AliTrackerBase::PropagateTrackTo(&trackITS2,iFCRadius,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
+          if (fRecoInfo<0 || (fRecoInfo&kFillITS2)==kFillITS2 ){
+            trackITS2 = track;
+            AliTrackerBase::PropagateTrackTo(&trackITS2,iFCRadius,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
+            trackITS2.Rotate(tOrigITS2.GetAlpha());
+            AliTrackerBase::PropagateTrackTo(&trackITS2,iFCRadius,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
+          }
         }
       }
 
       Int_t ctype(fCorrectionType);
-      
-      if (fStreamer) {
+
+      if (fillStreamer){
         (*fStreamer) << "Tracks" <<
         "iev="         << iev             <<
         "z0="          << z0              <<
         "t0="          << t0              <<
+        "lastt0="      << lastT0          <<
         "fTime0="      << fTime0          <<
         "itr="         << itr             <<
         "clsType="     << fClusterType    <<
@@ -262,26 +330,79 @@ void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
         "seed.="       << &seed           <<
         
         "tOrig.="      << &tOrig          <<
-        "track.="      << &track          <<
+        "track.="      << &track;
+
+        
         // ITS match
-        "tOrigITS.="   << &tOrigITS       <<
-        "tOrigITS1.="  << &tOrigITS1      <<
-        "tOrigITS2.="  << &tOrigITS2      <<
+        if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS  ){
+          (*fStreamer) << "Tracks" <<
+          "tOrigITS.="   << &tOrigITS       <<
+          "tRealITS.="   << &tRealITS       <<
+          "trackITS.="   << &trackITS;
+        }
         
-        "tRealITS.="   << &tRealITS       <<
-        "tRealITS1.="  << &tRealITS1      <<
-        "tRealITS2.="  << &tRealITS2      <<
+        if (fRecoInfo<0 || (fRecoInfo&kFillITS1) ==kFillITS1  ){
+          (*fStreamer) << "Tracks" <<
+          "tOrigITS1.="  << &tOrigITS1      <<
+          "tRealITS1.="  << &tRealITS1      <<
+          "trackITS1.="  << &trackITS1;
+        }
+
+        if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS  ){
+          (*fStreamer) << "Tracks" <<
+          "tOrigITS2.="  << &tOrigITS2      <<
+          "tRealITS2.="  << &tRealITS2      <<
+          "trackITS2.="  << &trackITS2;
+        }
+
+        if (arrClustRes) {
+          const Int_t nCl=arrClustRes->GetEntriesFast();
+          // fracktion of outliers from track extrapolation
+          // for 3, 3.5, 4, 4.5 and 5 sigma of the cluster resolution (~1mm)
+          Float_t fracY[5]={0.};
+          Float_t fracZ[5]={0.};
+          
+          for (Int_t icl=0; icl<nCl; ++icl) {
+            AliTPCclusterMI *cl=static_cast<AliTPCclusterMI*>(arrClustRes->At(icl));
+//             const Float_t sigmaY=TMath::Sqrt(cl->GetSigmaY2());
+//             const Float_t sigmaZ=TMath::Sqrt(cl->GetSigmaZ2());
+            for (Int_t inSig=0; inSig<5; ++inSig) {
+              fracY[inSig] += cl->GetY()>(3+inSig*.5)/**sigmaY*/;
+              fracZ[inSig] += cl->GetZ()>(3+inSig*.5)/**sigmaZ*/;
+            }
+          }
+          
+          if (nCl>0) {
+            for (Int_t inSig=0; inSig<5; ++inSig) {
+              fracY[inSig]/=nCl;
+              fracZ[inSig]/=nCl;
+            }
+          }
+          
+          (*fStreamer) << "Tracks" <<
+          "clustRes.=" << arrClustRes;
+          for (Int_t inSig=0; inSig<5; ++inSig) {
+            const char* fracYname=Form("clFracY%02d=", 30+inSig*5);
+            const char* fracZname=Form("clFracZ%02d=", 30+inSig*5);
+            (*fStreamer) << "Tracks" <<
+            fracYname << fracY[inSig] <<
+            fracZname << fracZ[inSig];
+          }
+        }
         
-        "trackITS.="   << &trackITS       <<
-        "trackITS1.="  << &trackITS1      <<
-        "trackITS2.="  << &trackITS2      <<
+        (*fStreamer) << "Tracks" <<
         "\n";
       }
       
       
     }
+    lastT0=t0;
   }
 
+  fStreamer->GetFile()->cd();
+  fHnDelta->Write();
+  
+  delete arrClustRes;
   Cleanup();
 }
 
@@ -1010,9 +1131,13 @@ AliExternalTrackParam* AliToyMCReconstruction::GetSeedFromTrack(const AliToyMCTr
   if (fCreateT0seed&&!fLongT0seed){
     // only propagate to vertex if we don't create a long seed
     // if fTime0 < 0 we assume that we create a seed for the T0 estimate
-    AliTrackerBase::PropagateTrackTo(seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
+    Int_t ret=AliTrackerBase::PropagateTrackTo2(seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
     if (TMath::Abs(seed->GetX())>3) {
-//       printf("Could not propagate track to 0, %.2f, %.2f, %.2f\n",seed->GetX(),seed->GetAlpha(),seed->Pt());
+//       printf("Could not propagate track to 0, x:%.2f, a:%.2f (%.2f), snp:%.2f (%.2f), pt:%.2f (%.2f), %d\n",seed->GetX(),seed->GetAlpha(),tr->GetAlpha(), seed->GetSnp(), tr->GetSnp(), seed->Pt(), tr->Pt(), ret);
+    }
+    if (fForceAlpha) {
+      seed->Rotate(tr->GetAlpha());
+      AliTrackerBase::PropagateTrackTo2(seed,0,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,kFALSE);
     }
   }
 
@@ -1164,14 +1289,20 @@ void AliToyMCReconstruction::ClusterToSpacePoint(const AliTPCclusterMI *cl, Floa
 }
 
 //____________________________________________________________________________________
-AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliToyMCTrack *tr, const AliExternalTrackParam *seed)
+AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, TClonesArray *arrClustRes)
 {
   //
   //
   //
 
+  if (arrClustRes) {
+    arrClustRes->Clear();
+  }
+  
   // create track
   AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
+  // track copy for propagation
+  AliExternalTrackParam trCopy(*tr);
 
   Int_t ncls=(fClusterType == 0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
 
@@ -1189,6 +1320,9 @@ AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliT
   const Double_t refX = tr->GetX();
   
   const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
+
+  // parametrised track resolution
+  Double_t trackRes=gRandom->Gaus();
   
   // loop over all other points and add to the track
   for (Int_t ipoint=ncls-1; ipoint>=0; --ipoint){
@@ -1245,6 +1379,70 @@ AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliT
     if (TMath::Abs(track->GetX())>kMaxR) break;
 //     if (TMath::Abs(track->GetZ())<kZcut)continue;
     //
+
+    // add residuals
+    if (arrClustRes) {
+      TClonesArray &arrDummy=*arrClustRes;
+      AliTPCclusterMI *clRes = new(arrDummy[arrDummy.GetEntriesFast()]) AliTPCclusterMI(*cl);
+      clRes->SetX(prot.GetX());
+      // residuals in terms of sigma cl and track
+      clRes->SetY((track->GetY()-prot.GetY())/( sqrt ( prot.GetCov()[3] + track->GetSigmaY2()) )  );
+      clRes->SetZ((track->GetZ()-prot.GetZ())/( sqrt ( prot.GetCov()[5] + track->GetSigmaZ2()) )  );
+    }
+
+    // fill cluster residuals to ideal track for calibration studies
+    // ideal cluster position
+    // require at least 2 TRD points
+    if (fRecoInfo<0 || (fRecoInfo&kFillDeltas) ==kFillDeltas  ) {
+      trCopy.Rotate(track->GetAlpha());
+      AliTrackerBase::PropagateTrackTo(&trCopy,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
+      // binning r, phi, z, delta (0=rphi, 1=z)
+      // resolution parametrisation
+      Float_t soneOverPt= trCopy.GetSigned1Pt();
+      Float_t oneOverPt = TMath::Abs(soneOverPt);
+      Float_t radius    = trCopy.GetX();
+      Float_t trackY    = trCopy.GetY();
+      Float_t trackZ    = trCopy.GetZ();
+      Float_t trackPhi  = trCopy.Phi();
+      Float_t alpha     = trCopy.GetAlpha();
+
+      Float_t pointY    = prot.GetY();
+      Float_t pointZ    = prot.GetZ();
+
+      Float_t resRphi   = 0.004390 + oneOverPt*(-0.136403) + oneOverPt*radius*(0.002266) + oneOverPt*radius*radius*(-0.000006);
+
+      Float_t resRphiRandom = resRphi*trackRes;
+      Float_t deviation     = trackY+resRphiRandom-pointY;
+      Short_t    npTRD         = tr->GetNumberOfTRDPoints();
+
+      // rphi residuals
+      Double_t xx[4]={radius, trackPhi, trackZ ,deviation};
+      if (npTRD>=2){
+        fHnDelta->Fill(xx);
+      }
+
+      Short_t event=fTree->GetReadEntry();
+
+      if (fStreamer) {
+        (*fStreamer) << "delta" <<
+        "soneOverPt=" << soneOverPt <<
+        "r="          << radius    <<
+        "trackPhi="   << trackPhi  <<
+        "trackY="     << trackY    <<
+        "trackZ="     << trackZ    <<
+        "alpha="      << alpha     <<
+        "resRphi="    << resRphi   <<
+        "trackRes="   << trackRes  <<
+        "pointY="     << pointY    <<
+        "pointZ="     << pointZ    <<
+        "npTRD="      << npTRD     <<
+        "event="      << event     <<
+        "\n";
+//           "point.="    << &prot     <<
+//           "track.="    << track     <<
+      }
+    }
+    
     Double_t pointPos[2]={0,0};
     Double_t pointCov[3]={0,0,0};
     pointPos[0]=prot.GetY();//local y
@@ -1258,7 +1456,7 @@ AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliT
 
   AliTrackerBase::PropagateTrackTo2(track,refX,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
 
-  if (!fCreateT0seed){
+  if (!fCreateT0seed || fForceAlpha){
     // rotate fittet track to the frame of the original track and propagate to same reference
     track->Rotate(tr->GetAlpha());
   
@@ -1268,7 +1466,6 @@ AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliT
   return track;
 }
 
-
 //____________________________________________________________________________________
 AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeedAllClusters(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, Int_t &nClus)
 {
@@ -1679,19 +1876,28 @@ void AliToyMCReconstruction::InitSpaceCharge()
   // Init the space charge map
   //
 
-  TString filename="$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root";
+//   TString filename="$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root";
+  TString filename;
   if (fTree) {
     TList *l=fTree->GetUserInfo();
     for (Int_t i=0; i<l->GetEntries(); ++i) {
-      TString s(l->At(i)->GetName());
-      if (s.Contains("SC_")) {
-        filename=s;
-        break;
+      TObject *o=l->At(i);
+      if (o->IsA() == TObjString::Class()){
+        TString s(o->GetName());
+        if (s.Contains("lookup.root")) {
+          filename=s;
+          break;
+        }
       }
     }
   }
 
-  printf("Initialising the space charge map using the file: '%s'\n",filename.Data());
+  if (filename.IsNull()) {
+    AliFatal("No SC map provided in the Userinfo of the simulation tree");
+    return;
+  }
+  
+  AliInfo(Form("Initialising the space charge map using the file: '%s'\n",filename.Data()));
   TFile f(filename.Data());
   fTPCCorrection=(AliTPCCorrection*)f.Get("map");
   
@@ -2476,7 +2682,9 @@ void AliToyMCReconstruction::Cleanup()
   
   delete fEvent;
   fEvent = 0x0;
-  
+
+  delete fHnDelta;
+  fHnDelta=0x0;
 //   delete fTree;
   fTree=0x0;
   
@@ -2922,3 +3130,35 @@ void AliToyMCReconstruction::CopyRieman(const AliRieman &from, AliRieman &to)
   for (Int_t i=0;i<from.GetN();++i) to.AddPoint(from.GetX()[i],from.GetY()[i],from.GetZ()[i],from.GetSy()[i],from.GetSz()[i]);
 }
 
+//____________________________________________________________________________________
+Float_t AliToyMCReconstruction::FindClosestT0(const TVectorF &t0list, const TVectorF &z0list, AliExternalTrackParam &t0seed)
+{
+  //
+  // find closes T0 in a list of T0s
+  //
+
+  Long64_t size=t0list.GetNrows();
+  const Float_t *array=t0list.GetMatrixArray();
+
+  Float_t vDrift=GetVDrift();
+  Float_t zLength=GetZLength(0);
+
+  Float_t sign=(1-2*(t0seed.GetTgl()>0));
+
+  Float_t vtxCorr=0.;
+  Float_t t0=t0seed.GetZ()-zLength/vDrift;
+  
+  Int_t index=0;
+  Float_t minDist=1e20;
+  for (Int_t it0=0; it0<size; ++it0) {
+    if (fUseZ0list) vtxCorr=sign*z0list[it0]/vDrift;
+//     printf("vtxcorr %d: %.2g, %.2g\n",it0, vtxCorr, z0list[it0]);
+    const Float_t dist=TMath::Abs(t0list[it0]-t0-vtxCorr);
+    if (dist<minDist) {
+      index=it0;
+      minDist=dist;
+    }
+  }
+
+  return array[index];
+}
index 8f36fb8eb4fbfacdcc50938d867d69513eaa9d2e..0a1a653a0526d1744b7771d2e0fcee1616b08c4e 100644 (file)
@@ -5,6 +5,8 @@
 #include <TObject.h>
 #include <TClonesArray.h>
 #include <TExMap.h>
+#include <TVectorFfwd.h>
+#include <THn.h>
 
 class TTree;
 
@@ -39,6 +41,19 @@ public:
     kTPC,
     kTRD
   };
+
+  enum ERecoFill {
+    kFillSeed = 0x01,
+    kFillOrig = 0x02,
+    kFillTrack= 0x04,
+    
+    kFillITS  = 0x08,
+    kFillITS1 = 0x10,
+    kFillITS2 = 0x20,
+
+    kFillDeltas = 0x40,
+    kFillNoTrackInfo= 0x80
+  };
   
   void RunReco(const char* file, Int_t nmaxEv=-1);
   void RunRecoAllClusters(const char* file, Int_t nmaxEv=-1);
@@ -67,13 +82,28 @@ public:
 
   void   SetIdealTracking(Bool_t tr)    { fIdealTracking = tr;    }
   Bool_t GetIdealTracking()  const      { return fIdealTracking;  }
+
+  void   SetFillClusterRes(Bool_t res)  { fFillClusterRes=res;    }
+  Bool_t GetFillClusterRes()  const     { return fFillClusterRes; }
+
+  void   SetUseT0list(Bool_t use)       { fUseT0list=use;    }
+  Bool_t GetUseT0list()  const          { return fUseT0list; }
+  
+  void   SetUseZ0list(Bool_t use)       { fUseZ0list=use;    }
+  Bool_t GetUseZ0list()  const          { return fUseZ0list; }
+  
+  void   SetForceAlpha(Bool_t use)       { fForceAlpha=use;    }
+  Bool_t GetForceAlpha()  const          { return fForceAlpha; }
+
+  void SetRecoInfo(Long64_t val) { fRecoInfo = val; }
+  Long64_t GetRecoInfo() const { return fRecoInfo; }
   
   void   SetTree(TTree *tree) { fTree=tree; }
   TTree* GetTree() const { return fTree; }
 
   AliExternalTrackParam* GetSeedFromTrack(const AliToyMCTrack * const tr, Bool_t forceSeed=kFALSE);
   AliExternalTrackParam* GetSeedFromTrackIdeal(const AliToyMCTrack * const tr, EDet det );
-  AliExternalTrackParam* GetFittedTrackFromSeed(const AliToyMCTrack *tr, const AliExternalTrackParam *seed);
+  AliExternalTrackParam* GetFittedTrackFromSeed(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, TClonesArray *arrClustRes=0x0);
   AliExternalTrackParam* GetFittedTrackFromSeedAllClusters(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, Int_t &nClus);
   AliExternalTrackParam* GetTrackRefit(const AliToyMCTrack * const tr, EDet det);
 
@@ -140,6 +170,8 @@ public:
 
   void MarkClustersUsed(AliTPCseed *seed);
   void ResetClustersZtoTime(AliTPCseed *seed);
+
+  Float_t FindClosestT0(const TVectorF &t0list, const TVectorF &z0list, AliExternalTrackParam &t0seed);
   
   // reco settings
   Int_t  fSeedingRow;            // first row used for seeding
@@ -156,6 +188,11 @@ public:
   Double_t fTime0;               // current time0 used for reconstruction
   Bool_t   fCreateT0seed;        // if current seed is the T0 seed
   Bool_t   fLongT0seed;          // if we should use a t0 seed including all clusters in the seed range
+  Bool_t   fFillClusterRes;      // fill cluster residuals?
+  Bool_t   fUseT0list;           // if the list of T0 information should be used to guess the T0
+  Bool_t   fUseZ0list;           // if the list of Z vertex information should be used to guess the T0
+  Bool_t   fForceAlpha;          // force the correct alpha for the t0 seed extrapolation
+  Long64_t fRecoInfo;            // what information to fill in the output trees
   
   TTreeSRedirector *fStreamer;   // debug streamer
   TFile *fInputFile;             // input file
@@ -175,6 +212,8 @@ public:
   TExMap fMapTrackEvent;          // map global track number -> event number
   TExMap fMapTrackTrackInEvent;   // map global track number -> track in event
 
+  THn    *fHnDelta;               // histogram with residuals
+
   Bool_t fIsAC;                     // if we are tracking with sector arrays running from 0-36 rather than 0-18
    
   ClassDef(AliToyMCReconstruction,0)
diff --git a/TPC/Upgrade/data/GEMMCscan/out_235_235_301_374.root b/TPC/Upgrade/data/GEMMCscan/out_235_235_301_374.root
new file mode 100644 (file)
index 0000000..a38122d
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_235_235_301_374.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_235_235_326_343.root b/TPC/Upgrade/data/GEMMCscan/out_235_235_326_343.root
new file mode 100644 (file)
index 0000000..2d49f04
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_235_235_326_343.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_235_285_273_342.root b/TPC/Upgrade/data/GEMMCscan/out_235_285_273_342.root
new file mode 100644 (file)
index 0000000..30d87e3
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_235_285_273_342.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_235_285_298_314.root b/TPC/Upgrade/data/GEMMCscan/out_235_285_298_314.root
new file mode 100644 (file)
index 0000000..eaa4ba4
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_235_285_298_314.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_255_235_292_364.root b/TPC/Upgrade/data/GEMMCscan/out_255_235_292_364.root
new file mode 100644 (file)
index 0000000..95a8191
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_255_235_292_364.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_255_235_316_333.root b/TPC/Upgrade/data/GEMMCscan/out_255_235_316_333.root
new file mode 100644 (file)
index 0000000..92b3ae2
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_255_235_316_333.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_255_285_266_330.root b/TPC/Upgrade/data/GEMMCscan/out_255_285_266_330.root
new file mode 100644 (file)
index 0000000..6487e19
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_255_285_266_330.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_255_285_289_305.root b/TPC/Upgrade/data/GEMMCscan/out_255_285_289_305.root
new file mode 100644 (file)
index 0000000..9b430fb
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_255_285_289_305.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_275_235_284_354.root b/TPC/Upgrade/data/GEMMCscan/out_275_235_284_354.root
new file mode 100644 (file)
index 0000000..53395f8
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_275_235_284_354.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_275_235_308_323.root b/TPC/Upgrade/data/GEMMCscan/out_275_235_308_323.root
new file mode 100644 (file)
index 0000000..59f2d00
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_275_235_308_323.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_275_285_256_321.root b/TPC/Upgrade/data/GEMMCscan/out_275_285_256_321.root
new file mode 100644 (file)
index 0000000..6a8c1f9
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_275_285_256_321.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_275_285_281_295.root b/TPC/Upgrade/data/GEMMCscan/out_275_285_281_295.root
new file mode 100644 (file)
index 0000000..c35195b
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_275_285_281_295.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_295_235_275_344.root b/TPC/Upgrade/data/GEMMCscan/out_295_235_275_344.root
new file mode 100644 (file)
index 0000000..f817fe2
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_295_235_275_344.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_295_235_298_314.root b/TPC/Upgrade/data/GEMMCscan/out_295_235_298_314.root
new file mode 100644 (file)
index 0000000..6bd0e58
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_295_235_298_314.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_295_285_248_311.root b/TPC/Upgrade/data/GEMMCscan/out_295_285_248_311.root
new file mode 100644 (file)
index 0000000..92d8f47
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_295_285_248_311.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_295_285_272_285.root b/TPC/Upgrade/data/GEMMCscan/out_295_285_272_285.root
new file mode 100644 (file)
index 0000000..8198c08
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_295_285_272_285.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_315_235_267_334.root b/TPC/Upgrade/data/GEMMCscan/out_315_235_267_334.root
new file mode 100644 (file)
index 0000000..34b39c5
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_315_235_267_334.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_315_235_289_305.root b/TPC/Upgrade/data/GEMMCscan/out_315_235_289_305.root
new file mode 100644 (file)
index 0000000..49ce1f8
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_315_235_289_305.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_315_285_240_300.root b/TPC/Upgrade/data/GEMMCscan/out_315_285_240_300.root
new file mode 100644 (file)
index 0000000..e24b6b0
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_315_285_240_300.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/out_315_285_263_276.root b/TPC/Upgrade/data/GEMMCscan/out_315_285_263_276.root
new file mode 100644 (file)
index 0000000..57ac1bc
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/out_315_285_263_276.root differ
diff --git a/TPC/Upgrade/data/GEMMCscan/readme b/TPC/Upgrade/data/GEMMCscan/readme
new file mode 100644 (file)
index 0000000..3a56b78
--- /dev/null
@@ -0,0 +1,64 @@
+variables in the tree:
+
+[1] result_sim.root
+NeCO2N2_sim
+////////////////
+ET1 : ET1 value
+ET2 : ET2 value
+ET3 : ET3 value
+ET4 : ET4 value
+UGEM1 : GEM1 voltage
+UGEM2 : GEM2 voltage
+UGEM3 : GEM3 voltage
+UGEM4 : GEM4 voltage
+UGEM3overUGEM4 : UGEM3/UGEM4
+Gain : Effective Gain estimated by the multiplication distribution (= Mean_ElectronsTransfer4). 158seeds, 10000 events
+IB: ion back flow (# of ions in the drift/# of electrons in the induction)
+Sigma: Resolution Sigma estimated by the multiplication distribution (= Mean_ElectronsTransfer4). 158seeds, 10000 events
+Mean_ElectronsTransfer1: Mean number of the electrons in transfer1 (calculation started from 1 seed)
+RMSoverMean_ElectronsTransfer1: RMS/Mean of number of the electrons in transfer1
+Mean_ElectronsTransfer2: Mean number of the electrons in transfer2 (calculation started from # of electrons in transfer1)
+RMSoverMean_ElectronsTransfer2: RMS/Mean of number of the electrons in transfer2
+Mean_ElectronsTransfer3: Mean number of the electrons in transfer3 (calculation started from # of electrons in transfer2)
+RMSoverMean_ElectronsTransfer3: RMS/Mean of number of the electrons in transfer3
+Mean_ElectronsTransfer4: Mean number of the electrons in transfer4 (calculation started from # of electrons in transfer3)
+RMSoverMean_ElectronsTransfer4: RMS/Mean of number of the electrons in transfer4
+
+Sigma_Meas : measured Sigma
+IB_Meas : measured IB 
+
+
+[2] out_UGEM1_UGEM2_UGEM3_UGEM4.root
+
+ElectronsInduction : the number of electrons in the induction (calculation started from 1 seed)
+ElectronsGEM1: total electrons created in GEM1 (from 1 seed)
+ElectronsGEM2: total electrons created in GEM2 (from # of electrons in transfer1)
+ElectronsGEM3: total electrons created in GEM3 (from # of electrons in transfer2)
+ElectronsGEM4: total electrons created in GEM4 (from # of electrons in transfer3)
+ElectronsTransfer12: total electrons in transfer1 (from 1 seed + GEM1 amplification)
+ElectronsTransfer23: total electrons in transfer2 (from ElectronsTransfer12 + GEM2 amplification)
+ElectronsTransfer34: total electrons in transfer3 (from ElectronsTransfer23 + GEM3 amplification)
+ElectronsTransfer45: total electrons in transfer4 (from ElectronsTransfer34 + GEM4 amplification)
+ElectronsGEM1Upper: number of electrons absorbed in GEM1 Upper Metal
+ElectronsGEM1Lower: number of electrons absorbed in GEM1 Lower Metal
+ElectronsGEM2Upper: number of electrons absorbed in GEM2 Upper Metal
+ElectronsGEM2Lower: number of electrons absorbed in GEM2 Lower Metal
+ElectronsGEM3Upper: number of electrons absorbed in GEM3 Upper Metal
+ElectronsGEM3Lower: number of electrons absorbed in GEM3 Lower Metal
+ElectronsGEM4Upper: number of electrons absorbed in GEM4 Upper Metal
+ElectronsGEM4Lower: number of electrons absorbed in GEM4 Lower Metal
+
+IonsGEM4 : total ions created at GEM4
+IonsGEM4Drift : number of ions from GEM4 going back the drift space
+IonsGEM3Drift : number of ions from GEM3 going back the drift space
+IonsGEM2Drift : number of ions from GEM2 going back the drift space
+IonsGEM1Drift : number of ions from GEM1 going back the drift space
+
+IonsGEM1Upper : the number of ions absorbed at GEM1 top out of the number of ions created in GEM1
+IonsGEM1Lower : the number of ions absorbed at GEM1 bottom out of the number of ions created in GEM1
+IonsGEM2Upper : the number of ions absorbed at GEM2 top out of the number of ions created in GEM2
+IonsGEM2Lower : the number of ions absorbed at GEM2 bottom out of the number of ions created in GEM2
+IonsGEM3Upper : the number of ions absorbed at GEM3 top out of the number of ions created in GEM3
+IonsGEM3Lower : the number of ions absorbed at GEM3 bottom out of the number of ions created in GEM3
+IonsGEM4Upper : the number of ions absorbed at GEM4 top out of the number of ions created in GEM4
+IonsGEM4Lower : the number of ions absorbed at GEM4 bottom out of the number of ions created in GEM4
\ No newline at end of file
diff --git a/TPC/Upgrade/data/GEMMCscan/result_sim.root b/TPC/Upgrade/data/GEMMCscan/result_sim.root
new file mode 100644 (file)
index 0000000..07e0759
Binary files /dev/null and b/TPC/Upgrade/data/GEMMCscan/result_sim.root differ
diff --git a/TPC/Upgrade/data/GEMscan/GEMScansIKF.root b/TPC/Upgrade/data/GEMscan/GEMScansIKF.root
new file mode 100644 (file)
index 0000000..f29fdc1
Binary files /dev/null and b/TPC/Upgrade/data/GEMscan/GEMScansIKF.root differ
diff --git a/TPC/Upgrade/data/GEMscan/S_LP_LP_S_ETscans_NeCO2N2.txt b/TPC/Upgrade/data/GEMscan/S_LP_LP_S_ETscans_NeCO2N2.txt
new file mode 100644 (file)
index 0000000..3018b43
--- /dev/null
@@ -0,0 +1,51 @@
+ET1/D:ET2/D:ET3/D:ET4/D:UGEM1/D:UGEM2/D:UGEM3/D:UGEM4/D:AnodeCurrent/D:CathodeCurrent/D:IB/D:PeakPosition/D:FWHM/D:CorrFWHM/D:RelFWHM/D:Sigma/D:Gain/D:UGEM3overUGEM4/D
+2000   1000    100     4000    315     235     260     324     18.1    0.331   1.83    767     187     185.8   24.2    10.3    2000    0.8
+3000   1000    100     4000    315     235     260     324     17.4    0.315   1.81    766     189     187.8   24.5    10.4    2000    0.8
+4000   1000    100     4000    315     235     260     325     17.2    0.312   1.81    765     190     188.8   24.7    10.5    2000    0.8
+5000   1000    100     4000    315     235     258     322     17.3    0.332   1.92    763     187     185.8   24.3    10.4    2000    0.8
+6000   1000    100     4000    315     235     248     310     17.4    0.425   2.44    763     207     205.9   27.0    11.5    2000    0.8
+2000   2000    100     4000    315     235     264     332     17.8    0.224   1.26    763     191     189.8   24.9    10.6    2000    0.8
+3000   2000    100     4000    315     235     264     334     17.2    0.222   1.29    769     194     192.8   25.1    10.7    2000    0.8
+4000   2000    100     4000    315     235     264     332     16.9    0.224   1.33    761     194     192.8   25.3    10.8    2000    0.8
+5000   2000    100     4000    315     235     262     328     17      0.25    1.47    769     192     190.8   24.8    10.6    2000    0.8
+6000   2000    100     4000    315     235     252     315     17      0.341   2.01    760     208     206.9   27.2    11.6    2000    0.8
+2000   3000    100     4000    315     235     266     332     17.7    0.218   1.23    761     191     189.8   24.9    10.6    2000    0.8
+3000   3000    100     4000    315     235     266     331     17      0.212   1.25    759     193     191.8   25.3    10.8    2000    0.8
+4000   3000    100     4000    315     235     266     333     17.1    0.214   1.25    770     195     193.8   25.2    10.7    2000    0.8
+5000   3000    100     4000    315     235     263     329     17.1    0.24    1.40    771     192     190.8   24.7    10.5    2000    0.8
+2000   1000    200     4000    315     235     249     310     17.6    0.369   2.10    763     181     179.7   23.6    10.0    2000    0.8
+3000   1000    200     4000    315     235     249     311     17.4    0.355   2.04    768     185     183.8   23.9    10.2    2000    0.8
+4000   1000    200     4000    315     235     249     313     17.4    0.35    2.01    771     188     186.8   24.2    10.3    2000    0.8
+5000   1000    200     4000    315     235     247     308     17.3    0.374   2.16    763     182     180.7   23.7    10.1    2000    0.8
+6000   1000    200     4000    315     235     236     297     17.6    0.472   2.68    773     207     205.9   26.6    11.3    2000    0.8
+2000   2000    200     4000    315     235     252     316     17.2    0.244   1.42    761     184     182.8   24.0    10.2    2000    0.8
+3000   2000    200     4000    315     235     253     316     17.1    0.24    1.40    768     190     188.8   24.6    10.5    2000    0.8
+4000   2000    200     4000    315     235     253     316     17.1    0.243   1.42    773     190     188.8   24.4    10.4    2000    0.8
+5000   2000    200     4000    315     235     250     314     17      0.268   1.58    768     186     184.8   24.1    10.2    2000    0.8
+6000   2000    200     4000    315     235     240     301     17.1    0.364   2.13    762     210     208.9   27.4    11.7    2000    0.8
+2000   3000    200     4000    315     235     255     319     17.2    0.221   1.28    762     187     185.8   24.4    10.4    2000    0.8
+3000   3000    200     4000    315     235     256     319     17.1    0.214   1.25    772     192     190.8   24.7    10.5    2000    0.8
+4000   3000    200     4000    315     235     256     320     16.7    0.216   1.29    761     191     189.8   24.9    10.6    2000    0.8
+5000   3000    200     4000    315     235     253     317     16.9    0.242   1.43    772     190     188.8   24.5    10.4    2000    0.8
+2000   1000    300     4000    315     235     244     306     17.4    0.396   2.28    759     179     177.7   23.4    10.0    2000    0.8
+3000   1000    300     4000    315     235     244     307     17.2    0.379   2.20    765     184     182.8   23.9    10.2    2000    0.8
+4000   1000    300     4000    315     235     245     308     17.3    0.376   2.17    771     185     183.8   23.8    10.1    2000    0.8
+5000   1000    300     4000    315     235     243     303     17.2    0.398   2.31    765     184     182.8   23.9    10.2    2000    0.8
+6000   1000    300     4000    315     235     232     292     17.6    0.495   2.81    770     208     206.9   26.9    11.4    2000    0.8
+2000   2000    300     4000    315     235     248     311     17.3    0.252   1.46    760     184     182.8   24.0    10.2    2000    0.8
+3000   2000    300     4000    315     235     248     312     17.1    0.246   1.44    765     189     187.8   24.5    10.4    2000    0.8
+4000   2000    300     4000    315     235     249     313     17.1    0.249   1.46    769     189     187.8   24.4    10.4    2000    0.8
+5000   2000    300     4000    315     235     247     308     17.1    0.276   1.61    764     185     183.8   24.1    10.2    2000    0.8
+6000   2000    300     4000    315     235     236     297     17.4    0.374   2.15    768     209     207.9   27.1    11.5    2000    0.8
+2000   3000    300     4000    315     235     252     313     17.3    0.227   1.31    764     187     185.8   24.3    10.3    2000    0.8
+3000   3000    300     4000    315     235     252     314     17.1    0.221   1.29    772     191     189.8   24.6    10.5    2000    0.8
+4000   3000    300     4000    315     235     252     315     16.8    0.221   1.32    761     191     189.8   24.9    10.6    2000    0.8
+5000   3000    300     4000    315     235     250     311     17      0.247   1.45    772     190     188.8   24.5    10.4    2000    0.8
+4000   4000    100     4000    315     235     268     335     17.3    0.214   1.24    775     196     194.8   25.1    10.7    2000    0.8
+4000   2000    100     1000    315     235     286     355     16.1    0.268   1.66    769     190     188.8   24.6    10.4    2000    0.8
+4000   2000    100     2000    315     235     272     340     15.9    0.244   1.53    769     190     188.8   24.6    10.4    2000    0.8
+4000   2000    100     3000    315     235     266     332     16      0.237   1.48    760     187     185.8   24.4    10.4    2000    0.8
+4000   2000    100     4000    315     235     263     329     17      0.235   1.38    772     190     188.8   24.5    10.4    2000    0.8
+4000   2000    100     5000    315     235     260     324     18.6    0.233   1.25    771     190     188.8   24.5    10.4    2000    0.8
+4000   2000    100     6000    315     235     253     316     21.7    0.229   1.06    760     192     190.8   25.1    10.7    2000    0.8
+
diff --git a/TPC/Upgrade/data/GEMscan/S_LP_LP_S_ETscans_NeCO2N2.xls b/TPC/Upgrade/data/GEMscan/S_LP_LP_S_ETscans_NeCO2N2.xls
new file mode 100644 (file)
index 0000000..07b6420
Binary files /dev/null and b/TPC/Upgrade/data/GEMscan/S_LP_LP_S_ETscans_NeCO2N2.xls differ
diff --git a/TPC/Upgrade/data/GEMscan/S_LP_LP_S_GEM1scans_ratio0.65_NeCO2N2.xls b/TPC/Upgrade/data/GEMscan/S_LP_LP_S_GEM1scans_ratio0.65_NeCO2N2.xls
new file mode 100644 (file)
index 0000000..31101f6
Binary files /dev/null and b/TPC/Upgrade/data/GEMscan/S_LP_LP_S_GEM1scans_ratio0.65_NeCO2N2.xls differ
diff --git a/TPC/Upgrade/data/GEMscan/S_LP_LP_S_scans_ArCO2.txt b/TPC/Upgrade/data/GEMscan/S_LP_LP_S_scans_ArCO2.txt
new file mode 100644 (file)
index 0000000..13a4357
--- /dev/null
@@ -0,0 +1,61 @@
+ET1/D:ET2/D:ET3/D:ET4/D:UGEM1/D:UGEM2/D:UGEM3/D:UGEM4/D:AnodeCurrent/D:CathodeCurrent/D:IB/D:PeakPosition/D:FWHM/D:CorrFWHM/D:RelFWHM/D:Sigma/D:Gain/D:UGEM3overUGEM4/D:ET2Scan/I:ET3Scan/I:GEM1Scan/I:GEM2Scan/I:UGEM3overUGEM4Scan/I
+4000   100     100     4000    225     235     302     377     21.1    0.378   1.79    413     230     228.99  55.45   23.6    1000    0.8     1       0       0       0       0
+4000   200     100     4000    225     235     295     369     23      0.484   2.10    414     220     218.95  52.89   22.5    1000    0.8     1       0       0       0       0
+4000   400     100     4000    225     235     298     372     24.5    0.386   1.58    422     217     215.93  51.17   21.8    1000    0.8     1       0       0       0       0
+4000   600     100     4000    225     235     301     375     23.8    0.287   1.21    414     227     225.98  54.58   23.2    1000    0.8     1       0       0       0       0
+4000   800     100     4000    225     235     304     378     23.8    0.227   0.95    418     228     226.98  54.30   23.1    1000    0.8     1       0       0       0       0
+4000   1000    100     4000    225     235     305     381     23.7    0.183   0.77    422     229     227.99  54.03   23.0    1000    0.8     1       0       0       0       0
+4000   1200    100     4000    225     235     306     382     23.1    0.151   0.65    410     222     220.96  53.89   22.9    1000    0.8     1       0       0       0       0
+4000   1400    100     4000    225     235     308     383     23.7    0.133   0.56    417     223     221.96  53.23   22.7    1000    0.8     1       0       0       0       0
+4000   1600    100     4000    225     235     308     385     24.1    0.116   0.48    422     228     226.98  53.79   22.9    1000    0.8     1       0       0       0       0
+4000   1800    100     4000    225     235     309     385     24.1    0.106   0.44    420     225     223.97  53.33   22.7    1000    0.8     1       0       0       0       0
+4000   2000    100     4000    225     235     309     385     23.5    0.098   0.42    408     225     223.97  54.89   23.4    1000    0.8     1       0       0       0       0
+4000   2200    100     4000    225     235     310     385     23.6    0.092   0.39    414     218     216.94  52.40   22.3    1000    0.8     1       0       0       0       0
+4000   2400    100     4000    225     235     310     386     23.8    0.088   0.37    416     215     213.92  51.42   21.9    1000    0.8     1       0       0       0       0
+4000   2600    100     4000    225     235     310     387     23.9    0.086   0.36    417     224     222.97  53.47   22.8    1000    0.8     1       0       0       0       0
+4000   100     100     4000    225     235     301     377     22.4    0.420   1.88    415     229     227.99  54.94   23.4    1000    0.8     0       1       0       0       0
+4000   100     200     4000    225     235     294     367     22      0.450   2.05    425     233     232.01  54.59   23.2    1000    0.8     0       1       0       0       0
+4000   100     300     4000    225     235     291     363     21.7    0.45    2.07    419     233     232.01  55.37   23.6    1000    0.8     0       1       0       0       0
+4000   100     400     4000    225     235     290     361     22      0.450   2.05    427     228     226.98  53.16   22.6    1000    0.8     0       1       0       0       0
+4000   100     600     4000    225     235     288     358     21.8    0.440   2.02    424     231     230.00  54.24   23.1    1000    0.8     0       1       0       0       0
+4000   100     800     4000    225     235     285     357     21.5    0.430   2.00    414     225     223.97  54.10   23.0    1000    0.8     0       1       0       0       0
+4000   100     1000    4000    225     235     284     355     21.4    0.420   1.96    413     228     226.98  54.96   23.4    1000    0.8     0       1       0       0       0
+4000   100     1400    4000    225     235     283     352     21.8    0.420   1.93    419     230     228.99  54.65   23.3    1000    0.8     0       1       0       0       0
+4000   100     1600    4000    225     235     282     351     21.9    0.410   1.87    417     227     225.98  54.19   23.1    1000    0.8     0       1       0       0       0
+4000   100     1800    4000    225     235     280     352     22.3    0.410   1.84    427     230     228.99  53.63   22.8    1000    0.8     0       1       0       0       0
+4000   100     2000    4000    225     235     280     350     21.9    0.400   1.83    414     231     230.00  55.55   23.6    1000    0.8     0       1       0       0       0
+4000   100     2400    4000    225     235     280     350     21.7    0.390   1.80    413     225     223.97  54.23   23.1    1000    0.8     0       1       0       0       0
+4000   100     2600    4000    225     235     280     351     21.9    0.390   1.78    419     225     223.97  53.45   22.7    1000    0.8     0       1       0       0       0
+4000   100     3000    4000    225     235     280     352     21.8    0.360   1.65    415     228     226.98  54.69   23.3    1000    0.8     0       1       0       0       0
+4000   100     3200    4000    225     235     281     352     21.9    0.360   1.64    419     231     230.00  54.89   23.4    1000    0.8     0       1       0       0       0
+4000   2000    100     4000    225     235     308     385     22.8    0.1     0.44    403     226     224.97  55.83   23.8    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    235     235     304     381     23      0.11    0.48    414     216     214.93  51.91   22.1    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    245     235     300     376     22.6    0.125   0.55    411     204     202.86  49.36   21.0    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    255     235     296     371     22.3    0.14    0.63    414     183     181.73  43.90   18.7    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    265     235     292     366     22.2    0.165   0.74    415     174     172.67  41.61   17.7    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    275     235     288     361     22.1    0.195   0.88    416     164     162.58  39.08   16.6    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    285     235     284     356     22.1    0.23    1.04    420     147     145.42  34.62   14.7    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    295     235     280     350     21.6    0.28    1.30    414     132     130.24  31.46   13.4    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    305     235     276     345     21.8    0.34    1.56    415     130     128.21  30.89   13.1    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    315     235     272     340     22.1    0.41    1.86    419     124     122.12  29.15   12.4    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    225     255     300     374     23.9    0.11    0.46    419     200     198.84  47.46   20.2    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    235     255     296     369     23.3    0.13    0.56    419     185     183.75  43.85   18.7    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    245     255     292     364     23.1    0.15    0.65    417     168     166.62  39.96   17.0    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    255     255     288     359     22.8    0.17    0.75    411     161     159.56  38.82   16.5    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    265     255     284     354     22.75   0.2     0.88    412     149     147.44  35.79   15.2    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    275     255     280     349     22.7    0.24    1.06    411     140     138.34  33.66   14.3    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    285     255     276     344     22.7    0.28    1.23    413     132     130.24  31.53   13.4    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    295     255     272     339     22.9    0.34    1.48    416     124     122.12  29.36   12.5    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    305     255     267     334     22.5    0.41    1.82    409     116     113.99  27.87   11.9    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    315     255     263     329     23      0.5     2.17    418     114     111.95  26.78   11.4    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    225     285     285     356     23.5    0.155   0.66    421     181     179.72  42.69   18.2    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    235     285     281     351     23.1    0.175   0.76    419     160     158.55  37.84   16.1    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    245     285     277     347     23.5    0.205   0.87    425     155     153.50  36.12   15.4    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    255     285     273     342     23.3    0.24    1.03    424     147     145.42  34.30   14.6    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    265     285     269     337     23.2    0.29    1.25    423     141     139.35  32.94   14.0    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    275     285     265     332     23.3    0.345   1.48    426     132     130.24  30.57   13.0    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    285     285     260     327     22.9    0.41    1.79    418     126     124.15  29.70   12.6    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    295     285     256     321     22.5    0.5     2.22    413     120     118.06  28.59   12.2    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    305     285     252     315     22.3    0.61    2.74    411     115     112.97  27.49   11.7    1000    0.8     0       0       1       0       0
+4000   2000    100     4000    315     285     248     309     22.2    0.75    3.38    414     111     108.90  26.30   11.2    1000    0.8     0       0       1       0       0
+
diff --git a/TPC/Upgrade/data/GEMscan/S_LP_LP_S_scans_NeCO2N2.txt b/TPC/Upgrade/data/GEMscan/S_LP_LP_S_scans_NeCO2N2.txt
new file mode 100644 (file)
index 0000000..f6408f9
--- /dev/null
@@ -0,0 +1,203 @@
+ET1/D:ET2/D:ET3/D:ET4/D:UGEM1/D:UGEM2/D:UGEM3/D:UGEM4/D:AnodeCurrent/D:CathodeCurrent/D:IB/D:PeakPosition/D:FWHM/D:CorrFWHM/D:RelFWHM/D:Sigma/D:Gain/D:UGEM3overUGEM4/D:ET2Scan/I:ET3Scan/I:GEM1Scan/I:GEM2Scan/I:UGEM3overUGEM4Scan/I
+4000   100     100     4000    225     235     300     377     64.6    0.93    1.44    842     330     329.3   39.1    16.64   2000    0.8     1       0       0       0       0
+4000   200     100     4000    225     235     291     364     64.7    1.14    1.76    832     310     309.3   37.2    15.82   2000    0.8     1       0       0       0       0
+4000   400     100     4000    225     235     292     367     65.5    0.87    1.33    828     315     314.3   38.0    16.15   2000    0.8     1       0       0       0       0
+4000   600     100     4000    225     235     294     372     65.9    0.66    1.00    838     321     320.3   38.2    16.26   2000    0.8     1       0       0       0       0
+4000   800     100     4000    225     235     296     375     64.9    0.53    0.82    829     325     324.3   39.1    16.65   2000    0.8     1       0       0       0       0
+4000   1000    100     4000    225     235     298     377     64.9    0.44    0.68    832     327     326.3   39.2    16.69   2000    0.8     1       0       0       0       0
+4000   1200    100     4000    225     235     300     380     64.7    0.38    0.59    842     339     338.3   40.2    17.10   2000    0.8     1       0       0       0       0
+4000   1400    100     4000    225     235     301     381     64.7    0.34    0.53    842     343     342.3   40.7    17.30   2000    0.8     1       0       0       0       0
+4000   1600    100     4000    225     235     301     382     63.7    0.30    0.47    832     341     340.3   40.9    17.41   2000    0.8     1       0       0       0       0
+4000   1800    100     4000    225     235     302     383     64.7    0.27    0.42    841     345     344.3   40.9    17.42   2000    0.8     1       0       0       0       0
+4000   2000    100     4000    225     235     303     383     63.9    0.25    0.39    835     345     344.3   41.2    17.55   2000    0.8     1       0       0       0       0
+4000   2200    100     4000    225     235     304     383     63.7    0.24    0.38    831     346     345.3   41.6    17.68   2000    0.8     1       0       0       0       0
+4000   2400    100     4000    225     235     305     383     63.5    0.22    0.35    828     348     347.3   41.9    17.85   2000    0.8     1       0       0       0       0
+4000   2600    100     4000    225     235     306     383     63.2    0.21    0.33    826     347     346.3   41.9    17.84   2000    0.8     1       0       0       0       0
+4000   100     100     4000    225     235     301     377     66.3    1.15    1.73    834     324     323.3   38.8    16.5    2000    0.8     0       1       0       0       0
+4000   100     200     4000    225     235     291     364     66.4    1.27    1.91    841     328     327.3   38.9    16.6    2000    0.8     0       1       0       0       0
+4000   100     400     4000    225     235     284     355     64.9    1.27    1.96    829     320     319.3   38.5    16.4    2000    0.8     0       1       0       0       0
+4000   100     600     4000    225     235     281     351     64.4    1.23    1.91    826     321     320.3   38.8    16.5    2000    0.8     0       1       0       0       0
+4000   100     800     4000    225     235     279     349     65.1    1.21    1.86    837     321     320.3   38.3    16.3    2000    0.8     0       1       0       0       0
+4000   100     1000    4000    225     235     279     347     56.8    1.20    1.82    839     325     324.3   38.7    16.4    2000    0.8     0       1       0       0       0
+4000   100     1200    4000    225     235     277     346     65.9    1.18    1.79    840     325     324.3   38.6    16.4    2000    0.8     0       1       0       0       0
+4000   100     1400    4000    225     235     276     344     65.2    1.15    1.76    834     324     323.3   38.8    16.5    2000    0.8     0       1       0       0       0
+4000   100     1600    4000    225     235     275     343     65.7    1.14    1.74    840     325     324.3   38.6    16.4    2000    0.8     0       1       0       0       0
+4000   100     1800    4000    225     235     273     342     64.5    1.11    1.72    827     318     317.3   38.4    16.3    2000    0.8     0       1       0       0       0
+4000   100     2000    4000    225     235     273     341     64.8    1.10    1.7     834     323     322.3   38.6    16.4    2000    0.8     0       1       0       0       0
+4000   100     2200    4000    225     235     273     341     64.7    1.08    1.67    836     324     323.3   38.7    16.5    2000    0.8     0       1       0       0       0
+4000   100     2400    4000    225     235     273     342     65.9    1.06    1.61    845     326     325.3   38.5    16.4    2000    0.8     0       1       0       0       0
+4000   100     2600    4000    225     235     273     342     65.2    1.03    1.58    838     326     325.3   38.8    16.5    2000    0.8     0       1       0       0       0
+4000   100     2800    4000    225     235     273     342     64.5    1.00    1.55    832     325     324.3   39.0    16.6    2000    0.8     0       1       0       0       0
+4000   100     3000    4000    225     235     274     342     65.1    0.98    1.51    844     325     324.3   38.4    16.4    2000    0.8     0       1       0       0       0
+4000   100     3200    4000    225     235     274     342     64.1    0.94    1.47    833     324     323.3   38.8    16.5    2000    0.8     0       1       0       0       0
+4000   2000    100     4000    225     235     304     382     67.1    0.23    0.34    837     336     335.31  40.06   17.0    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    235     235     301     374     65.4    0.26    0.40    831     311     310.26  37.34   15.9    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    245     235     296     370     65.8    0.29    0.44    838     292     291.21  34.75   14.8    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    255     235     292     364     65.1    0.33    0.51    828     269     268.14  32.38   13.8    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    265     235     287     360     65.6    0.37    0.56    833     257     256.10  30.74   13.1    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    275     235     284     354     66      0.43    0.65    831     238     237.03  28.52   12.1    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    285     235     280     349     66.8    0.49    0.73    839     228     226.98  27.05   11.5    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    295     235     275     344     66.1    0.57    0.86    827     215     213.92  25.87   11.0    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    305     235     271     339     67.3    0.66    0.98    834     205     203.87  24.44   10.4    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    315     235     267     334     68.3    0.775   1.13    839     197     195.82  23.34   9.9     2000    0.8     0       0       1       0       0
+4000   2000    100     4000    225     255     292     365     66.8    0.29    0.43    834     305     304.24  36.48   15.5    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    235     255     288     359     66.2    0.32    0.48    829     284     283.19  34.16   14.5    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    245     255     285     354     67      0.36    0.54    835     267     266.13  31.87   13.6    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    255     255     280     250     67.6    0.41    0.61    844     254     253.09  29.99   12.8    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    265     255     276     344     67.1    0.47    0.70    831     236     235.02  28.28   12.0    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    275     255     272     339     68.2    0.54    0.79    827     222     220.96  26.72   11.4    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    285     255     268     334     69.6    0.63    0.91    840     213     211.91  25.23   10.7    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    295     255     263     329     69.3    0.73    1.05    829     202     200.85  24.23   10.3    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    305     255     259     323     70.8    0.86    1.21    835     194     192.80  23.09   9.8     2000    0.8     0       0       1       0       0
+4000   2000    100     4000    315     255     255     319     72.3    1.01    1.40    842     189     187.77  22.30   9.5     2000    0.8     0       0       1       0       0
+4000   2000    100     4000    225     285     278     346     67.2    0.39    0.58    828     275     274.16  33.11   14.1    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    235     285     273     242     68.3    0.45    0.66    834     258     257.10  30.83   13.1    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    245     285     269     336     67.8    0.51    0.75    827     242     241.04  29.15   12.4    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    255     285     266     330     68.8    0.59    0.86    836     231     230.00  27.51   11.7    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    265     285     261     326     69.8    0.68    0.97    839     219     217.94  25.98   11.1    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    275     285     256     321     69.6    0.79    1.14    829     208     206.89  24.96   10.6    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    285     285     252     316     70.9    0.925   1.30    833     199     197.84  23.75   10.1    2000    0.8     0       0       1       0       0
+4000   2000    100     4000    295     285     248     311     72.4    1.09    1.51    837     192     190.79  22.79   9.7     2000    0.8     0       0       1       0       0
+4000   2000    100     4000    305     285     244     306     74.1    1.29    1.74    843     186     184.75  21.92   9.3     2000    0.8     0       0       1       0       0
+4000   2000    100     4000    315     285     240     300     74.2    1.52    2.05    832     180     178.71  21.48   9.1     2000    0.8     0       0       1       0       0
+4000   2000    100     4000    225     235     304     381     67.6    0.23    0.34    834     336     335.31  40.21   17.1    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     245     299     374     67.8    0.26    0.38    839     322     321.28  38.29   16.3    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     255     294     367     67.1    0.28    0.42    833     305     304.24  36.52   15.5    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     265     289     361     67.7    0.3     0.44    842     299     298.23  35.42   15.1    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     275     284     355     67.9    0.34    0.50    839     290     289.20  34.47   14.7    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     285     279     348     67.2    0.38    0.57    833     281     280.18  33.63   14.3    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     295     274     342     67.8    0.43    0.63    837     273     272.15  32.52   13.8    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     305     269     335     68.3    0.49    0.72    839     268     267.14  31.84   13.5    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     315     264     329     69      0.56    0.81    841     263     262.12  31.17   13.3    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     325     259     323     70      0.66    0.94    841     261     260.11  30.93   13.2    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     335     254     317     70.9    0.77    1.09    842     258     257.10  30.53   13.0    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     345     249     311     71.6    0.9     1.26    838     249     248.07  29.60   12.6    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     235     290     362     67      0.34    0.51    835     270     269.14  32.23   13.7    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     245     285     357     67.9    0.37    0.54    839     266     265.13  31.60   13.4    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     255     280     351     68.4    0.41    0.60    842     262     261.12  31.01   13.2    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     265     275     344     67.8    0.46    0.68    829     248     247.07  29.80   12.7    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     275     270     338     68.4    0.51    0.75    832     241     240.04  28.85   12.3    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     285     265     332     69.3    0.59    0.85    837     235     234.01  27.96   11.9    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     295     260     326     70.2    0.67    0.95    839     231     230.00  27.41   11.7    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     305     256     319     71      0.78    1.10    838     227     225.98  26.97   11.5    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     315     251     313     71.7    0.91    1.27    834     223     221.96  26.61   11.3    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     325     246     307     72.4    1.06    1.46    830     218     216.94  26.14   11.1    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     335     241     301     73.4    1.24    1.69    829     215     213.92  25.80   11.0    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    255     345     237     295     75.8    1.48    1.95    842     215     213.92  25.41   10.8    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     235     284     354     66      0.43    0.65    831     238     237.03  28.52   12.1    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     245     278     348     66      0.47    0.71    831     234     233.01  28.04   11.9    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     255     273     342     66.6    0.52    0.78    834     227     225.98  27.10   11.5    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     265     268     336     67.6    0.58    0.86    842     225     223.97  26.60   11.3    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     275     264     329     68.2    0.66    0.97    842     218     216.94  25.76   11.0    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     285     259     323     68.2    0.76    1.11    834     211     209.90  25.17   10.7    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     295     252     314     70.8    0.92    1.30    830     203     201.86  24.32   10.3    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     305     247     308     71.8    1.06    1.48    830     199     197.84  23.84   10.1    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     315     243     302     73.5    1.25    1.70    831     199     197.84  23.81   10.1    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     325     237     297     74.1    1.46    1.97    828     196     194.82  23.53   10.0    2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     335     233     291     76.6    1.73    2.26    843     195     193.81  22.99   9.8     2000    0.8     0       0       0       1       0
+4000   2000    100     4000    275     345     228     285     77.3    2.05    2.65    839     195     193.81  23.10   9.8     2000    0.8     0       0       0       1       0
+4000   2000    100     4000    225     235     331     348     65.1    0.27    0.41    836     324     323.29  38.67   16.5    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    235     235     326     343     65.3    0.3     0.46    842     304     303.24  36.01   15.3    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    245     235     321     338     64.4    0.34    0.53    835     283     282.18  33.79   14.4    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    255     235     316     333     63.9    0.38    0.59    828     264     263.12  31.78   13.5    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    265     235     312     328     64.6    0.43    0.67    832     249     248.07  29.82   12.7    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    275     235     308     323     64.8    0.49    0.76    835     236     235.02  28.15   12.0    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    285     235     303     319     65.7    0.56    0.85    841     225     223.97  26.63   11.3    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    295     235     298     314     65      0.64    0.98    829     212     210.91  25.44   10.8    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    305     235     294     309     66      0.74    1.12    832     204     202.86  24.38   10.4    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    315     235     289     305     66.6    0.86    1.29    830     193     191.80  23.11   9.8     2000    0.95    0       0       1       0       0
+4000   2000    100     4000    225     255     320     336     63.6    0.33    0.52    841     298     297.22  35.34   15.0    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    235     255     315     331     62.9    0.36    0.57    835     278     277.17  33.19   14.1    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    245     255     310     327     63.2    0.4     0.63    837     262     261.12  31.20   13.3    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    255     255     306     322     64.5    0.47    0.73    843     250     249.07  29.55   12.6    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    265     255     301     317     63.8    0.52    0.82    833     235     234.01  28.09   12.0    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    275     255     297     312     64.6    0.6     0.93    837     224     222.97  26.64   11.3    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    285     255     292     307     64      0.69    1.08    826     212     210.91  25.53   10.9    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    295     255     287     303     64.7    0.79    1.22    828     205     203.87  24.62   10.5    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    305     255     283     298     65.8    0.92    1.40    832     199     197.84  23.78   10.1    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    315     255     279     293     66.9    1.1     1.64    836     193     191.80  22.94   9.8     2000    0.95    0       0       1       0       0
+4000   2000    100     4000    225     285     302     319     62.4    0.44    0.71    831     271     270.15  32.51   13.8    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    235     285     298     314     62.7    0.5     0.80    830     251     250.08  30.13   12.8    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    245     285     294     309     63.2    0.57    0.90    832     236     235.02  28.25   12.0    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    255     285     289     305     63.9    0.64    1.00    835     228     226.98  27.18   11.6    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    265     285     285     300     64.6    0.74    1.15    837     217     215.93  25.80   11.0    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    275     285     281     295     65.6    0.86    1.31    840     206     204.87  24.39   10.4    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    285     285     276     291     66.7    1       1.50    841     200     198.84  23.64   10.1    2000    0.95    0       0       1       0       0
+4000   2000    100     4000    295     285     272     285     66.5    1.2     1.80    826     188     186.77  22.61   9.6     2000    0.95    0       0       1       0       0
+4000   2000    100     4000    305     285     267     281     67.5    1.4     2.07    828     183     181.73  21.95   9.3     2000    0.95    0       0       1       0       0
+4000   2000    100     4000    315     285     263     276     69      1.6     2.32    835     179     177.70  21.28   9.1     2000    0.95    0       0       1       0       0
+4000   2000    100     4000    225     235     304     382     67.1    0.23    0.34    837     336     335.31  40.06   17.0    2000    0.80    0       0       0       0       1
+4000   2000    100     4000    225     235     307     379     67      0.23    0.34    837     335     334.31  39.94   17.0    2000    0.81    0       0       0       0       1
+4000   2000    100     4000    225     235     317     368     67.6    0.245   0.36    837     335     334.31  39.94   17.0    2000    0.86    0       0       0       0       1
+4000   2000    100     4000    225     235     327     358     68.3    0.26    0.38    845     334     333.31  39.44   16.8    2000    0.91    0       0       0       0       1
+4000   2000    100     4000    225     235     337     346     66.5    0.28    0.42    829     325     324.29  39.12   16.6    2000    0.97    0       0       0       0       1
+4000   2000    100     4000    225     235     341     342     66.5    0.29    0.44    826     325     324.29  39.26   16.7    2000    1.00    0       0       0       0       1
+4000   2000    100     4000    225     235     350     333     67.5    0.31    0.46    839     325     324.29  38.65   16.4    2000    1.05    0       0       0       0       1
+4000   2000    100     4000    225     235     270     417     17      0.065   0.38    760     328     327.3   43.1    18.3    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    235     235     267     411     17.1    0.071   0.42    761     312     311.3   40.9    17.4    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    255     235     259     400     16.9    0.089   0.53    760     271     270.2   35.5    15.1    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    275     235     252     388     16.8    0.115   0.68    761     239     238.0   31.3    13.3    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    295     235     243     378     16.7    0.153   0.92    765     216     214.9   28.1    12.0    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    315     235     236     365     16.4    0.206   1.26    764     197     195.8   25.6    10.9    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    225     255     261     403     17      0.074   0.44    766     301     300.2   39.2    16.7    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    235     255     257     398     17.1    0.083   0.49    774     285     284.2   36.7    15.6    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    255     255     250     385     16.6    0.105   0.63    758     243     242.1   31.9    13.6    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    275     255     243     374     16.9    0.14    0.83    775     223     222.0   28.6    12.2    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    295     255     235     363     16.8    0.186   1.11    773     205     203.9   26.4    11.2    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    315     255     228     351     16.6    0.255   1.54    767     189     187.8   24.5    10.4    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    225     285     248     382     16.9    0.1     0.59    762     274     273.2   35.8    15.3    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    235     285     245     376     16.8    0.111   0.66    763     257     256.1   33.6    14.3    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    255     285     237     366     17      0.145   0.85    771     230     229.0   29.7    12.6    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    275     285     229     355     16.9    0.197   1.17    767     209     207.9   27.1    11.5    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    295     285     222     343     16.8    0.269   1.60    766     189     187.8   24.5    10.4    2000    0.65    0       0       1       0       0
+4000   2000    100     4000    315     285     215     330     16.4    0.376   2.29    756     177     175.7   23.2    9.9     2000    0.65    0       0       1       0       0
+2000   1000    100     4000    315     235     260     324     18.1    0.331   1.83    767     187     185.8   24.2    10.3    2000    0.8     0       0       0       0       0
+3000   1000    100     4000    315     235     260     324     17.4    0.315   1.81    766     189     187.8   24.5    10.4    2000    0.8     0       0       0       0       0
+4000   1000    100     4000    315     235     260     325     17.2    0.312   1.81    765     190     188.8   24.7    10.5    2000    0.8     0       0       0       0       0
+5000   1000    100     4000    315     235     258     322     17.3    0.332   1.92    763     187     185.8   24.3    10.4    2000    0.8     0       0       0       0       0
+6000   1000    100     4000    315     235     248     310     17.4    0.425   2.44    763     207     205.9   27.0    11.5    2000    0.8     0       0       0       0       0
+2000   2000    100     4000    315     235     264     332     17.8    0.224   1.26    763     191     189.8   24.9    10.6    2000    0.8     0       0       0       0       0
+3000   2000    100     4000    315     235     264     334     17.2    0.222   1.29    769     194     192.8   25.1    10.7    2000    0.8     0       0       0       0       0
+4000   2000    100     4000    315     235     264     332     16.9    0.224   1.33    761     194     192.8   25.3    10.8    2000    0.8     0       0       0       0       0
+5000   2000    100     4000    315     235     262     328     17      0.25    1.47    769     192     190.8   24.8    10.6    2000    0.8     0       0       0       0       0
+6000   2000    100     4000    315     235     252     315     17      0.341   2.01    760     208     206.9   27.2    11.6    2000    0.8     0       0       0       0       0
+2000   3000    100     4000    315     235     266     332     17.7    0.218   1.23    761     191     189.8   24.9    10.6    2000    0.8     0       0       0       0       0
+3000   3000    100     4000    315     235     266     331     17      0.212   1.25    759     193     191.8   25.3    10.8    2000    0.8     0       0       0       0       0
+4000   3000    100     4000    315     235     266     333     17.1    0.214   1.25    770     195     193.8   25.2    10.7    2000    0.8     0       0       0       0       0
+5000   3000    100     4000    315     235     263     329     17.1    0.24    1.40    771     192     190.8   24.7    10.5    2000    0.8     0       0       0       0       0
+2000   1000    200     4000    315     235     249     310     17.6    0.369   2.10    763     181     179.7   23.6    10.0    2000    0.8     0       0       0       0       0
+3000   1000    200     4000    315     235     249     311     17.4    0.355   2.04    768     185     183.8   23.9    10.2    2000    0.8     0       0       0       0       0
+4000   1000    200     4000    315     235     249     313     17.4    0.35    2.01    771     188     186.8   24.2    10.3    2000    0.8     0       0       0       0       0
+5000   1000    200     4000    315     235     247     308     17.3    0.374   2.16    763     182     180.7   23.7    10.1    2000    0.8     0       0       0       0       0
+6000   1000    200     4000    315     235     236     297     17.6    0.472   2.68    773     207     205.9   26.6    11.3    2000    0.8     0       0       0       0       0
+2000   2000    200     4000    315     235     252     316     17.2    0.244   1.42    761     184     182.8   24.0    10.2    2000    0.8     0       0       0       0       0
+3000   2000    200     4000    315     235     253     316     17.1    0.24    1.40    768     190     188.8   24.6    10.5    2000    0.8     0       0       0       0       0
+4000   2000    200     4000    315     235     253     316     17.1    0.243   1.42    773     190     188.8   24.4    10.4    2000    0.8     0       0       0       0       0
+5000   2000    200     4000    315     235     250     314     17      0.268   1.58    768     186     184.8   24.1    10.2    2000    0.8     0       0       0       0       0
+6000   2000    200     4000    315     235     240     301     17.1    0.364   2.13    762     210     208.9   27.4    11.7    2000    0.8     0       0       0       0       0
+2000   3000    200     4000    315     235     255     319     17.2    0.221   1.28    762     187     185.8   24.4    10.4    2000    0.8     0       0       0       0       0
+3000   3000    200     4000    315     235     256     319     17.1    0.214   1.25    772     192     190.8   24.7    10.5    2000    0.8     0       0       0       0       0
+4000   3000    200     4000    315     235     256     320     16.7    0.216   1.29    761     191     189.8   24.9    10.6    2000    0.8     0       0       0       0       0
+5000   3000    200     4000    315     235     253     317     16.9    0.242   1.43    772     190     188.8   24.5    10.4    2000    0.8     0       0       0       0       0
+2000   1000    300     4000    315     235     244     306     17.4    0.396   2.28    759     179     177.7   23.4    10.0    2000    0.8     0       0       0       0       0
+3000   1000    300     4000    315     235     244     307     17.2    0.379   2.20    765     184     182.8   23.9    10.2    2000    0.8     0       0       0       0       0
+4000   1000    300     4000    315     235     245     308     17.3    0.376   2.17    771     185     183.8   23.8    10.1    2000    0.8     0       0       0       0       0
+5000   1000    300     4000    315     235     243     303     17.2    0.398   2.31    765     184     182.8   23.9    10.2    2000    0.8     0       0       0       0       0
+6000   1000    300     4000    315     235     232     292     17.6    0.495   2.81    770     208     206.9   26.9    11.4    2000    0.8     0       0       0       0       0
+2000   2000    300     4000    315     235     248     311     17.3    0.252   1.46    760     184     182.8   24.0    10.2    2000    0.8     0       0       0       0       0
+3000   2000    300     4000    315     235     248     312     17.1    0.246   1.44    765     189     187.8   24.5    10.4    2000    0.8     0       0       0       0       0
+4000   2000    300     4000    315     235     249     313     17.1    0.249   1.46    769     189     187.8   24.4    10.4    2000    0.8     0       0       0       0       0
+5000   2000    300     4000    315     235     247     308     17.1    0.276   1.61    764     185     183.8   24.1    10.2    2000    0.8     0       0       0       0       0
+6000   2000    300     4000    315     235     236     297     17.4    0.374   2.15    768     209     207.9   27.1    11.5    2000    0.8     0       0       0       0       0
+2000   3000    300     4000    315     235     252     313     17.3    0.227   1.31    764     187     185.8   24.3    10.3    2000    0.8     0       0       0       0       0
+3000   3000    300     4000    315     235     252     314     17.1    0.221   1.29    772     191     189.8   24.6    10.5    2000    0.8     0       0       0       0       0
+4000   3000    300     4000    315     235     252     315     16.8    0.221   1.32    761     191     189.8   24.9    10.6    2000    0.8     0       0       0       0       0
+5000   3000    300     4000    315     235     250     311     17      0.247   1.45    772     190     188.8   24.5    10.4    2000    0.8     0       0       0       0       0
+4000   4000    100     4000    315     235     268     335     17.3    0.214   1.24    775     196     194.8   25.1    10.7    2000    0.8     0       0       0       0       0
+4000   2000    100     1000    315     235     286     355     16.1    0.268   1.66    769     190     188.8   24.6    10.4    2000    0.8     0       0       0       0       0
+4000   2000    100     2000    315     235     272     340     15.9    0.244   1.53    769     190     188.8   24.6    10.4    2000    0.8     0       0       0       0       0
+4000   2000    100     3000    315     235     266     332     16      0.237   1.48    760     187     185.8   24.4    10.4    2000    0.8     0       0       0       0       0
+4000   2000    100     4000    315     235     263     329     17      0.235   1.38    772     190     188.8   24.5    10.4    2000    0.8     0       0       0       0       0
+4000   2000    100     5000    315     235     260     324     18.6    0.233   1.25    771     190     188.8   24.5    10.4    2000    0.8     0       0       0       0       0
+4000   2000    100     6000    315     235     253     316     21.7    0.229   1.06    760     192     190.8   25.1    10.7    2000    0.8     0       0       0       0       0
+
diff --git a/TPC/Upgrade/macros/AnaDelta.C b/TPC/Upgrade/macros/AnaDelta.C
new file mode 100644 (file)
index 0000000..fe42c67
--- /dev/null
@@ -0,0 +1,565 @@
+#include <TStyle.h>
+#include <TROOT.h>
+#include <TAxis.h>
+#include <TF1.h>
+#include <TFile.h>
+#include <TH1.h>
+#include <THn.h>
+#include <TObjArray.h>
+#include <TObject.h>
+#include <TString.h>
+#include <TVectorT.h>
+#include <TCanvas.h>
+#include <TProfile2D.h>
+#include <TGraphErrors.h>
+#include <TTreeStream.h>
+
+#include <AliExternalTrackParam.h>
+#include <AliTPCComposedCorrection.h>
+#include <AliTPCCorrectionLookupTable.h>
+
+#include <AliToyMCEventGenerator.h>
+
+/*
+
+.L $ALICE_ROOT/TPC/Upgrade/macros/AnaDelta.C+g
+
+
+*/
+TVectorD* MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax);
+TVectorD* MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax);
+TVectorD* MakeArbitraryBinning(const char* bins);
+
+void DumpHn(THn *hn, TTreeSRedirector &stream);
+void AnaDeltaBase(TString file, TString outDir=".");
+void AnaDeltaTree(TString file, TString outFile="deltas_tree.root");
+
+void AnaDelta(Int_t type, TString file, TString output="")
+{
+  switch (type) {
+    case 0:
+      AnaDeltaBase(file,output);
+      break;
+    case 1:
+      AnaDeltaTree(file,output);
+      break;
+  }
+}
+
+
+void AnaDeltaBase(TString file, TString outDir)
+{
+  //
+  //
+  //
+
+  gStyle->SetOptFit();
+  
+  TTreeSRedirector stream(Form("%s/deltas.root",outDir.Data()));
+  gROOT->cd();
+  
+  TFile f(file);
+  THn *hn=(THn*)f.Get("hn");
+
+  DumpHn(hn, stream);
+
+  delete hn;
+}
+
+
+void AnaDeltaTree(TString file, TString outFile)
+{
+  if (outFile.IsNull()) outFile="deltas_tree.root";
+  TFile f(file);
+  gROOT->cd();
+  TTree *t = (TTree*)f.Get("delta");
+  Float_t soneOverPt=0.;
+  Float_t radius=0.;
+  Float_t trackPhi=0.;
+  Float_t trackY=0.;
+  Float_t trackZ=0.;
+  Float_t resRphi=0.;
+  Double_t trackRes=0.;
+  Float_t pointY=0.;
+  Float_t pointZ=0.;
+  Short_t npTRD=0.;
+  Short_t event=0.;
+  
+  t->SetBranchAddress("soneOverPt" , &soneOverPt);
+  t->SetBranchAddress("r"          , &radius);
+  t->SetBranchAddress("trackPhi"   , &trackPhi);
+  t->SetBranchAddress("trackY"     , &trackY);
+  t->SetBranchAddress("trackZ"     , &trackZ);
+  t->SetBranchAddress("resRphi"    , &resRphi);
+  t->SetBranchAddress("trackRes"   , &trackRes);
+  t->SetBranchAddress("pointY"     , &pointY);
+  t->SetBranchAddress("pointZ"     , &pointZ);
+  t->SetBranchAddress("npTRD"      , &npTRD);
+  t->SetBranchAddress("event"      , &event);
+  
+  // make binning
+  TVectorD *vR   = MakeLinBinning(10,86.,250.);
+  TVectorD *vPhi = MakeLinBinning(18*8,0.,2*TMath::Pi());
+  TVectorD *vZ   = MakeLinBinning(50,-250.,250.);
+
+  const Int_t nbins=4;
+  Int_t bins[nbins]    = {vR->GetNrows()-1, vPhi->GetNrows()-1, vZ->GetNrows()-1, 80};
+//   Int_t bins[nbins]    = {16, 18*5, 50, 80};
+  Double_t xmin[nbins] = {86. , 0.,           -250., -2.};
+  Double_t xmax[nbins] = {250., 2*TMath::Pi(), 250.,  2.};
+  THnF *hn = new THnF("hn", "hn", nbins, bins, xmin, xmax);
+
+  hn->GetAxis(0)->Set(vR  ->GetNrows()-1, vR  ->GetMatrixArray());
+  hn->GetAxis(1)->Set(vPhi->GetNrows()-1, vPhi->GetMatrixArray());
+  hn->GetAxis(2)->Set(vZ  ->GetNrows()-1, vZ  ->GetMatrixArray());
+
+  hn->GetAxis(0)->SetNameTitle("r","r (cm)");
+  hn->GetAxis(1)->SetNameTitle("phi","#varphi");
+  hn->GetAxis(2)->SetNameTitle("z","z (cm)");
+  hn->GetAxis(3)->SetNameTitle("drphi","#Delta(r#varphi)");
+  
+  for (Int_t iev=0; iev<t->GetEntries(); ++iev) {
+    t->GetEntry(iev);
+    
+    // cuts
+    // -- on trd
+    if (npTRD<2) continue;
+    Double_t pt=1./TMath::Abs(soneOverPt);
+    if (pt<0.8) continue;
+    
+    Float_t resRphiRandom = resRphi*trackRes;
+    Float_t deviation     = pointY-(trackY+resRphiRandom);
+    
+    Double_t xx[4]={radius, trackPhi, trackZ ,deviation};
+    hn->Fill(xx);
+  }
+  
+  // do fits and fill tree
+  TTreeSRedirector stream(outFile.Data());
+  gROOT->cd();
+
+  DumpHn(hn, stream);
+
+  stream.GetFile()->cd();
+  hn->Write();
+  
+  delete hn;
+  delete vR;
+  delete vPhi;
+  delete vZ;
+}
+
+
+void AnaDeltaTree2(TString file/*, TString outDir="."*/)
+{
+  //
+  // NOTE: not finished
+  //
+  TFile f(file);
+  gROOT->cd();
+  TTree *t = (TTree*)f.Get("delta");
+  Float_t soneOverPt=0.;
+  Float_t radius=0.;
+  Float_t trackPhi=0.;
+  Float_t trackY=0.;
+  Float_t trackZ=0.;
+  Float_t resRphi=0.;
+  Float_t trackRes=0.;
+  Float_t pointY=0.;
+  Float_t pointZ=0.;
+  Float_t npTRD=0.;
+  Float_t event=0.;
+  
+  t->SetBranchAddress("soneOverPt" , &soneOverPt);
+  t->SetBranchAddress("r"          , &radius);
+  t->SetBranchAddress("trackPhi"   , &trackPhi);
+  t->SetBranchAddress("trackY"     , &trackY);
+  t->SetBranchAddress("trackZ"     , &trackZ);
+  t->SetBranchAddress("resRphi"    , &resRphi);
+  t->SetBranchAddress("trackRes"   , &trackRes);
+  t->SetBranchAddress("pointY"     , &pointY);
+  t->SetBranchAddress("pointZ"     , &pointZ);
+  t->SetBranchAddress("npTRD"      , &npTRD);
+  t->SetBranchAddress("event"      , &event);
+
+  // make binning
+  TVectorD *vZ   = MakeLinBinning(50,-250.,250.);
+  TVectorD *vPhi = MakeLinBinning(18*8,0.,TMath::Pi());
+  TVectorD *vR   = MakeLinBinning(16,86.,250.);
+
+  TObjArray arrZ(vZ->GetNrows()-1);
+  arrZ.SetOwner();
+  
+  for (Int_t iev=0; iev<t->GetEntries(); ++iev) {
+    t->GetEntry(iev);
+    
+    // cuts
+    // -- on trd
+    if (npTRD<2) continue;
+
+    Float_t resRphiRandom=resRphi*trackRes;
+
+    Int_t binZ   = TMath::BinarySearch(vZ->GetNrows(),vZ->GetMatrixArray(),(Double_t)trackZ);
+    Int_t binPhi = TMath::BinarySearch(vPhi->GetNrows(),vPhi->GetMatrixArray(),(Double_t)trackPhi);
+    Int_t binR   = TMath::BinarySearch(vR->GetNrows(),vR->GetMatrixArray(),(Double_t)radius);
+
+    if (binZ<0)   binZ=0;
+    if (binPhi<0) binPhi=0;
+    if (binR<0)   binR=0;
+
+    TObjArray *arrPhi=(TObjArray*)arrZ.UncheckedAt(binZ);
+    if (!arrPhi) {
+      arrPhi=new TObjArray(vPhi->GetNrows()-1);
+      arrZ.AddAt(arrPhi,binZ);
+    }
+
+    TObjArray *arrR=(TObjArray*)arrPhi->UncheckedAt(binPhi);
+    if (!arrR) {
+      arrR=new TObjArray(vR->GetNrows()-1);
+      arrPhi->AddAt(arrR,binPhi);
+    }
+
+    TH1S *h = (TH1S*)arrR->UncheckedAt(binR);
+    if (!h) {
+      h = new TH1S(Form("h_%02d_%02d_%d02",binZ, binPhi, binR),
+                   Form("z,phi,r: %02d,%02d,%d02; #Delta r#phi (cm)",binZ, binPhi, binR),
+                   80, -2., 2.);
+      arrR->AddAt(h, binR);
+    }
+
+    h->Fill(trackY+resRphiRandom-pointY);
+  }
+
+  // do fits and fill tree
+}
+
+void AnaDeltaResiduals(TString fluctuationMap, TString averageMap, TString outFile="deltas_residuals.root")
+{
+  //
+  //
+  //
+
+  TFile fFluct(fluctuationMap);
+  AliTPCCorrectionLookupTable *corrFluct = (AliTPCCorrectionLookupTable*)fFluct.Get("map");
+  fFluct.Close();
+  
+  TFile fAverage(averageMap);
+  AliTPCCorrectionLookupTable *corrAverage = (AliTPCCorrectionLookupTable*)fAverage.Get("map");
+  fAverage.Close();
+  
+//   TObjArray *arrMaps = new TObjArray(2);
+//   arrMaps->Add(corrAverage); // correction with the average Map
+//   arrMaps->Add(corrFluct);   // distortion with the fluctuation Map
+  
+  // create the composed correction
+  // if the weight are set to +1 and -1, the first map will be responsible for the distortions
+  // The second map for the corrections
+  // !!!!! In AliTPCComposedCorrection::GetDistortion MakeInverseIterator is called !!!!
+  // for this reason we have to add the maps in the wrong order
+  
+//   AliTPCComposedCorrection *residualDistortion = new AliTPCComposedCorrection(arrMaps, AliTPCComposedCorrection::kQueueResidual);
+  Float_t dummy=0;
+//   TVectorD weights(2);
+//   weights(0)=+1.;
+//   weights(1)=-AliToyMCEventGenerator::GetSCScalingFactor(corrFluct, corrAverage,dummy);
+//   residualDistortion->SetWeights(&weights);
+
+  corrAverage->SetCorrScaleFactor(AliToyMCEventGenerator::GetSCScalingFactor(corrFluct, corrAverage,dummy));
+
+  TVectorD *vR   = MakeLinBinning(10,86.,250.);
+  TVectorD *vPhi = MakeLinBinning(18*8,0.,2*TMath::Pi());
+  TVectorD *vZ   = MakeLinBinning(50,-250.,250.);
+  
+  const Int_t nbins=4;
+  Int_t bins[nbins]    = {vR->GetNrows()-1, vPhi->GetNrows()-1, vZ->GetNrows()-1, 80};
+  //   Int_t bins[nbins]    = {16, 18*5, 50, 80};
+  Double_t xmin[nbins] = {86. , 0.,           -250., -2.};
+  Double_t xmax[nbins] = {250., 2*TMath::Pi(), 250.,  2.};
+  THnF *hn = new THnF("hn", "hn", nbins, bins, xmin, xmax);
+  
+  hn->GetAxis(0)->Set(vR  ->GetNrows()-1, vR  ->GetMatrixArray());
+  hn->GetAxis(1)->Set(vPhi->GetNrows()-1, vPhi->GetMatrixArray());
+  hn->GetAxis(2)->Set(vZ  ->GetNrows()-1, vZ  ->GetMatrixArray());
+  
+  AliExternalTrackParam vv;
+  
+  for (Float_t iz=-245; iz<=245; iz+=2) {
+    Short_t roc=(iz>=0)?0:18;
+    for (Float_t ir=86; ir<250; ir+=1) {
+      for (Float_t iphi=0; iphi<TMath::TwoPi(); iphi+=0.5*TMath::DegToRad()){
+        Float_t x=ir*(Float_t)TMath::Cos(iphi);
+        Float_t y=ir*(Float_t)TMath::Sin(iphi);
+        Float_t x3[3]    = {x,y,iz};
+        Float_t x3dc[3]    = {x,y,iz};
+        Float_t dx3[3]   = {0.,0.,0.};
+//         residualDistortion->GetDistortion(x3,roc,dx3);
+        corrFluct->DistortPoint(x3dc,roc);
+        corrAverage->CorrectPoint(x3dc,roc);
+        dx3[0]=x3dc[0]-x3[0];
+        dx3[1]=x3dc[1]-x3[1];
+        dx3[2]=x3dc[2]-x3[2];
+        
+        Double_t ddx3[3]={dx3[0], dx3[1], dx3[2]};
+        vv.Global2LocalPosition(ddx3,iphi);
+
+        Double_t xx[4]={ir, iphi, iz ,ddx3[1]};
+        hn->Fill(xx);
+        
+      }
+    }
+  }
+
+  TTreeSRedirector stream(outFile.Data());
+  gROOT->cd();
+  
+  DumpHn(hn, stream);
+  
+  stream.GetFile()->cd();
+  hn->Write();
+  
+  delete hn;
+  delete vR;
+  delete vPhi;
+  delete vZ;
+  
+//   delete residualDistortion;
+}
+
+void DumpHn(THn *hn, TTreeSRedirector &stream)
+{
+  TAxis *ar   = hn->GetAxis(0);
+  TAxis *aphi = hn->GetAxis(1);
+  TAxis *az   = hn->GetAxis(2);
+
+  // output Hn
+  const Int_t nbins=3;
+  Int_t bins[nbins]    = {1,1,1};
+  Double_t xmin[nbins] = {0.,0.,0.};
+  Double_t xmax[nbins] = {1.,1.,1.};
+  THnF hnRes("hnRes", "hnRes", nbins, bins, xmin, xmax);
+
+  ar  ->Copy(*hnRes.GetAxis(0));
+  aphi->Copy(*hnRes.GetAxis(1));
+  az  ->Copy(*hnRes.GetAxis(2));
+  
+  
+  for (Int_t iz=0; iz<az->GetNbins(); ++iz) {
+    az->SetRange(iz+1,iz+1);
+    TObjArray arrFits;
+    arrFits.SetName(Form("z_%02d",iz));
+    arrFits.SetOwner();
+    
+    for (Int_t ir=0; ir<ar->GetNbins(); ++ir) {
+      ar->SetRange(ir+1,ir+1);
+      for (Int_t iphi=0; iphi<aphi->GetNbins(); ++iphi) {
+        aphi->SetRange(iphi+1,iphi+1);
+
+        Float_t cr       = 0.;
+        Float_t cphi     = 0.;
+        Float_t cz       = 0.;
+        Float_t mean     = 0.;
+        Float_t meanErr  = 0.;
+        Float_t sigma    = 0.;
+        Float_t sigmaErr = 0.;
+        Int_t   entries  = 0.;
+        Float_t chi2ndf  = 0.;
+        Float_t mean2    = 0.;
+        Float_t meanErr2 = 0.;
+        Float_t rms2     = 0.;
+        Float_t rmsErr2  = 0.;
+        
+        TH1 *hProj = hn->Projection(3);
+        if (hProj->GetEntries()>1) {
+          TF1 fg("fg","gaus",-2,2);
+          cr   = ar->GetBinCenter(ir+1);
+          cphi = aphi->GetBinCenter(iphi+1);
+          cz   = az->GetBinCenter(iz+1);
+          hProj->SetNameTitle(Form("h_%02d_%02d_%02d",iz, iphi, ir),
+          Form("z,phi,r: %02d,%02d,%02d (%.2f, %.2f, %.2f)",iz,iphi,ir, cz, cphi, cr )
+          );
+          hProj->Fit(&fg,"LMQR");
+          arrFits.Add(hProj);
+
+          mean     = fg.GetParameter(1);
+          meanErr  = fg.GetParError(1);
+          sigma    = fg.GetParameter(2);
+          sigmaErr = fg.GetParError(2);
+          entries  = hProj->GetEntries();
+          chi2ndf  = fg.GetChisquare()/fg.GetNDF();
+          mean2    = hProj->GetMean();
+          meanErr2 = hProj->GetMeanError();
+          rms2     = hProj->GetRMS();
+          rmsErr2  = hProj->GetRMSError();
+        } else {
+          delete hProj;
+        }
+        
+        stream << "d" <<
+        "ir="          << ir       <<
+        "iphi="        << iphi     <<
+        "iz="          << iz       <<
+        "cr="          << cr       <<
+        "cphi="        << cphi     <<
+        "cz="          << cz       <<
+        "mean="        << mean     <<
+        "meanErr="     << meanErr  <<
+        "sigma="       << sigma    <<
+        "sigmaErr="    << sigmaErr <<
+        "histMean="    << mean2    <<
+        "histMeanErr=" << meanErr2 <<
+        "histRMS="     << rms2    <<
+        "histRMSErr="  << rmsErr2 <<
+        "entries="     << entries  <<
+        "chi2ndf="     << chi2ndf  <<
+        "\n";
+
+//        Double_t x[nbins]={cr, cphi, cz};
+//        if (meanErr<0.3) hnRes.Fill(x,mean);
+      }
+    }
+    stream.GetFile()->cd();
+    arrFits.Write(0x0,TObject::kSingleKey);
+    gROOT->cd();
+  }
+
+  stream.GetFile()->cd();
+  hnRes.Write();
+  gROOT->cd();
+}
+
+//______________________________________________________________________________
+TVectorD* MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax)
+{
+  //
+  // Make logarithmic binning
+  // the user has to delete the array afterwards!!!
+  //
+  
+  //check limits
+  if (xmin<1e-20 || xmax<1e-20){
+    printf("For Log binning xmin and xmax must be > 1e-20. Using linear binning instead!");
+    return MakeLinBinning(nbinsX, xmin, xmax);
+  }
+  if (xmax<xmin){
+    Double_t tmp=xmin;
+    xmin=xmax;
+    xmax=tmp;
+  }
+  TVectorD *binLim=new TVectorD(nbinsX+1);
+  Double_t first=xmin;
+  Double_t last=xmax;
+  Double_t expMax=TMath::Log(last/first);
+  for (Int_t i=0; i<nbinsX+1; ++i){
+    (*binLim)[i]=first*TMath::Exp(expMax/nbinsX*(Double_t)i);
+  }
+  return binLim;
+}
+
+//______________________________________________________________________________
+TVectorD* MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax)
+{
+  //
+  // Make linear binning
+  // the user has to delete the array afterwards!!!
+  //
+  if (xmax<xmin){
+    Double_t tmp=xmin;
+    xmin=xmax;
+    xmax=tmp;
+  }
+  TVectorD *binLim=new TVectorD(nbinsX+1);
+  Double_t first=xmin;
+  Double_t last=xmax;
+  Double_t binWidth=(last-first)/nbinsX;
+  for (Int_t i=0; i<nbinsX+1; ++i){
+    (*binLim)[i]=first+binWidth*(Double_t)i;
+  }
+  return binLim;
+}
+
+//_____________________________________________________________________________
+TVectorD* MakeArbitraryBinning(const char* bins)
+{
+  //
+  // Make arbitrary binning, bins separated by a ','
+  //
+  TString limits(bins);
+  if (limits.IsNull()){
+    printf("Bin Limit string is empty, cannot add the variable");
+    return 0x0;
+  }
+  
+  TObjArray *arr=limits.Tokenize(",");
+  Int_t nLimits=arr->GetEntries();
+  if (nLimits<2){
+    printf("Need at leas 2 bin limits, cannot add the variable");
+    delete arr;
+    return 0x0;
+  }
+  
+  TVectorD *binLimits=new TVectorD(nLimits);
+  for (Int_t iLim=0; iLim<nLimits; ++iLim){
+    (*binLimits)[iLim]=(static_cast<TObjString*>(arr->At(iLim)))->GetString().Atof();
+  }
+  
+  delete arr;
+  return binLimits;
+}
+
+void PlotFromTree(TTree *d, TString outDir=".")
+{
+  TCanvas *c=new TCanvas;
+  gStyle->SetOptStat(0);
+  d->SetMarkerStyle(20);
+  d->SetMarkerSize(1);
+  
+  TProfile2D pRZ("pRZ",";z (cm); r(cm)",50,-250,250,10,85,250);
+  d->Draw("entries:cr:cz>>pRZ","","profcolz");
+  pRZ.GetZaxis()->UnZoom();
+  c->SaveAs(Form("%s/entries_average.png",outDir.Data()));
+  d->Draw("entries:cr:cz>>pRZ","iphi==2","profcolz");
+  c->SaveAs(Form("%s/entries_onePhi.png",outDir.Data()));
+  
+  pRZ.SetMaximum(0.04);
+  d->Draw("meanErr:cr:cz>>pRZ","","profcolz");
+  c->SaveAs(Form("%s/meanErr_average.png",outDir.Data()));
+  d->Draw("meanErr:cr:cz>>pRZ","iphi==2","profcolz");
+  c->SaveAs(Form("%s/meanErr_onePhi.png",outDir.Data()));
+  
+  
+  d->Draw("mean:cphi:cr","iz==25","colz");
+  c->SaveAs(Form("%s/mean_oneZ_phi_allR.png",outDir.Data()));
+  d->Draw("mean:meanErr:cphi","iz==25&&ir==2","goff");
+  TGraphErrors *grmean_phi=new TGraphErrors(d->GetSelectedRows(),d->GetV3(),d->GetV1(),0,d->GetV2());
+  grmean_phi->SetTitle(";#varphi;#LT#Delta r#varphi#GT");
+  grmean_phi->SetMarkerStyle(20);
+  grmean_phi->SetMarkerSize(1);
+  grmean_phi->Draw("ap");
+  c->SaveAs(Form("%s/mean_oneZ_phi_oneR.png",outDir.Data()));
+  
+  d->Draw("mean:cr:cphi","iz==25","colz");
+  c->SaveAs(Form("%s/mean_oneZ_r_allPhi.png",outDir.Data()));
+  
+  d->Draw("mean:meanErr:cr","iz==25&&iphi==2","goff");
+  TGraphErrors *grmean_r=new TGraphErrors(d->GetSelectedRows(),d->GetV3(),d->GetV1(),0,d->GetV2());
+  grmean_r->SetTitle(";r (cm);#LT#Delta r#varphi#GT");
+  grmean_r->SetMarkerStyle(20);
+  grmean_r->SetMarkerSize(1);
+  grmean_r->Draw("ap");
+  c->SaveAs(Form("%s/mean_oneZ_r_onePhi.png",outDir.Data()));
+  
+  
+  d->Draw("meanErr:cphi:cr","iz==25","colz");
+  c->SaveAs(Form("%s/meanErr_oneZ_phi_allR.png",outDir.Data()));
+  d->Draw("meanErr:cphi","iz==25&&ir==2");
+  c->SaveAs(Form("%s/meanErr_oneZ_phi_oneR.png",outDir.Data()));
+  
+  d->Draw("meanErr:cr:cphi","iz==25","colz");
+  c->SaveAs(Form("%s/meanErr_oneZ_r_allPhi.png",outDir.Data()));
+  
+  d->Draw("meanErr:cr","iz==25&&iphi==2");
+  c->SaveAs(Form("%s/meanErr_oneZ_r_onePhi.png",outDir.Data()));
+  
+}
+
+
diff --git a/TPC/Upgrade/macros/AnaEpsScan.C b/TPC/Upgrade/macros/AnaEpsScan.C
new file mode 100644 (file)
index 0000000..c282dc0
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+
+.L $ALICE_ROOT/TPC/Upgrade/macros/AnaEpsScan.C
+AnaEpsScan();
+
+*/
+
+void AnaEpsScan(TString dir=".",TString baseFile="0.0_1_2_130_10", Float_t nSigmas=3.)
+{
+  gStyle->SetOptTitle(0);
+  gStyle->SetOptStat(0);
+  gStyle->SetPadGridX(0);
+  gStyle->SetPadGridY(0);
+  gStyle->SetPadTopMargin(0.05);
+  gStyle->SetPadRightMargin(0.025);
+  gStyle->SetPadTickX(1);
+  gStyle->SetPadTickY(1);
+  
+  TString files=gSystem->GetFromPipe( Form("ls %s/eps*/*%s*.root", dir.Data(), baseFile.Data() ) );
+  TObjArray *arr=files.Tokenize("\n");
+
+  TGraph *grFrac01=new TGraph;
+  TGraph *grFrac05=new TGraph;
+  TGraph *grFrac10=new TGraph;
+
+  grFrac01->SetNameTitle("grFrac01",";#varepsilon;fraction of tracks");
+  grFrac01->SetMarkerStyle(20);
+  grFrac01->SetMarkerSize(1);
+
+//   grFrac05->SetNameTitle("grFrac05",";#varepsilon;fraction of tracks");
+  grFrac05->SetLineColor(kBlue);
+  grFrac05->SetMarkerColor(kBlue);
+  grFrac05->SetMarkerStyle(21);
+  grFrac05->SetMarkerSize(1);
+  
+  grFrac10->SetLineColor(kRed);
+  grFrac10->SetMarkerColor(kRed);
+  grFrac10->SetMarkerStyle(22);
+  grFrac10->SetMarkerSize(1);
+  
+  Int_t colors[7]={kBlack, kRed, kBlue, kGreen, kMagenta, kCyan, kYellow};
+  Int_t markers[7]={20,21,22,23,24,25,26};
+  
+  TObjArray arrHists;
+  for (Int_t ifile=0; ifile<arr->GetEntriesFast(); ++ifile) {
+    TString file=arr->At(ifile)->GetName();
+    TString epsilon=gSystem->GetFromPipe(Form("echo %s | sed 's|.*/eps\\([0-9][0-9]\\)/.*|\\1|'",file.Data()));
+
+    printf("%s: %s\n", file.Data(), epsilon.Data());
+    TH1F *h=new TH1F(Form("hResY%.0f_%s",10*nSigmas, epsilon.Data()), Form("#varepsilon %d;fraction of clusters more than %.1f#sigma from track;#tracks", nSigmas, epsilon.Atoi()),200,0,1);
+    h->SetLineColor(colors[ifile]);
+    h->SetMarkerColor(colors[ifile]);
+    h->SetMarkerStyle(colors[ifile]);
+
+    arrHists.Add(h);
+
+    TFile f(file);
+    gROOT->cd();
+    TTree *t=(TTree*)f.Get("Tracks");
+//     Float_t clFracY30=0.;
+
+//     t->SetBranchStatus("*",0);
+//     t->SetBranchStatus("clFracY30",1);
+//     t->SetBranchAddress("clFracY30",&clFracY30);
+
+    t->Draw(Form("clFracY%.0f>>hResY%.0f_%s",10*nSigmas,10*nSigmas,epsilon.Data()),"","goff");
+
+    printf("entries: %d %d %d\n", grFrac05->GetN(), h->GetEntries(), t->GetEntries());
+
+    Double_t frac01 = h->Integral(h->FindBin(.02),h->GetNbinsX())/h->GetEntries();
+    Double_t frac05 = h->Integral(h->FindBin(.05),h->GetNbinsX())/h->GetEntries();
+    Double_t frac10 = h->Integral(h->FindBin(.10),h->GetNbinsX())/h->GetEntries();
+
+    grFrac01->SetPoint(grFrac01->GetN(), epsilon.Atoi(), frac01);
+    grFrac05->SetPoint(grFrac05->GetN(), epsilon.Atoi(), frac05);
+    grFrac10->SetPoint(grFrac10->GetN(), epsilon.Atoi(), frac10);
+
+    delete t;
+    f.Close();
+  }
+
+  TCanvas *c1=new TCanvas("c1");
+  c1->cd();
+  gPad->SetLogy();
+
+  TLegend *leg = new TLegend(.7,.3,.9,.9);
+  leg->SetBorderSize(1);
+  leg->SetFillColor(10);
+  
+  for (Int_t ihist=0; ihist<arrHists.GetEntriesFast();++ihist) {
+    TH1F *h=(TH1F*)arrHists.At(ihist);
+    h->Draw((ihist==0)?"":"same");
+    leg->AddEntry(h,h->GetTitle(),"lp");
+  }
+  leg->Draw("same");
+
+  c1->SaveAs(Form("~/tmp/epsScan_clFrac_%.0fsigma.png",10*nSigmas));
+  c1->SaveAs(Form("~/tmp/epsScan_clFrac_%.0fsigma.eps",10*nSigmas));
+  
+  TCanvas *c2=new TCanvas("c2");
+  c2->cd();
+  
+  TLegend *leg2 = new TLegend(.1,.75,.6,.95);
+  leg2->SetBorderSize(1);
+  leg2->SetFillColor(10);
+
+  TH1F *hDummy = new TH1F("hDummy",";#varepsilon;fraction of tracks",100,0,42.5);
+  hDummy->SetMinimum(0);
+  hDummy->SetMaximum(.21);
+  hDummy->GetYaxis()->SetTitleOffset(1.2);
+  hDummy->Draw();
+  grFrac01->Draw("lp");
+  grFrac05->Draw("lp");
+  grFrac10->Draw("lp");
+
+  //leg2->AddEntry(grFrac01,Form("%.1f#sigma deviation >2%%",nSigmas),"lp");
+  //leg2->AddEntry(grFrac05,Form("%.1f#sigma deviation >5%%",nSigmas),"lp");
+  //leg2->AddEntry(grFrac10,Form("%.1f#sigma deviation >10%%",nSigmas),"lp");
+  leg2->AddEntry(grFrac01,"fraction of deviating clusters >2%","lp");
+  leg2->AddEntry(grFrac05,"fraction of deviating clusters >5%","lp");
+  leg2->AddEntry(grFrac10,"fraction of deviating clusters >10%","lp");
+  TLatex l;
+  l.DrawLatex(3,.14,Form("cluster deviation > %.1f#sigma",nSigmas));
+  leg2->Draw("same");
+  c2->SaveAs(Form("~/tmp/epsScan_trFrac_eps_%.0fsigma.png",10*nSigmas));
+  c2->SaveAs(Form("~/tmp/epsScan_trFrac_eps_%.0fsigma.eps",10*nSigmas));
+}
+
index 513310018d37d8413eee5980d257077baaf98c47..3058b82c3724c38c1580f6a857c1cd6a85a99dd7 100644 (file)
@@ -8,23 +8,55 @@
 #include "TSystem.h"
 #include "TStyle.h"
 #include "AliTPCCorrection.h"
+#include "AliTPCCorrectionLookupTable.h"
+#include <AliToyMCEventGenerator.h>
+
+
 
 void makeComparisonTree(TString filename, TString addToName)
 {
+  
+  AliTPCCorrectionLookupTable *fTPCCorrection2=0x0;
+
+  Bool_t doScaling=kTRUE;
+  if (filename.Contains(":")) {
+    TObjArray *arr=filename.Tokenize(":");
+    TString s2(arr->At(1)->GetName());
+    if (s2.Contains("-scale")) {
+      doScaling=kFALSE;
+      s2.ReplaceAll("-scale","");
+    }
+    TFile f2(s2);
+    gROOT->cd();
+    fTPCCorrection2=(AliTPCCorrectionLookupTable*)f2.Get("map");
+    f2.Close();
+    filename=arr->At(0)->GetName();
+    delete arr;
+  }
   TFile fn(filename.Data());
   gROOT->cd();
-  AliTPCCorrection *fTPCCorrection=(AliTPCCorrection*)fn.Get("map");
+  AliTPCCorrectionLookupTable *fTPCCorrection=(AliTPCCorrectionLookupTable*)fn.Get("map");
   fn.Close();
+  if (fTPCCorrection2 && doScaling) {
+    Float_t dummy=0;
+    fTPCCorrection2->SetCorrScaleFactor(AliToyMCEventGenerator::GetSCScalingFactor(fTPCCorrection, fTPCCorrection2,dummy));
+    
+  }
+//   fTPCCorrection->BuildExactInverse();
 
+//   TFile f("/tmp/corrTest.Root","recreate");
+//   fTPCCorrection->Write("map");
+//   f.Close();
+  
   TString outFile=addToName;
   outFile.Append(".root");
   TTreeSRedirector *sred=new TTreeSRedirector(outFile.Data());
   
   Float_t dx[3]={0,0,0};
   
-  for (Float_t iz=-240; iz<=240; iz+=20) {
+  for (Float_t iz=-245; iz<=245; iz+=10) {
     Short_t roc=(iz>=0)?0:18;
-    for (Float_t ir=86; ir<250; ir+=20) {
+    for (Float_t ir=86; ir<250; ir+=10) {
       for (Float_t iphi=0; iphi<TMath::TwoPi(); iphi+=10*TMath::DegToRad()){
         Float_t x=ir*(Float_t)TMath::Cos(iphi);
         Float_t y=ir*(Float_t)TMath::Sin(iphi);
@@ -53,8 +85,12 @@ void makeComparisonTree(TString filename, TString addToName)
         
         // correct back distorted point
         Float_t xd3[3]={xd,yd,zd};
-        
-        fTPCCorrection->GetCorrection(xd3,roc,dx);
+
+        if (fTPCCorrection2) {
+          fTPCCorrection2->GetCorrection(xd3,roc,dx);
+        } else {
+          fTPCCorrection->GetCorrection(xd3,roc,dx);
+        }
         Float_t xdc   = xd+dx[0];
         Float_t ydc   = yd+dx[1];
         Float_t zdc   = zd+dx[2];
@@ -87,13 +123,35 @@ void makeAllComparisonTrees()
   makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps20_50kHz_precal.lookup.root","LUT_20");
 }
 
+void makeAllComparisonTreesNew()
+{
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2N2_eps5_50kHz_precal.lookup.root","LUT_05");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2N2_eps10_50kHz_precal.lookup.root","LUT_10");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_20");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_25");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_30");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_35");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_40");
+}
+
+void makeAllComparisonTreesOld()
+{
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/old/SC_NeCO2N2_eps5_50kHz_precal.lookup.root","LUT_05");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/old/SC_NeCO2N2_eps10_50kHz_precal.lookup.root","LUT_10");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/old/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_20");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/old/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_25");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/old/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_30");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/old/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_35");
+  makeComparisonTree("$ALICE_ROOT/TPC/Calib/maps/old/SC_NeCO2N2_eps20_50kHz_precal.lookup.root","LUT_40");
+}
+
 TCanvas *GetCanvas(TString addToName);
 
 void makeHistos(TString addToName) {
-  TString fileName; //("test_");
-  fileName.Append(addToName.Data());
-  fileName.Append(".root");
-  TFile f(fileName.Data());
+  TString filename; //("test_");
+  filename.Append(addToName.Data());
+  filename.Append(".root");
+  TFile f(filename.Data());
   gROOT->cd();
   TTree *t=(TTree*)f.Get("t");
   gStyle->SetTitleX(0.18);
@@ -112,21 +170,42 @@ void makeHistos(TString addToName) {
   c->SaveAs(Form("%s_rRes.png",addToName.Data()));
   //
   c=GetCanvas(addToName+"_phiRes");
-  t->Draw("phidc-phi:z:r","abs(phidc-phi)<1","colz");
+  t->SetAlias("phiFix","-((phidc-phi)>4)*2*TMath::Pi()+((phidc-phi)<-4)*2*TMath::Pi()");
+  t->Draw("phidc-phi+phiFix:z:r","","colz");
   c->SaveAs(Form("%s_phiRes.png",addToName.Data()));
   //
   c=GetCanvas(addToName+"_rphiRes");
   t->Draw("(phidc*rdc)-(phi*r):z+(r-84)/(254-84)*18:r","abs(phidc-phi)<1","colz");
   c->SaveAs(Form("%s_rphiRes.png",addToName.Data()));
 
+  TCanvas *c2=0x0;
+  c2=GetCanvas(addToName+"_Res_1D");
+  c2->Divide(2,2);
+  
+  c2->cd(1);
+  t->Draw("zdc-z","","");
+  //
+  c2->cd(2);
+  t->Draw("rdc-r","","");
+  //
+  c2->cd(3);
+  t->SetAlias("phiFix","-((phidc-phi)>4)*2*TMath::Pi()+((phidc-phi)<-4)*2*TMath::Pi()");
+  t->SetAlias("phiRes","phidc-phi+phiFix");
+  t->Draw("phiRes","","");
+  //
+  c2->cd(4);
+  t->Draw("(phidc*rdc)-(phi*r)","abs(phidc-phi)<1","");
+
+  c2->SaveAs(Form("%s_Res_1D.png",addToName.Data()));
+  
   f.Close();
 }
 
 void makeHistosDist(TString addToName) {
-  TString fileName; //("test_");
-  fileName.Append(addToName.Data());
-  fileName.Append(".root");
-  TFile f(fileName.Data());
+  TString filename; //("test_");
+  filename.Append(addToName.Data());
+  filename.Append(".root");
+  TFile f(filename.Data());
   gROOT->cd();
   TTree *t=(TTree*)f.Get("t");
   gStyle->SetTitleX(0.18);
@@ -160,13 +239,21 @@ void makeAllHistos() {
   makeHistos("LUT_05");
   makeHistos("LUT_10");
   makeHistos("LUT_20");
-
+  makeHistos("LUT_25");
+  makeHistos("LUT_30");
+  makeHistos("LUT_35");
+  makeHistos("LUT_40");
+  
 }
 
 void makeAllHistosDist() {
   makeHistosDist("LUT_05");
   makeHistosDist("LUT_10");
   makeHistosDist("LUT_20");
+  makeHistosDist("LUT_25");
+  makeHistosDist("LUT_30");
+  makeHistosDist("LUT_35");
+  makeHistosDist("LUT_40");
   
 }
 
diff --git a/TPC/Upgrade/macros/GetComposedResidualDistortion.C b/TPC/Upgrade/macros/GetComposedResidualDistortion.C
new file mode 100644 (file)
index 0000000..df0e234
--- /dev/null
@@ -0,0 +1,67 @@
+#include <TString.h>
+#include <TVectorD.h>
+#include <TObjArray.h>
+#include <TFile.h>
+
+#include <AliTPCComposedCorrection.h>
+#include <AliTPCCorrectionLookupTable.h>
+
+#include <AliToyMCEventGenerator.h>
+
+
+AliTPCComposedCorrection* GetComposedResidualDistortion(TString fluctuationMap, TString averageMap, Bool_t rescale=kTRUE)
+{
+  //
+  //
+  //
+
+
+  TFile fFluct(fluctuationMap);
+  AliTPCCorrectionLookupTable *corrFluct = (AliTPCCorrectionLookupTable*)fFluct.Get("map");
+  fFluct.Close();
+
+  TFile fAverage(averageMap);
+  AliTPCCorrectionLookupTable *corrAverage = (AliTPCCorrectionLookupTable*)fAverage.Get("map");
+  fAverage.Close();
+
+  TObjArray *arrMaps = new TObjArray(2);
+  // !!!!! In AliTPCComposedCorrection::GetDistortion MakeInverseIterator is called !!!!
+  // for this reason we have to add the maps in the wrong order
+  
+  arrMaps->Add(corrAverage); // correction with the average Map
+  arrMaps->Add(corrFluct);   // distortion with the fluctuation Map
+
+  // create the composed correction
+  // if the weight are set to +1 and -1, the first map will be responsible for the distortions
+  // The second map for the corrections
+  AliTPCComposedCorrection *residualDistortion = new AliTPCComposedCorrection(arrMaps, AliTPCComposedCorrection::kQueueResidual);
+  TVectorD weights(2);
+  weights(0)=+1.;
+  weights(1)=-1.;
+  if (rescale) {
+    Float_t dummy=0;
+    weights(1)=-AliToyMCEventGenerator::GetSCScalingFactor(corrFluct, corrAverage,dummy);
+  }
+  residualDistortion->SetWeights(&weights);
+
+  return residualDistortion;
+}
+
+AliTPCCorrectionLookupTable* GetResidualTable(TString fluctuationMap, TString averageMap, Bool_t rescale=kTRUE)
+{
+  TFile fFluct(fluctuationMap);
+  AliTPCCorrectionLookupTable *corrFluct = (AliTPCCorrectionLookupTable*)fFluct.Get("map");
+  fFluct.Close();
+  
+  TFile fAverage(averageMap);
+  AliTPCCorrectionLookupTable *corrAverage = (AliTPCCorrectionLookupTable*)fAverage.Get("map");
+  fAverage.Close();
+
+  Double_t scale=AliToyMCEventGenerator::GetSCScalingFactor(corrFluct, corrAverage,dummy);
+
+  corrAverage->SetCorrScaleFactor(scale);
+
+  AliTPCCorrectionLookupTable *tab=new AliTPCCorrectionLookupTable;
+  tab->CreateResidual(corrFluct, corrAverage);
+  
+}
\ No newline at end of file
diff --git a/TPC/Upgrade/macros/NimStyle.C b/TPC/Upgrade/macros/NimStyle.C
new file mode 100644 (file)
index 0000000..bbef977
--- /dev/null
@@ -0,0 +1,38 @@
+Int_t kmicolors[10]={1,2,3,4,6,7,8,9,10,11};
+Int_t kmimarkers[10]={21,22,23,24,25,26,27,28,29,30};
+
+
+void NimStyle(){
+  TStyle *stNimTPC = new TStyle("tpcNimStyle","tpcNimStyle");
+  gROOT->GetStyle("Plain")->Copy((*stNimTPC));
+  Int_t nimTPCFont=22; //or 62 for sans serif font
+  //default definitions
+  stNimTPC->SetTextFont(nimTPCFont);
+  stNimTPC->SetTitleFont(nimTPCFont, "T");
+  stNimTPC->SetTitleFont(nimTPCFont, "XYZ");
+  stNimTPC->SetLabelFont(nimTPCFont,"XYZ");
+  stNimTPC->SetStatFont(nimTPCFont);
+  stNimTPC->SetOptTitle(0);
+  stNimTPC->SetNumberContours(50);
+  stNimTPC->SetPalette(1,0);
+  stNimTPC->SetStatBorderSize(1);
+  new TColor(101,1,1,1);
+  stNimTPC->SetFillColor(101);
+  if (nimTPCFont==22){
+    stNimTPC->SetLabelSize(0.045,"XYZ");
+    stNimTPC->SetTitleSize(0.05,"XYZ");
+    stNimTPC->SetTitleOffset(0.92,"XYZ");
+  }
+  //depending on taste
+  stNimTPC->SetTitleX(0.1);
+  stNimTPC->SetTitleW(0.8);
+  stNimTPC->SetTitleH(0.08);
+  stNimTPC->SetStatX(.9);
+  stNimTPC->SetStatY(.9);
+  stNimTPC->SetOptStat(1100);
+  stNimTPC->cd();
+  //
+  //
+}
+
+
diff --git a/TPC/Upgrade/macros/createSCprecal.C b/TPC/Upgrade/macros/createSCprecal.C
new file mode 100644 (file)
index 0000000..60fc4b1
--- /dev/null
@@ -0,0 +1,26 @@
+void createSCprecal(TString input, Int_t gas=1)
+{
+  AliTPCSpaceCharge3D *spaceCharge = new AliTPCSpaceCharge3D;
+  spaceCharge->SetSCDataFileName(input.Data());
+  
+  const Int_t nOmegaTau = 5;
+  Double_t omegaTau[nOmegaTau] = {0.34, 0.32, 0.43, 1.77, 1.84};
+  Double_t T1[nOmegaTau]       = {1.00, 1.00, 0.99, 0.41, 0.41};
+  Double_t T2[nOmegaTau]       = {1.01, 0.99, 1.03, 0.70, 0.70};
+  
+  TString tGas[nOmegaTau] = {"NeCO2","NeCO2_2","ArCO2","NeCF4","NeCF4_2"}; // CF4 is the same as CO2 here, but different omegaTau
+  TString sGas[nOmegaTau] = {"Ne-CO_{2} (90-10)","Ne-CO_{2}-N_{2} (90-10-5)","Ar-CO_{2} (90-10)","Ne-CF_{4} (90-10)","Ne-CF_{4} (80-20)"};
+
+  spaceCharge->SetOmegaTauT1T2(omegaTau[gas], T1[gas] , T2[gas]);
+  spaceCharge->InitSpaceCharge3DDistortion();
+
+  TString outName=input;
+  outName.ReplaceAll(".root","_precal.root");
+
+  TFile fout(outName,"recreate");
+  spaceCharge->Write("map");
+  fout.Write();
+  fout.Close();
+
+  delete spaceCharge;
+}
diff --git a/TPC/Upgrade/macros/fastToyMCMI.C b/TPC/Upgrade/macros/fastToyMCMI.C
new file mode 100644 (file)
index 0000000..2f22546
--- /dev/null
@@ -0,0 +1,546 @@
+/*
+  Fast toy MC for different purposes. primary goal prepare the motivation figures for the TPC TDR and
+  expalantion internal note.
+  
+  testExtrapolationError() - to show track extrapolation errror
+  testdEdxGEM();  -to show the dEdx respolution detoriation as function of the electron trasnparency
+
+  .x $HOME/NimStyle.C
+  .L $ALICE_ROOT/TPC/Upgrade/macros/fastToyMCMI.C+
+*/
+#include "TStyle.h"
+#include "TCut.h"
+#include "TCanvas.h"
+#include "TMath.h"
+#include "TVectorD.h"
+#include "TLinearFitter.h"
+#include "TGeoGlobalMagField.h"
+#include "TRandom.h"
+#include "TGraphErrors.h"
+#include "TStatToolkit.h"
+
+#include "TTreeStream.h"
+#include "AliExternalTrackParam.h"
+#include "AliCDBManager.h"
+#include "AliMagF.h"
+#include "AliTrackerBase.h"
+#include "TAxis.h"
+#include "TLegend.h"
+#include "AliGeomManager.h"
+#include "TCut.h"
+#include "TCanvas.h"
+#include "TH2.h"
+#include "TF1.h"
+#include "TStyle.h"
+
+
+
+void testdEdxGEM(const Int_t ntracks=10000, Double_t clNoise=2, Double_t corrNoiseAdd=0.15, Double_t sigmaLandau=0.26);
+void testExtrapolationError(Int_t ntracks, Int_t useGeo=kFALSE, Int_t seed=0);
+
+
+void fastToyMCMI(Int_t action=1, Float_t arg0=200, Float_t arg1=0, Float_t arg2=0){
+  //
+  //
+  //
+  if (action==1)  testExtrapolationError(arg0,arg1,arg2); 
+}
+
+
+void testdEdxGEM(const Int_t ntracks, Double_t clNoise, Double_t corrNoiseAdd, Double_t sigmaLandau){
+  //
+  // test dEdx performance as function of the electron transparency.
+  //
+  // For simulation standard gRandom->Landau() generator with mean 15 is used
+  // Charge between pad-rows are corelated via diffusion - qm = (0.15*q-1+0.7*q0+0.15*q1)
+  // Electrons are randomly absorbed dependending on the transparency parameter
+  // 
+  // Parameters:
+  //   clNoise       - noise integrated by cluster (snoise~1 x 4 bins ~ 2)
+  //   corrNoiseAdd  - additional correlated noise to be added
+  //   sigmaLandau   - relative sigma of Landau distirbution
+  // Setup emulation
+  //   pp   setup testdEdxGEM(20000,2,0.15,0.26)
+  //   PbPb setup testdEdxGEM(20000,4,0.5,0.26)
+  //   PbPb setup testdEdxGEM(20000,4,0.6,0.26)
+  //   PbPb setup testdEdxGEM(20000,4,0.7,0.26)
+  // 
+  TTreeSRedirector *pcstream = new TTreeSRedirector("testdEdxResolution.root","update");
+  TH2F * phisdEdx = (TH2F*)pcstream->GetFile()->Get("hisdEdx");
+  if (!phisdEdx){
+
+    TVectorD qVector(160);
+    TVectorD qVectorCorr(160);
+    TVectorD qVectorAcc(160);
+    TVectorD qVectorSorted(160);
+    Int_t indexes[160];
+    Int_t ntrans=20;
+    TVectorD vecdEdx(ntrans);
+    TVectorD vecT(ntrans);
+    //
+    
+    for (Int_t itrack=0; itrack<ntracks; itrack++){
+      Double_t meanEl=15*(1.+1*gRandom->Rndm());
+      Double_t sigmaEl=sigmaLandau*meanEl*TMath::Power(15./meanEl,0.25);
+      for (Int_t irow=0; irow<160; irow++){
+       qVector[irow]=gRandom->Landau(meanEl, sigmaEl);      
+      }
+      qVectorCorr[0]=qVector[0];
+      qVectorCorr[158]=qVector[158];
+      for (Int_t irow=1; irow<159; irow++){  //corralte measurement via diffusion
+       qVectorCorr[irow]= 0.15*(qVector[irow-1]+ qVector[irow+1])+0.7*qVector[irow];
+      }
+      
+      for (Int_t itrans=0; itrans<ntrans; itrans++){
+       Double_t transparency=(itrans+1.)/ntrans;
+       vecT[itrans]=transparency;
+       for (Int_t irow=0; irow<160; irow++) {
+         qVectorAcc[irow]=0;
+         for (Int_t iel=0; iel<TMath::Nint(qVectorCorr[irow]); iel++) {
+           if (gRandom->Rndm()<transparency)   qVectorAcc[irow]+=1./transparency;      
+         }
+       }      
+       for (Int_t irow=0; irow<160; irow++) {
+         qVectorAcc[irow]+=gRandom->Gaus(0, clNoise);
+         if (qVectorAcc[irow]<0) qVectorAcc[irow]=0;
+       }
+       TMath::Sort(160,qVectorAcc.GetMatrixArray(), indexes, kFALSE);
+       for (Int_t irow=0; irow<160; irow++) {
+         qVectorSorted[irow]=qVectorAcc[indexes[irow]];
+       }
+       vecdEdx[itrans]=TMath::Mean(0.6*160.,   qVectorSorted.GetMatrixArray());    
+       vecdEdx[itrans]+=gRandom->Gaus(0, corrNoiseAdd);
+      }
+      (*pcstream)<<"dEdx"<<
+       "itrack="<<itrack<<              // itrack 
+       "meanEl="<<meanEl<<              // 
+       "sigmaEl="<<sigmaEl<<            //
+       "vecT.="<<&vecT<<                //
+       "vecdEdx.="<<&vecdEdx<<
+       "qVector.="<<&qVector<<
+       "\n";
+    }
+    TTree * tree = (TTree*)(pcstream->GetFile()->Get("dEdx"));
+    tree->Draw("vecdEdx.fElements/(meanEl):vecT.fElements>>hisdEdx(16,0.199,1,100,0.70,1.50)","meanEl<100","colz");    
+    phisdEdx= (TH2F*)tree->GetHistogram()->Clone();    
+    gStyle->SetOptFit(1);
+    gStyle->SetOptStat(0);
+    phisdEdx->Write("hisdEdx");
+  }
+  delete pcstream;
+  gStyle->SetOptStat(0);
+  gStyle->SetOptFit(1);
+  pcstream = new TTreeSRedirector("testdEdxResolution.root","update"); 
+  phisdEdx = (TH2F*)pcstream->GetFile()->Get("hisdEdx");
+  TObjArray *arrFit = new TObjArray(3);
+  phisdEdx->FitSlicesY(0,0,-1,0,"QNR",arrFit);
+  TH1D * hisRes = (TH1D*)arrFit->At(2);
+  hisRes->Divide((TH1D*)arrFit->At(1)); 
+  hisRes->Scale(100);
+  hisRes->SetTitle("dEdx resolution");
+  hisRes->SetMarkerStyle(21);
+  hisRes->GetXaxis()->SetTitle("Eff. electron  transparency");
+  hisRes->GetYaxis()->SetTitle("#sigma_{dEdx}/dEdx (%)");
+  hisRes->SetMinimum(4);
+  hisRes->SetMaximum(8);
+  //
+  TF1 * ftrans = new TF1("ftrans","[0]*x**(-(abs([1])+0.000001))");
+  ftrans->SetParName(0,"#sigma_{T1}");
+  ftrans->SetParName(1,"#sigma slope");
+  ftrans->SetParameters(0.05,1,0.05);
+  hisRes->SetMarkerStyle(21);
+  hisRes->SetMarkerSize(0.9);
+  TCanvas * canvasTrans = new TCanvas("canvasTrans", "canvasTrans",600,500);
+  canvasTrans->SetTicks(1,1);
+  hisRes->Fit(ftrans,"","",0.2,1);
+  canvasTrans->SaveAs("canvasElTrans.pdf");
+  //TH
+  
+  
+}
+
+void testExtrapolationError(Int_t ntracks, Int_t useGeo, Int_t seed){
+  //
+  // check the extrapolation error
+  // 2 scenarios 
+  //     - ITS extrapolation
+  //     - ITS + TRD interpolation
+  //
+  //
+  gRandom->SetSeed(seed);
+  const char *  ocdbpath = "local://$ALICE_ROOT/OCDB/";  
+  AliCDBManager * man = AliCDBManager::Instance();
+  man->SetDefaultStorage(ocdbpath);
+  man->SetRun(0);
+  TGeoGlobalMagField::Instance()->SetField(new AliMagF("Maps","Maps", -1., -1., AliMagF::k5kG,       AliMagF::kBeamTypepp, 2.76/2.));
+  Double_t   bz=AliTrackerBase::GetBz(); 
+  if ( useGeo)   AliGeomManager::LoadGeometry("geometry.root");
+  if (!useGeo)   AliGeomManager::LoadGeometry();
+  //
+  //  Double_t rpoints[13]={2.2,   2.8,   3.6,   20,    22,    41,     43,       300,315,330,345,360,375};
+  Double_t spoints[13]={0.0004,0.0004,0.0004,0.0004,0.0004,0.0004, 0.0004,   0.02,0.02,0.02,0.02,0.02,0.02}; // ITS layers R poition (http://arxiv.org/pdf/1304.1306v3.pdf - pixel scenario) 
+  //
+  Double_t rpoints[13]={2.32,   3.13,   3.91,   19.41,    24.71,    35.33,     40.53,       300,315,330,345,360,375};
+
+  //
+  // 
+  //
+  const Int_t nbins=40;  
+  TFile * f = TFile::Open("testExtrapolationErr.root","update");
+  if (f->Get("extrapol")==0){
+    delete f;
+    f=0;
+    Double_t cv[21]={0}; 
+    Double_t covarSeed[15]={0};
+    for (Int_t i=0; i<15; i++) covarSeed[i]=0;
+    covarSeed[0]=0.1;
+    covarSeed[2]=0.1;
+    covarSeed[5]=0.001;
+    covarSeed[9]=0.001;
+    covarSeed[14]=0.03;
+    //
+    Double_t vertex[3]={0,0,0};
+    TTreeSRedirector *pcstream = new TTreeSRedirector("testExtrapolationErr.root","update");
+    //
+    TVectorD vecR(nbins);
+    TVectorD vecITSErr0(nbins);
+    TVectorD vecITSTRDErr0(nbins);
+    //
+    for (Int_t itrack=0; itrack<ntracks; itrack++){
+      //
+      //Double_t phi = gRandom->Uniform(0.0, 2*TMath::Pi());
+      if (itrack%20==0) printf("processing\t%d\n", itrack);
+      Double_t phi = (gRandom->Rndm()-1)*TMath::Pi()/18;
+      Double_t eta = gRandom->Uniform(-1, 1);
+      Double_t pt = 1./(gRandom->Rndm()+0.00001);   
+      Double_t theta = 2*TMath::ATan(TMath::Exp(-eta))-TMath::Pi()/2.;
+      Double_t pxyz[3];
+      pxyz[0]=pt*TMath::Cos(phi);
+      pxyz[1]=pt*TMath::Sin(phi);
+      pxyz[2]=pt*TMath::Tan(theta);
+      Short_t psign=(gRandom->Rndm()>0.5)? -1.:1.;
+      AliExternalTrackParam *track= new AliExternalTrackParam(vertex, pxyz, cv, psign);   
+      Double_t alpha=TMath::ATan2(pxyz[1],pxyz[0]);
+      track->Rotate(alpha);
+      //
+      // 0.) Estimate the error using the ITS extrapolation and ITS+TRD interpolation - neglecting the MS -inf. momanta tracks
+      // 
+      for (Int_t irbin=0; irbin<nbins; irbin++){
+       Double_t x0 =85+Double_t(irbin)*(245.-85.)/Double_t(nbins);
+       Double_t x;
+       //
+       // parabolic fit
+       //
+       TLinearFitter fitterITS(3,"pol2");
+       TLinearFitter fitterITSTRD(3,"pol2");
+       vecR[irbin]=x0;
+       for (Int_t i=0; i<13; i++) { 
+         Double_t y = 0;
+         if (track->GetYAt(rpoints[irbin],bz,y)){
+           x=rpoints[i]-x0; 
+           if (i<7) fitterITS.AddPoint(&x,y,spoints[i]);
+           fitterITSTRD.AddPoint(&x,y,spoints[i]);      
+         }
+       }
+       fitterITS.Eval();
+       fitterITSTRD.Eval();
+       vecITSErr0[irbin]=fitterITS.GetParError(0);
+       vecITSTRDErr0[irbin]=fitterITSTRD.GetParError(0);
+      }
+      //
+      //  1.) estimate q/pt resolution for the ITS+TPC, ITS+TPC+TRD and ITS+TRD scenario
+      //
+      AliExternalTrackParam * param = new AliExternalTrackParam(*track);
+      Double_t *covar = (Double_t*)  param->GetCovariance();
+      for (Int_t i=0; i<15; i++) covar[i]=covarSeed[i];
+      AliTrackerBase::PropagateTrackToBxByBz(param, 370,0.13,1,kFALSE);
+      
+      AliExternalTrackParam *trackITSTPC= new AliExternalTrackParam(*param);   
+      AliExternalTrackParam *trackITSTPCTRD= new AliExternalTrackParam(*param);   
+      AliExternalTrackParam *trackITSTRD= new AliExternalTrackParam(*param);   
+      AliExternalTrackParam *trackTPCTRD= new AliExternalTrackParam(*param); 
+      //
+      Bool_t tStatus=kTRUE;
+      for (Int_t idet=2;idet>=0; idet--){
+       Int_t nlayers=7;
+       if (idet==1) nlayers=159;
+       if (idet==2) nlayers=6;
+       for (Int_t ilayer=nlayers; ilayer>=0; ilayer--){
+         Double_t rlayer=245.-ilayer;
+         Double_t slayer=0.1;
+         if (idet==0) {rlayer=rpoints[ilayer];  slayer=spoints[ilayer];}
+         if (idet==2) {rlayer=rpoints[ilayer+7]; slayer=spoints[ilayer+7];}
+         param->PropagateTo(rlayer,bz);
+         tStatus&=!AliTrackerBase::PropagateTrackToBxByBz(param, rlayer,0.13,1,kFALSE);
+         tStatus&=!AliTrackerBase::PropagateTrackToBxByBz(trackITSTPC, rlayer,0.13,1,kFALSE);
+         tStatus&=!AliTrackerBase::PropagateTrackToBxByBz(trackITSTPCTRD, rlayer,0.13,1,kFALSE);
+         tStatus&=!AliTrackerBase::PropagateTrackToBxByBz(trackITSTRD, rlayer,0.13,1,kFALSE);
+         tStatus&=!AliTrackerBase::PropagateTrackToBxByBz(trackTPCTRD, rlayer,0.13,1,kFALSE);
+         //if (tStatus==kFALSE) break;
+         Double_t pointPos[2]={param->GetY(),param->GetZ()};
+         Double_t pointCov[3]= { slayer*slayer,0,slayer*slayer};
+         tStatus&=!trackITSTPCTRD->Update(pointPos,pointCov);
+         if (idet!=2) {
+           trackITSTPC->Update(pointPos,pointCov);
+         }
+         if (idet!=1) {
+           trackITSTRD->Update(pointPos,pointCov);
+         }
+         if (idet!=0) {
+           trackTPCTRD->Update(pointPos,pointCov);
+         }
+       }
+      }
+      //
+      // 2.) Estimate propagation error at given radius
+      //
+      //  2.a) Fit ITS and TRD track (gauss smeared point error 0 not MS used)
+      AliExternalTrackParam *trackITS= new AliExternalTrackParam(*track);
+      AliExternalTrackParam *trackITS0= new AliExternalTrackParam(*track);
+      covar = (Double_t*)  trackITS->GetCovariance();
+      for (Int_t i=0; i<15; i++) covar[i]=covarSeed[i];
+      AliExternalTrackParam *trackTRD= new AliExternalTrackParam(*param);      
+      AliExternalTrackParam *trackTRD0= new AliExternalTrackParam(*param);      
+      {for (Int_t ilayer=0; ilayer<7; ilayer++){ 
+         AliTrackerBase::PropagateTrackToBxByBz(trackITS, rpoints[ilayer],0.13,1,kFALSE);
+         AliTrackerBase::PropagateTrackToBxByBz(trackITS0, rpoints[ilayer],0.13,1,kFALSE);
+         Double_t pointPos[2]={trackITS0->GetY()+gRandom->Gaus(0,spoints[ilayer]),trackITS0->GetZ()+gRandom->Gaus(0,spoints[ilayer])};
+         Double_t pointCov[3]= {spoints[ilayer]*spoints[ilayer],0,spoints[ilayer]*spoints[ilayer]};
+         trackITS->Update(pointPos,pointCov);
+       }}
+      {for (Int_t ilayer=5; ilayer>=0; ilayer--){ 
+         AliTrackerBase::PropagateTrackToBxByBz(trackTRD, rpoints[ilayer+7],0.13,1,kFALSE);
+         AliTrackerBase::PropagateTrackToBxByBz(trackTRD0, rpoints[ilayer+7],0.13,1,kFALSE);
+         Double_t pointPos[2]={trackTRD0->GetY()+gRandom->Gaus(0,spoints[ilayer+7]),trackTRD0->GetZ()+gRandom->Gaus(0,spoints[ilayer+7])};
+         Double_t pointCov[3]= {spoints[ilayer+7]*spoints[ilayer+7],0,spoints[ilayer+7]*spoints[ilayer+7]};
+         trackTRD->Update(pointPos,pointCov);
+       }}
+      //
+      // 2.b) get ITS extrapolation and TRD interpolation errors at random radisues positions
+      //
+      const Int_t npoints=20;
+      TVectorD vecRKalman(npoints);
+      TVectorD vecITSDeltaY(npoints),    vecITSTRDDeltaY(npoints);
+      TVectorD vecITSErrY(npoints),      vecITSTRDErrY(npoints);
+      for (Int_t ipoint=0; ipoint<npoints; ipoint++){
+       Double_t rLayer= 85.+gRandom->Rndm()*(245.-85.);
+       AliExternalTrackParam *trackITSP= new AliExternalTrackParam(*trackITS);
+       AliExternalTrackParam *trackITSP0= new AliExternalTrackParam(*trackITS0);
+       AliExternalTrackParam *trackTRDP= new AliExternalTrackParam(*trackTRD);
+       AliTrackerBase::PropagateTrackToBxByBz(trackITSP, rLayer,0.13,1,kFALSE);
+       AliTrackerBase::PropagateTrackToBxByBz(trackITSP0, rLayer,0.13,1,kFALSE);
+       AliTrackerBase::PropagateTrackToBxByBz(trackTRDP, rLayer,0.13,1,kFALSE); 
+       vecRKalman[ipoint]=rLayer;
+       trackTRDP->Rotate(trackITSP->GetAlpha());
+       vecITSDeltaY[ipoint]=trackITSP->GetY()-trackITSP0->GetY();
+       vecITSErrY[ipoint]=TMath::Sqrt(trackITSP->GetSigmaY2());
+       AliTrackerBase::UpdateTrack(*trackITSP, *trackTRDP);
+       vecITSTRDDeltaY[ipoint]=trackITSP->GetY()-trackITSP0->GetY();
+       vecITSTRDErrY[ipoint]=TMath::Sqrt(trackITSP->GetSigmaY2());
+      }
+      //
+
+      //vecITSErr0.Print();
+      (*pcstream)<<"extrapol"<<
+       "itrack="<<itrack<<
+       "track.="<<track<<
+       "vecR.="<<&vecR<<
+       //
+       "vecITSErr0.="<<&vecITSErr0<<
+       "vecITSTRDErr0.="<<&vecITSTRDErr0<<
+       "tStatus="<<tStatus<<
+       "trackITSTPC.="<<trackITSTPC<<
+       "trackITSTPCTRD.="<<trackITSTPCTRD<<
+       "trackITSTRD.="<<trackITSTRD<<
+       "trackTPCTRD.="<<trackTPCTRD<<
+       //
+       // kalman extapoltation einterplotaltion studies 
+       // extrapolation and ITSTRDitnerpolation at different radiuses 
+       "verRKalman.="<<&vecRKalman<<            
+       "vecITSDeltaY.="<<&vecITSDeltaY<<
+       "vecITSErrY.="<<&vecITSErrY<<
+       "vecITSTRDDeltaY.="<<&vecITSTRDDeltaY<<
+       "vecITSTRDErrY.="<<&vecITSTRDErrY<<
+       "\n";
+    }
+    delete pcstream;
+  }
+  delete f;
+
+  gStyle->SetOptTitle(0);
+  f = TFile::Open("testExtrapolationErr.root","update");
+  TTree * tree = (TTree*)f->Get("extrapol");
+  tree->SetMarkerStyle(25);
+  tree->SetMarkerSize(0.3);
+
+  //
+  TGraphErrors * grITS0    = TStatToolkit::MakeGraphErrors(tree,"10*vecITSErr0.fElements:vecR.fElements","",25,4,0);
+  TGraphErrors * grITSTRD0 = TStatToolkit::MakeGraphErrors(tree,"10*vecITSTRDErr0.fElements:vecR.fElements","",21,2,0);
+  //
+  grITS0->GetXaxis()->SetTitle("radius (cm)");
+  grITS0->GetYaxis()->SetTitle("#sigma_{r#varphi} (mm)");
+  grITS0->Draw("ap");
+  grITSTRD0->Draw("p");
+  TLegend * legend  = new TLegend(0.11,0.65,0.55,0.89,"Track residuals at TPC (q/p_{t}=0)");
+  legend->AddEntry(grITS0,"ITS extrapolation","p");
+  legend->AddEntry(grITSTRD0,"ITS-TRD interpolation","p");
+  legend->SetFillColor(10);
+  legend->Draw();
+  //
+  //
+  //
+  TCut cut="abs(track.fP[4])<0.25";
+  TGraphErrors * grITSTPCqPt    = TStatToolkit::MakeGraphErrors(tree,"sqrt(trackITSTPC.fC[14]):abs(track.fP[4])",cut,20,1,0.8);
+  TGraphErrors * grITSTRDqPt    = TStatToolkit::MakeGraphErrors(tree,"sqrt(trackITSTRD.fC[14]):abs(track.fP[4])",cut,21,4,0.8);
+  TGraphErrors * grITSTPCTRDqPt = TStatToolkit::MakeGraphErrors(tree,"sqrt(trackITSTPCTRD.fC[14]):abs(track.fP[4])",cut,24,2,0.8);
+  TGraphErrors * grTPCTRDqPt    = TStatToolkit::MakeGraphErrors(tree,"sqrt(trackTPCTRD.fC[14]):abs(track.fP[4])",cut,25,3,0.8);
+  grITSTPCqPt->GetXaxis()->SetTitle("q/p_{t} (c/GeV)");
+  grITSTPCqPt->GetYaxis()->SetTitle("#sigma_{q/p_{t}} (c/GeV)");
+  grITSTPCqPt->SetMaximum(0.003);
+  TCanvas * canvasResol = new TCanvas("canvasResol","canvasResol",800,600);
+  canvasResol->cd();
+  canvasResol->SetLeftMargin(0.15);
+  grITSTPCqPt->GetYaxis()->SetTitleOffset(1.3);
+
+  {
+    grITSTPCqPt->Draw("ap");
+    grITSTRDqPt->Draw("p");
+    grITSTPCTRDqPt->Draw("p");
+    grTPCTRDqPt->Draw("p");
+    TLegend * legendQpt  = new TLegend(0.41,0.11,0.89,0.4,"q/p_{t} resolution (from covariance matrix) ");
+    legendQpt->AddEntry(grITSTPCqPt,"ITS+TPC","p");
+    legendQpt->AddEntry(grITSTRDqPt,"ITS+TRD","p");
+    legendQpt->AddEntry(grITSTPCTRDqPt,"ITS+TPC+TRD","p");
+    legendQpt->AddEntry(grTPCTRDqPt,"TPC+TRD","p");
+    legendQpt->Draw();
+  }
+  //
+  //
+  TCanvas *canvasResolution = new TCanvas("canvasResolution","canvasResolution",600,600);
+  canvasResolution->Divide(1,3);
+  //
+  canvasResolution->cd(1);
+  tree->Draw("vecITSErrY.fElements:verRKalman.fElements:abs(track.fP[4])","","colz");
+  canvasResolution->cd(2);
+  tree->Draw("vecITSTRDErrY.fElements:verRKalman.fElements:abs(track.fP[4])","","colz");
+  canvasResolution->cd(3);
+  tree->Draw("vecITSTRDErrY.fElements/vecITSErrY.fElements:verRKalman.fElements:abs(track.fP[4])","","colz");
+  canvasResolution->SaveAs("canvasResolution.pdf");
+  canvasResolution->SaveAs("canvasResolution.png");
+  //
+  //
+  //
+  TStatToolkit toolkit;
+  Double_t chi2=0;
+  Int_t    npoints=0;
+  TVectorD param;
+  TMatrixD covar;  
+  //
+  TCut cut="";
+  TString  fstringITS="";
+  fstringITS+="abs(track.fP[4])*(verRKalman.fElements-40)^2++";   
+  fstringITS+="(verRKalman.fElements-40)^2++";   
+  TString * fitErrITS = TStatToolkit::FitPlane(tree,"vecITSErrY.fElements:(0.1+track.fP[4]**2)", fstringITS.Data(),"verRKalman.fElements>0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  tree->SetAlias("fitErrITS",fitErrITS->Data());
+  fitErrITS->Tokenize("++")->Print();
+  tree->Draw("vecITSErrY.fElements/fitErrITS:verRKalman.fElements:abs(track.fP[4])","","colz");
+  //
+  //
+  TString  fstringITSTRD="";
+  fstringITSTRD+="abs(track.fP[4])++";   
+  fstringITSTRD+="abs(track.fP[4]*verRKalman.fElements)++";   
+  fstringITSTRD+="abs(track.fP[4]*verRKalman.fElements**2)++";   
+  for (Int_t iter=0; iter<3; iter++){
+    TCut cutOut="1";
+    if (iter>0) cutOut="abs(vecITSTRDErrY.fElements/fitErrITSTRD-1)<0.8";
+    TString * fitErrITSTRD = TStatToolkit::FitPlane(tree,"vecITSTRDErrY.fElements:(0.1+track.fP[4]**2)", fstringITSTRD.Data(),"verRKalman.fElements>0"+cutOut, chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+    tree->SetAlias("fitErrITSTRD",fitErrITSTRD->Data());
+    fitErrITSTRD->Tokenize("++")->Print();
+  }
+  tree->Draw("vecITSTRDErrY.fElements/fitErrITSTRD:verRKalman.fElements:abs(track.fP[4])","","colz");
+
+  
+  TCanvas *canvasResolutionFit = new TCanvas("canvasResolutionFit","canvasResolutionFit",700,700);
+  canvasResolutionFit->Divide(1,3);
+  canvasResolutionFit->cd(1);
+  tree->Draw("fitErrITS:verRKalman.fElements:abs(track.fP[4])>>hITS","","colz"); 
+  htemp = (TH2F*)gPad->GetPrimitive("hITS")->Clone();
+  htemp->GetXaxis()->SetTitle("#it{r} (cm)");
+  htemp->GetYaxis()->SetTitle("#sigma_{r#phi} (cm) ITS");
+  htemp->GetZaxis()->SetTitle("q/#it{p_{t}} (#it{c}/GeV)");
+  htemp->Draw("colz");
+  canvasResolutionFit->cd(2);
+  tree->Draw("fitErrITSTRD:verRKalman.fElements:abs(track.fP[4])>>hITSTRD","","colz");
+  htemp = (TH2F*)gPad->GetPrimitive("hITSTRD")->Clone();
+  htemp->GetXaxis()->SetTitle("#it{r} (cm)");
+  htemp->GetYaxis()->SetTitle("#sigma_{r#phi} (cm) ITS+TRD");
+  htemp->GetZaxis()->SetTitle("q/#it{p_{t}} (#it{c}/GeV)");
+  htemp->Draw("colz");
+  canvasResolutionFit->cd(3);
+  tree->Draw("fitErrITSTRD:verRKalman.fElements:abs(track.fP[4])>>hITSTRD","","colz");
+  htemp = (TH2F*)gPad->GetPrimitive("hITSTRD")->Clone();
+  htemp->GetXaxis()->SetTitle("#it{r} (cm)");
+  htemp->GetYaxis()->SetTitle("#sigma_{r#phi} (cm) ITS+TRD");
+  htemp->GetZaxis()->SetTitle("q/#it{p_{t}} (#it{c}/GeV)");
+  htemp->Draw("colz");
+  canvasResolutionFit->SaveAs("canvasResolutionFit.pdf");
+  canvasResolutionFit->SaveAs("canvasResolutionFit.png");
+
+}
+
+
+void DrawInerpolationResolution(){
+
+  // resRphi = 0.004390 + oneOverPt*(-0.136403) + oneOverPt*radius*(0.002266) + oneOverPt*radius*radius*(-0.000006);
+
+  //TF1 f1("f1","[0]+[1]*(
+}
+
+void MakeRobustFitTest(){
+  //
+  //
+  //
+  // 
+  TH2F *   his2D   = new TH2F("his2D", "his2D",50,0,1., 100,-2.,2.);
+  TH2F *   his2DW   = new TH2F("his2DW", "his2DW",50,0,1., 100,-2.,2.);
+  Double_t probRND = 0.1;
+  Int_t    ntracks = 20*50000;
+  Int_t    nclusters = 16;
+  Double_t sigmaCluster=0.1;
+  //
+  for (Int_t itrack=0; itrack<ntracks; itrack++){
+    Double_t x     = gRandom->Rndm();
+    Double_t widthTrack = 0.1/(0.5+gRandom->Exp(0.5));
+    Double_t y     = 0;
+    y= gRandom->Gaus(0.0,widthTrack);
+    Bool_t isRandom=gRandom->Rndm()<probRND;
+    //if (gRandom->Rndm()<probRND) y= -2+4*gRandom->Rndm();  
+    //
+    Double_t sigmaTrack= TMath::Sqrt(sigmaCluster*sigmaCluster/nclusters+widthTrack*widthTrack);
+    for (Int_t icl=0; icl<nclusters; icl++){
+      his2D->Fill(x,y+gRandom->Gaus(0,sigmaCluster));
+      his2DW->Fill(x,y+gRandom->Gaus(0,sigmaCluster),1/sigmaTrack);
+    }
+  }
+  {
+    his2D->Draw("colz");
+    his2DW->Draw("colz");
+    his2D->FitSlicesY();
+    his2DW->FitSlicesY();    
+    his2D_1->Draw();
+    his2DW_1->Draw("same");
+  }
+  TMath::RMS(50, &(his2D_1->GetArray()[1]));
+
+  TH1D * phis1D = his2D->ProjectionY("aaa",5,5);
+  Int_t nbinsY= phis1D->GetXaxis()->GetNbins();
+  TVectorD vector(nbinsY, &(phis1D->GetArray()[1]));
+
+  TStatToolkit::MakeStat1D((TH2*)his2D, 1,0.8,0,25,1)->Draw("alp");
+  TStatToolkit::MakeStat1D((TH2*)his2D, 1,0.8,2,20,2)->Draw("lp");
+  TStatToolkit::MakeStat1D((TH2*)his2D, 1,0.8,4,21,4)->Draw("lp");
+
+}
diff --git a/TPC/Upgrade/macros/fastToyMCMI.sh b/TPC/Upgrade/macros/fastToyMCMI.sh
new file mode 100755 (executable)
index 0000000..96fb95b
--- /dev/null
@@ -0,0 +1,24 @@
+            
+source $1 
+aliroot -b -q $ALICE_ROOT/TPC/Upgrade/macros/fastToyMCMI.C+\($2,$3,$4)
+exit;
+
+
+# Example usage local 
+# jobs to be submitted form the lxb1001 or lxb1002
+#(here we have 80 nodes and user disk)
+#
+export baliceTPC=/u/miranov/.baliceTPC
+export flucPath=$HOME/AliRoot/TPCdev/TPC/Upgrade/macros/
+export batchCommand="qsub -cwd  -V "
+
+wdir=`pwd`
+for idir in {0..20}; do  
+    mkdir $wdir/dir$idir
+    cd  $wdir/dir$idir
+    ln -sf ../geometry.root .
+    rm testdEdxResolution.root
+   $batchCommand    -o  fastToyMCMI.log  $flucPath/fastToyMCMI.sh  $baliceTPC  1 200 0 $idir
+   
+done;
+
index 1ee604401ca6a0704445c692528a9ee8a8553dc2..5788ff99b9de556b5595dba4fc077f10a3d7dbed 100644 (file)
@@ -38,7 +38,7 @@ void finalPlots(const char* filesEps20, TString saveDir="")
   TString idealDistorted("t1_1_3_130_10.");
   TString distorted("t0_1_0_130_10.");
   TString realTracking("t0_1_2_130_10.");
-  TString realTrackingPreT0("t0_1_4_130_10.");
+//  TString realTrackingPreT0("t0_1_4_130_10.");
   
   SetStyle();
   
@@ -51,7 +51,7 @@ void finalPlots(const char* filesEps20, TString saveDir="")
     return;
   }
 
-  if (/*tEps10->GetListOfFriends()->GetEntries()!=5 ||*/ tEps20->GetListOfFriends()->GetEntries()!=6) {
+  if (/*tEps10->GetListOfFriends()->GetEntries()!=5 ||*/ tEps20->GetListOfFriends()->GetEntries()!=5) {
     printf("ERROR: wrong number of entries in the friends, not default\n");
     return;
   }
@@ -77,9 +77,9 @@ void finalPlots(const char* filesEps20, TString saveDir="")
   drawStr=Form("(%sfTime0-t0)*vDrift",realTracking.Data());
   tEps20->Draw(drawStr+">>hT0resDC","","goff");
 
-  TH1F *hT0resDCPreT0 = new TH1F("hT0resDCPreT0","T0 resolution;(#it{t}_{0}^{seed}-#it{t}_{0}) #upoint #it{v}_{drift};#tracks",100,-50.1,50.1);
-  drawStr=Form("(%sfTime0-t0)*vDrift",realTrackingPreT0.Data());
-  tEps20->Draw(drawStr+">>hT0resDCPreT0","","goff");
+//  TH1F *hT0resDCPreT0 = new TH1F("hT0resDCPreT0","T0 resolution;(#it{t}_{0}^{seed}-#it{t}_{0}) #upoint #it{v}_{drift};#tracks",100,-50.1,50.1);
+//  drawStr=Form("(%sfTime0-t0)*vDrift",realTrackingPreT0.Data());
+//  tEps20->Draw(drawStr+">>hT0resDCPreT0","","goff");
   
   //   hT0resI->Draw();
   //   hT0resD->Draw("same");
@@ -128,7 +128,7 @@ void finalPlots(const char* filesEps20, TString saveDir="")
   
   TCanvas *cYresDistCorrTzeroSeed=GetCanvas("YresDistCorrTzeroSeed","Yres for fully distorted/corrected clusters (Tzero seed)");
   //ideal clusters at the ITS outermost point
-  TH1F *hYresDistCorrTzeroSeed = new TH1F("hYresDistCorrTzeroSeed",";#it{y}_{TPC}-#it{y}_{ITS} (cm);#tracks",100,-.85,0.85);
+  TH1F *hYresDistCorrTzeroSeed = new TH1F("hYresDistCorrTzeroSeed",";#it{y}_{TPC}-#it{y}_{ITS} (cm);#tracks",100,-.85,1.15);
   drawStr=Form("%strackITS2.fP[0]-%stRealITS2.fP[0]",realTracking.Data(),realTracking.Data());
   tEps20->Draw(drawStr+">>hYresDistCorrTzeroSeed","","goff");
   
@@ -157,8 +157,10 @@ void finalPlots(const char* filesEps20, TString saveDir="")
   //
 
   TString titles[5]={"#it{y}_{TPC}-#it{y}_{ITS} (cm)","#it{z}_{TPC}-#it{z}_{ITS} (cm)","sin(#it{#alpha})_{TPC}-sin(#it{#alpha})_{ITS}","tan(#it{#lambda})_{TPC}-tan(#it{#lambda})_{ITS}","1/#it{p}_{T TPC}-1/#it{p}_{T ITS} ((GeV/#it{c})^{-1})"};
-  Double_t min[5]={-.85,-15,-.009,-.005,-.05};
-  Double_t max[5]={ .85, 15, .009, .005, .05};
+  //Double_t min[5]={-.85,-15,-.009,-.005,-.05};
+  //Double_t max[5]={ .85, 15, .009, .005, .05};
+  Double_t min[5]={-.85,-15,-.015,-.005,-.075};
+  Double_t max[5]={1.15, 15, .015, .005, .075};
   TString type[3]={idealUndistorted,idealDistorted,realTracking};
   Int_t colors[3]={kBlack,kGreen-2,kRed};
 
@@ -191,6 +193,27 @@ void finalPlots(const char* filesEps20, TString saveDir="")
   cResParams->cd(6);
   leg->Draw();
   SaveCanvas(cResParams);
+
+  TCanvas *cResRPhi=GetCanvas("ResRPhi","Resolution of rPhi");
+  TLegend *leg2=new TLegend(.12,.7,.48,.95);
+  TObjArray arr;
+  Int_t i=0;
+  for (Int_t it=0; it<3; ++it) {
+    TH1F *hResParams=new TH1F(Form("hResParams_%d_%d",i,it),
+                              Form(";%s;#tracks",titles[i].Data()),
+                              100,min[i],max[i]);
+    drawStr=Form("%strackITS2.fP[%d]-tRealITS2.fP[%d]",type[it].Data(),i,i);
+    tEps20->Draw(drawStr+Form(">>hResParams_%d_%d",i,it),"","goff");
+    hResParams->SetLineColor(colors[it]);
+    arr.Add(hResParams);
+  }
+  leg2->AddEntry(arr.At(0),"no distortions (ideal)","l");
+  leg2->AddEntry(arr.At(1),"distorted/corrected (t_{0})","l");
+  leg2->AddEntry(arr.At(2),"distorted/corrected (t_{0}^{seed})","l");
+  DrawOnTop(cResRPhi,arr,kTRUE);
+  leg2->Draw("same");
+  SaveCanvas(cResRPhi);
+  
 }
 
 
@@ -212,6 +235,7 @@ void SaveCanvas(TCanvas *c)
   if (fSaveDir.IsNull()) return;
   
   c->SaveAs(Form("/tmp/%s.eps",c->GetName()));
+  c->SaveAs(Form("%s/%s.png",fSaveDir.Data(),c->GetName()));
   gSystem->Exec(Form("ps2pdf -dEPSCrop /tmp/%s.eps %s/%s.pdf",c->GetName(),fSaveDir.Data(),c->GetName()));
 }
 
@@ -254,7 +278,7 @@ void SetStyle()
 {
   const Int_t NCont=255;
   //const Int_t NCont=50;
-  
+  TH1::AddDirectory();
   TStyle *st = new TStyle("mystyle","mystyle");
   gROOT->GetStyle("Plain")->Copy((*st));
   st->SetTitleX(0.1);
diff --git a/TPC/Upgrade/macros/fitResolution.C b/TPC/Upgrade/macros/fitResolution.C
new file mode 100644 (file)
index 0000000..ab92774
--- /dev/null
@@ -0,0 +1,138 @@
+void EmpiricalGEMQFit(const char * input ="GEMScansIKF.root" ){
+  //
+  // Empirical fit of the relative Q resolution for the iron source with 4 GEM layers
+  // Fit:
+  // Assumption : 
+  // 1.) Effective electron transparency proportiaonal to the effective ion transparency
+  // 2.) RMS of the effecitive gain can be expressed as linear function of U1/U3,U2/U4 and U3/U4
+  //
+  // Agreement with data within the expect error estimate -relative agreement 
+  // RMS (sigma_{meas}/sigma_{fit}) ~ 3%
+  // 
+  TFile *fgem = TFile::Open(input);
+  TTree * tree= (TTree*)fgem->Get("NeCO2N2");
+  tree->SetMarkerStyle(25);
+  TStatToolkit toolkit;
+  Double_t chi20=0;
+  Int_t    npoints=0;
+  Int_t npointsMax=10000;
+  TVectorD param0,param1,param2,param3;
+  TMatrixD covar0,covar1,covar2,covar3;
+  
+  tree->SetAlias("UGEMA","(UGEM1+UGEM2+UGEM3+UGEM4)");
+  TString fstringFast="";
+  fstringFast+="1/IB++";                // fraction of the 
+  fstringFast+="(UGEM1/UGEM4)/IB++";    // fraction of the gain
+  fstringFast+="(UGEM2/UGEM4)/IB++";    // fraction of the gain
+  fstringFast+="(UGEM3/UGEM4)/IB++";    // fraction of the gain
+  //
+  TCut cutFit="ET2Scan+ET3Scan==0";
+  TString *strResolFit = TStatToolkit::FitPlane(tree,"Sigma^2:Sigma^2", fstringFast.Data(),cutFit, chi20,npoints,param0,covar0,-1,0, npointsMax, 0);
+  strResolFit->Tokenize("++")->Print();
+  tree->SetAlias("fitSigma2",strResolFit->Data());
+  //
+  gStyle->SetOptTitle(0);
+  //
+  TCanvas *canvas = new TCanvas("canvasEmp","canvasEmp",600,500);
+  canvas->SetBottomMargin(0.15);
+  canvas->SetRightMargin(0.1);
+  canvas->SetTicks(1,1);
+  tree->SetMarkerSize(0.7);
+  {
+    tree->Draw("Sigma:sqrt(fitSigma2):sqrt(1/IB)",cutFit,"colz");  
+    TH2F *htemp = (TH2F*)gPad->GetPrimitive("htemp");
+    htemp->GetXaxis()->SetTitle("#sigma_{fit}(%)");
+    htemp->GetYaxis()->SetTitle("#sigma_{meas}(%)");
+    htemp->GetZaxis()->SetTitle("#sqrt{IBF}");
+    htemp->SetTitle("Fe resolution");
+    htemp->GetXaxis()->SetLimits(8,20);
+    htemp->GetYaxis()->SetLimits(8,20);
+    htemp->Draw("colz");
+    TLatex latex;
+    latex.DrawLatex(8.5,18.5,"#sigma=#sqrt{p_{0}+p_{1}#frac{1}{IB}+p_{2}#frac{U1}{U4xIB}+p_{3}#frac{U2}{U4xIB} + p_{4}#frac{U3}{U4xIB}}");
+    latex.DrawLatex(8.5,17,TString::Format("p_{0}=%1.f",param0[0]));
+    latex.DrawLatex(8.5,16,TString::Format("p_{1}=%1.f",param0[1]));
+    latex.DrawLatex(8.5,15,TString::Format("p_{2}=%1.f",param0[2]));
+    latex.DrawLatex(8.5,14,TString::Format("p_{3}=%1.f",param0[3]));
+    latex.DrawLatex(8.5,13,TString::Format("p_{4}=%1.f",param0[4]));
+  }
+  
+  canvas->SaveAs("canvasFEResolutionFit.pdf");
+  canvas->SaveAs("canvasFEResolutionFit.png");
+}
+
+
+void EmpiricalGEMQFit(){
+  //
+  // Empirical fit of the relative Q resolution for the iron source with 4 GEM layers
+  // Fit:
+  // Assumption : 
+  // 1.) Effective electron transparency proportiaonal to the effective ion transparency
+  // 2.) RMS of the effecitive gain can be expressed as linear function of U1/U3,U2/U4 and U3/U4
+  //
+  // Agreement with data within the expect error estimate -relative agreement 
+  // RMS (sigma_{meas}/sigma_{fit}) ~ 3%
+  // 
+  TFile *fgem = TFile::Open("ETscansIKF.root");
+  TTree * tree= (TTree*)fgem->Get("NeCO2N2");
+  tree->SetMarkerStyle(25);
+  TStatToolkit toolkit;
+  Double_t chi20=0;
+  Int_t    npoints=0;
+  Int_t npointsMax=10000;
+  TVectorD param0,param1,param2,param3;
+  TMatrixD covar0,covar1,covar2,covar3;
+  //
+  TString fstringFast="";
+  fstringFast+="1/IB++";                // fraction of the 
+  fstringFast+="(ET1/1000)/IB++";    // fraction of the gain
+  fstringFast+="(ET2/1000)/IB++";    // fraction of the gain
+  fstringFast+="(ET3/1000)/IB++";    // fraction of the gain
+  fstringFast+="(ET4/1000)/IB++";    // fraction of the gain
+  //fstringFast+="(UGEM1/UGEM4)/IB++";    // fraction of the gain
+  //
+  TCut cutFit="ET1<5500";
+  TString *strResolFit = TStatToolkit::FitPlane(tree,"Sigma^2:Sigma^2", fstringFast.Data(),cutFit, chi20,npoints,param0,covar0,-1,0, npointsMax, 0);
+  strResolFit->Tokenize("++")->Print();
+  tree->SetAlias("fitSigma2",strResolFit->Data());
+  //
+  gStyle->SetOptTitle(0);
+  //
+  TCanvas *canvas = new TCanvas("canvasEmp","canvasEmp",600,500);
+  canvas->SetBottomMargin(0.15);
+  canvas->SetRightMargin(0.1);
+  canvas->SetTicks(1,1);
+  tree->SetMarkerSize(0.7);
+  {
+    tree->Draw("Sigma:sqrt(fitSigma2):sqrt(1/IB)",cutFit,"colz");  
+    TH2F *htemp = (TH2F*)gPad->GetPrimitive("htemp");
+    htemp->GetXaxis()->SetTitle("#sigma_{fit}(%)");
+    htemp->GetYaxis()->SetTitle("#sigma_{meas}(%)");
+    htemp->GetZaxis()->SetTitle("#sqrt{IBF}");
+    htemp->SetTitle("Fe resolution");
+    htemp->GetXaxis()->SetLimits(8,20);
+    htemp->GetYaxis()->SetLimits(8,20);
+    htemp->Draw("colz");
+    TLatex latex;
+    latex.DrawLatex(8.5,18.5,"#sigma=#sqrt{p_{0}+p_{1}#frac{1}{IB}+p_{2}#frac{ET1}{1000xIB}+p_{3}#frac{ET2}{1000xIB} + p_{4}#frac{ET3}{1000xIB}} +  p_{4}#frac{ET4}{1000xIB}} ");
+    latex.DrawLatex(8.5,17,TString::Format("p_{0}=%1.f",param0[0]));
+    latex.DrawLatex(8.5,16,TString::Format("p_{1}=%1.f",param0[1]));
+    latex.DrawLatex(8.5,15,TString::Format("p_{2}=%1.f",param0[2]));
+    latex.DrawLatex(8.5,14,TString::Format("p_{3}=%1.f",param0[3]));
+    latex.DrawLatex(8.5,13,TString::Format("p_{4}=%1.f",param0[4]));
+    latex.DrawLatex(8.5,12,TString::Format("p_{5}=%1.f",param0[5]));
+  }
+  
+  canvas->SaveAs("canvasFEResolutionFitET.pdf");
+  canvas->SaveAs("canvasFEResolutionFitET.png");
+}
+
+
+void FitMCParam(){
+  //
+  // Fit the parmaterizations
+  //
+  TChain *chain  = AliXRDPROOFtoolkit::MakeChain("outscan_all.list","d",0,100000);
+  
+
+}
index eeb21cc8ef79fba164e07151d2bc4606028ad066..6bf8dc9d678d7d5281a5f2199df668e7869ff6d0 100644 (file)
@@ -7,7 +7,7 @@ void loadlibs(const char *dir=".")
   gSystem->AddIncludePath("-I$ROOTSYS/include");
    Bool_t hasAR=!TString(gSystem->Getenv("ALICE_ROOT")).IsNull();
   // if (hasAR) gSystem->AddIncludePath("-I$ALICE_ROOT/ -I$ALICE_ROOT/include -I$ALICE_ROOT/STEER  -I$ALICE_ROOT/ANALYSIS -I$ALICE_ROOT/TPC -I$ALICE_ROOT/RAW");
-   if (hasAR) gSystem->AddIncludePath("-I$ALICE_ROOT/ -I$ALICE_ROOT/include -I$ALICE_ROOT/STEER  -I$ALICE_ROOT/ANALYSIS -I$ALICE_ROOT/TPC -I$ALICE_ROOT/TPC/Base -I$ALICE_ROOT/TPC/Rec -I$ALICE_ROOT/TPC/Upgrade -I$ALICE_ROOT/RAW -I$ALICE_ROOT/STEER/STEERBase/ -I$ALICE_ROOT/STEER/ESD/ -I$ALICE_ROOT/HLT/BASE/");
+   if (hasAR) gSystem->AddIncludePath("-I$ALICE_ROOT/ -I$ALICE_ROOT/include -I$ALICE_ROOT/STEER  -I$ALICE_ROOT/ANALYSIS -I$ALICE_ROOT/TPC -I$ALICE_ROOT/TPC/Base -I$ALICE_ROOT/TPC/Rec -I$ALICE_ROOT/TPC/Upgrade -I$ALICE_ROOT/RAW -I$ALICE_ROOT/STEER/STEERBase/ -I$ALICE_ROOT/STEER/ESD/ -I$ALICE_ROOT/HLT/BASE/ -I$ALICE_ROOT/STAT");
 
   gSystem->Load("libCore");
   gSystem->Load("libPhysics");
diff --git a/TPC/Upgrade/macros/makeCurrentCorrection.C b/TPC/Upgrade/macros/makeCurrentCorrection.C
new file mode 100644 (file)
index 0000000..620eec1
--- /dev/null
@@ -0,0 +1,821 @@
+/*
+.x $ALICE_ROOT/TPC/Upgrade/macros/NimStyle.C
+
+.x $HOME/rootlogon.C
+
+.L $ALICE_ROOT/TPC/Upgrade/macros/makeCurrentCorrection.C+
+
+*/
+
+#include "TMath.h"
+#include "TRandom.h"
+#include "TTreeStream.h"
+#include "TVectorD.h"
+#include "TCanvas.h"
+#include "TStopwatch.h"
+#include "AliTPCParam.h"
+#include "AliTPCcalibDB.h"
+#include "AliTPCAltroMapping.h"
+#include "AliAltroRawStream.h"
+#include "AliSysInfo.h"
+#include "AliTPCRawStreamV3.h"
+#include "AliCDBManager.h"
+#include "TGeoGlobalMagField.h"
+#include "AliMagF.h"
+#include "AliRawReaderRoot.h"
+#include "AliRawReader.h"
+#include "TH3.h"
+#include "TH2.h"
+#include "AliTPCCalPad.h"
+#include "AliTPCCalROC.h"
+#include "TChain.h"
+#include "AliXRDPROOFtoolkit.h"
+#include "TLegend.h"
+#include "TCut.h"
+#include "TGraphErrors.h"
+#include "TStatToolkit.h"
+#include "TF2.h"
+
+#include "AliDCSSensor.h"
+#include "AliCDBEntry.h"
+#include "AliDCSSensorArray.h"
+#include "TStyle.h"
+#include "AliTPCSpaceCharge3D.h"
+#include "AliExternalTrackParam.h"
+#include "AliTrackerBase.h"
+#include "TDatabasePDG.h"
+#include "TROOT.h"
+#include "AliMathBase.h"
+#include "TLatex.h"
+#include "AliTPCCorrectionLookupTable.h"
+//
+
+const Int_t kColors[6]={1,2,3,4,6,7};
+const Int_t kMarkers[6]={20,21,24,25,24,25};
+TObjArray garrayFit(3);
+
+
+void MakeLocalDistortionCurrentTree(Int_t npointsZ=20000, Int_t id=0);
+void MakeSmoothKernelStudy(Int_t npoints, Int_t nkernels, Int_t mapID);
+
+void makeCurrentCorrection(Int_t action=0, Int_t arg0=5000, Int_t arg1=0, Int_t arg2=0){
+  //
+  //
+  //
+  if (action==0) MakeLocalDistortionCurrentTree(arg0,arg1);
+  if (action==1) MakeSmoothKernelStudy(arg0,arg1,arg2);
+}
+
+void SetGraphTDRStyle(TGraph * graph){
+  graph->GetXaxis()->SetLabelSize(0.08);
+  graph->GetXaxis()->SetTitleSize(0.08);
+  graph->GetYaxis()->SetLabelSize(0.08);
+  graph->GetYaxis()->SetTitleSize(0.08);
+  graph->GetXaxis()->SetNdivisions(510);
+  graph->GetYaxis()->SetNdivisions(505);
+}
+
+void MakeLocalDistortionCurrentTree(Int_t npointsZ, Int_t id){
+  //
+  // Macro to make trees with local distortions 
+  // Results are later visualized in the function DrawLocalDistortionPlots()
+  //
+  /*
+    Int_t npointsZ=1000;
+    Int_t id=0;
+  */
+  Int_t nitteration=300;
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localCurrent.root","update");
+  //
+  TFile *fCurrent = TFile::Open("SpaceChargeFluc10_1.root");
+  TFile *fRef = TFile::Open("SpaceChargeFluc0_1.root");
+  //
+  AliTPCSpaceCharge3D* distortion = ( AliTPCSpaceCharge3D*)fCurrent->Get("DistRef"); 
+  AliTPCSpaceCharge3D* distortionRef = ( AliTPCSpaceCharge3D*)fRef->Get("DistRef"); 
+  //
+  Int_t nz= distortion->GetInputSpaceCharge3D()->GetZaxis()->GetNbins();
+  TH3 *hisOrig = (TH3*)distortionRef->GetInputSpaceCharge3D();
+  printf("Make mean histo\n");
+  TStopwatch timer;
+  //
+  for (Int_t iside=0; iside<2; iside++){
+    for (Int_t iphi=1; iphi<distortion->GetInputSpaceCharge3D()->GetXaxis()->GetNbins(); iphi+=3){
+      for (Int_t ir=1; ir<distortion->GetInputSpaceCharge3D()->GetYaxis()->GetNbins(); ir+=3){
+       Double_t sum=0, sumW=0;
+       if (iside==0) for (Int_t iz2=1; iz2<nz/2; iz2++)   {sum+= hisOrig->GetBinContent(iphi,ir,iz2); sumW++;}
+       if (iside==1) for (Int_t iz2=nz/2; iz2<nz;  iz2++) {sum+= hisOrig->GetBinContent(iphi,ir,iz2); sumW++;}
+       //
+       if (iside==0) for (Int_t iz=1; iz<nz/2; iz++) hisOrig->SetBinContent(iphi,ir,iz,sum/sumW);
+       if (iside==1) for (Int_t iz=nz/2; iz<=nz; iz++) hisOrig->SetBinContent(iphi,ir,iz,sum/sumW);
+      }
+    }
+  }
+  timer.Print();
+  printf("Make mean histo\n");
+  //
+  distortion->InitSpaceCharge3DPoisson(129, 129, 144,nitteration);
+  distortionRef->InitSpaceCharge3DPoisson(129, 129, 144,nitteration);
+  //
+  distortion->AddVisualCorrection(distortion,1);
+  distortionRef->AddVisualCorrection(distortionRef,2);
+  //
+  TVectorD normZR(125), normZRPhi(125), normZZ(125), normZPos(125);
+  TVectorD normDZR(125), normDZRPhi(125), normDZZ(125);
+  TVectorD normZRChi2(125), normZRPhiChi2(125), normZZChi2(125);
+  TVectorD qCurrent(125), qRef(125);
+  TVectorD qCurrentInt(125), qRefInt(125);
+  
+  //
+  for (Int_t iz =0; iz<125; iz++){
+    for (Int_t iphi=1; iphi<distortion->GetInputSpaceCharge3D()->GetXaxis()->GetNbins(); iphi+=3)
+      for (Int_t ir=1; ir<distortion->GetInputSpaceCharge3D()->GetYaxis()->GetNbins(); ir+=3){
+       qCurrent[iz]+=  distortion->GetInputSpaceCharge3D()->GetBinContent(iphi,ir,iz+1);
+       qRef[iz]+=      distortionRef->GetInputSpaceCharge3D()->GetBinContent(iphi,ir,iz+1);            
+      }   
+  } 
+  //
+  for (Int_t iz =0; iz<125; iz++){
+    for (Int_t jz =0; jz<125; jz++){
+      if (iz<125/2 && jz<=iz){
+       qCurrentInt[iz]+=qCurrent[jz];
+       qRefInt[iz]+=qRef[jz];
+      }
+      if (iz>125/2 && jz>=iz){
+       qCurrentInt[iz]+=qCurrent[jz];
+       qRefInt[iz]+=qRef[jz];
+      }
+    }
+  }
+  //    
+  //
+  for (Int_t iz =0; iz<125; iz++){
+    Double_t z0 = -250+iz*4;
+    TLinearFitter fitterR(2,"pol1");
+    TLinearFitter fitterRPhi(2,"pol1");
+    TLinearFitter fitterZ(2,"pol1");
+    Double_t xvalue[10]={0};
+    for (Int_t ipoint =0; ipoint<npointsZ; ipoint++){      
+      Double_t r0   = 95+gRandom->Rndm()*(245-95.);
+      Double_t phi0 = gRandom->Rndm()*TMath::TwoPi();      
+      if (TMath::Abs(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1))>20) continue;
+      if (TMath::Abs(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,2))>20) continue;
+      xvalue[0]=distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,2);
+      fitterR.AddPoint(xvalue,distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,1));
+      xvalue[0]=distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,2);
+      fitterRPhi.AddPoint(xvalue,distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1));
+      xvalue[0]=distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,2);
+      fitterZ.AddPoint(xvalue,distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,1));
+    }    
+    fitterR.Eval();
+    fitterRPhi.Eval();
+    fitterZ.Eval();    
+    normZR[iz]=fitterR.GetParameter(1);
+    normZRPhi[iz]=fitterRPhi.GetParameter(1);
+    normZZ[iz]=fitterZ.GetParameter(1);
+    normZRChi2[iz]=TMath::Sqrt(fitterR.GetChisquare()/fitterR.GetNpoints());    
+    normZRPhiChi2[iz]=TMath::Sqrt(fitterRPhi.GetChisquare()/fitterRPhi.GetNpoints());    
+    normZZChi2[iz]=TMath::Sqrt(fitterZ.GetChisquare()/fitterZ.GetNpoints());    
+    //
+    if (iz>0){
+      normDZR[iz]=(normZR[iz]-normZR[iz-1]);
+      normDZRPhi[iz]=(normZRPhi[iz]-normZRPhi[iz-1]);
+    }
+    normZPos[iz]=z0;    
+  }
+  {    
+    (*pcstream)<<"meanCurrent"<<
+      "id="<<id<<                       // lookup ID
+      "normZPos.="<<&normZPos<<         // zposition
+      //
+      "qCurrent.="<<&qCurrent<<         // current measuremn 
+      "qRef.="<<&qRef<<                 // current in refenece sample
+      "qCurrentInt.="<<&qCurrentInt<<   // integral of current
+      "qRefInt.="<<&qRefInt<<           // integral of current 
+      //
+      //
+      //
+      "normZR.="<<&normZR<<             // mult. scaling to minimize R distortions
+      "normDZR.="<<&normDZR<<           // mult. scaling to minimize R distortions
+      "normZRPhi.="<<&normZRPhi<<       // mult. scaling 
+      "normDZRPhi.="<<&normDZRPhi<<     // mult. scaling 
+      "normZZ.="<<&normZZ<<
+      //
+      "normZRChi2.="<<&normZRChi2<<            // mult. scaling to minimize R distortions
+      "normZRPhiChi2.="<<&normZRPhiChi2<<      // mult. scaling 
+      "normZZChi2.="<<&normZZChi2<<
+      "\n";
+  }
+  delete pcstream;
+  
+  pcstream = new TTreeSRedirector("localCurrent.root","update");
+  TTree * treeNormZ= (TTree*)pcstream->GetFile()->Get("meanCurrent");
+  TGraphErrors * grZRfit= TStatToolkit::MakeGraphErrors( treeNormZ, "normZR.fElements:normZPos.fElements","",25,2,0.5);
+  TGraphErrors * grZRPhifit= TStatToolkit::MakeGraphErrors( treeNormZ, "normZRPhi.fElements:normZPos.fElements","",25,4,0.5);
+  grZRfit->Draw("alp");
+  grZRPhifit->Draw("lp");
+}
+
+
+void Fit(){
+  //
+  // Not good  rsponse should be more complicated
+  //
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localCurrent.root","update");
+  TTree * treeCurrent= (TTree*)pcstream->GetFile()->Get("meanCurrent");
+  //
+  TVectorD* pnormZR=0, *pnormZRPhi=0, *pnormZZ=0, *pnormZPos=0;
+  TVectorD* pqCurrent=0, *pqRef=0;
+  TVectorD* pqCurrentInt=0, *pqRefInt=0;
+  //
+  treeCurrent->SetBranchAddress("normZR.",&pnormZR);
+  treeCurrent->SetBranchAddress("normZPos.",&pnormZPos);
+  treeCurrent->SetBranchAddress("normZRPhi.",&pnormZRPhi);
+  treeCurrent->SetBranchAddress("qCurrent.",&pqCurrent);
+  treeCurrent->SetBranchAddress("qRef.",&pqRef);
+  treeCurrent->SetBranchAddress("qCurrentInt.",&pqCurrentInt);
+  treeCurrent->SetBranchAddress("qRefInt.",&pqRefInt);
+  Int_t entries = treeCurrent->GetEntries();
+  //
+  //
+  for (Double_t sigma=1; sigma<40; sigma++){    
+    for (Int_t entry=0; entry<entries; entry++){
+      treeCurrent->GetEntry(entry);
+      //
+      TVectorD vecCurrentRefInt(125);
+      for (Int_t i=0; i<125; i++){
+       Double_t sumW=0;
+       for (Int_t j=0; j<125; j++){
+         if (((*pnormZPos)[i]*(*pnormZPos)[j])<0) continue;
+         Double_t weight = 0;
+         if ((*pnormZPos)[i]<0) weight=0.5*(TMath::Erf(Double_t(i-j)/Double_t(sigma))+1);
+         if ((*pnormZPos)[i]>0) weight=0.5*(TMath::Erf(Double_t(j-i)/Double_t(sigma))+1);
+         vecCurrentRefInt[i]+=weight*(*pqCurrent)[j]/(*pqRef)[j];        
+         sumW+=weight;
+       }
+       vecCurrentRefInt[i]/=sumW;
+      }
+      (*pcstream)<<"sigmaScan"<<
+       "entry="<<entry<<
+       "sigma="<<sigma<<
+       "normZPos.="<<pnormZPos<<
+       "normZR.="<<pnormZR<<
+       "normZRPhi.="<<pnormZRPhi<<
+       "vecCurrent.="<<&vecCurrentRefInt<<
+       "\n";
+    }
+  }
+  delete pcstream; 
+  pcstream = new TTreeSRedirector("localCurrent.root","update");
+  TTree * treeScan= (TTree*)pcstream->GetFile()->Get("sigmaScan"); 
+  treeCurrent= (TTree*)pcstream->GetFile()->Get("meanCurrent");
+  treeScan->SetMarkerStyle(25);
+  treeScan->SetMarkerSize(0.4); 
+  treeScan->Draw("vecCurrent.fElements:normZR.fElements:sigma","abs(normZPos.fElements-100)<20&&sigma>10","colz");
+
+}
+
+void FitLinear(){
+  //
+  // deltaX_i = A_ij*deltaI_j
+  // 
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localCurrent.root","update");
+  TTree * treeCurrent= (TTree*)pcstream->GetFile()->Get("meanCurrent");
+  //
+  TVectorD* pnormZR=0, *pnormZRPhi=0, *pnormZZ=0, *pnormZPos=0;
+  TVectorD* pqCurrent=0, *pqRef=0;
+  TVectorD* pqCurrentInt=0, *pqRefInt=0;
+  //
+  treeCurrent->SetBranchAddress("normZR.",&pnormZR);
+  treeCurrent->SetBranchAddress("normZPos.",&pnormZPos);
+  treeCurrent->SetBranchAddress("normZRPhi.",&pnormZRPhi);
+  treeCurrent->SetBranchAddress("qCurrent.",&pqCurrent);
+  treeCurrent->SetBranchAddress("qRef.",&pqRef);
+  treeCurrent->SetBranchAddress("qCurrentInt.",&pqCurrentInt);
+  treeCurrent->SetBranchAddress("qRefInt.",&pqRefInt);
+  Int_t entries = treeCurrent->GetEntries();
+  //
+  //
+  //
+  Int_t nParamSide=62;               // number of z bins on 1 side
+  Int_t group=3;                     // grouping of bins
+  Int_t nParams=nParamSide/group;    // parameters
+  Int_t nParamsFit=nParams*nParams;  //
+  TLinearFitter fitter(nParamsFit+1,TString::Format("hyp%d",nParamsFit));
+  TVectorD xVector(nParamsFit+1);
+  TVectorD pVector(nParamsFit+1);
+  //
+  for (Int_t ievent=0; ievent<entries; ievent++){
+    treeCurrent->GetEntry(ievent);
+    for (Int_t iz=0; iz<nParamSide; iz++){      
+      Int_t dPar=iz/group;
+      if (dPar>nParams-1) dPar=nParams-1;
+      // 1.) clear X vectors
+      for (Int_t ipar=0; ipar<nParamsFit; ipar++) xVector[ipar]=0;
+      // 2.) set   X vector of interest
+      for (Int_t cPar=0; cPar<nParams; cPar++){
+       xVector[dPar*nParams+cPar] += (*pqCurrent)[cPar*group]/(*pqRef)[cPar*group];
+       xVector[dPar*nParams+cPar] += (*pqCurrent)[TMath::Min(cPar*group+1,nParamSide)]/(*pqRef)[TMath::Min(cPar*group+1,nParamSide)];
+       xVector[dPar*nParams+cPar] += (*pqCurrent)[TMath::Max(cPar*group-1,0)]/(*pqRef)[TMath::Max(cPar*group-1,0)];
+      }
+      Double_t val = 0;
+      val+=(*pnormZR)[dPar*group];
+      val+=(*pnormZR)[TMath::Max(dPar*group-1,0)];
+      val+=(*pnormZR)[TMath::Min(dPar*group,nParamSide)];
+      val/=3.;
+      fitter.AddPoint(xVector.GetMatrixArray(),val,0.0035);
+    }
+  }
+  for (Int_t cPar=1; cPar<nParams-1; cPar++){
+    //
+    for (Int_t ipar=0; ipar<nParamsFit; ipar++) xVector[ipar]=0;
+    xVector[(cPar-1)*nParams+cPar-1]=0.5;
+    xVector[(cPar)*nParams+cPar]    =-1;
+    xVector[(cPar+1)*nParams+cPar+1]=0.5;
+    fitter.AddPoint(xVector.GetMatrixArray(),0,0.05);
+  }
+  fitter.Eval();
+  //
+  //
+  TVectorD fitVector(nParamsFit);
+  TVectorD czVector(nParamsFit);
+  TVectorD fitVectorErr(nParamsFit);
+  fitter.GetParameters(fitVector);
+  for (Int_t iPar=0; iPar<nParamsFit; iPar++)  {
+    pVector[iPar]=iPar;
+    czVector[iPar]=250.*((iPar-1)%nParams)/nParams;
+    fitVectorErr[iPar]=fitter.GetParError(iPar);
+  }
+  Double_t chi2= TMath::Sqrt(fitter.GetChisquare()/fitter.GetNpoints());
+  printf("Chi2=%f\n",chi2);
+  TGraphErrors * gr  = new TGraphErrors(nParamsFit,  pVector.GetMatrixArray(), fitVector.GetMatrixArray(), 0,fitVectorErr.GetMatrixArray());
+  gr->SetMarkerStyle(25); gr->SetMarkerSize(0.3);
+  gr->Draw("alp");
+  
+  TGraphErrors * vgraphs[20]={0};
+  for (Int_t ipar=0; ipar<20; ipar++){
+    vgraphs[ipar]=new TGraphErrors(nParams, &(czVector.GetMatrixArray()[ipar*nParams+1]), &(fitVector.GetMatrixArray()[ipar*nParams+1]), 0,  &(fitVectorErr.GetMatrixArray()[ipar*nParams+1])); 
+    vgraphs[ipar]->GetXaxis()->SetTitle("z_{I} (cm)");
+    vgraphs[ipar]->GetYaxis()->SetTitle("#it{A}_{i_{I},j_{#DeltaR}}");
+    vgraphs[ipar]->SetMinimum(0);
+    vgraphs[ipar]->SetMaximum(0.1);
+    SetGraphTDRStyle(vgraphs[ipar]);
+  }
+  
+  TCanvas * canvasFit = new TCanvas("canvasFit","canvasFit",700,700); 
+  canvasFit->SetRightMargin(0.05);
+  canvasFit->SetLeftMargin(0.15);
+  canvasFit->SetBottomMargin(0.18);
+  canvasFit->Divide(1,2,0,0);
+  TLegend * legend0 = new TLegend(0.4,0.4,0.95,0.95,"Current fluctuation correction matrix. #DeltaR_{zi}=A_{ij}I_{zj}");
+  legend0->SetBorderSize(0);
+  TLegend * legend1 = new TLegend(0.4,0.5,0.95,0.95,"Current fluctuation correction matrix. #DeltaR_{zi}=A_{ij}I_{zj}");
+  legend1->SetBorderSize(0);
+
+  for (Int_t ipar=0; ipar<10; ipar++){
+    canvasFit->cd(ipar/5+1)->SetTicks(3,3);
+    vgraphs[ipar*2]->SetMarkerStyle(kMarkers[ipar%5]);
+    vgraphs[ipar*2]->SetMarkerColor(kColors[ipar%5]);
+    vgraphs[ipar*2]->SetLineColor(kColors[ipar%5]);
+    if (ipar%5==0) vgraphs[ipar*2]->Draw("alp");
+    vgraphs[ipar*2]->Draw("lp");
+    if (ipar<5) legend0->AddEntry(vgraphs[ipar*2],TString::Format("z_{#DeltaR}=%1.0f (cm)",250.*ipar/10.),"p");
+    if (ipar>=5) legend1->AddEntry(vgraphs[ipar*2],TString::Format("z_{#DeltaR}=%1.0f (cm)",250.*ipar/10.),"p");
+  }    
+  legend0->SetTextSize(0.05);
+  legend1->SetTextSize(0.05);
+  //
+  canvasFit->cd(1);
+  legend0->Draw();
+  canvasFit->cd(2);
+  legend1->Draw();
+  canvasFit->SaveAs("canvasAIJ_CurrenToDR.pdf");
+  canvasFit->SaveAs("canvasAIJ_CurrenToDR.png");
+}
+
+void MakeSmoothKernelStudy(Int_t npoints, Int_t nkernels, Int_t mapID){
+  //
+  // Compare the input and reconstructed distortion maps
+  // Input files are expected to have predefined names
+  // 
+  // Values and smoothed vaules using differnt smoothing algorithms are used
+  // Results of given studies will be used to define "optimal" smoothing algorithm
+  // and optimal Kernel parameters
+  // 
+  //
+  gRandom->SetSeed(mapID);
+  const Double_t cutMaxDist=3;
+  const Double_t cutMinDist=0.00001;
+  const Int_t kMinPoints=10;
+  TFile *foutput = TFile::Open("MeasureResidual.root");
+  TFile *finput = TFile::Open("RealResidualScaled.root");
+  AliTPCCorrectionLookupTable *mapIn = (AliTPCCorrectionLookupTable *)finput->Get("map");
+  AliTPCCorrectionLookupTable *mapOut = (AliTPCCorrectionLookupTable *)foutput->Get("map");
+  AliTPCCorrection::AddVisualCorrection(mapIn,1);    // input==1
+  AliTPCCorrection::AddVisualCorrection(mapOut,2);   // output (reconstructed==2)
+  TF1 * fin = new TF1("fin","AliTPCCorrection::GetCorrXYZ(x,5,10,1,1)",85,245);
+  TF1 * fout = new TF1("fout","AliTPCCorrection::GetCorrXYZ(x,5,10,1,2)",85,245);  
+  TTreeSRedirector * pcstream = new TTreeSRedirector("smoothLookupStudy.root","recreate");
+  //
+  //
+  // 1. Generate random point of interest
+  //
+  TVectorD  sigmaKernelR(nkernels);
+  TVectorD  sigmaKernelRPhi(nkernels);
+  TVectorD  sigmaKernelZ(nkernels);
+  //
+  TVectorD  fitValuesOut(nkernels);
+  TVectorD  fitValuesOutR(nkernels);
+  TVectorD  fitValuesIn(nkernels);
+  TVectorD  fitValuesInR(nkernels);
+  //
+  TVectorD  fitValuesOutErr(nkernels);
+  TVectorD  fitValuesOutChi2(nkernels);
+  TVectorD  fitSumW(nkernels);
+  TVectorD  fitValuesOutN(nkernels);
+  //
+  TLinearFitter *fittersOut[nkernels];
+  TLinearFitter *fittersOutR[nkernels];
+  TLinearFitter *fittersIn[nkernels];
+  TLinearFitter *fittersInR[nkernels];
+  for (Int_t ipoint=0; ipoint<npoints; ipoint++){ 
+    if (ipoint%10==0) printf("%d\n",ipoint);
+    for (Int_t i=0; i<nkernels; i++) {
+      fittersOut[i]=new TLinearFitter(7,"hyp6");
+      fittersOutR[i]=new TLinearFitter(7,"hyp6");
+      fittersIn[i]=new TLinearFitter(7,"hyp6");
+      fittersInR[i]=new TLinearFitter(7,"hyp6");
+    }
+    Double_t phi = gRandom->Rndm()*TMath::TwoPi();
+    Double_t r   = 85+gRandom->Rndm()*(245-85);
+    Double_t theta   = -0.9+gRandom->Rndm()*1.8;
+    Double_t z=r*theta;     
+    //
+    Double_t x = r*TMath::Cos(phi);
+    Double_t y = r*TMath::Sin(phi);
+    Double_t drphiInput = AliTPCCorrection::GetCorrXYZ(x,y,z,1,1);   // 
+    Double_t drphiOutput = AliTPCCorrection::GetCorrXYZ(x,y,z,1,2);  //
+    Double_t drInput = AliTPCCorrection::GetCorrXYZ(x,y,z,0,1);
+    Double_t drOutput = AliTPCCorrection::GetCorrXYZ(x,y,z,0,2);
+    if (TMath::Abs(drphiOutput)<cutMinDist) continue; // beter condition needed
+    if (TMath::Abs(drphiInput)<cutMinDist) continue; // beter condition needed
+    if (TMath::Abs(drphiOutput)>cutMaxDist) continue; // beter condition needed
+    if (TMath::Abs(drphiInput)>cutMaxDist) continue; // beter condition needed
+    //
+    for (Int_t i=0; i<nkernels; i++) {
+      sigmaKernelR[i]    = 0.5+30.*TMath::Power(gRandom->Rndm(),2); 
+      sigmaKernelRPhi[i] = 0.5+30.*TMath::Power(gRandom->Rndm(),2);
+      sigmaKernelZ[i]    = 0.5+30.*TMath::Power(gRandom->Rndm(),2);
+      fitSumW[i]=0;
+    }
+    for (Int_t idphi=-12; idphi<=12; idphi++){
+      Double_t dphi=idphi*TMath::Pi()/90.;            // we need to know actual segentation of the histograms - lookup should by multiple
+      for (Double_t dR=-50; dR<=50.; dR+=5){
+       for (Double_t dZ=-50; dZ<=50.; dZ+=5){
+         if (r+dR<85) continue;
+         if (r+dR>245) continue;
+         if (z+dZ<-240) continue;
+         if (z+dZ>240) continue;
+         if (z*(z+dZ)<0) continue;
+         //
+         Double_t x2=(r+dR)*TMath::Cos(phi+dphi);
+         Double_t y2=(r+dR)*TMath::Sin(phi+dphi);
+         Double_t z2=z+dZ;
+         Double_t drphiInput2=AliTPCCorrection::GetCorrXYZ(x2,y2,z2,1,1);
+         Double_t drInput2=AliTPCCorrection::GetCorrXYZ(x2,y2,z2,0,1);
+         Double_t drphiOutput2=AliTPCCorrection::GetCorrXYZ(x2,y2,z2,1,2);
+         Double_t drOutput2=AliTPCCorrection::GetCorrXYZ(x2,y2,z2,0,2);
+         if (TMath::Abs(drphiOutput2)<cutMinDist) continue; // hard cut beter condition needed
+         if (TMath::Abs(drphiOutput2)>cutMaxDist) continue; // beter condition needed
+         if (TMath::Abs(drphiInput2)<cutMinDist) continue; // hard cut beter condition needed
+         if (TMath::Abs(drphiInput2)>cutMaxDist) continue; // beter condition needed
+
+         Double_t xfit[7]={dphi,dphi*dphi,dR,dR*dR,dZ,dZ*dZ};
+         for (Int_t i=0; i<nkernels; i++) {
+           Double_t weight=1;
+           weight*=TMath::Gaus(dphi*r,0,sigmaKernelRPhi[i]);
+           weight*=TMath::Gaus(dR,0,sigmaKernelR[i]);
+           weight*=TMath::Gaus(dZ,0,sigmaKernelZ[i]);
+           weight+=0.00000001;
+           fitSumW[i]+=weight;
+           fittersOut[i]->AddPoint(xfit,drphiOutput2,0.1/weight);
+           fittersOutR[i]->AddPoint(xfit,drOutput2,0.1/weight);
+           //
+           fittersIn[i]->AddPoint(xfit,drphiInput2,0.1/weight);
+           fittersInR[i]->AddPoint(xfit,drInput2,0.1/weight);
+         }
+       }
+      }
+    }   
+    
+    for (Int_t ifix=0; ifix<=1; ifix++){
+      Bool_t isOK=kTRUE;
+      for (Int_t i=0; i<nkernels; i++) {
+       if( fittersOut[i]->GetNpoints() < kMinPoints) {
+         isOK=kFALSE;
+         break;
+       }
+       if (fitSumW[i]<0.01/*kMinWeight*/){
+         isOK=kFALSE;
+         break;
+       }
+       if (ifix==1){
+         fittersOut[i]->FixParameter(4,0);
+         fittersOut[i]->FixParameter(5,0);
+         fittersOut[i]->FixParameter(6,0);
+         fittersOutR[i]->FixParameter(4,0);
+         fittersOutR[i]->FixParameter(5,0);
+         fittersOutR[i]->FixParameter(6,0);
+         fittersIn[i]->FixParameter(4,0);
+         fittersIn[i]->FixParameter(5,0);
+         fittersIn[i]->FixParameter(6,0);
+         fittersInR[i]->FixParameter(4,0);
+         fittersInR[i]->FixParameter(5,0);
+         fittersInR[i]->FixParameter(6,0);
+       }
+       fittersOut[i]->Eval();
+       fittersOutR[i]->Eval();
+       fittersIn[i]->Eval();
+       fittersInR[i]->Eval();
+       //
+       fitValuesOut[i]=fittersOut[i]->GetParameter(0);
+       fitValuesOutR[i]=fittersOutR[i]->GetParameter(0);
+       fitValuesIn[i]=fittersIn[i]->GetParameter(0);
+       fitValuesInR[i]=fittersInR[i]->GetParameter(0);
+       //
+       fitValuesOutErr[i]=fittersOut[i]->GetParError(0);
+       fitValuesOutChi2[i]=TMath::Sqrt(fittersOut[i]->GetChisquare()/fitSumW[i]);
+       fitValuesOutN[i]=fittersOut[i]->GetNpoints();
+      }
+      if (isOK){
+      (*pcstream)<<"smoothLookup"<<
+       "ipoint"<<ipoint<<
+       "mapID="<<mapID<<
+       "ifix="<<ifix<<
+       // coordinates
+       "x="<<x<<
+       "y="<<y<<
+       "z="<<z<<
+       "phi="<<phi<<
+       "r="<<r<<
+       "z="<<z<<
+       // Input output values
+       "drphiInput="<<drphiInput<<       // input lookup tables disotrions
+       "drphiOutput="<<drphiOutput<<     // reconstructed lookup tables distortion
+       "drInput="<<drInput<<       // input lookup tables disotrions
+       "drOutput="<<drOutput<<     // reconstructed lookup tables distortion
+       // Smoothed values
+       "fitValuesIn.="<<&fitValuesIn<<            // smoothed input values - rphi direction
+       "fitValuesInR.="<<&fitValuesInR<<          // smoothed input values - r direction
+       "fitValuesOut.="<<&fitValuesOut<<          // smoothed measuured values - rphi
+       "fitValuesOutR.="<<&fitValuesOutR<<        // smoothed measuured values -r 
+       "fitValuesOutErr.="<<&fitValuesOutErr<<
+       "fitValuesOutChi2.="<<&fitValuesOutChi2<<
+       "fitValuesOutN.="<<&fitValuesOutN<<
+       "fitSumW.="<<&fitSumW<<
+       // Kernel sigma
+       "sigmaKernelR.="<<&sigmaKernelR<<
+       "sigmaKernelRPhi.="<<&sigmaKernelRPhi<<
+       "sigmaKernelZ.="<<&sigmaKernelZ<<
+       "\n";
+      }
+    }
+    for (Int_t i=0; i<nkernels; i++) {
+      delete fittersOut[i];
+      delete fittersOutR[i];
+      delete fittersIn[i];
+      delete fittersInR[i];
+    }
+  }
+  delete pcstream;
+  //
+  //
+  /* 
+     TFile *ff = TFile::Open("smoothLookupStudy.root")
+     TChain * chain = AliXRDPROOFtoolkit::MakeChain("smooth.list", "smoothLookup", 0,100)
+
+   */
+}
+void MakeSmoothKernelStudyDraw(Int_t npoints){
+  //
+  // make figure for kernel smoothing Draw
+  //
+  // npoints=20000
+  TFile *finput = TFile::Open("smoothLookupStudy.root");
+  TTree * chain = (TTree*)finput->Get("smoothLookup");  
+  chain->SetCacheSize(100000000);
+  TH2* hisInputsS[10]={0};
+  TH3* hisInputs3D[10]={0};
+  TH1* hisSigmaS[10]={0};
+  //
+  // 1.) Resolution not smoothed make nice plots
+  //
+  TH2 * his2DBase[10]={0};
+  TH1 * hisSigmas[10]={0};
+  chain->Draw("10*drphiInput:r>>hisIn(30,85,245,100,-2,2)","","colz");
+  his2DBase[0]=(TH2*)chain->GetHistogram()->Clone();
+  chain->Draw("10*(drphiOutput-drphiInput):r>>hisOutIn(30,85,245,100,-2,2)","","colz");
+  his2DBase[1]=(TH2*)chain->GetHistogram()->Clone();
+  his2DBase[0]->FitSlicesY(0,0,-1,0,"QNR",&garrayFit);
+  hisSigmas[0] = (TH1*)garrayFit.At(2)->Clone();
+  his2DBase[1]->FitSlicesY(0,0,-1,0,"QNR",&garrayFit);
+  hisSigmas[1] = (TH1*)garrayFit.At(2)->Clone();
+  //
+  TCanvas *canvasInOut = new TCanvas("deltaInOut","deltaInOut",600,500);
+  for (Int_t i=0; i<2; i++) {
+    hisSigmas[i]->SetMinimum(0); 
+    hisSigmas[i]->SetMaximum(1.5); 
+    hisSigmas[i]->SetMarkerStyle(kMarkers[i]);
+    hisSigmas[i]->SetMarkerColor(kColors[i]);
+    hisSigmas[i]->GetXaxis()->SetTitle("R (cm)");
+    hisSigmas[i]->GetYaxis()->SetTitle("#Delta_{R#phi} (mm)");
+    if (i==0) hisSigmas[i]->Draw("");
+    hisSigmas[i]->Draw("same");
+  }
+  TLegend * legend = new TLegend(0.4,0.5,0.89,0.89,"Residual #Delta_{r#phi}");
+  legend->SetBorderSize(0);
+  legend->AddEntry(hisSigmas[0],"#Delta_{current}-k#Delta_{mean}");
+  legend->AddEntry(hisSigmas[1],"(#Delta_{current}-k#Delta_{mean})_{align}-(#Delta_{current}-k#Delta_{mean})");
+  legend->Draw();
+  canvasInOut->SaveAs("canvasDistortionAlignmentInOut.pdf");
+  canvasInOut->SaveAs("canvasDistortionAlignmentInOut.png");
+  //
+  // 1.b) phi modulation plots
+  //
+  TCanvas * canvasPhi= new TCanvas("canvasPhi","canvasPhi",800,600);
+  canvasPhi->Divide(1,3,0,0);
+  gStyle->SetOptTitle(1);
+  chain->SetAlias("sector","9*phi/pi");
+  {
+    chain->SetMarkerStyle(25);
+    chain->SetMarkerSize(0.3);
+    canvasPhi->cd(1);
+    chain->Draw("(drphiOutput-drphiInput):sector","abs((drphiOutput-drphiInput))<0.2&&abs(r-100)<20","",npoints);
+    canvasPhi->cd(2);
+    chain->Draw("(drphiOutput-drphiInput):sector","abs((drphiOutput-drphiInput))<0.2&&abs(r-160)<25","",npoints);
+    canvasPhi->cd(3);
+    chain->Draw("(drphiOutput-drphiInput):sector","abs((drphiOutput-drphiInput))<0.2&&abs(r-220)<30","",npoints);
+  }
+  canvasPhi->SaveAs("canvasDistortionPhiSlice.pdf");
+
+  TCanvas * canvasDistortionSliceHisto= new TCanvas("canvasDistortionSliceHisto","canvasDistortionSliceHisto",800,600);
+  canvasDistortionSliceHisto->Divide(1,3,0,0);
+  gStyle->SetOptTitle(1);
+  chain->SetAlias("sector","9*phi/pi");
+  {
+    chain->SetMarkerStyle(25);
+    chain->SetMarkerSize(0.3);
+    canvasDistortionSliceHisto->cd(1);
+    chain->Draw("(drphiOutput-drphiInput):sector-int(sector)>>hisSec100(40,0,1,50,-0.2,0.2)","abs((drphiOutput-drphiInput))<0.2&&abs(r-110)<30","colz");
+    canvasDistortionSliceHisto->cd(2);
+    chain->Draw("(drphiOutput-drphiInput):sector-int(sector)>>hisSec160(40,0,1,50,-0.2,0.2)","abs((drphiOutput-drphiInput))<0.2&&abs(r-160)<25","colz");
+    canvasDistortionSliceHisto->cd(3);
+    chain->Draw("(drphiOutput-drphiInput):sector-int(sector)>>hisSec2200(40,0,1,50,-0.2,0.2)","abs((drphiOutput-drphiInput))<0.2&&abs(r-220)<30","colz");
+  }
+  canvasDistortionSliceHisto->SaveAs("canvasDistortionSectorSliceHisto.pdf");
+
+
+  //
+  //
+  // 2.) Draw plot resolution as fucntion of the kernel smooth sigma
+  //      a.) Smoothed input- input
+  //      b.) Smoothed
+  TObjArray fitResols(1000);
+  const char* varSmooth[4]={"Smoothed(Input,Pol1)-Input","Smoothed(Output,Pol1)-Smoothed(Input,Pol1)","Smoothed(Output,Pol2)-Input","Smoothed(Output,Pol1)-Input"};
+  //
+  chain->Draw("10*(fitValuesIn.fElements-drphiInput):sqrt(sigmaKernelR.fElements**2+sigmaKernelRPhi.fElements**2+sigmaKernelZ.fElements**2):r>>hisSmoothDiff0(5,83,245, 15,5,40,100,-2.2,2.2)","ifix==1&&fitValuesOutErr.fElements<0.2","goff",npoints);
+  hisInputs3D[0]= (TH3*)chain->GetHistogram()->Clone();
+  chain->Draw("10*(fitValuesOut.fElements-fitValuesIn.fElements):sqrt(sigmaKernelR.fElements**2+sigmaKernelRPhi.fElements**2+sigmaKernelZ.fElements**2):r>>hisSmoothDiff1(5,83,245, 15,5,40,100,-2.2,2.2)","ifix==1&&fitValuesOutErr.fElements<0.2","goff",npoints);
+  hisInputs3D[1]= (TH3*)chain->GetHistogram()->Clone();
+  chain->Draw("10*(fitValuesOut.fElements-drphiInput):sqrt(sigmaKernelR.fElements**2+sigmaKernelRPhi.fElements**2+sigmaKernelZ.fElements**2):r>>hisSmoothDiff2(5,83,245, 15,5,40,100,-2.2,2.2)","ifix==0&&fitValuesOutErr.fElements<0.2","goff",npoints);
+  hisInputs3D[2]= (TH3*)chain->GetHistogram()->Clone();
+  chain->Draw("10*(fitValuesOut.fElements-drphiInput):sqrt(sigmaKernelR.fElements**2+sigmaKernelRPhi.fElements**2+sigmaKernelZ.fElements**2):r>>hisSmoothDiff3(5,83,245, 15,5,40,100,-2.2,2.2)","ifix==1&&fitValuesOutErr.fElements<0.2","goff",npoints);
+  hisInputs3D[3]= (TH3*)chain->GetHistogram()->Clone();
+  //
+  //
+  //
+  TCanvas *canvasSmooth = new TCanvas("DistortionAlignmentSmooth3D","DistortionAlignmentSmooth3D",800,800);
+  canvasSmooth->Divide(2,2,0,0);
+  gStyle->SetOptStat(0);  
+  for (Int_t itype=0; itype<4; itype++){
+    canvasSmooth->cd(itype+1);
+    TLegend * legend = new TLegend(0.2,0.7,0.9,0.99,varSmooth[itype]);
+    legend->SetBorderSize(0);
+    for (Int_t ibin=0; ibin<5; ibin++){
+      hisInputs3D[itype]->GetXaxis()->SetRange(ibin+1,ibin+1);
+      Double_t radius=hisInputs3D[itype]->GetXaxis()->GetBinCenter(ibin+1);
+      TH2 * his2D= (TH2*)hisInputs3D[itype]->Project3D("zy");
+      his2D->FitSlicesY(0,0,-1,0,"QNR",&garrayFit);
+      delete his2D;
+      TH1* his1D = (TH1*)garrayFit.At(2)->Clone();
+      fitResols.AddLast(his1D);
+      his1D->SetMarkerColor(kColors[ibin%6]);
+      his1D->SetMarkerStyle(kMarkers[ibin%6]);
+      his1D->SetMinimum(0);
+      his1D->SetMaximum(0.75);
+      his1D->GetXaxis()->SetTitle("#sigma_{kernel} (cm) in 3D (r,r#phi,z)");
+      his1D->GetYaxis()->SetTitle("#sigma_{r#phi} (mm)");
+      if (ibin==0) his1D->Draw();
+      his1D->Draw("same");
+      legend->AddEntry(his1D,TString::Format("R=%2.0f (cm)",radius));
+    }
+    legend->Draw();
+  }
+  canvasSmooth->SaveAs("DistortionAlignmentSmooth3D.pdf");
+  canvasSmooth->SaveAs("DistortionAlignmentSmooth3D.pdf");
+
+
+
+}
+
+void FFTexample(){
+  //
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localCurrent.root","update");
+  //
+  TFile *fCurrent = TFile::Open("SpaceChargeFluc10_1.root");
+  TFile *fRef = TFile::Open("SpaceChargeFluc0_1.root");
+  //  
+  AliTPCSpaceCharge3D* distortion = ( AliTPCSpaceCharge3D*)fCurrent->Get("DistRef"); 
+  AliTPCSpaceCharge3D* distortionRef = ( AliTPCSpaceCharge3D*)fRef->Get("DistRef"); 
+
+  distortion->AddVisualCorrection(distortion,1);
+  distortionRef->AddVisualCorrection(distortionRef,2);
+  //
+  TF2 f2("f2","AliTPCCorrection::GetCorrXYZ(x,0,y,0,1)-1.07*AliTPCCorrection::GetCorrXYZ(x,0,y,0,2)",85,245,0,250);
+  TF2 f2c("f2c","AliTPCCorrection::GetCorrXYZ(x,0,y,0,1)-1.07*AliTPCCorrection::GetCorrXYZ(x,0,y,0,2)+sqrt(12.)*(rndm-0.5)*0.04",85,245,0,250);
+  f2.SetNpx(32); f2.SetNpy(32);
+  f2c.SetNpx(32); f2c.SetNpy(32);
+  f2.Draw("colz");
+  f2c.Draw("colz");
+  
+  TH2D * his2D = (TH2D*)f2.GetHistogram();
+  TH2D * his2Dc = (TH2D*)f2c.GetHistogram();
+  TH2D * his2DSmooth=new TH2D(*his2Dc);
+  Double_t sigma = 3;
+  Int_t nx=his2D->GetXaxis()->GetNbins();
+  Int_t ny=his2D->GetYaxis()->GetNbins();
+  //
+  for (Int_t ibin=2; ibin<=nx-1;ibin++){
+    for (Int_t jbin=2; jbin<ny-1;jbin++){
+      TLinearFitter fitter(4,"hyp3");
+      for (Int_t di=-3; di<=3; di++)
+       for (Int_t dj=-3; dj<=3; dj++){
+         if (ibin+di<=1) continue;
+         if (jbin+dj<=1) continue;
+         if (ibin+di>=nx) continue;
+         if (jbin+dj>=ny) continue;
+         Double_t x[3]={di,dj,dj*dj};
+         Double_t w = 1./(TMath::Gaus(di/sigma)*TMath::Gaus(dj/sigma));          
+         Double_t y = his2Dc->GetBinContent(ibin+di,jbin+dj);
+         fitter.AddPoint(x,y,w);
+       }
+      fitter.Eval();
+      printf("%d\t%d\t%3.3f\n",ibin,jbin,10*(fitter.GetParameter(0)-his2Dc->GetBinContent(ibin,jbin)));
+      his2DSmooth->SetBinContent(ibin,jbin,fitter.GetParameter(0));
+    } 
+  }
+  TH2D hisDiff=*his2DSmooth;
+  hisDiff.Add(his2D,-1);
+  
+
+  TH1 * hisMag = his2D->FFT(0,"MAG");
+  TH1 * hisMagc = his2Dc->FFT(0,"MAG");
+  TH1 * hisPhi = his2D->FFT(0,"PH");
+  TH1 * hisPhic = his2Dc->FFT(0,"PH");
+  hisMag->Draw("surf2");
+  hisMagc->Draw("surf2");
+
+    
+}
+
+/*
+void MakeFFT(){
+  //
+  //
+  //
+  Int_t nSize = 125;
+  TVirtualFFT *fft_own = TVirtualFFT::FFT(1, &nSize, "R2C ES K");
+  fft_own->SetPoints(normZR->GetMatrixArray());
+  fft_own->Transform();
+
+  TH1 *hre = 0, *hco=0;  
+  hre = TH1::TransformHisto(fft_own, hre, "RE");
+  hco = TH1::TransformHisto(fft_own, hco, "C");
+
+
+  hr->SetTitle("Real part of the 3rd (array) tranfsorm");
+  hr->Draw();
+  hr->SetStats(kFALSE);
+  hr->GetXaxis()->SetLabelSize(0.05);
+  hr->GetYaxis()->SetLabelSize(0.05);
+  c1_6->cd();
+  TH1 *him = 0;
+  him = TH1::TransformHisto(fft_own, him, "IM");
+  him->SetTitle("Im. part of the 3rd (array) transform");
+  him->Draw();
+  him->SetStats(kFALSE);
+  him->GetXaxis()->SetLabelSize(0.05);
+  him->GetYaxis()->SetLabelSize(0.05);
+  //
+}
+*/
diff --git a/TPC/Upgrade/macros/makeCurrentCorrection.sh b/TPC/Upgrade/macros/makeCurrentCorrection.sh
new file mode 100755 (executable)
index 0000000..7e6b2a4
--- /dev/null
@@ -0,0 +1,53 @@
+#  
+# shell script to submit small jobs for the current makeCurrentCorrection.C root macro
+# used for the TPC TDR studies 
+#         
+source $1 
+aliroot -b -q $flucPath/NimStyle.C $ALICE_ROOT/TPC/Upgrade/macros/makeCurrentCorrection.C+\($2,$3,$4\)
+exit;
+
+#
+# Example usage local jobs to be submitted form the lxb1001 or lxb1002
+#(here we have 80 nodes and user disk)
+#
+
+makeEnvLocal(){
+#
+#
+#
+    export baliceTPC=/u/miranov/.baliceTPC
+    export flucPath=$HOME/AliRoot/git/TPCdev/TPC/Upgrade/macros/
+    export batchCommand="qsub -cwd  -V "
+}
+
+submitCurrentExtractionJobs(){
+#
+# Action
+# 1.) submit current extraction jobs
+#
+    wdir=`pwd`
+    counter=0;
+    for a in `ls -d dir*`; do
+       cd $wdir/$a
+       rm localCurent.root current.log 
+       $batchCommand    -o  current.log  $flucPath/makeCurrentCorrection.sh $baliceTPC  0  20000 $counter
+       let counter=counter+1
+       cd $wdir
+    done;
+}
+
+submitSmoothingJobs(){
+#
+# Action:
+# 2.) Submit smoothing jobs
+#
+    for imap  in {0..40}; do
+       mkdir /hera/alice/miranov/SpaceCharge/Smoothing2D_2/test$imap
+       cd  /hera/alice/miranov/SpaceCharge/Smoothing2D_2/test$imap
+       ln -sf /hera/alice/wiechula/Upgrade/LUTs_fluctuation_eps20/MeasuredResidual2D/residualMap.$imap.root MeasureResidual.root
+       ln -sf /hera/alice/wiechula/Upgrade/LUTs_fluctuation_eps20/RealResidualScaled/residualMap.$imap.root RealResidualScaled.root
+       cd  /hera/alice/miranov/SpaceCharge/Smoothing2D_2/test$imap
+       $batchCommand    -o  smoothing.log  $flucPath/makeCurrentCorrection.sh $baliceTPC  1 2000 80 $imap
+    done;
+}
+
diff --git a/TPC/Upgrade/macros/makeResidualSpaceChargeOCDB.C b/TPC/Upgrade/macros/makeResidualSpaceChargeOCDB.C
new file mode 100644 (file)
index 0000000..f6c5edd
--- /dev/null
@@ -0,0 +1,273 @@
+//
+// macro to create a residual OCDB 
+//
+
+/*
+//
+//
+//
+.x $ALICE_ROOT/TPC/Upgrade/macros/ConfigOCDB.C(1)
+.L $ALICE_ROOT/TPC/Upgrade/macros/makeResidualSpaceChargeOCDB.C
+
+Example usage:
+
+ln -sf /hera/alice/wiechula/Upgrade/LUTs_fluctuation/dir1/SpaceChargeFluc10_1.lookup.root current.root
+ln -sf /hera/alice/wiechula/Upgrade/LUTs_fluctuation/average/SpaceChargeFluc0_1.lookup.root  mean.root
+ln -sf $ALICE_ROOT/OCDB/TPC/Calib/Correction/Run0_999999999_v0_s2.root ocdb.root
+aliroot -b -q $ALICE_ROOT/TPC/Upgrade/macros/makeResidualSpaceChargeOCDB.C
+
+*/
+
+void makeResidualSpaceChargeOCDBLookup(const char *ocdbInName="ocdb.root",const char *scCurrentName="current.root", const char *scMeanName="mean.root"){
+  //
+  // Macro to create a clone original  OCDB entry with space point distortion and add there space point
+  // distortions cause by resifual sapce charge
+  // Output is stored by default in the current directory.
+  // 
+
+  // Parameters to Specify:
+  //    ocdbInName      : path to the original OCDB entry
+  //    scCurrentName   : path to the fluctuetaed distortion map
+  //    scMeanName      : path to the mean distortion map
+  //    
+  
+  /*
+    scCurrentName="/hera/alice/wiechula/Upgrade/LUTs_fluctuation/dir1/SpaceChargeFluc10_1.lookup.root";
+    scMeanName="/hera/alice/wiechula/Upgrade/LUTs_fluctuation/average/SpaceChargeFluc0_1.lookup.root";
+    ocdbInName="$ALICE_ROOT/OCDB/TPC/Calib/Correction/Run0_999999999_v0_s2.root"
+  */
+  TFile * finCurrent = TFile::Open(scCurrentName);
+  TFile * finMean = TFile::Open(scMeanName);
+  //
+  AliTPCCorrectionLookupTable *spaceChargeCurrent=  (AliTPCCorrectionLookupTable *)finCurrent->Get("map");
+  AliTPCCorrectionLookupTable *spaceChargeMean   =  (AliTPCCorrectionLookupTable *)finMean->Get("map");
+  AliTPCInverseCorrection * spaceChargeInverseMean = new AliTPCInverseCorrection(spaceChargeMean);
+  //
+  TObjArray * arraySC = new TObjArray(2);
+  arraySC->AddAt(spaceChargeCurrent,0);
+  arraySC->AddAt(spaceChargeMean,1);
+  AliTPCComposedCorrection *corrSC = new AliTPCComposedCorrection(arraySC,AliTPCComposedCorrection::kParallel);
+  AliTPCComposedCorrection *corrSCW = new AliTPCComposedCorrection(arraySC,AliTPCComposedCorrection::kParallel);
+  AliTPCComposedCorrection::AddVisualCorrection(spaceChargeCurrent,1);
+  AliTPCComposedCorrection::AddVisualCorrection(spaceChargeMean,2);
+  AliTPCComposedCorrection::AddVisualCorrection(spaceChargeInverseMean,3);
+  AliTPCComposedCorrection::AddVisualCorrection(corrSC,4);
+  AliTPCComposedCorrection::AddVisualCorrection(corrSCW,5);
+  //
+  //
+  TLinearFitter fitterR(2,"pol1");
+  for (Int_t ipoint =0; ipoint<10000; ipoint++){
+    Double_t z0 = -250+gRandom->Rndm()*500;
+    Double_t r0   = 85+gRandom->Rndm()*(245-85.);
+    Double_t phi0 = gRandom->Rndm()*TMath::TwoPi();
+    // some problematic parts to be skipped  - investigated later
+    Double_t xvalue[2]={0};
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,1))>50) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,2))>50) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1))>20) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,2))>20) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,1))>50) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,2))>50) continue;
+    //
+    //
+    xvalue[0]=AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,2);
+    fitterR.AddPoint(xvalue,AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,1));
+  }
+  fitterR->Eval();
+  TVectorD weights(2);
+  weights[0]=1;
+  weights[1]=-1;
+  corrSC->SetWeights( &weights);
+  weights[1]=-fitterR->GetParameter(1);
+  corrSCW->SetWeights( &weights);
+  //
+  //
+  //
+  TF1 *fSC = new TF1("fSC","AliTPCCorrection::GetCorrXYZ(x,0,10,0,4)",85,245);  
+  TF1 *fSCW = new TF1("fSCW","AliTPCCorrection::GetCorrXYZ(x,0,10,0,5)",85,245);
+  fSC->SetLineColor(2);
+  fSC->SetLineColor(4);
+  fSC->Draw();
+  fSCW->Draw("same");
+  gPad->SaveAs("residualMap.pdf");
+  
+  //
+  //
+  //
+  TFile *fileOCDBIn=TFile::Open(ocdbInName);
+  AliCDBEntry   *entry =  ( AliCDBEntry   *)fileOCDBIn->Get("AliCDBEntry");
+  TObjArray * array = (TObjArray*)entry->GetObject();
+  for (Int_t i=0;  i<3;  i++){
+    AliTPCComposedCorrection *corr = ( AliTPCComposedCorrection*)array->At(i);
+    if (corr){
+      TObjArray* corrArray = corr->GetCorrections();
+      corrArray->AddLast(corrSCW);
+    }    
+  }
+  AliCDBMetaData *metaData= new AliCDBMetaData();
+  metaData->SetObjectClassName("TObjArray");
+  metaData->SetResponsible("Marian Ivanov");
+  metaData->SetBeamPeriod(1);
+  metaData->SetAliRootVersion("05-25-01"); //root version
+  metaData->SetComment("Standard+fluctuation");
+  AliCDBId* id1=NULL;
+  id1=new AliCDBId("TPC/Calib/Correction", 0, 9999999999999999);
+  //
+  TString localStorage = "local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
+  pocdbStorage = AliCDBManager::Instance()->GetStorage(localStorage.Data());
+  pocdbStorage->Put(array, (*id1), metaData);
+
+
+}
+
+
+
+
+
+void makeResidualSpaceChargeOCDB(const char *ocdbInName="ocdb.root",const char *scCurrentName="current.root", const char *scMeanName="mean.root"){
+  //
+  // Macro to create a clone original  OCDB entry with space point distortion and add there space point
+  // distortions cause by resifual sapce charge
+  // Output is stored by default in the current directory.
+  // 
+
+  // Parameters to Specify:
+  //    ocdbInName      : path to the original OCDB entry
+  //    scCurrentName   : path to the fluctuetaed distortion map
+  //    scMeanName      : path to the mean distortion map
+  //    
+  
+  /*
+    scCurrentName="/hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain/dirmergeAll/dEpsilon20/dir0/SpaceChargeFluc10_1.root";
+    scMeanName="/hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain/dirmergeAll/dEpsilon20/dir0//SpaceChargeFluc0_1.root";
+    ocdbInName="$ALICE_ROOT/OCDB/TPC/Calib/Correction/Run0_999999999_v0_s2.root"
+  */
+  TFile * finCurrent = TFile::Open(scCurrentName);
+  TFile * finMean = TFile::Open(scMeanName);
+  //
+  AliTPCCorrectionLookupTable *spaceChargeCurrent=  (AliTPCCorrectionLookupTable *)finCurrent->Get("DistRef");
+  AliTPCCorrectionLookupTable *spaceChargeMean   =  (AliTPCCorrectionLookupTable *)finMean->Get("DistRef");
+  AliTPCInverseCorrection * spaceChargeInverseMean = new AliTPCInverseCorrection(spaceChargeMean);
+  //
+  TObjArray * arraySC = new TObjArray(2);
+  arraySC->AddAt(spaceChargeCurrent,0);
+  arraySC->AddAt(spaceChargeMean,1);
+  AliTPCComposedCorrection *corrSC = new AliTPCComposedCorrection(arraySC,AliTPCComposedCorrection::kParallel);
+  AliTPCComposedCorrection *corrSCW = new AliTPCComposedCorrection(arraySC,AliTPCComposedCorrection::kParallel);
+  AliTPCComposedCorrection::AddVisualCorrection(spaceChargeCurrent,1);
+  AliTPCComposedCorrection::AddVisualCorrection(spaceChargeMean,2);
+  AliTPCComposedCorrection::AddVisualCorrection(spaceChargeInverseMean,3);
+  AliTPCComposedCorrection::AddVisualCorrection(corrSC,4);
+  AliTPCComposedCorrection::AddVisualCorrection(corrSCW,5);
+  //
+  //
+  TLinearFitter fitterR(2,"pol1");
+  for (Int_t ipoint =0; ipoint<10000; ipoint++){
+    Double_t z0 = -250+gRandom->Rndm()*500;
+    Double_t r0   = 85+gRandom->Rndm()*(245-85.);
+    Double_t phi0 = gRandom->Rndm()*TMath::TwoPi();
+    // some problematic parts to be skipped  - investigated later
+    Double_t xvalue[2]={0};
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,1))>50) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,2))>50) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1))>20) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,2))>20) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,1))>50) continue;
+    if (TMath::Abs(AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,2))>50) continue;
+    //
+    //
+    xvalue[0]=AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,2);
+    fitterR.AddPoint(xvalue,AliTPCCorrection::GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1));
+  }
+  fitterR->Eval();
+  TVectorD weights(2);
+  weights[0]=1;
+  weights[1]=-1;
+  corrSC->SetWeights( &weights);
+  weights[1]=-fitterR->GetParameter(1);
+  corrSCW->SetWeights( &weights);
+  //
+  //
+  //
+  TF1 *fSC = new TF1("fSC","AliTPCCorrection::GetCorrXYZ(x,0,10,1,4)",85,245);  
+  TF1 *fSCW = new TF1("fSCW","AliTPCCorrection::GetCorrXYZ(x,0,10,1,5)",85,245);
+  fSC->SetLineColor(2);
+  fSC->SetLineColor(4);
+  fSC->GetXaxis()->SetTitle(" R (cm)");
+  fSC->GetYaxis()->SetTitle(" #Delta_{R#phi} (cm)");
+  TCanvas * canvasDist = new TCanvas("canvasDist","canvasDist",600,500);
+  TF1 *f1sc = new TF1("f1sc","[0]+[1]*x+[2]*x**2",85,245);
+  TF1 *f1scw = new TF1("f1scw","[0]+[1]*x+[2]*x**2",85,245);
+
+  {
+    fSC->Draw();
+    fSCW->Draw();
+    fSC->SetMinimum(-1);
+    fSC->SetMaximum(2.);
+    fSC->GetHistogram()->SetLineColor(2);
+    fSCW->GetHistogram()->SetLineColor(4);
+    //
+    f1sc->SetLineColor(2);
+    f1scw->SetLineColor(4);
+    f1sc->SetLineWidth(0.5);
+    f1scw->SetLineWidth(0.5);
+    //
+    fSC->GetHistogram()->Fit(f1sc);
+    fSCW->GetHistogram()->Fit(f1scw);
+    //
+    fSC->GetHistogram()->Draw("");
+    fSCW->GetHistogram()->Draw("same");
+    //
+    TF1 *f1scp=new TF1(*f1sc);
+    TF1 *f1scm=new TF1(*f1sc);
+    f1scp->SetLineStyle(2); f1scm->SetLineStyle(2);
+    f1scp->SetParameter(0, f1sc->GetParameter(0)+ 0.3);
+    f1scm->SetParameter(0, f1sc->GetParameter(0)- 0.3);
+    f1scp->Draw("same");
+    f1scm->Draw("same");
+    //
+    TF1 *f1scwp=new TF1(*f1scw);
+    TF1 *f1scwm=new TF1(*f1scw);
+    f1scwp->SetLineStyle(2); f1scwm->SetLineStyle(2);
+    f1scwp->SetParameter(0, f1scw->GetParameter(0)+ 0.3);
+    f1scwm->SetParameter(0, f1scw->GetParameter(0)- 0.3);
+    f1scwp->Draw("same");
+    f1scwm->Draw("same");
+  }
+  TLegend * legend = new TLegend(0.3,0.5,0.89,0.89,"Residual #Delta_{R#phi} distortions and helix fit");
+  legend->SetBorderSize(0);
+  legend->AddEntry(fSC->GetHistogram(),"Stage 0: #Delta_{R#phic}-#Delta_{R#phimean}");
+  legend->AddEntry(fSCW->GetHistogram(),"Stage 1: #Delta_{R#phic}-k_{fit}#Delta_{R#phimean}");
+  legend->Draw();
+  gPad->SaveAs("residualMapTrackFit.pdf");
+  
+  //
+  //
+  //
+  TFile *fileOCDBIn=TFile::Open(ocdbInName);
+  AliCDBEntry   *entry =  ( AliCDBEntry   *)fileOCDBIn->Get("AliCDBEntry");
+  TObjArray * array = (TObjArray*)entry->GetObject();
+  for (Int_t i=0;  i<3;  i++){
+    AliTPCComposedCorrection *corr = ( AliTPCComposedCorrection*)array->At(i);
+    if (corr){
+      TObjArray* corrArray = corr->GetCorrections();
+      corrArray->AddLast(corrSCW);
+    }    
+  }
+  AliCDBMetaData *metaData= new AliCDBMetaData();
+  metaData->SetObjectClassName("TObjArray");
+  metaData->SetResponsible("Marian Ivanov");
+  metaData->SetBeamPeriod(1);
+  metaData->SetAliRootVersion("05-25-01"); //root version
+  metaData->SetComment("Standard+fluctuation");
+  AliCDBId* id1=NULL;
+  id1=new AliCDBId("TPC/Calib/Correction", 0, 9999999999999999);
+  //
+  TString localStorage = "local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
+  pocdbStorage = AliCDBManager::Instance()->GetStorage(localStorage.Data());
+  pocdbStorage->Put(array, (*id1), metaData);
+
+
+}
+
+
index b86f074ddbe6608e9dd17302c85039749fba7e96..2b807545ea95a7229df008228ca8cff491ab5358 100755 (executable)
@@ -7,11 +7,16 @@ SCtype=$4
 nevents=$5
 ntracks=$6
 rate=$7
+gas=$8
 
 if [ "x$rate" == "x" ]; then
   rate=50
 fi
 
+if [ "x$gas" == "x" ]; then
+  gas=0
+fi
+  
 module use /cvmfs/alice.gsi.de/modules
 module purge
 #module load ALICE/${vers}
@@ -21,4 +26,5 @@ module load $mod
 test -d $outDir || mkdir -p $outDir
 cd $outDir
 
-root.exe -l -b -q $ALICE_ROOT/TPC/Upgrade/macros/{loadlibs.C,ConfigOCDB.C} $ALICE_ROOT/TPC/Upgrade/macros/runSimRec.C\($simtype,$SCtype,$nevents,$ntracks,$rate\)
+echo root.exe -l -b -q $ALICE_ROOT/TPC/Upgrade/macros/{loadlibs.C,ConfigOCDB.C} $ALICE_ROOT/TPC/Upgrade/macros/runSimRec.C\($simtype,$SCtype,$nevents,$ntracks,$rate,$gas\)
+root.exe -l -b -q $ALICE_ROOT/TPC/Upgrade/macros/{loadlibs.C,ConfigOCDB.C} $ALICE_ROOT/TPC/Upgrade/macros/runSimRec.C\($simtype,$SCtype,$nevents,$ntracks,$rate,$gas\)
index 1ff502b84ee6566085f6dfff73ee30d7549b6d11..6f7f04cd189b86d4d8874e8fc92efecafc323a9d 100644 (file)
@@ -1,6 +1,10 @@
-void runSimRec(Int_t simtype, Int_t SCtype, Int_t nevents, Int_t ntracks, Int_t rate=50)
+void runSimRec(Int_t simtype, Int_t SCtype, Int_t nevents, Int_t ntracks, Int_t rate=50, Int_t gas=0)
 {
   //rate is in kHz
+  // recType: 0 = LongT0
+  //          1 = noLongT0 
+  //          2 = LongT0, T0list
+  //          3 = LongT0, Z0list
 
   Int_t recoType=simtype/10;
   recoType%=10;
@@ -13,7 +17,7 @@ void runSimRec(Int_t simtype, Int_t SCtype, Int_t nevents, Int_t ntracks, Int_t
   TString outputFile="toyMC";
 
   //for simtype also below
-  switch (simtype) {
+  switch (simtype%2) {
     case 0:
       outputFile.Append(Form("_fixed_%dkHz",rate));
       break;
@@ -21,20 +25,49 @@ void runSimRec(Int_t simtype, Int_t SCtype, Int_t nevents, Int_t ntracks, Int_t
       outputFile.Append(Form("_train_%dkHz",rate));
       break;
   }
+
+  AliToyMCEventGeneratorSimple::EGasType gasType=AliToyMCEventGeneratorSimple::kNeCO2_9010;
+  
+  switch (gas) {
+    case 0:
+      gasType=AliToyMCEventGeneratorSimple::kNeCO2_9010;
+      outputFile.Append("_NeCO2");
+      break;
+    case 1:
+      gasType=AliToyMCEventGeneratorSimple::kNeCO2N2_90105;
+      outputFile.Append("_NeCO2N2");
+      break;
+  }
   
   switch (SCtype) {
     case 0:
-      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps5);
+      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps5, gasType);
       outputFile.Append("_eps05");
       break;
     case 1:
-      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps10);
+      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps10, gasType);
       outputFile.Append("_eps10");
       break;
     case 2:
-      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps20);
+      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps20, gasType);
       outputFile.Append("_eps20");
       break;
+    case 3:
+      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps25, gasType);
+      outputFile.Append("_eps25");
+      break;
+    case 4:
+      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps30, gasType);
+      outputFile.Append("_eps30");
+      break;
+    case 5:
+      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps35, gasType);
+      outputFile.Append("_eps35");
+      break;
+    case 6:
+      s.SetSpaceCharge(AliToyMCEventGeneratorSimple::kEps40, gasType);
+      outputFile.Append("_eps40");
+      break;
   }
 
   outputFile.Append(Form("_%04dev_%04dtr",nevents,ntracks));
@@ -53,34 +86,52 @@ void runSimRec(Int_t simtype, Int_t SCtype, Int_t nevents, Int_t ntracks, Int_t
 
   //reconstruction part
   AliToyMCReconstruction rec;
+  rec.SetForceAlpha(kTRUE);
   // rec.SetUseMaterialBudget(kTRUE)
+  if (recoType==0) {
+    rec.SetFillClusterRes(kTRUE);
+    rec.SetLongT0seed(kTRUE);
+    //rec.SetUseT0list(kTRUE);
+  } else if (recoType==1) {
+    rec.SetFillClusterRes(kTRUE);
+    rec.SetLongT0seed(kFALSE);
+    //rec.SetUseT0list(kTRUE);
+  } else if (recoType==2) {
+    rec.SetFillClusterRes(kTRUE);
+    rec.SetLongT0seed(kTRUE);
+    rec.SetUseT0list(kTRUE);
+  } else if (recoType==3) {
+    rec.SetFillClusterRes(kTRUE);
+    rec.SetLongT0seed(kTRUE);
+    rec.SetUseZ0list(kTRUE);
+  }
 
-  if (recoType==0){
-    rec.SetRecoSettings(1,0,AliToyMCReconstruction::kNoCorrection);
-    if (!subRecoType||subRecoType==1) rec.RunReco(outputFile.Data());
+//  if (recoType==0){
+  rec.SetRecoSettings(1,0,AliToyMCReconstruction::kNoCorrection);
+  if (!subRecoType||subRecoType==1) rec.RunReco(outputFile.Data());
 
-    rec.SetRecoSettings(1,1,AliToyMCReconstruction::kIdeal);
-    if (!subRecoType||subRecoType==2) rec.RunReco(outputFile.Data());
+  rec.SetRecoSettings(1,1,AliToyMCReconstruction::kIdeal);
+  if (!subRecoType||subRecoType==2) rec.RunReco(outputFile.Data());
 
-    rec.SetRecoSettings(0,1,AliToyMCReconstruction::kIdeal);
-    if (!subRecoType||subRecoType==3) rec.RunReco(outputFile.Data());
+  rec.SetRecoSettings(0,1,AliToyMCReconstruction::kIdeal);
+  if (!subRecoType||subRecoType==3) rec.RunReco(outputFile.Data());
 
-    rec.SetRecoSettings(0,1,AliToyMCReconstruction::kAverageEta);
-    if (!subRecoType||subRecoType==4) rec.RunReco(outputFile.Data());
+  rec.SetRecoSettings(0,1,AliToyMCReconstruction::kAverageEta);
+  if (!subRecoType||subRecoType==4) rec.RunReco(outputFile.Data());
 
-    rec.SetRecoSettings(0,1,AliToyMCReconstruction::kNoCorrection);
-    if (!subRecoType||subRecoType==5) rec.RunReco(outputFile.Data());
+  rec.SetRecoSettings(0,1,AliToyMCReconstruction::kNoCorrection);
+  if (!subRecoType||subRecoType==5) rec.RunReco(outputFile.Data());
 
-    rec.SetRecoSettings(0,0,AliToyMCReconstruction::kNoCorrection);
-    if (!subRecoType||subRecoType==6) rec.RunReco(outputFile.Data());
-  }
+  rec.SetRecoSettings(0,0,AliToyMCReconstruction::kNoCorrection);
+  if (!subRecoType||subRecoType==6) rec.RunReco(outputFile.Data());
+// }
 
-  if (recoType==1) {
-    rec.SetRecoSettings(0,1,AliToyMCReconstruction::kNoCorrection);
-    if (!subRecoType||subRecoType==1) rec.RunFullTracking(outputFile.Data());
-    
-    rec.SetRecoSettings(0,0,AliToyMCReconstruction::kNoCorrection);
-    if (!subRecoType||subRecoType==2) rec.RunFullTracking(outputFile.Data());
-  }
+//  if (recoType==1) {
+//    rec.SetRecoSettings(0,1,AliToyMCReconstruction::kNoCorrection);
+//    if (!subRecoType||subRecoType==1) rec.RunFullTracking(outputFile.Data());
+//    
+//    rec.SetRecoSettings(0,0,AliToyMCReconstruction::kNoCorrection);
+//    if (!subRecoType||subRecoType==2) rec.RunFullTracking(outputFile.Data());
+//  }
   
 }
index c8c8eefa682e737527ab0164054c4655b530a79a..4212e91a952e9b53e4401a7ea43a036d201d2e99 100644 (file)
 #include "TStyle.h"
 #include "AliTPCSpaceCharge3D.h"
 #include "AliExternalTrackParam.h"
+#include "AliTrackerBase.h"
+#include "TDatabasePDG.h"
+#include "TROOT.h"
+#include "AliMathBase.h"
+#include "TLatex.h"
 //
 // constants
 //
@@ -76,6 +81,9 @@ TH3D *  PermutationHistoLocalPhi(TH3D * hisInput, Int_t deltaPhi);
 void MakeSpaceChargeFluctuationScan(Double_t scale, Int_t nfiles, Int_t sign);
 void DrawFluctuationdeltaZ(Int_t stat=0, Double_t norm=10000);
 void DrawFluctuationSector(Int_t stat=0, Double_t norm=10000);
+void MakeLocalDistortionPlotsGlobalFitPolDrift(Float_t xmin, Float_t xmax);
+void MakeLocalDistortionPlots(Int_t npoints=20000, Int_t npointsZ=10000);
+
 
 void spaceChargeFluctuation(Int_t mode=0, Float_t arg0=0, Float_t arg1=0, Float_t arg2=0){
   //
@@ -91,8 +99,23 @@ void spaceChargeFluctuation(Int_t mode=0, Float_t arg0=0, Float_t arg1=0, Float_
     DrawFluctuationdeltaZ(arg0,arg1);
     DrawFluctuationSector(arg0,arg1);
   }
+  if (mode==6) { 
+    MakeLocalDistortionPlotsGlobalFitPolDrift(arg0,arg1);
+  }
+  if (mode==7) { 
+    MakeLocalDistortionPlots(arg0,arg1);
+    
+  }
 }
 
+void SetGraphTDRStyle(TGraph * graph){
+  graph->GetXaxis()->SetLabelSize(0.08);
+  graph->GetXaxis()->SetTitleSize(0.08);
+  graph->GetYaxis()->SetLabelSize(0.08);
+  graph->GetYaxis()->SetTitleSize(0.08);
+  graph->GetXaxis()->SetNdivisions(505);
+  graph->GetYaxis()->SetNdivisions(510);
+}
 
 Double_t RndmdNchdY(Double_t s){
   //
@@ -1170,21 +1193,23 @@ void MakeSpaceChargeFluctuationScan(Double_t scale, Int_t nfilesMerge, Int_t sig
   //
   //
   // Input:
-  //   scale           - scaling of the space charge
+  //   scale           - scaling of the space charge (defaul 1 corrsponds to the epsilon ~ 5)
   //   nfilesMerge     - amount of chunks to merge
   //                   - =0  all chunks used
   //                     <0  subset form full statistic
-  //                     >0  subset from the  limited (1000 mean) stistic
+  //                     >0  subset from the  limited (1000 mean) statistic
+  // Output"  
+  // For given SC setups the distortion on the space point and track level characterezed
+  //    SpaceChargeFluc%d_%d.root        - space point distortion maps       
+  //    SpaceChargeTrackFluc%d%d.root    - tracks distortion caused by  space point distortion 
+  //
+
   // Make fluctuation scan:
   //   1.) Shift of z disk - to show which granularity in time needed
   //   2.) Shift in sector - to show influence of the gass gain and epsilon
   //   3.) Smearing in phi - to define phi granularity needed
-  //   4.) Rebin z
-  //   5.) Rebin phi
-  // For given SC setups the distortion on the space point and track level characterezed
-  //    SpaceChargeFluc%d_%d.root
-  //    SpaceChargeTrackFluc%d%d.root
-  //
+  //   4.) Rebin z         - commented out (not delete it for the moment)
+  //   5.) Rebin phi       - commented out 
   
 
   //
@@ -1192,7 +1217,7 @@ void MakeSpaceChargeFluctuationScan(Double_t scale, Int_t nfilesMerge, Int_t sig
   //
   Int_t nitteration=100;    // number of itteration in the lookup
   Int_t fullNorm  =10000;  // normalization  fro the full statistic
-
+  gROOT->ProcessLine(".x $ALICE_ROOT/TPC/Upgrade/macros/ConfigOCDB.C\(1\)");
   //
   // Init magnetic field and OCDB
   //
@@ -1467,10 +1492,19 @@ void MakeSpaceChargeFluctuationScan(Double_t scale, Int_t nfilesMerge, Int_t sig
       }
     }
   }
+  pcstream->GetFile()->cd();
+  for (Int_t idist=0; idist<ndist; idist++){
+    AliTPCCorrection * corr  = (AliTPCCorrection *)distortionArray->At(idist);
+    corr->Write(corr->GetName());
+  }
   delete pcstream;
   //
   // generate track distortions
   //
+  const Double_t xITSlayer[7]={2.2, 2.8 ,3.6 , 20, 22,41,43 };  // ITS layers R poition (http://arxiv.org/pdf/1304.1306v3.pdf)
+  const Double_t resITSlayer[7]={0.0004, 0.0004 ,0.0004 , 0.0004, 0.0004, 0.0004, 0.0004 };  // ITS layers R poition (http://arxiv.org/pdf/1304.1306v3.pdf - pixel scenario) 
+  const Double_t kMaxSnp = 0.85;   
+  const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
   if (nTracks>0){
     for(Int_t nt=1; nt<=nTracks; nt++){
       gRandom->SetSeed(nt);
@@ -1496,36 +1530,110 @@ void MakeSpaceChargeFluctuationScan(Double_t scale, Int_t nfilesMerge, Int_t sig
       Double_t refX1=1.;
       Int_t dir=-1;
       (*pcstreamTrack)<<"trackFit"<<
+       "bsign="<<bsign<<
        "neventsAll="<<neventsAll<<         // total number of events used for the Q reference
        "nfiles="<<nfiles<<                 // number of files to define properties
        "nfilesMerge="<<nfilesMerge<<       // number of files to define propertiesneventsCorr
        "neventsCorr="<<neventsCorr<<       // number of events used to define the corection
        "fullNorm="<<fullNorm<<             // in case full statistic used this is the normalization coeficient
-       "itrack="<<nt<<
-       "input.="<<t;
+       "itrack="<<nt<<                     //
+       "input.="<<t;                       // 
+      
+      Bool_t isOK0=kTRUE;
+      Bool_t isOK1=kTRUE;
+      Bool_t itsOK=kTRUE;
+      Bool_t itsUpdateOK=kTRUE;
+
       for (Int_t idist=0; idist<ndist; idist++){
        AliTPCCorrection * corr   = (AliTPCCorrection *)distortionArray->At(idist);
+       // 0. TPC only information at the entrance
+       // 1. TPC only information close to vertex ( refX=1 cm) 
+       // 2. TPC constrained information close to the primary vertex
+       // 3. TPC +ITS
        AliExternalTrackParam *ot0= new AliExternalTrackParam(vertex, pxyz, cv, psign);   
        AliExternalTrackParam *ot1= new AliExternalTrackParam(vertex, pxyz, cv, psign);   
        AliExternalTrackParam *td0 =  corr->FitDistortedTrack(*ot0, refX0, dir,  0);
        AliExternalTrackParam *td1 =  corr->FitDistortedTrack(*ot1, refX1, dir,  0);
+       if (td0==0) { // if fit fail use dummy values
+         ot0= new AliExternalTrackParam(vertex, pxyz, cv, psign);
+         td0= new AliExternalTrackParam(vertex, pxyz, cv, psign);
+         printf("Propagation0 failed: track\t%d\tdistortion\t%d\n",nt,idist);
+         isOK0=kFALSE;
+       }
+       if (td1==0) {
+         ot1= new AliExternalTrackParam(vertex, pxyz, cv, psign);
+         td1= new AliExternalTrackParam(vertex, pxyz, cv, psign);
+         printf("Propagation1 failed: track\t%d\tdistortion\t%d\n",nt,idist);
+         isOK1=kFALSE;
+       }
+       // 2. TPC constrained emulation
+       AliExternalTrackParam *tdConstrained =  new  AliExternalTrackParam(*td1);
+       tdConstrained->Rotate(ot1->GetAlpha());
+       tdConstrained->PropagateTo(ot1->GetX(), AliTrackerBase::GetBz());
+       Double_t pointPos[2]={ot1->GetY(),ot1->GetZ()};  // local y and local z of point
+       Double_t pointCov[3]={0.0001,0,0.0001};                    // 
+       tdConstrained->Update(pointPos,pointCov);
+       // 3. TPC+ITS  constrained umulation
+       AliExternalTrackParam *tdITS     =  new  AliExternalTrackParam(*td0); 
+       AliExternalTrackParam *tdITSOrig =  new  AliExternalTrackParam(*ot0); 
+       //
+       if ( isOK0 && isOK1 ) {
+         for (Int_t ilayer=6; ilayer>=0; ilayer--){
+           if (!AliTrackerBase::PropagateTrackTo(tdITSOrig,xITSlayer[ilayer],kMass,5.,kTRUE,kMaxSnp)) itsOK=kFALSE;
+           if (!AliTrackerBase::PropagateTrackTo(tdITS,xITSlayer[ilayer],kMass,5.,kTRUE,kMaxSnp)) {
+             itsOK=kFALSE;
+             printf("PropagationITS failed: track\t%d\tdistortion\t%d\t%d\n",nt,idist,ilayer);
+           }
+           //
+           tdITS->Rotate(tdITSOrig->GetAlpha());
+           if (tdITS->PropagateTo(tdITSOrig->GetX(), AliTrackerBase::GetBz())){
+             Double_t itspointPos[2]={tdITSOrig->GetY(),tdITSOrig->GetZ()};  // local y and local z of point
+             Double_t itspointCov[3]={resITSlayer[ilayer]*resITSlayer[ilayer],0,resITSlayer[ilayer]*resITSlayer[ilayer]};   
+             if (!tdITS->Update(itspointPos,itspointCov)){
+               itsUpdateOK=kFALSE;
+             }
+           }
+         } 
+       }else{
+         itsOK=kFALSE;
+       }
+       //
        trackArray.AddLast(td0);
        trackArray.AddLast(td1);
+       trackArray.AddLast(tdConstrained);
+       trackArray.AddLast(tdITS);
+       trackArray.AddLast(tdITSOrig);
+       //
        trackArray.AddLast(ot0);
        trackArray.AddLast(ot1);
-       char name0[100], name1[1000];
-       char oname0[100], oname1[1000];
+       char name0[100], name1[1000], nameITS[1000];
+       char oname0[100], oname1[1000], onameConstrained[1000], onameITS[1000];
        snprintf(name0, 100, "T_%s_0.=",corr->GetName());
        snprintf(name1, 100, "T_%s_1.=",corr->GetName());
        snprintf(oname0, 100, "OT_%s_0.=",corr->GetName());
        snprintf(oname1, 100, "OT_%s_1.=",corr->GetName());
+       snprintf(onameConstrained, 100, "OConst_%s_1.=",corr->GetName());
+       //
+       snprintf(nameITS, 100, "TPCITS_%s_1.=",corr->GetName());
+       snprintf(onameITS, 100, "OTPCITS_%s_1.=",corr->GetName());
        (*pcstreamTrack)<<"trackFit"<<
-         name0<<td0<< 
-         name1<<td1<< 
-         oname0<<ot0<< 
-         oname1<<ot1; 
+         name0<<td0<<                       // distorted TPC track only at the refX=85
+         name1<<td1<<                       // distorted TPC track only at the refX=1
+         onameConstrained<<tdConstrained<<  // distorted TPC constrained track only at the refX=1 
+         //
+         onameITS<<tdITSOrig<<              //  original TPC+ITS track
+         nameITS<<tdITS<<                   //  distorted TPC+ (indistrted)ITS track fit
+         //
+         oname0<<ot0<<                      // original track at the entrance refX=85
+         oname1<<ot1;                       // original track at the refX=1 cm (to be used for TPC only and also for the constrained
+       
       }
-      (*pcstreamTrack)<<"trackFit"<<"\n";
+      (*pcstreamTrack)<<"trackFit"<<
+       "isOK0="<<isOK0<<  // propagation good at the inner field cage
+       "isOK1="<<isOK1<<  // god at 1 cm (close to vertex)
+       "itsOK="<<itsOK<<  // 
+       "itsUpdateOK="<<itsOK<<  // 
+       "\n";
     }
   }
   delete pcstreamTrack;
@@ -1944,9 +2052,9 @@ void DrawTrackFluctuation(){
   TCut cutOut="abs(T_DistRef_0.fX-OT_DistRef_0.fX)<0.1&&T_DistRef_0.fX>1&&abs(OT_DistRef_0.fP[4])<4";
   TCut cutOutF="abs(R.T_DistRef_0.fX-R.OT_DistRef_0.fX)<0.1&&R.T_DistRef_0.fX>1&&abs(R.OT_DistRef_0.fP[4])<4";
   TChain * chains[5]={0};
-  TChain * chainR = AliXRDPROOFtoolkit::MakeChain("track0_1.list","trackFit",0,1000);
+  TChain * chainR = AliXRDPROOFtoolkit::MakeChain("track0_1.list","trackFit",0,1000);  // list of the reference data (full stat used)
   chainR->SetCacheSize(1000000000);
-  for (Int_t ichain=0; ichain<5; ichain++){
+  for (Int_t ichain=0; ichain<5; ichain++){ // create the chain for given mulitplicity bin 
     chains[ichain] = AliXRDPROOFtoolkit::MakeChain(Form("track%d_1.list",2*(ichain+1)),"trackFit",0,1000);
     chains[ichain]->AddFriend(chainR,"R");
     chains[ichain]->SetCacheSize(1000000000);
@@ -2201,7 +2309,7 @@ void DrawTrackFluctuationFrame(){
       ftrackFit->Flush();
     }
   }
-
   for (Int_t ihis=0; ihis<7; ihis++){
     printf("\n\nProcessing frames\t%d\nnn",(ihis+1)*2000);
     hisM = (TH2F*)ftrackFit->Get(Form("hisMean_%d",(ihis+1)*2000));
@@ -2274,3 +2382,807 @@ void DrawTrackFluctuationFrame(){
   canvasFit->SaveAs("canvasFrameFitRPhiVersion0.png");
   //
 }
+
+
+
+void MakeLocalDistortionPlotsGlobalFitPolDrift(Float_t xmin, Float_t xmax){
+  //
+  // Make local distortion plots correcting using global z fits of order 0,2,4,6,8,10,12
+  // Currently polynomial correction as an multiplicative factor of the mean distortion map used
+  // To be done - calculate numerical derivative of distortion maps 
+  //              corresponding  the local change of densities - after TDR?  
+  //
+  // As input:
+  //    1.) distortion file with the setup 10000 pileup events used
+  //    2.) mean distortion file
+  // distortions are fitted rescaling (z dependent) mean distortion file
+  //
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localFit.root","update");
+  TFile *fRef = TFile::Open("SpaceChargeFluc0_1.root");
+  TFile *fCurrent = TFile::Open("SpaceChargeFluc10_1.root");
+  TTree * treeRef = (TTree*)fRef->Get("hisDump");  
+  TTree * treeCurrent = (TTree*)fCurrent->Get("hisDump");  
+  treeCurrent->AddFriend(treeRef,"R");
+  treeCurrent->SetAlias("refR","(neventsCorr*R.DistRefDR/10000)");
+  treeCurrent->SetAlias("refRPhi","(neventsCorr*R.DistRefDRPhi/10000)");
+  treeCurrent->SetCacheSize(1000000000);
+  treeCurrent->SetAlias("drift","1.-abs(z/250.)");
+  TStatToolkit toolkit;
+  Double_t chi2=0;
+  Int_t    npoints=0;
+  TVectorD param;
+  TMatrixD covar;  
+  //
+  TCut cut="z>0";
+  TString  fstringG0="refR++";              // global part - for z dependence we should use the Chebischev
+  TString  fstringG1="refR++";              // global part - for z dependence we should use the Chebischev
+  TString  fstringG2="refR++";              // global part - for z dependence we should use the Chebischev
+  TString  fstringG3="refR++";              // global part - for z dependence we should use the Chebischev
+  TString  fstringG4="refR++";              // global part - for z dependence we should use the Chebischev
+  TString  fstringG5="refR++";              // global part - for z dependence we should use the Chebischev
+  TString  fstringG6="refR++";              // global part - for z dependence we should use the Chebischev
+  TString  fstringG7="refR++";              // global part - for z dependence we should use the Chebischev
+  TString  fstringG8="refR++";              // global part - for z dependence we should use the Chebischev
+  //
+  for (Int_t i=1; i<=1; i++) fstringG1+=TString::Format("refR*pow(drift,%d)++",i);
+  for (Int_t i=1; i<=2; i++) fstringG2+=TString::Format("refR*pow(drift,%d)++",i);
+  for (Int_t i=1; i<=3; i++) fstringG3+=TString::Format("refR*pow(drift,%d)++",i);
+  for (Int_t i=1; i<=4; i++) fstringG4+=TString::Format("refR*pow(drift,%d)++",i);
+  for (Int_t i=1; i<=5; i++) fstringG5+=TString::Format("refR*pow(drift,%d)++",i);
+  for (Int_t i=1; i<=6; i++) fstringG6+=TString::Format("refR*pow(drift,%d)++",i);
+  for (Int_t i=1; i<=7; i++) fstringG7+=TString::Format("refR*pow(drift,%d)++",i);
+  for (Int_t i=1; i<=8; i++) fstringG8+=TString::Format("refR*pow(drift,%d)++",i);
+
+
+  TString * fitResultG0 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG0.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  TString * fitResultG1 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG1.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  TString * fitResultG2 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG2.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  TString * fitResultG3 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG3.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  TString * fitResultG4 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG4.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  TString * fitResultG5 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG5.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  TString * fitResultG6 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG6.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  TString * fitResultG7 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG7.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  TString * fitResultG8 = TStatToolkit::FitPlane(treeCurrent,"DistRefDR-refR", fstringG8.Data(),cut+"Entry$%7==0", chi2,npoints,param,covar,-1,0,180000 , kFALSE);
+  //
+  treeCurrent->SetAlias("fitG0",fitResultG0->Data());  
+  treeCurrent->SetAlias("fitG1",fitResultG1->Data());  
+  treeCurrent->SetAlias("fitG2",fitResultG2->Data());  
+  treeCurrent->SetAlias("fitG3",fitResultG3->Data());  
+  treeCurrent->SetAlias("fitG4",fitResultG4->Data());  
+  treeCurrent->SetAlias("fitG5",fitResultG5->Data());  
+  treeCurrent->SetAlias("fitG6",fitResultG6->Data());  
+  treeCurrent->SetAlias("fitG7",fitResultG7->Data());  
+  treeCurrent->SetAlias("fitG8",fitResultG8->Data());  
+  treeCurrent->SetMarkerStyle(25);
+  treeCurrent->SetMarkerSize(0.2);
+  //
+  gStyle->SetOptFit(1);
+  gStyle->SetOptStat(0);
+  gStyle->SetOptTitle(1);
+
+  TCut cutDrawGraph="z>0&&abs(z-30)<5&&abs(r-90)<10";
+  TCut cutDrawHisto="z>0&&abs(z)<125&&abs(r-90)<10";
+  TH1F *hisFull=new TH1F("hisFull","hisFull",100,xmin,xmax);
+  TH1F *hisG0=new TH1F("hisG0","hisG0",100,xmin,xmax);
+  TH1F *hisG1=new TH1F("hisG1","hisG1",100,xmin,xmax);
+  TH1F *hisG2=new TH1F("hisG2","hisG2",100,xmin,xmax);
+  TH1F *hisG3=new TH1F("hisG3","hisG3",100,xmin,xmax);
+  TH1F *hisG4=new TH1F("hisG4","hisG4",100,xmin,xmax);
+  TH1F *hisG5=new TH1F("hisG5","hisG5",100,xmin,xmax);
+  TH1F *hisG6=new TH1F("hisG6","hisG6",100,xmin,xmax);
+  TH1F *hisG7=new TH1F("hisG7","hisG7",100,xmin,xmax);
+  TH1F *hisG8=new TH1F("hisG8","hisG8",100,xmin,xmax);
+  TH1F * hisResG[10]={hisFull, hisG0, hisG1,hisG2, hisG3,hisG4, hisG5,hisG6, hisG7,hisG8};
+  treeCurrent->Draw("DistRefDR-refR>>hisFull",cutDrawHisto,"");
+  for (Int_t ihis=0; ihis<9; ihis++){
+    treeCurrent->Draw(TString::Format("DistRefDR-refR-fitG%d>>hisG%d",ihis,ihis),cutDrawHisto,"");        
+  }
+  //
+  TF1 *fg = new TF1("fg","gaus");
+  TVectorD vecP(10), vecRes(10), vecResE(10);
+  for (Int_t ihis=0; ihis<10; ihis++){
+    hisResG[ihis]->Fit(fg);
+    vecP[ihis]=ihis-1;
+    vecRes[ihis]=fg->GetParameter(2);
+    vecResE[ihis]=fg->GetParError(2);
+    hisResG[ihis]->GetXaxis()->SetTitle("#Delta_{R} (cm)");
+    pcstream->GetFile()->cd();
+    hisResG[ihis]->Write();
+    (*pcstream)<<"residuals"<<
+      TString::Format("diffHis%d.=",ihis)<<hisResG[ihis];
+  }
+  TGraphErrors *gr = new TGraphErrors(10,vecP.GetMatrixArray(), vecRes.GetMatrixArray(),0, vecResE.GetMatrixArray());
+  gr->SetMarkerStyle(25);
+  gr->Draw("alp");
+  (*pcstream)<<"residuals"<<
+    "graph.="<<gr<<
+    "\n";
+
+  TCanvas *canvasRes = new TCanvas("canvasRes","canvasRes",900,900);
+  canvasRes->Divide(2,4);
+  TH2* htemp=0;
+  for (Int_t  ihis=0; ihis<4; ihis++){
+    canvasRes->cd(ihis*2+1);
+    if (ihis==0) {
+      treeCurrent->Draw("DistRefDR-refR:phi:r",cutDrawGraph,"colz");      
+    }
+    if (ihis>0) {
+      treeCurrent->Draw(TString::Format("DistRefDR-refR-fitG%d:phi:r",(ihis-1)*2),cutDrawGraph,"colz"); 
+    }
+    htemp = (TH2F*)gPad->GetPrimitive("htemp");
+    htemp->GetXaxis()->SetTitle("#phi");
+    htemp->GetYaxis()->SetTitle("#Delta_{R} (cm)");
+    htemp->GetZaxis()->SetTitle("r (cm)");
+    //    htemp->SetTitle("1/pT difference");
+    //htemp->GetYaxis()->SetRangeUser(xmin,xmax);
+    canvasRes->cd(ihis*2+2);
+    if (ihis>0) hisResG[(ihis-1)*2+1]->Draw();
+    if (ihis==0)  hisResG[0]->Draw();
+  }
+  delete pcstream;
+
+  canvasRes->SaveAs("locaFluctuationR.pdf");
+  canvasRes->SaveAs("locaFluctuationR.png");
+}
+
+void MakeLocalDistortionPlotsGlobalFitPolDriftSummary(Float_t xmin, Float_t xmax){
+  //
+  // Make local distortion plots correcting using global z fits of order 0,2,4,6,8,10,12
+  // Currently polynomial correction as an multiplicative factor of the mean distortion map used
+  // To be done - calculate numerical derivative of distortion maps 
+  //              corresponding  the local change of densities - after TDR?  
+  //
+  // As input:
+  //    1.) distortion file with the setup 10000 pileup events used
+  //    2.) mean distortion file
+  // distortions are fitted rescaling (z dependent) mean distortion file
+  //
+  gStyle->SetOptStat(0);
+  gStyle->SetOptFit(1);
+  gStyle->SetOptTitle(1);
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localFit.root","update");
+  TH1 *hisResG[10] = {0};
+  hisResG[0]=(TH1*)(pcstream->GetFile()->Get("hisFull"));
+  TF1 *fg = new TF1("fg","gaus");
+  TVectorD vecP(10), vecRes(10), vecResE(10);
+  for (Int_t ihis=0; ihis<10; ihis++){
+    hisResG[ihis+1]=(TH1*)(pcstream->GetFile()->Get(TString::Format("hisG%d",ihis)));
+    hisResG[ihis]->Fit(fg);
+    vecP[ihis]=ihis-1;
+    vecRes[ihis]=fg->GetParameter(2);
+    vecResE[ihis]=fg->GetParError(2);
+  }
+  //
+  TCanvas *canvasRes = new TCanvas("canvasRes","canvasRes",800,800);
+  canvasRes->Divide(2,3,0,0);
+  for (Int_t ihis=0; ihis<6; ihis++){
+    canvasRes->cd(ihis+1);
+    hisResG[ihis]->GetXaxis()->SetTitle("#Delta_{R} (cm)");
+    hisResG[ihis]->Draw();
+  }
+  canvasRes->SaveAs("fluctuationTableSummaryHist.pdf");
+  canvasRes->SaveAs("fluctuationTableSummaryHist.png");
+
+  TCanvas *canvasFluctuationGraph = new TCanvas("canvasGraph","canvasGraph",600,500);
+  TGraphErrors *gr = new TGraphErrors(10,vecP.GetMatrixArray(), vecRes.GetMatrixArray(),0, vecResE.GetMatrixArray());
+  gr->SetMarkerStyle(25);
+  gr->SetMinimum(0);
+  gr->GetXaxis()->SetTitle("#Fit parameters");
+  gr->GetYaxis()->SetTitle("#sigma_{R} (cm)");
+  gr->Draw("alp");
+  //  
+  canvasFluctuationGraph->SaveAs("canvasFluctuationGraphR.pdf");
+  canvasFluctuationGraph->SaveAs("canvasFluctuationGraphR.png");
+
+}
+
+
+
+void MakeLocalDistortionPlots(Int_t npoints, Int_t npointsZ){
+  //
+  // Macro to make trees with local distortions 
+  // Results are later visualized in the function DrawLocalDistortionPlots()
+  //
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localBins.root","update");
+  TFile *fCurrent = TFile::Open("SpaceChargeFluc10_1.root");
+  TFile *fRef = TFile::Open("SpaceChargeFluc0_1.root");
+  //
+  AliTPCSpaceCharge3D* distortion = ( AliTPCSpaceCharge3D*)fCurrent->Get("DistRef"); 
+  AliTPCSpaceCharge3D* distortionRef = ( AliTPCSpaceCharge3D*)fRef->Get("DistRef"); 
+  distortion->AddVisualCorrection(distortion,1);
+  distortionRef->AddVisualCorrection(distortionRef,2);
+  //
+  //
+  //
+  TVectorD normZR(125), normZRPhi(125), normZZ(125), normZPos(125);
+  TVectorD normZRChi2(125), normZRPhiChi2(125), normZZChi2(125);
+  //
+  for (Int_t iz =0; iz<125; iz++){
+    Double_t z0 = -250+iz*4;
+    TLinearFitter fitterR(2,"pol1");
+    TLinearFitter fitterRPhi(2,"pol1");
+    TLinearFitter fitterZ(2,"pol1");
+    Double_t xvalue[10]={0};
+    //fitterR.AddPoint(xvalue,0,0.001/npointsZ);
+    //fitterRPhi.AddPoint(xvalue,0,0.000001/npointsZ);
+    //fitterZ.AddPoint(xvalue,0,0.001/npointsZ);    
+    for (Int_t ipoint =0; ipoint<npointsZ; ipoint++){      
+      Double_t r0   = 85+gRandom->Rndm()*(245-85.);
+      Double_t phi0 = gRandom->Rndm()*TMath::TwoPi();
+      // some problematic parts to be skipped  - investigated later
+      if (TMath::Abs(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,1))>50) continue;
+      if (TMath::Abs(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,2))>50) continue;
+      if (TMath::Abs(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1))>20) continue;
+      if (TMath::Abs(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,2))>20) continue;
+      if (TMath::Abs(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,1))>50) continue;
+      if (TMath::Abs(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,2))>50) continue;
+      //
+      //
+      xvalue[0]=distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,2);
+      fitterR.AddPoint(xvalue,distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,1));
+      xvalue[0]=distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,2);
+      fitterRPhi.AddPoint(xvalue,distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1));
+      xvalue[0]=distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,2);
+      fitterZ.AddPoint(xvalue,distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,1));
+    }    
+    fitterR.Eval();
+    fitterRPhi.Eval();
+    fitterZ.Eval();    
+    normZR[iz]=fitterR.GetParameter(1);
+    normZRPhi[iz]=fitterRPhi.GetParameter(1);
+    normZZ[iz]=fitterZ.GetParameter(1);
+    normZRChi2[iz]=TMath::Sqrt(fitterR.GetChisquare()/fitterR.GetNpoints());    
+    normZRPhiChi2[iz]=TMath::Sqrt(fitterRPhi.GetChisquare()/fitterRPhi.GetNpoints());    
+    normZZChi2[iz]=TMath::Sqrt(fitterZ.GetChisquare()/fitterZ.GetNpoints());
+    
+    normZPos[iz]=z0;    
+  }
+  
+  {    
+  (*pcstream)<<"meanNormZ"<<
+    "normZPos.="<<&normZPos<<
+    //
+    "normZR.="<<&normZR<<            // mult. scaling to minimize R distortions
+    "normZRPhi.="<<&normZRPhi<<      // mult. scaling 
+    "normZZ.="<<&normZZ<<
+    //
+    "normZRChi2.="<<&normZRChi2<<            // mult. scaling to minimize R distortions
+    "normZRPhiChi2.="<<&normZRPhiChi2<<      // mult. scaling 
+    "normZZChi2.="<<&normZZChi2<<
+    "\n";
+  }
+  delete pcstream;
+  pcstream = new TTreeSRedirector("localBins.root","update");
+  //
+  TTree * treeNormZ= (TTree*)pcstream->GetFile()->Get("meanNormZ");
+  TGraphErrors * grZRfit= TStatToolkit::MakeGraphErrors( treeNormZ, "normZR.fElements:normZPos.fElements","",25,2,0.5);
+  TGraphErrors * grZRPhifit= TStatToolkit::MakeGraphErrors( treeNormZ, "normZRPhi.fElements:normZPos.fElements","",25,4,0.5);
+  grZRfit->Draw("alp");
+  grZRPhifit->Draw("lp");
+
+  //
+  for (Int_t ipoint=0; ipoint<npoints; ipoint++){
+    //
+    for (Int_t izNorm=0; izNorm<2; izNorm++){      
+      Double_t r0   = 85+gRandom->Rndm()*(245-85.);
+      Double_t z0   = gRandom->Rndm()*250;
+      Double_t phi0 = gRandom->Rndm()*TMath::TwoPi();
+      Double_t fSector=18.*phi0/TMath::TwoPi();
+      Double_t dSector=fSector-Int_t(fSector);
+      
+
+      Int_t    iz0  =  TMath::Nint(125.*(z0+250.)/500.);
+      if (iz0<0) iz0=0;
+      if (iz0>=125) iz0=124;
+      Double_t rNorm=1,rphiNorm=1,zNorm=1;      
+      if (izNorm==1){
+       rNorm=normZR[iz0];
+       rphiNorm=normZRPhi[iz0];
+       zNorm=normZZ[iz0];      
+      }
+    
+      Double_t deltaR0  =distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,1);
+      Double_t deltaRPhi0=distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1);
+      Double_t deltaZ0  =distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,1);
+      //
+      Double_t ddeltaR0  =distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,1)-rNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,0,2);
+      Double_t ddeltaRPhi0=distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,1)-rphiNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,1,2);
+      Double_t ddeltaZ0  =distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,1)-zNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z0,2,2);
+      //
+      //
+      TVectorD vecDMeanRPhi(20), vecDMeanR(20), vecDMeanZ(20), vecDPhi(20);
+      TVectorD vecDMeanRPhiBinR(20), vecDMeanRBinR(20), vecDMeanZBinR(20), vecDBinR(20);
+      TVectorD vecDMeanRPhiBinZ(20), vecDMeanRBinZ(20), vecDMeanZBinZ(20), vecDBinZ(20);
+      
+      for (Int_t  ideltaBin=0; ideltaBin<20; ideltaBin++){
+       Double_t  deltaPhi=ideltaBin*TMath::TwoPi()/360.;
+       Double_t  deltaZ=ideltaBin*2;
+       Double_t  deltaR=ideltaBin*2;
+       //
+       vecDPhi[ideltaBin]=deltaPhi;
+       vecDMeanRPhi[ideltaBin]=0;
+       vecDMeanR[ideltaBin]=0;
+       vecDMeanZ[ideltaBin]=0;  
+       //
+       vecDBinR[ideltaBin]=deltaR;
+       vecDMeanRPhiBinR[ideltaBin]=0;
+       vecDMeanRBinR[ideltaBin]=0;
+       vecDMeanZBinR[ideltaBin]=0;  
+       //
+       //
+       vecDBinZ[ideltaBin]=deltaZ;
+       vecDMeanRPhiBinZ[ideltaBin]=0;
+       vecDMeanRBinZ[ideltaBin]=0;
+       vecDMeanZBinZ[ideltaBin]=0;  
+       //
+       Double_t norm=1./9.;
+       for (Int_t idelta=-4; idelta<=4; idelta++){
+         Double_t i=(idelta/4.);
+         Double_t phi1= phi0+deltaPhi*i;
+         Double_t r1= r0+deltaR*i;
+         Double_t z1= z0+deltaZ*i;
+         if (z1*z0<0) z1=z0;
+         if (z1>245) z1=245;
+         if (z1<-245) z1=-245;
+         if (r1<85) r1=85;
+         if (r1>245) r1=245;
+         //
+         //
+         vecDMeanR[ideltaBin]+=norm*(distortion->GetCorrXYZ(r0*TMath::Cos(phi1), r0*TMath::Sin(phi1), z0,0,1)-rNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi1), r0*TMath::Sin(phi1), z0,0,2));
+         vecDMeanRPhi[ideltaBin]+=norm*(distortion->GetCorrXYZ(r0*TMath::Cos(phi1), r0*TMath::Sin(phi1), z0,1,1)-rphiNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi1), r0*TMath::Sin(phi1), z0,1,2));
+         vecDMeanZ[ideltaBin]+=norm*(distortion->GetCorrXYZ(r0*TMath::Cos(phi1), r0*TMath::Sin(phi1), z0,2,1)-zNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi1), r0*TMath::Sin(phi1), z0,2,2));      
+         //
+         //
+         //
+         vecDMeanRBinR[ideltaBin]+=norm*(distortion->GetCorrXYZ(r1*TMath::Cos(phi0), r1*TMath::Sin(phi0), z0,0,1)-rNorm*distortion->GetCorrXYZ(r1*TMath::Cos(phi0), r1*TMath::Sin(phi0), z0,0,2));
+         vecDMeanRPhiBinR[ideltaBin]+=norm*(distortion->GetCorrXYZ(r1*TMath::Cos(phi0), r1*TMath::Sin(phi0), z0,1,1)-rphiNorm*distortion->GetCorrXYZ(r1*TMath::Cos(phi0), r1*TMath::Sin(phi0), z0,1,2));
+         vecDMeanZBinR[ideltaBin]+=norm*(distortion->GetCorrXYZ(r1*TMath::Cos(phi0), r1*TMath::Sin(phi0), z0,2,1)-zNorm*distortion->GetCorrXYZ(r1*TMath::Cos(phi0), r1*TMath::Sin(phi0), z0,2,2));      
+         //
+         //
+         vecDMeanRBinZ[ideltaBin]+=norm*(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z1,0,1)-rNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z1,0,2));
+         vecDMeanRPhiBinZ[ideltaBin]+=norm*(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z1,1,1)-rphiNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z1,1,2));
+         vecDMeanZBinZ[ideltaBin]+=norm*(distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z1,2,1)-zNorm*distortion->GetCorrXYZ(r0*TMath::Cos(phi0), r0*TMath::Sin(phi0), z1,2,2));      
+         
+       }      
+      }
+
+      TVectorD vecDMeanRPhiRND(40), vecDMeanRRND(40), vecDMeanZRND(40), vecPhiRND(40), vecZRND(40), vecRRND(40);
+      Int_t nintegral=25;
+      Double_t norm=1./Double_t(nintegral);
+      for (Int_t  ideltaBin=0; ideltaBin<40; ideltaBin++){
+       vecDMeanRPhiRND[ideltaBin]=0;
+       vecDMeanRRND[ideltaBin]=0;
+       vecDMeanZRND[ideltaBin]=0; 
+       vecPhiRND[ideltaBin]=gRandom->Rndm()*0.3; 
+       vecZRND[ideltaBin]  =gRandom->Rndm()*30;
+       vecRRND[ideltaBin]  =gRandom->Rndm()*30;
+       for (Int_t ipoint=0; ipoint<nintegral; ipoint++){
+         Double_t phi1=phi0+2*(gRandom->Rndm()-0.5)*vecPhiRND[ideltaBin];
+         Double_t z1=z0+2*(gRandom->Rndm()-0.5)*vecZRND[ideltaBin];
+         Double_t r1=r0+2*(gRandom->Rndm()-0.5)*vecRRND[ideltaBin];
+         vecDMeanRRND[ideltaBin]+=norm*(distortion->GetCorrXYZ(r1*TMath::Cos(phi1), r1*TMath::Sin(phi1), z1,0,1)-rNorm*distortion->GetCorrXYZ(r1*TMath::Cos(phi1), r1*TMath::Sin(phi1), z1,0,2));
+         vecDMeanRPhiRND[ideltaBin]+=norm*(distortion->GetCorrXYZ(r1*TMath::Cos(phi1), r1*TMath::Sin(phi1), z1,1,1)-rphiNorm*distortion->GetCorrXYZ(r1*TMath::Cos(phi1), r1*TMath::Sin(phi1), z1,1,2));
+         vecDMeanZRND[ideltaBin]+=norm*(distortion->GetCorrXYZ(r1*TMath::Cos(phi1), r1*TMath::Sin(phi1), z1,2,1)-zNorm*distortion->GetCorrXYZ(r1*TMath::Cos(phi1), r1*TMath::Sin(phi1), z1,2,2));      
+       }
+      }
+
+
+
+
+      (*pcstream)<<"meanDistortion"<<
+       "npoints="<<npoints<<            // number of points genrated per file
+       "npointsZ="<<npointsZ<<            // number of points generated to fit z bin
+       "izNorm="<<izNorm<<              // z normalizatio flag
+       "fSector="<<fSector<<            // sector position
+       "dSector="<<dSector<<            // distance to the sector boundary
+       //
+       "r0="<<r0<<                      // r0 at center
+       "z0="<<z0<<
+       "phi0="<<phi0<<
+       //
+       "rNorm="<<rNorm<<
+       "rphiNorm="<<rphiNorm<<
+       "zNorm="<<zNorm<<
+       //
+       "deltaR0="<<deltaR0<<
+       "deltaZ0="<<deltaZ0<<
+       "deltaRPhi0="<<deltaRPhi0<<
+       //
+       "ddeltaR0="<<ddeltaR0<<
+       "ddeltaZ0="<<ddeltaZ0<<
+       "ddeltaRPhi0="<<ddeltaRPhi0<<
+       //
+       "vecDMeanRPhi.="<<&vecDMeanRPhi<<   
+       "vecDMeanR.="<<&vecDMeanR<<   
+       "vecDMeanZ.="<<&vecDMeanZ<<   
+       "vecDPhi.="<<&vecDPhi<<
+       //
+       "vecDMeanRPhiBinZ.="<<&vecDMeanRPhiBinZ<<   
+       "vecDMeanRBinZ.="<<&vecDMeanRBinZ<<   
+       "vecDMeanZBinZ.="<<&vecDMeanZBinZ<<   
+       "vecDBinZ.="<<&vecDBinZ<<
+       //
+       "vecDMeanRPhiBinR.="<<&vecDMeanRPhiBinR<<   
+       "vecDMeanRBinR.="<<&vecDMeanRBinR<<   
+       "vecDMeanZBinR.="<<&vecDMeanZBinR<<   
+       "vecDBinR.="<<&vecDBinR<<
+       //
+       "vecDMeanRPhiRND.="<<&vecDMeanRPhiRND<<   
+       "vecDMeanRRND.="<<&vecDMeanRRND<<   
+       "vecDMeanZRND.="<<&vecDMeanZRND<<   
+       "vecPhiRND.="<<&vecPhiRND<<
+       "vecZRND.="<<&vecZRND<<
+       "vecRRND.="<<&vecRRND<<
+       "\n";
+      //TVectorD vecDMeanRPhiRND(10), vecDMeanRRND(10), vecDMeanZRND(10), vecPhiRND(10), vecZRND(10), vecRRND(10);
+    }
+  }  
+  delete pcstream;
+  pcstream = new TTreeSRedirector("localBins.root","update");
+  /*
+    meanDistortion->Draw("vecDMeanR.fElements-ddeltaR0:vecDPhi.fElements","izNorm==1&&abs(phi0-pi)>0.2&&abs(ddeltaRPhi0)<10","")
+
+   */
+}
+
+
+void DrawLocalDistortionPlots(){
+  //
+  // Draw summary residuals plots after applying z dependent q normalization.
+  // Plots used for the TPC TDR and internal note
+  //
+  // Two input trees are used:
+  //    meanNormZ        - here we store the result of the q ze dependent fits for Radial, RPhi and Z distortions
+  //    meanDistortion   - phi averaged residual distortion before and after applying q(z) dependent correction
+  //
+  // It is assumed that the correction table for randomly selected pile-up setup
+  // can be approximated rescaling the mean correction table.
+  //   Rescaling coeficients are fitted separatelly in 125 z bins
+  //
+
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localBins.root","update"); 
+  TTree * meanNormZ  = (TTree*) pcstream->GetFile()->Get("meanNormZ");
+  TTree * meanDistortion  = (TTree*) pcstream->GetFile()->Get("meanDistortion");
+  meanNormZ->SetMarkerStyle(25);   meanNormZ->SetMarkerSize(0.5);  
+  meanDistortion->SetMarkerStyle(25);   meanDistortion->SetMarkerSize(0.5);  
+  Int_t colors[5]={1,2,3,4,6};
+  Int_t markers[5]={21,20,23,24,25};
+  TH2 * his2D;
+  TObjArray arrFit(3);
+  //
+  // 1. Z dependence of the normalization is smooth function - about 10 bins to represent 
+  //
+  TGraphErrors *graphZRnorm[100]= {0};
+  TGraphErrors *graphZRRPhinorm[100]= {0};
+  TCanvas * canvasRFit = new TCanvas("canvasRFit","canvasRFit",600,500);
+  TLegend * legendRFit = new TLegend(0.12,0.12,0.88,0.4,"Q normalization fit. #DeltaR=c(z)#DeltaR_{ref}"); 
+  legendRFit->SetBorderSize(0);  
+  for (Int_t igraph=0; igraph<5; igraph++){    
+    Int_t color = colors[igraph];
+    Int_t marker = markers[igraph];
+    Int_t event=gRandom->Rndm()*meanNormZ->GetEntries();
+    graphZRnorm[igraph] = TStatToolkit::MakeGraphErrors( meanNormZ, "normZR.fElements:normZPos.fElements",TString::Format("Entry$==%d&&abs(normZPos.fElements)<220",event),marker,color,0.7);
+    graphZRnorm[igraph]->SetTitle(TString::Format("Pile-up setup=%d",igraph));   
+    graphZRnorm[igraph]->SetMinimum(0.60);
+    graphZRnorm[igraph]->SetMaximum(1.2);   
+    graphZRnorm[igraph]->GetXaxis()->SetTitle("z (cm)");    
+    graphZRnorm[igraph]->GetYaxis()->SetTitle("c(z)");    
+    if (igraph==0) graphZRnorm[igraph]->Draw("alp");
+    graphZRnorm[igraph]->Draw("lp");    
+    legendRFit->AddEntry( graphZRnorm[igraph],TString::Format("Pile-up setup=%d",event),"p");
+  }
+  legendRFit->Draw(); 
+  canvasRFit->SaveAs("canvasZRFit5Random.pdf");   // ~/hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain/dirmergeAll/dEpsilon20/canvasZRRPhiFit5Random.png
+  canvasRFit->SaveAs("canvasZRFit5Random.png");  
+  //
+  // 2. 
+  //
+  TCanvas * canvasRRPhiFit = new TCanvas("canvasRRPhiFit","canvasRRPhiFit",600,500);
+  TLegend * legendRRPhiFit = new TLegend(0.12,0.12,0.88,0.4,"Q normalization fit. #DeltaR=c_{R}(z)#DeltaR_{ref} #DeltaR#phi=c_{R#phi}(z)#Delta_{R#phi}_{ref}"); 
+  legendRRPhiFit->SetBorderSize(0);  
+  for (Int_t igraph=0; igraph<5; igraph++){    
+    Int_t color = colors[igraph];
+    Int_t marker = markers[igraph];
+    Int_t event=gRandom->Rndm()*meanNormZ->GetEntries();
+    graphZRRPhinorm[igraph] = TStatToolkit::MakeGraphErrors( meanNormZ, "normZR.fElements:normZRPhi.fElements",TString::Format("Entry$==%d&&abs(normZPos.fElements)<220",event),marker,color,0.7);
+    graphZRRPhinorm[igraph]->GetXaxis()->SetLimits(0.6,1.2);    
+    graphZRRPhinorm[igraph]->SetTitle(TString::Format("Pile-up setup=%d",igraph));   
+    graphZRRPhinorm[igraph]->SetMinimum(0.6);
+    graphZRRPhinorm[igraph]->SetMaximum(1.2);   
+    graphZRRPhinorm[igraph]->GetXaxis()->SetTitle("c_{R#phi}");    
+    graphZRRPhinorm[igraph]->GetYaxis()->SetTitle("c_{R}");    
+    if (igraph==0) graphZRRPhinorm[igraph]->Draw("alp");
+    graphZRRPhinorm[igraph]->Draw("lp");    
+    legendRRPhiFit->AddEntry( graphZRRPhinorm[igraph],TString::Format("Pile-up setup=%d",event),"p");
+  }
+  legendRRPhiFit->Draw(); 
+  canvasRRPhiFit->SaveAs("canvasZRRPhiFit5Random.pdf");   // ~/hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain/dirmergeAll/dEpsilon20/canvasZRRPhiFit5Random.png
+  canvasRRPhiFit->SaveAs("canvasZRRPhiFit5Random.png");  
+  //
+
+  //
+  // 3. Residual distortion after z dependent q distortion 
+  //
+  gStyle->SetOptStat(0);
+  TH1D * hisRRes, *hisRRphiRes=0;
+  meanDistortion->Draw("ddeltaRPhi0:r0>>hisdRPhi0(40,85,245,100,-0.25,0.25)","abs(z0)<85.&&izNorm==1","colz");
+  his2D = (TH2D*)meanDistortion->GetHistogram();
+  his2D->FitSlicesY(0,0,-1,0,"QNR",&arrFit);
+  hisRRphiRes=(TH1D*)arrFit.At(2)->Clone();
+  meanDistortion->Draw("ddeltaR0:r0>>hisdR(40,85,245,100,-0.25,0.25)","abs(z0)<85.&&izNorm==1","colz");
+  his2D = (TH2D*)meanDistortion->GetHistogram();
+  his2D->FitSlicesY(0,0,-1,0,"QNR",&arrFit);
+  hisRRes=(TH1D*)arrFit.At(2)->Clone();
+  hisRRphiRes->SetMarkerStyle(25);
+  hisRRes->SetMarkerStyle(21);
+  hisRRphiRes->SetMarkerColor(2);
+  hisRRes->SetMarkerColor(4);  
+
+  hisRRes->GetXaxis()->SetTitle("R (cm)");
+  hisRRes->GetYaxis()->SetTitle("#sigma_{res} (cm)");  
+  hisRRes->SetMinimum(0); 
+  TCanvas * canvasResidualsFit = new TCanvas("canvasResidualsFit","canvasResidualsFit",600,500);
+  TLegend * legendRRPhiFitSigma = new TLegend(0.2,0.6,0.88,0.88,"Distortion residuals. RMS(#Delta-c(z)#Delta_{ref}) (|z|<85)"); 
+  legendRRPhiFit->SetBorderSize(0);  
+  hisRRes->Draw("");
+  hisRRphiRes->Draw("same");
+  legendRRPhiFitSigma->AddEntry(hisRRes,"Radial");
+  legendRRPhiFitSigma->AddEntry(hisRRphiRes,"R#phi");
+  legendRRPhiFitSigma->Draw();
+  canvasResidualsFit->SaveAs("canvasResidualsFit.pdf"); //~/hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain/dirmergeAll/dEpsilon20/canvasResidualsFit.png
+  canvasResidualsFit->SaveAs("canvasResidualsFit.png");
+  //
+  //  4. Residual distortion after z dependent q distortion - local phi average 
+  //
+  TH1D * hisRResPhi, *hisRRphiResPhi=0;
+  meanDistortion->Draw("ddeltaR0-vecDMeanR.fElements:vecDPhi.fElements>>hisRResPhi(18,0.0,0.32,100,-0.3,0.3)","abs(z0)<85.&&izNorm==1&&r0<120","colz",100000);
+  his2D = (TH2D*)meanDistortion->GetHistogram()->Clone();
+  his2D->FitSlicesY(0,0,-1,0,"QNR",&arrFit);
+  hisRResPhi=(TH1D*)arrFit.At(2)->Clone();
+  //
+  meanDistortion->Draw("ddeltaRPhi0-vecDMeanRPhi.fElements:vecDPhi.fElements>>hisRRphResPhi(18,0.0,0.32,100,-0.3,0.3)","abs(z0)<85.&&izNorm==1","colz",100000);
+  his2D = (TH2D*)meanDistortion->GetHistogram()->Clone();
+  his2D->FitSlicesY(0,0,-1,0,"QNR",&arrFit);
+  hisRRphiResPhi=(TH1D*)arrFit.At(2)->Clone();
+  //
+  hisRRphiResPhi->SetMarkerStyle(25);
+  hisRResPhi->SetMarkerStyle(21);
+  hisRRphiResPhi->SetMarkerColor(2);
+  hisRResPhi->SetMarkerColor(4);  
+  hisRResPhi->GetXaxis()->SetTitle("#Delta#phi bin width");
+  hisRResPhi->GetYaxis()->SetTitle("#sigma_{res} (cm)");  
+  hisRResPhi->SetMinimum(0); 
+  hisRResPhi->SetMaximum(2.*hisRResPhi->GetMaximum()); 
+  gStyle->SetOptStat(0);
+  TCanvas * canvasResidualsFitPhi = new TCanvas("canvasResidualsFitPhi","canvasResidualsFitPhi",600,500);
+  TLegend * legendRRPhiFitSigmaPhi = new TLegend(0.2,0.6,0.88,0.88,"Distortion residuals-mean in bin. RMS((#Delta-c(z)#Delta_{ref})) (|z|<85)"); 
+  {  
+    hisRResPhi->Draw("");
+    hisRRphiResPhi->Draw("same");
+    legendRRPhiFitSigmaPhi->AddEntry(hisRResPhi,"Radial");
+    legendRRPhiFitSigmaPhi->SetBorderSize(0);  
+    legendRRPhiFitSigmaPhi->AddEntry(hisRRphiResPhi,"R#phi");
+    legendRRPhiFitSigmaPhi->Draw();
+  }
+  
+  canvasResidualsFitPhi->SaveAs("canvasResidualsFitPhi.pdf"); //~/hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain/dirmergeAll/dEpsilon20/canvasResidualsFitPhi.png
+  canvasResidualsFitPhi->SaveAs("canvasResidualsFitPhi.png");
+  //
+  // 5.) Draw mean residuals 
+  //
+  TCanvas *canvasResDist = new TCanvas("canvasResDist","canvasResDist",800,800);
+  canvasResDist->Divide(2,3,0,0);
+  {    
+    canvasResDist->cd(1);    
+    meanDistortion->Draw("vecDMeanR.fElements[2]:phi0:r0","abs(z0)<85.&&izNorm==1&&r0<120","colz",100000,0);
+    canvasResDist->cd(2);    
+    meanDistortion->Draw("vecDMeanR.fElements[2]:phi0:r0","abs(z0)<85.&&izNorm==1&&r0<120","colz",100000,200000);
+    canvasResDist->cd(3);    
+    meanDistortion->Draw("vecDMeanR.fElements[2]:phi0:r0","abs(z0)<85.&&izNorm==1&&r0<120","colz",100000,400000);
+    canvasResDist->cd(4);    
+    meanDistortion->Draw("vecDMeanR.fElements[2]:phi0:r0","abs(z0)<85.&&izNorm==1&&r0<120","colz",100000,600000);
+    canvasResDist->cd(5);    
+    meanDistortion->Draw("vecDMeanR.fElements[2]:phi0:r0","abs(z0)<85.&&izNorm==1&&r0<120","colz",100000,800000);
+    canvasResDist->cd(6);    
+    meanDistortion->Draw("vecDMeanR.fElements[2]:phi0:r0","abs(z0)<85.&&izNorm==1&&r0<120","colz",100000,1000000);
+  }
+  canvasResDist->SaveAs("canvasResidualsFitGraph.pdf");  //~/hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain/dirmergeAll/dEpsilon20/canvasResidualsFitGraph.png
+  canvasResDist->SaveAs("canvasResidualsFitGraph.png");
+}
+
+void BinScan(Int_t npoints){
+
+  
+  TTreeSRedirector *pcstream = new TTreeSRedirector("localBins.root","update"); 
+  TTree * resolScan = (TTree*)pcstream->GetFile()->Get("resolScan");
+  if (!resolScan){
+    TTree * meanNormZ  = (TTree*) pcstream->GetFile()->Get("meanNormZ");
+    TTree * meanDistortion  = (TTree*) pcstream->GetFile()->Get("meanDistortion");
+    //  meanNormZ->SetMarkerStyle(25);   meanNormZ->SetMarkerSize(0.5);  
+    //   meanDistortion->SetMarkerStyle(25);   meanDistortion->SetMarkerSize(0.5);  
+    //   Int_t colors[5]={1,2,3,4,6};
+    //   Int_t markers[5]={21,20,23,24,25};
+    //   TH2 * his2D;
+    //   TObjArray arrFit(3);
+    
+    {
+      //Int_t npoints=50000;
+      TCut cutDist="abs(ddeltaR0-vecDMeanRRND.fElements)<1&&abs(ddeltaRPhi0-vecDMeanRPhiRND.fElements)<1";
+      TCut cutGeom="abs(z0)<85&&r0<120.";
+      //
+      Int_t entries1 = meanDistortion->Draw("vecZRND.fElements:vecRRND.fElements:vecPhiRND.fElements","izNorm==1"+cutGeom+cutDist,"goff",npoints);
+      TVectorD vecBR1(entries1,meanDistortion->GetV1());
+      TVectorD vecBZ1(entries1,meanDistortion->GetV2());
+      TVectorD vecBPhi1(entries1,meanDistortion->GetV3());
+      meanDistortion->Draw("ddeltaR0-vecDMeanRRND.fElements:ddeltaRPhi0-vecDMeanRPhiRND.fElements","izNorm==1"+cutGeom+cutDist,"goff",npoints);
+      TVectorD vecDR1(entries1,meanDistortion->GetV1());
+      TVectorD vecDRPhi1(entries1,meanDistortion->GetV2());
+      //
+      Int_t entries0 = meanDistortion->Draw("vecZRND.fElements:vecRRND.fElements:vecPhiRND.fElements","izNorm==0"+cutGeom+cutDist,"goff",npoints);
+      TVectorD vecBR0(entries0,meanDistortion->GetV1());
+      TVectorD vecBZ0(entries0,meanDistortion->GetV2());
+      TVectorD vecBPhi0(entries0,meanDistortion->GetV3());
+      meanDistortion->Draw("ddeltaR0-vecDMeanRRND.fElements:ddeltaRPhi0-vecDMeanRPhiRND.fElements","izNorm==0"+cutGeom+cutDist,"goff",npoints);
+      TVectorD vecDR0(entries0,meanDistortion->GetV1());
+      TVectorD vecDRPhi0(entries0,meanDistortion->GetV2());
+      //
+      TVectorD vecSelR(TMath::Max(entries0,entries1));
+      TVectorD vecSelRPhi(TMath::Max(entries0,entries1));
+      //
+      for (Int_t iz=1; iz<10; iz+=1){
+       for (Int_t ir=1; ir<10; ir+=1){
+         for (Int_t iphi=1; iphi<10; iphi++){
+           Double_t zbin=3*iz;
+           Double_t rbin=3*ir;
+           Double_t phibin=0.025*iphi;
+           Int_t counter=0;
+           //
+           counter=0;
+           for (Int_t ipoint=0; ipoint<entries1; ipoint++){
+             Bool_t isOK=TMath::Abs(vecBZ1[ipoint]/zbin-1)<0.2;
+             isOK&=TMath::Abs(vecBR1[ipoint]/rbin-1.)<0.2;
+             isOK&=TMath::Abs(vecBPhi1[ipoint]/phibin-1.)<0.2;
+             if (isOK) {
+               vecSelRPhi[counter]=vecDRPhi1[ipoint];
+               vecSelR[counter]=vecDR1[ipoint];
+               counter++;
+             }
+           }
+           Double_t meanR1=0,rmsR1=0;
+           Double_t meanRPhi1=0,rmsRPhi1=0;
+           if (counter>3) AliMathBase::EvaluateUni(counter,vecSelR.GetMatrixArray(),meanR1,rmsR1,0.9*counter);
+           if (counter>3) AliMathBase::EvaluateUni(counter,vecSelRPhi.GetMatrixArray(),meanRPhi1,rmsRPhi1,0.9*counter);
+           //
+           counter=0;
+           for (Int_t ipoint=0; ipoint<entries0; ipoint++){
+             Bool_t isOK=TMath::Abs(vecBZ0[ipoint]/zbin-1)<0.2;
+             isOK&=TMath::Abs(vecBR0[ipoint]/rbin-1.)<0.2;
+             isOK&=TMath::Abs(vecBPhi0[ipoint]/phibin-1.)<0.2;
+             if (isOK) {
+               vecSelRPhi[counter]=vecDRPhi0[ipoint];
+               vecSelR[counter]=vecDR0[ipoint];
+               counter++;
+             }
+           }
+           Double_t meanR0=0, rmsR0=0;
+           Double_t meanRPhi0=0, rmsRPhi0=0;
+           if (counter>3) AliMathBase::EvaluateUni(counter,vecSelR.GetMatrixArray(),meanR0,rmsR0,0.9*counter);
+           if (counter>3) AliMathBase::EvaluateUni(counter,vecSelRPhi.GetMatrixArray(),meanRPhi0,rmsRPhi0,0.9*counter);
+           //
+           printf("%f\t%f\t%f\t%f\t%f\n",zbin,rbin,phibin,rmsR0/(rmsR1+0.0001), rmsRPhi0/(rmsRPhi1+0.00001));
+           (*pcstream)<<"resolScan"<<
+             "counter="<<counter<<
+             //
+             "iz="<<iz<<
+             "ir="<<ir<<
+             "iphi="<<iphi<<
+             //
+             "zbin="<<zbin<<
+             "rbin="<<rbin<<
+             "phibin="<<phibin<<
+             //
+             "meanR0="<<meanR0<<
+             "rmsR0="<<rmsR0<<
+             "meanRPhi0="<<meanRPhi0<<
+             "rmsRPhi0="<<rmsRPhi0<<
+             //
+             "meanR1="<<meanR1<<
+             "rmsR1="<<rmsR1<<
+             "meanRPhi1="<<meanRPhi1<<
+             "rmsRPhi1="<<rmsRPhi1<<
+             "\n";
+         } 
+       }
+      }
+    }
+    delete pcstream;
+  }
+  //
+  pcstream = new TTreeSRedirector("localBins.root","update"); 
+  resolScan = (TTree*)pcstream->GetFile()->Get("resolScan");
+  resolScan->SetMarkerStyle(25);
+  //
+  Int_t colors[5]={1,2,3,4,6};
+  Int_t markers[5]={21,20,23,24,25};
+  gStyle->SetTitleFontSize(32);
+  gStyle->SetTitleFontSize(35);
+  //
+  //
+  //
+  for (Int_t itype=0; itype<2; itype++){
+    TCanvas * canvasRes = new TCanvas(TString::Format("canvasRes%d",itype),"canvasRes",800,800);
+    canvasRes->SetRightMargin(0.05);
+    canvasRes->SetLeftMargin(0.2);
+    canvasRes->SetBottomMargin(0.18);
+    canvasRes->Divide(2,3,0,0);
+    TLatex  latexDraw;
+    latexDraw.SetTextSize(0.08);
+    //
+    for (Int_t iz=1; iz<6; iz+=2){
+      TLegend * legend0 = new TLegend(0.17,0.3,0.80,0.6,TString::Format("Residuals after mean correction"));
+      TLegend * legend1 = new TLegend(0.07,0.3,0.90,0.6,TString::Format("Residual after applying #it{q(z)} correction"));
+      legend0->SetBorderSize(0);
+      legend1->SetBorderSize(0);
+      for (Int_t ir=1; ir<8; ir+=2){
+       TCut cutR(TString::Format("ir==%d",ir));
+       TCut cutZ(TString::Format("iz==%d",iz));
+       TGraphErrors * gr0=0, *gr1=0;
+       if (itype==0){
+         gr0=TStatToolkit::MakeGraphErrors(resolScan,"10*rmsR0:phibin:10*rmsR0/sqrt(counter)",cutR+cutZ,markers[ir/2],colors[ir/2],0.75);
+         gr1=TStatToolkit::MakeGraphErrors(resolScan,"10*rmsR1:phibin:10*rmsR1/sqrt(counter)",cutR+cutZ,markers[ir/2],colors[ir/2],0.75);
+         gr0->GetYaxis()->SetTitle("#it{#sigma(#Delta_{R}-#bar{#Delta_{R}})} (mm)"); 
+       }
+       if (itype==1){
+         gr0=TStatToolkit::MakeGraphErrors(resolScan,"10*rmsRPhi0:phibin:10*rmsRPhi0/sqrt(counter)",cutR+cutZ,markers[ir/2],colors[ir/2],0.75);
+         gr1=TStatToolkit::MakeGraphErrors(resolScan,"10*rmsPhi1:phibin:10*rmsPhi1/sqrt(counter)",cutR+cutZ,markers[ir/2],colors[ir/2],0.75);
+         gr0->GetYaxis()->SetTitle("#it{#sigma(#Delta_{R#phi}-#bar{#Delta_{R#phi}})} (mm)"); 
+       }
+       gr0->GetXaxis()->SetTitle("#Delta#phi bin width");
+       gr1->GetXaxis()->SetTitle("#Delta#phi bin width");
+       SetGraphTDRStyle(gr0);
+       SetGraphTDRStyle(gr1);
+       gr0->GetXaxis()->SetLimits(0,0.25);
+       gr1->GetXaxis()->SetLimits(0,0.25);
+       gr0->SetMinimum(-0.5);
+       gr0->SetMaximum(0.7);
+       gr1->SetMinimum(-0.5);
+       gr1->SetMaximum(0.7);
+       canvasRes->cd(iz)->SetTicks(3,3);
+       canvasRes->cd(iz)->SetGrid(0,3);
+       canvasRes->cd(iz)->SetLeftMargin(0.15);
+       if (ir==1) gr0->Draw("alp");
+       gr0->Draw("lp");
+       canvasRes->cd(iz+1)->SetTicks(3,3);
+       canvasRes->cd(iz+1)->SetGrid(0,3);
+       if (ir==1) gr1->Draw("alp");
+       gr1->Draw("lp");
+       legend0->AddEntry(gr0,TString::Format("#it{#Delta_{R}}=%1.1f (cm)",ir*3.),"p");
+       legend1->AddEntry(gr1,TString::Format("#it{#Delta_{R}}=%1.1f (cm)",ir*3.),"p");
+       //
+       canvasRes->cd(iz);
+       latexDraw.DrawLatex(0.01,-0.45,TString::Format("#Delta_{Z}=%1.0f cm, R<120 cm, |Z|<85 cm ",iz*3.));
+       canvasRes->cd(iz+1);
+       latexDraw.DrawLatex(0.01,-0.45,TString::Format("#Delta_{Z}=%1.0f cm, R<120 cm, |Z|<85 cm ",iz*3.));
+      }
+      if (iz==5){
+       legend0->SetTextSize(0.06);
+       legend1->SetTextSize(0.06);
+       canvasRes->cd(iz);
+       legend0->Draw();
+       canvasRes->cd(iz+1);
+       legend1->Draw();
+      }
+    }
+    if (itype==0){
+       canvasRes->SaveAs("canvasSpaceChargeBinFlucR.pdf");
+       canvasRes->SaveAs("canvasSpaceChargeBinFlucR.png");
+    }
+    if (itype==1){
+      canvasRes->SaveAs("canvasSpaceChargeBinFlucRPhi.pdf");
+      canvasRes->SaveAs("canvasSpaceChargeBinFlucRPhi.png"); //~/hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain/dirmergeAll/dEpsilon20/canvasSpaceChargeBinFlucRPhi.pdf
+    }
+  }
+
+}
+
+  
index 16c91a09b7402a512282f53b78cb820366e5286f..0fb1d17f73b4d347b4e8e3f18baf4426c3aa6a07 100755 (executable)
@@ -1,3 +1,4 @@
+
 #
 # shell scipt to 
 #
@@ -8,26 +9,29 @@
 #                if (mode==1) DoMerge();  
 #                if (mode==2) spaceChargeFluctuationToyMC(arg0,arg1);
 # argument 3 -  according the C++ code
-export flucPath=$HOME/AliRoot/TPCdev/TPC/Upgrade/macros
+#export flucPath=$HOME/AliRoot/TPCdev/TPC/Upgrade/macros
               
 source $1 
-aliroot -b -q $HOME/NimStyle.C $ALICE_ROOT/TPC/Upgrade/macros/spaceChargeFluctuation.C+\($2,$3,$4,$5\)
+aliroot -b -q $flucPath/NimStyle.C $ALICE_ROOT/TPC/Upgrade/macros/spaceChargeFluctuation.C+\($2,$3,$4,$5\)
 exit;
 
 
 #
-#Example usage hera
-#
+#Example usage hera (here we have 1000 nodes, but no acces to user disk)
+# (to install aliroot on hera, the best is to use the rsync)
+# jobs to be submitted form the lxsub0x
 export baliceTPC=/hera/alice/miranov/.baliceHera
 export flucPath=$HOME/AliRoot/TPCdev/TPC/Upgrade/macros/
-export batchCommand="qsub -cwd -l h_rt=24:0:0,h_rss=4G  "
+export batchCommand="qsub -cwd -V -l h_rt=24:0:0,h_rss=4G  "
 #
 #
-#Example usage local
+# Example usage local 
+# jobs to be submitted form the lxb1001 or lxb1002
+#(here we have 80 nodes and user disk)
 #
 export baliceTPC=/u/miranov/.baliceTPC
 export flucPath=$HOME/AliRoot/TPCdev/TPC/Upgrade/macros/
-export batchCommand="qsub -cwd   "
+export batchCommand="qsub -cwd  -V "
 #
 # 0.) sumbmit jobs to process raw data and accumlate space charge
 #
@@ -76,7 +80,7 @@ done;
 
 
 #
-# 4.)  submit fluctuation code dist scan - 11 minutes
+# 4.)  submit fluctuation code dist scan
 #
 rm dir*/SpaceCharg*root 
 rm dir*/filter*.log
@@ -110,6 +114,39 @@ done;
 cd $wdir
 done
 
+#
+# 4.b) submit the code for the epsilon scan
+#
+#example directory
+cd /hera/alice/miranov/SpaceCharge/Fluctuations/PbPbWithGain
+wdir=`pwd`
+
+ls $wdir/dirmerge*/fluct*.root| grep -v mergeAll >  $wdir/dirmergeAll/fluctuation.list 
+cd $wdir/dirmergeAll
+for epsilon in {10,20}; do
+   #create and clean  directories for epsilon
+   mkdirhier  $wdir/dirmergeAll/dEpsilon$epsilon
+   rm -rf $wdir/dirmergeAll/dEpsilon$epsilon/*
+   cp $wdir/dirmergeAll/fluctuation.list  $wdir/dirmergeAll/dEpsilon$epsilon/
+done;
+#submit epsilon scan jobs
+for epsilon in {10,20}; do         # loop over epsilons
+    for idir in {0..40}; do         # loop  create different random  ion pileup frames
+       mkdir $wdir/dirmergeAll/dEpsilon$epsilon/dir$idir
+       cd  $wdir/dirmergeAll/dEpsilon$epsilon/dir$idir
+       cp $wdir/dirmergeAll/fluctuation.list $wdir/dirmergeAll/dEpsilon$epsilon/dir$idir/
+       for i in {0..14..2} ; do         # specify differnt mulitpliicty of ions in pilepy frame run B0, B+, B-
+          scaling=$(($epsilon/5))
+          $batchCommand    -o  filterFluc0$i.log  $flucPath/spaceChargeFluctuation.sh $baliceTPC  4  $scaling $i 0
+          $batchCommand    -o  filterFlucP$i.log  $flucPath/spaceChargeFluctuation.sh $baliceTPC  4  $scaling $i 1
+          $batchCommand    -o  filterFlucM$i.log  $flucPath/spaceChargeFluctuation.sh $baliceTPC  4  $scaling $i 2
+       done;
+       cd $wdir
+    done;
+done; 
+
+
+
 
 #
 # 5.)  submit drawing jobs
@@ -122,6 +159,28 @@ for a in `ls -d dirmerge*`; do
 done;
 
 
+#
+# 6.)  submit drawing fluctuation jobs
+#
+wdir=`pwd`
+for a in `ls -d dir*`; do
+    cd $wdir/$a
+    rm localFit.root
+    $batchCommand    -o  drawFlucFit.log  $flucPath/spaceChargeFluctuation.sh $baliceTPC  6  -1.5 1.5 0 0
+    cd $wdir
+done;
+
+#
+# 7.)  submit drawing fluctuation jobs
+#
+wdir=`pwd`
+for a in `ls -d dir*`; do
+    cd $wdir/$a
+    rm localBins.root
+    $batchCommand    -o  drawFlucBin.log  $flucPath/spaceChargeFluctuation.sh $baliceTPC  7  100000 10000 0 0
+    cd $wdir
+done;
+
 
 #
 # 6.) make chain files
index b76a17c8638c4f3c52c4fcf5258af060453cab31..0013f9776224961fdb717fcff01f70d547ebe99d 100644 (file)
@@ -11,7 +11,9 @@ void toyMCRecPlots(TString inFileName = "toyMC.debug.root",Bool_t doPlots = kFAL
   //
 
   //gStyle->SetOptStat(0);
-
+  st->SetTitleX(0.17);
+  st->SetTitleW(0.73);
+  
   // parameters
   const Int_t nT0          = 2;
   const Int_t nT02D        = 2;
@@ -19,7 +21,8 @@ void toyMCRecPlots(TString inFileName = "toyMC.debug.root",Bool_t doPlots = kFAL
   const Int_t nTrackParams = 9;
   const Int_t nTrackParamsITS = 9;
   const Int_t nEff         = 1;
-
+  Int_t nTrackParamsPlot=5;
+  Int_t ydiv=2;  //divisions in y for track parameters plot, usually 3
   Int_t col = kBlack;
 
   TString sT0[nT0] = {"fTime0-t0","fTime0-t0+z0*TMath::Sign(1,tOrig.Eta())/vDrift"};
@@ -28,6 +31,8 @@ void toyMCRecPlots(TString inFileName = "toyMC.debug.root",Bool_t doPlots = kFAL
   //TString sT02D[nT02D] = {"(fTime0-t0)*vDrift:tOrig.fP[3]","(fTime0-t0)*vDrift:tOrig.fP[4]"};
   TString sTrackParams[nTrackParams] = {"track.fP[0]-tOrig.fP[0]","track.fP[1]-tOrig.fP[1]","track.fP[2]-tOrig.fP[2]","track.fP[3]-tOrig.fP[3]","track.fP[4]-tOrig.fP[4]","track.fAlpha-tOrig.fAlpha","track.fX/tOrig.fX","track.fP[0]/tOrig.fP[0]","track.fP[1]/tOrig.fP[1]"};
   TString sTrackParamsITS[nTrackParamsITS] = {"trackITS.fP[0]-tOrigITS.fP[0]","trackITS.fP[1]-tOrigITS.fP[1]","trackITS.fP[2]-tOrigITS.fP[2]","trackITS.fP[3]-tOrigITS.fP[3]","trackITS.fP[4]-tOrigITS.fP[4]","trackITS.fAlpha-tOrigITS.fAlpha","trackITS.fX/tOrigITS.fX","trackITS.fP[0]/tOrigITS.fP[0]","trackITS.fP[1]/tOrigITS.fP[1]"};
+  TString sTrackParamsITS1[nTrackParamsITS] = {"trackITS1.fP[0]-tOrigITS1.fP[0]","trackITS1.fP[1]-tOrigITS1.fP[1]","trackITS1.fP[2]-tOrigITS1.fP[2]","trackITS1.fP[3]-tOrigITS1.fP[3]","trackITS1.fP[4]-tOrigITS1.fP[4]","trackITS1.fAlpha-tOrigITS1.fAlpha","trackITS1.fX/tOrigITS1.fX","trackITS1.fP[0]/tOrigITS1.fP[0]","trackITS1.fP[1]/tOrigITS1.fP[1]"};
+  TString sTrackParamsITS2[nTrackParamsITS] = {"trackITS2.fP[0]-tOrigITS2.fP[0]","trackITS2.fP[1]-tOrigITS2.fP[1]","trackITS2.fP[2]-tOrigITS2.fP[2]","trackITS2.fP[3]-tOrigITS2.fP[3]","trackITS2.fP[4]-tOrigITS2.fP[4]","trackITS2.fAlpha-tOrigITS2.fAlpha","trackITS2.fX/tOrigITS2.fX","trackITS2.fP[0]/tOrigITS2.fP[0]","trackITS2.fP[1]/tOrigITS2.fP[1]"};
   TString sZ0[nZ0] = {"(fTime0-t0)*vDrift","(fTime0-t0+z0*TMath::Sign(1,tOrig.Eta())/vDrift)*vDrift"};
   TString sEff[nEff] = {"nSeedClustersID/nClustersMC:nSeedClusters/nClustersMC"};
 
@@ -72,12 +77,22 @@ void toyMCRecPlots(TString inFileName = "toyMC.debug.root",Bool_t doPlots = kFAL
   TCanvas *cZ0 = new TCanvas(Form("cZ0_%s",sConfig.Data()),Form("cZ0_%s",sConfig.Data()),1200,500);
   cZ0->Divide(2,1);
 
+  //TCanvas *cTrackParams = new TCanvas(Form("cTrackParams_%s",sConfig.Data()),Form("cTrackParams_%s",sConfig.Data()),1200,900/3.*ydiv);
+  //cTrackParams->Divide(3,ydiv);
   TCanvas *cTrackParams = new TCanvas(Form("cTrackParams_%s",sConfig.Data()),Form("cTrackParams_%s",sConfig.Data()),4800,3600);
   cTrackParams->Divide(3,3);
 
+  //TCanvas *cTrackParamsITS = new TCanvas(Form("cTrackParamsITS_%s",sConfig.Data()),Form("cTrackParamsITS_%s",sConfig.Data()),1200,900/3.*ydiv);
+  //cTrackParamsITS->Divide(3,ydiv);
+  
+  TCanvas *cTrackParamsITS1 = new TCanvas(Form("cTrackParamsITS1_%s",sConfig.Data()),Form("cTrackParamsITS1_%s",sConfig.Data()),1200,900/3.*ydiv);
+  cTrackParamsITS1->Divide(3,ydiv);
   TCanvas *cTrackParamsITS = new TCanvas(Form("cTrackParamsITS_%s",sConfig.Data()),Form("cTrackParamsITS_%s",sConfig.Data()),4800,3600);
   cTrackParamsITS->Divide(3,3);
 
+  TCanvas *cTrackParamsITS2 = new TCanvas(Form("cTrackParamsITS2_%s",sConfig.Data()),Form("cTrackParamsITS2_%s",sConfig.Data()),1200,900/3.*ydiv);
+  cTrackParamsITS2->Divide(3,ydiv);
+  
   TCanvas *cEff = new TCanvas(Form("cEff_%s",sConfig.Data()),Form("cEff_%s",sConfig.Data()),1200,900);
   //cEff->Divide(2,1);
 
@@ -120,22 +135,28 @@ void toyMCRecPlots(TString inFileName = "toyMC.debug.root",Bool_t doPlots = kFAL
   }
 
   // draw track parameters
-  for(Int_t iTrackParams = 0; iTrackParams < nTrackParams; iTrackParams ++){
+  for(Int_t iTrackParams = 0; iTrackParams < nTrackParamsPlot ; iTrackParams ++){
 
     cTrackParams->cd(iTrackParams+1);
     if(inFileName.Contains("allClusters") && iTrackParams==nTrackParams-1) 
       TStatToolkit::DrawHistogram(Tracks,sTrackParams[iTrackParams].Data(),sSel.Data(),Form("hTrackParams_%s_%d",sConfig.Data(),iTrackParams),Form("%s",tTrackParams[iTrackParams].Data()),5);
     else
-      TStatToolkit::DrawHistogram(Tracks,sTrackParams[iTrackParams].Data(),sSel.Data(),Form("hTrackParams_%s_%d",sConfig.Data(),iTrackParams),Form("%s",tTrackParams[iTrackParams].Data()),3);
+      TStatToolkit::DrawHistogram(Tracks,sTrackParams[iTrackParams].Data(),sSel.Data(),Form("hTrackParams_%s_%d",sConfig.Data(),iTrackParams),Form("%s",tTrackParams[iTrackParams].Data()),6);
 
   }
 
 
   // draw track parameters at ITS outer layer
-  for(Int_t iTrackParamsITS = 0; iTrackParamsITS < nTrackParamsITS; iTrackParamsITS ++){
+  for(Int_t iTrackParamsITS = 0; iTrackParamsITS < nTrackParamsPlot; iTrackParamsITS ++){
 
     cTrackParamsITS->cd(iTrackParamsITS+1);
-    TStatToolkit::DrawHistogram(Tracks,sTrackParamsITS[iTrackParamsITS].Data(),sSel.Data(),Form("hTrackParamsITS_%s_%d",sConfig.Data(),iTrackParamsITS),Form("%s",tTrackParamsITS[iTrackParamsITS].Data()),3);
+    TStatToolkit::DrawHistogram(Tracks,sTrackParamsITS[iTrackParamsITS].Data(),sSel.Data(),Form("hTrackParamsITS_%s_%d",sConfig.Data(),iTrackParamsITS),Form("%s",tTrackParamsITS[iTrackParamsITS].Data()),6);
+
+    cTrackParamsITS1->cd(iTrackParamsITS+1);
+    TStatToolkit::DrawHistogram(Tracks,sTrackParamsITS1[iTrackParamsITS].Data(),sSel.Data(),Form("hTrackParamsITS1_%s_%d",sConfig.Data(),iTrackParamsITS),Form("%s",tTrackParamsITS[iTrackParamsITS].Data()),6);
+
+    cTrackParamsITS2->cd(iTrackParamsITS+1);
+    TStatToolkit::DrawHistogram(Tracks,sTrackParamsITS2[iTrackParamsITS].Data(),sSel.Data(),Form("hTrackParamsITS2_%s_%d",sConfig.Data(),iTrackParamsITS),Form("%s",tTrackParamsITS[iTrackParamsITS].Data()),6);
     
   }
 
@@ -155,19 +176,21 @@ void toyMCRecPlots(TString inFileName = "toyMC.debug.root",Bool_t doPlots = kFAL
   if(doPlots){
     TString outFileName = gSystem->BaseName(inFileName.Data());
     outFileName.ReplaceAll(".root","");
-    cT0->SaveAs(Form("%s_T0.eps",outFileName.Data()));
-    cZ0->SaveAs(Form("%s_Z0.eps",outFileName.Data()));
-    cT02D->SaveAs(Form("%s_T02D.eps",outFileName.Data()));
-    cTrackParams->SaveAs(Form("%s_TrackParams.eps",outFileName.Data()));
-    cTrackParamsITS->SaveAs(Form("%s_TrackParamsITS.eps",outFileName.Data()));
-    if(inFileName.Contains("allClusters"))
-      cEff->SaveAs(Form("%s_Eff.eps",outFileName.Data()));
+//     cT0->SaveAs(Form("%s_T0.eps",outFileName.Data()));
+//     cZ0->SaveAs(Form("%s_Z0.eps",outFileName.Data()));
+//     cT02D->SaveAs(Form("%s_T02D.eps",outFileName.Data()));
+//     cTrackParams->SaveAs(Form("%s_TrackParams.eps",outFileName.Data()));
+//     cTrackParamsITS->SaveAs(Form("%s_TrackParamsITS.eps",outFileName.Data()));
+//     if(inFileName.Contains("allClusters"))
+//       cEff->SaveAs(Form("%s_Eff.eps",outFileName.Data()));
 
     cT0->SaveAs(Form("%s_T0.png",outFileName.Data()));
     cZ0->SaveAs(Form("%s_Z0.png",outFileName.Data()));
     cT02D->SaveAs(Form("%s_T02D.png",outFileName.Data()));
     cTrackParams->SaveAs(Form("%s_TrackParams.png",outFileName.Data()));
     cTrackParamsITS->SaveAs(Form("%s_TrackParamsITS.png",outFileName.Data()));
+    cTrackParamsITS1->SaveAs(Form("%s_TrackParamsITS1.png",outFileName.Data()));
+    cTrackParamsITS2->SaveAs(Form("%s_TrackParamsITS2.png",outFileName.Data()));
     if(inFileName.Contains("allClusters"))
       cEff->SaveAs(Form("%s_Eff.eps",outFileName.Data()));
 
index 27fcdc5526ba3c4471912c90684a02a2a4afa37d..41c38b97d8639634cc1bc30303e1d991a4e444a3 100644 (file)
@@ -21,7 +21,6 @@
 #include "TVectorD.h"
 #include "TMatrixD.h"
 #include "TH1.h"
-#include "THnSparse.h"
 #include "TClonesArray.h"
 #include "TTreeStream.h"
 
@@ -80,8 +79,6 @@ public:
   AliTPCtrackFast();
   void Add(AliTPCtrackFast &track2);
   void MakeTrack();
-  void UpdatedEdxHisto();
-  void MakeHisto();
   static void Simul(const char* simul, Int_t ntracks);
   Double_t  CookdEdxNtot(Double_t f0,Float_t f1);
   Double_t  CookdEdxQtot(Double_t f0,Float_t f1);
@@ -99,15 +96,6 @@ public:
   TClonesArray *fCl;   // array of clusters  
   //
   Bool_t   fInit;      // initialization flag
-  THnSparse    *fHistoNtot;    // histograms of trunc mean Ntot
-  THnSparse    *fHistoQtot;    // histograms of trunc mean Qtot
-  THnSparse    *fHistoQNtot;   // histograms of trunc mean Qtot/Ntot
-  //
-  THnSparse    *fHistoDtot;    // histograms of trunc mean digit tot
-  THnSparse    *fHistoDmax;    // histograms of trunc mean digit max
-  THnSparse    *fHistoDtotRaw;    // histograms of trunc mean digit tot
-  THnSparse    *fHistoDmaxRaw;    // histograms of trunc mean digit max
-
   //
   //
   ClassDef(AliTPCtrackFast,2)  // container for
@@ -133,14 +121,7 @@ AliTPCtrackFast::AliTPCtrackFast():
   fAngleZ(0),
   fN(0),
   fCl(0),
-  fInit(kFALSE),
-  fHistoNtot(0),
-  fHistoQtot(0),
-  fHistoQNtot(0),
-  fHistoDtot(0),
-  fHistoDmax(0),
-  fHistoDtotRaw(0),
-  fHistoDmaxRaw(0)
+  fInit(kFALSE)
 {
   //
   //
@@ -150,96 +131,9 @@ AliTPCtrackFast::AliTPCtrackFast():
 void AliTPCtrackFast::Add(AliTPCtrackFast &track2){
   if (!track2.fInit) return;
   
-  fHistoNtot->Add(track2.fHistoNtot);    // histograms of trunc mean Ntot
-  fHistoQtot->Add(track2.fHistoQtot);    // histograms of trunc mean Qtot
-  fHistoQNtot->Add(track2.fHistoQNtot);   // histograms of trunc mean Qtot/Ntot
-  //
-  fHistoDtot->Add(track2.fHistoDtot);    // histograms of trunc mean digit tot
-  fHistoDmax->Add(track2.fHistoDmax);    // histograms of trunc mean digit max
-  fHistoDtotRaw->Add(track2.fHistoDtotRaw);    // histograms of trunc mean digit tot
-  fHistoDmaxRaw->Add(track2.fHistoDmaxRaw);    // histograms of trunc mean digit max
 }
 
-void AliTPCtrackFast::MakeHisto(){
-  //
-  // make default histo
-  //
-  // dEdx histogram THnSparse
-  // 0 - value
-  // 1 - fMNprim - number of generated primaries
-  // 2 - fNpoints
-  // 3 - fFraction
-  // 4 - fDiff
-  // 5 - fAngleY
-  // 6 - fAngleZ
-  
-  Double_t xmin[7],  xmax[7];
-  Int_t    nbins[7];
-  if (fInit) return;
-  //
-  nbins[1] = 10; xmin[1]=10;  xmax[1]=30;    // fMNprim
-  nbins[2] = 8;  xmin[2]=80;  xmax[2]=160;   // fNPoints
-  nbins[3] = 6;  xmin[3]=0.45; xmax[3]=1.05;     // trunc mean fraction
-
-  nbins[4] = 5;  xmin[4]=0.0; xmax[4]=0.4;   // fDiff
-  nbins[5] = 10; xmin[5]=0;   xmax[5]=2;     // fAngleY
-  nbins[6] = 10; xmin[6]=0;   xmax[6]=2;     // fAngleZ
-  //
-  nbins[0] =100; xmin[0]=2; xmax[0]=8;
-  fHistoNtot = new THnSparseF("dNdxall/dNdxprim","dNdxall/dNdxprim", 4, nbins, xmin,xmax);
-  nbins[0] =100; xmin[0]=2; xmax[0]=8;
-  fHistoQtot = new THnSparseF("dQdx/dNdxprim","dQdxall/dNdxprim", 4, nbins, xmin,xmax);
-  nbins[0] =100; xmin[0]=0.5; xmax[0]=1.5;
-  fHistoQNtot = new THnSparseF("dQdx/dNdxprim","dQdxprim/dNdxprim", 4, nbins, xmin,xmax);
-  //
-  nbins[0] =100; xmin[0]=0.05; xmax[0]=8;
-  fHistoDtot = new THnSparseF("dQtotdx/dNdxprim","dQtotdx/dNdx", 7, nbins, xmin,xmax);
-  fHistoDmax = new THnSparseF("dQmaxdx/dNdxprim","dQmaxdx/dNdx", 7, nbins, xmin,xmax);
-  fHistoDtotRaw = new THnSparseF("raw dQtotdx/dNdxprim","raw dQtotdx/dNdx", 7, nbins, xmin,xmax);
-  fHistoDmaxRaw = new THnSparseF("raw dQmaxdx/dNdxprim","raw dQmaxdx/dNdx", 7, nbins, xmin,xmax);
-  fInit=kTRUE;
-}
 
-void  AliTPCtrackFast::UpdatedEdxHisto(){
-  //
-  //fill default histo
-  //
-  if (!fInit) MakeHisto();
-  Double_t x[7];
-  x[1] = fMNprim;
-  x[2] = fN;
-  //
-  x[4] = fDiff;
-  x[5] = TMath::Abs(fAngleY);
-  x[6] = TMath::Abs(fAngleZ);
-
-  for (Int_t i=0;i<7;i++){
-    Float_t frac = 0.5+Float_t(i)*0.1;
-    x[3] = frac;
-    Double_t cNtot = CookdEdxNtot(0.01,frac);
-    Double_t cQtot = CookdEdxQtot(0.01,frac);
-    // MC -using hits
-    x[0] = cNtot/fMNprim;
-    fHistoNtot->Fill(x);
-    x[0] = cQtot/fMNprim;
-    fHistoQtot->Fill(x);
-    x[0] = cQtot/cNtot;
-    fHistoQNtot->Fill(x);
-    // MC - using digits 
-    Double_t dQtot = CookdEdxDtot(0.01,frac,1,2.5,1,kTRUE);
-    Double_t dQmax = CookdEdxDmax(0.01,frac,1,2.5,1,kTRUE);
-    Double_t dQrawtot = CookdEdxDtot(0.01,frac,1,2.5,1,kFALSE);
-    Double_t dQrawmax = CookdEdxDmax(0.01,frac,1,2.5,1,kFALSE);
-    x[0] = dQtot/fMNprim;
-    fHistoDtot->Fill(x);
-    x[0] = dQmax/fMNprim;
-    fHistoDmax->Fill(x);
-    x[0] = dQrawtot/fMNprim;
-    fHistoDtotRaw->Fill(x);
-    x[0] = dQrawmax/fMNprim;
-    fHistoDmaxRaw->Fill(x);
-  }
-}
 
 void AliTPCtrackFast::MakeTrack(){
   //
@@ -259,7 +153,6 @@ void AliTPCtrackFast::MakeTrack(){
     cluster->GenerElectrons();
     cluster->Digitize();
   }
-  UpdatedEdxHisto();
 }
 
 Double_t  AliTPCtrackFast::CookdEdxNtot(Double_t f0,Float_t f1){
@@ -344,7 +237,7 @@ void AliTPCtrackFast::Simul(const char* fname, Int_t ntracks){
   // 
   //
   AliTPCtrackFast fast;
-  TTreeSRedirector cstream(fname);
+  TTreeSRedirector cstream(fname,"recreate");
   for (Int_t itr=0; itr<ntracks; itr++){
     //
     fast.fMNprim=(5+50*gRandom->Rndm());
index 75b52bdca5721e92d255e948c2c1e8de05296a25..4f3fc004e3c3b2f954983235137bd78304969f91 100644 (file)
@@ -1,9 +1,34 @@
+#############################################################################################
 Macros to do fast simulation of processes important for tuning of reconstruction.
+Currently fast simulation of ionization digitization and cluster finder - AliTPCclusterFast
+#############################################################################################
 
-Currently fast simulation of ionization digitization and cluster
-finder - AliTPCclusterFast
 
-And the edge effect in rphi testEdgeFit.C
+How to use it?
+a) which macro to use (I know it was somewhere in AliRoot but with the GIT page I dont find it anymore),
+b) what is the basic functionality of the functions
+c) what do I need to run it (aliroot version?) 
+d) how would I run it and extract space point resolution and dEdx resolution
+    (best step by step for dummies)?
 
 
 
+
+a) Which macro to use (I know it was somewhere in AliRoot
+
+   Example case - submit 40 jobs with 100 tracks.
+   
+   source $ALICE_ROOT/TPCdev/TPC/fastSimul/simul.sh
+   makeEnvLocal             #this is just example please setup your environmnet script to set env variables 
+   makeSubmitRUN 40 100
+
+c) what do I need to run it (aliroot version?) 
+   Recent AliRoot
+
+
+b) What is the basic functionality of the functions?
+   Provides cluster and track functionitility - possible to modify parameters of the reconstruction/ resp. harware setup   See example usage simul.C:DrawdEdxResolExample()
+   
+   
+   
+
index c7d42001a4622d028b4a8c8bf9a847c22c80e382..3b5f76bc4d9704d9599d60a87e64bd001655f8d0 100644 (file)
@@ -1,24 +1,11 @@
 /*
 
-gROOT->LoadMacro("$ALICE_ROOT/TPC/fastSimul/AliTPCclusterFast.cxx+");
-.L $ALICE_ROOT/TPC/fastSimul/simul.C
-//Merge()
+  Macro to generate random tracks and clusters.
+  Fast MC - Geant equivalent used
 
-TFile f("mergetrack.root");
-track = (AliTPCtrackFast*)f.Get("track");
-//
-// Draw debug stream
-//
-gSystem->AddIncludePath("-I$ALICE_ROOT/TPC/macros");
-gROOT->LoadMacro("$ALICE_ROOT/TPC/macros/AliXRDPROOFtoolkit.cxx+");
-AliXRDPROOFtoolkit tool;
-TChain * chain = tool.MakeChain("track.txt","simulTrack",0,200000);
-chain->Lookup();
- gProof->Exec("gSystem->Load(\"$ALICE_ROOT/TPC/fastSimul/AliTPCclusterFast_cxx.so\")",kFALSE);
 
 */
 
-class THnSparse;
 
 void simul(Int_t npoints){ 
   //
@@ -26,7 +13,8 @@ void simul(Int_t npoints){
   //
   printf("Hallo world\n");
   gRandom->SetSeed(0);
-  gROOT->LoadMacro("$ALICE_ROOT/TPC/fastSimul/AliTPCclusterFast.cxx+");
+  gROOT->LoadMacro("$mcPath/AliTPCclusterFast.cxx+");
   AliTPCclusterFast::fPRF = new TF1("fprf","gausn",-5,5);
   AliTPCclusterFast::fTRF = new TF1("ftrf","gausn",-5,5);
   AliTPCclusterFast::fPRF->SetParameters(1,0,0.5);
@@ -65,119 +53,25 @@ void Merge(){
 
 
 
-void DrawDedxMC(THnSparse * hstat){
-  //
+
+void DrawdEdxResolExample(){
   //
+  // Example analysis to make an space point resolution study
   //
-  TH1 * hisMean[7];
-  TH1 * hisSigma[7];
-  TObjArray arr;
-  for (Int_t ifrac=0; ifrac<6; ifrac++){
-    Float_t frac = 0.5+0.1*Float_t(ifrac);
-    hstat->GetAxis(3)->SetRange(ifrac+1,ifrac+1);
-    hstat->GetAxis(2)->SetRangeUser(120,160);
-    TH2F * his = (TH2F*)hstat->Projection(0,1);
-    his->FitSlicesY(0,0,-1,0,"QNR",&arr);
-    delete his;
-    hisMean[ifrac]  = (TH1*) arr.At(1)->Clone();
-    hisSigma[ifrac] = (TH1*) arr.At(2)->Clone();
-    arr.SetOwner(kTRUE); arr.Delete();
-    //
-    hisSigma[ifrac]->Divide(hisMean[ifrac]);
-    hisMean[ifrac]->SetMaximum(6);
-    hisMean[ifrac]->SetMinimum(0);
-    hisSigma[ifrac]->SetMaximum(0.07);
-    hisSigma[ifrac]->SetMinimum(0.03);
-    //
-    hisMean[ifrac]->SetDirectory(0);
-    hisSigma[ifrac]->SetDirectory(0);
-    hisMean[ifrac]->SetXTitle("N_{prim}");
-    hisSigma[ifrac]->SetXTitle("N_{prim}");
-    hisMean[ifrac]->SetYTitle("Q/N_{prim}");
-    hisSigma[ifrac]->SetYTitle("#sigma_{Q/N_{prim}}/(Q/N_{prim})");
-    hisMean[ifrac]->SetMarkerColor(kmicolors[ifrac+1]);
-    hisMean[ifrac]->SetMarkerStyle(kmimarkers[ifrac+1]);
-    hisSigma[ifrac]->SetMarkerColor(kmicolors[ifrac+1]);
-    hisSigma[ifrac]->SetMarkerStyle(kmimarkers[ifrac+1]);
-  }
-  TCanvas * c = new TCanvas(hstat->GetName(),hstat->GetName(),600,800);
-  TLegend *legend = new TLegend(0.55,0.70,0.95,0.95, hstat->GetName());
-  c->Divide(1,2);
-  for (Int_t ifrac=0; ifrac<6; ifrac++){
-    c->cd(1);
-    if (ifrac==0) hisMean[ifrac]->Draw();
-    legend->AddEntry(hisMean[ifrac],Form("%f",0.5+0.1*ifrac));
-    hisMean[ifrac]->Draw("same");
-    c->cd(2);
-    if (ifrac==0) hisSigma[ifrac]->Draw();
-    hisSigma[ifrac]->Draw("same");
-  }
-  c->Draw();
-  legend->Draw();
-  TString fname=hstat->GetName();
-  fname.ReplaceAll("/","_");
-  c->SaveAs(Form("pic/%s.eps",fname.Data()));
-  c->SaveAs(Form("pic/%s.gif",fname.Data()));
-  c->SaveAs(Form("pic/%s.root",fname.Data()));
-}
-
-
-
+  TChain * chain  = AliXRDPROOFtoolkit::MakeChain("trackerSimul.list", "simulTrack",0,100); 
+  chain->SetCacheSize(10000000000);
 
-void DrawDedxN(THnSparse * hstat){
   //
+  // 1.) Qmax/Qtot as function of the input ionization density
   //
+  chain->Draw("tr.CookdEdxDmax(0,0.6,1,0,1,0)/tr.CookdEdxDtot(0,0.6,1,0,1,0):tr.fMNprim>>hisQtotMax(10,10,50)","","prof",10000);
   //
-  TH1 * hisMean[7];
-  TH1 * hisSigma[7];
-  TObjArray arr;
-  for (Int_t ifrac=0; ifrac<6; ifrac++){
-    Float_t frac = 0.5+0.1*Float_t(ifrac);
-    hstat->GetAxis(3)->SetRange(ifrac+1,ifrac+1);
-    hstat->GetAxis(2)->SetRangeUser(80,160);
-    hstat->GetAxis(1)->SetRangeUser(15,18);
-    TH2F * his = (TH2F*)hstat->Projection(0,2);
-    his->FitSlicesY(0,0,-1,0,"QNR",&arr);
-    delete his;
-    hisMean[ifrac]  = (TH1*) arr.At(1)->Clone();
-    hisSigma[ifrac] = (TH1*) arr.At(2)->Clone();
-    arr.SetOwner(kTRUE); arr.Delete();
-    //
-    hisSigma[ifrac]->Divide(hisMean[ifrac]);
-    hisMean[ifrac]->SetMaximum(6);
-    hisMean[ifrac]->SetMinimum(0);
-    hisSigma[ifrac]->SetMaximum(0.07);
-    hisSigma[ifrac]->SetMinimum(0.03);
-    //
-    hisMean[ifrac]->SetDirectory(0);
-    hisSigma[ifrac]->SetDirectory(0);
-    hisMean[ifrac]->SetXTitle("N_{cl}");
-    hisSigma[ifrac]->SetXTitle("N_{cl}");
-    hisMean[ifrac]->SetYTitle("Q/N_{prim}");
-    hisSigma[ifrac]->SetYTitle("#sigma_{Q/N_{prim}}/(Q/N_{prim})");
-    hisMean[ifrac]->SetMarkerColor(kmicolors[ifrac+1]);
-    hisMean[ifrac]->SetMarkerStyle(kmimarkers[ifrac+1]);
-    hisSigma[ifrac]->SetMarkerColor(kmicolors[ifrac+1]);
-    hisSigma[ifrac]->SetMarkerStyle(kmimarkers[ifrac+1]);
-  }
-  TCanvas * c = new TCanvas(hstat->GetName(),hstat->GetName(),600,800);
-  TLegend *legend = new TLegend(0.55,0.70,0.95,0.95, hstat->GetName());
-  c->Divide(1,2);
-  for (Int_t ifrac=0; ifrac<6; ifrac++){
-    c->cd(1);
-    if (ifrac==0) hisMean[ifrac]->Draw();
-    legend->AddEntry(hisMean[ifrac],Form("%f",0.5+0.1*ifrac));
-    hisMean[ifrac]->Draw("same");
-    c->cd(2);
-    if (ifrac==0) hisSigma[ifrac]->Draw();
-    hisSigma[ifrac]->Draw("same");
-  }
-  c->Draw();
-  legend->Draw();
-  TString fname=hstat->GetName();
-  fname+="NCl";
-  fname.ReplaceAll("/","_");
-  c->SaveAs(Form("pic/%s.eps",fname.Data()));
-  c->SaveAs(Form("pic/%s.gif",fname.Data()));
-  c->SaveAs(Form("pic/%s.root",fname.Data()));
+  // 2.) Non linearity due to the tucncation Qtot_{60%}/Qtot 100% 
+  //
+  chain->Draw("tr.CookdEdxDtot(0,0.6,1,0,1,0)/tr.CookdEdxDtot(0,0.99,1,0,1,0):tr.fMNprim>>hisQtot60100(10,10,50)","","prof",10000);
+  //
+  //
+  //
+
+
 }
index bab94432601934b593dcdbbcd106c68a3cf7295d..9d555b811cf181126c6f87a0853b418c8606e05b 100755 (executable)
@@ -1,32 +1,93 @@
 #!/bin/sh
 
-# 1 argument      - the path to the environment setup
-# 2 argument      - the job ID
-# 3 argument      - number of events in the file
-# 4 argument      - output path
-
-# Example
-# myvar=0
-# $ALICE_ROOT/TPC/fastSimul/simul.sh  /u/miranov/.balice64HEAD0108 $myvar 1000 `pwd`
-# while [ $myvar -ne 100 ] ; do bsub  do something ;  myvar=$(( $myvar + 1 )) ; echo $myvar ; done
+
+
+main()
+{
+  #
+  # run in proper action depending on the selection
+  #  
+  if [[ $# -lt 1 ]]; then
+    if [[ ! "$0" =~ "bash" ]]; then
+      echo " Please select action"
+    fi
+    return
+  fi
+  runMode=$1
+  umask 0002
+  shift
+  case $runMode in
+   "runJob") runJob "$@";;
+    "makeEnvLocal") makeEnvLocal "$@";;
+    "makeSubmitRun") makeSubmitRun "$@";;
+   *) 
+   eval "${runMode} $@" 
+   ;;
+  esac
+  return;
+}
+
+
+
+exampleCase(){
 #
-# 1 SETUP given ROOT and ALIROOT
+#  Example case to subit Toy MC jobs
+# 
+   source $ALICE_ROOT/TPCdev/TPC/fastSimul/simul.sh
+   makeEnvLocal
+   makeSubmitRUN 40 100
+   ls `pwd`/MC*/trackerSimul.root >  trackerSimul.list
+
+}
+
+
+
+runJob()
+{
+#runFastMCJob      
+    echo  $ROOTSYS
+    which root.exe
+    which aliroot
+    echo PWD `pwd`
+    ntracks=$1
+    echo Submitting ntracks = $ntracks
+    echo command aliroot  -q -b  "$mcPath/simul.C\($ntracks\)"    
+    command aliroot  -q -b  "$mcPath/simul.C($ntracks)"    
+    return;
+}
+
+
+makeEnvLocal(){
 #
-echo   $1
-source $1
-echo  $ROOTSYS
-which root.exe
-which aliroot
 #
-#  make directory
+# Example usage local 
+# jobs to be submitted form the lxb1001 or lxb1002
+#(here we have 80 nodes and user disk)
+# 
+    echo makeEnvLocal
+    export baliceTPC=$HOME/.baliceTPC
+    export mcPath=$ALICE_ROOT/TPC/fastSimul
+    export batchCommand="qsub -cwd  -V "
+}
+
+makeSubmitRUN(){
 #
+# submits jobs
+#   
+    wdir=`pwd`;
+    njobs=$1
+    ntracks=$2
+    for (( job=1; job <= $njobs; job++ ));  do  
+       echo $job;  
+       mkdir $wdir/MC$job
+       cd $wdir/MC$job
+       echo $batchCommand    -o  toyMC.log  $mcPath/simul.sh runJob  $ntracks
+       $batchCommand    -o  toyMC.log  $mcPath/simul.sh runJob $ntracks
+       cd $wdir
+    done 
+}
+
+
 
-cd $4
-mkdir $2
-cd $2
-cp ~/rootlogon.C .
-echo Job ID  $2
-echo
-echo PWD `pwd`
+main "$@"
 
-command aliroot  -q -b  "$ALICE_ROOT/TPC/fastSimul/simul.C($3)"
\ No newline at end of file
diff --git a/TPC/macros/CalibratedEdxRegion.C b/TPC/macros/CalibratedEdxRegion.C
new file mode 100644 (file)
index 0000000..df253bc
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+  Macro to make an per region dEdx calibration.
+  Here we assue we have suufiecint ammount of V) PID selected tracks for the calibration
+
+  .x $HOME/rootlogon.C
+  .L $ALICE_ROOT/TPC/macros/CalibratedEdxRegion.C+
+  
+ */
+
+#include "TTree.h"
+#include "TFile.h"
+#include "TH1.h"
+#include "TH2.h" 
+#include "TCut.h"
+#include "TStatToolkit.h"
+#include "TGraphErrors.h"
+
+#include "AliESDtrack.h"
+#include "AliESDv0.h"
+#include "AliExternalTrackParam.h"
+#include "AliTPCdEdxInfo.h"
+#include "AliTPCParamSR.h"
+
+//TTree * trees[4]={treeK0, treeLambda,treeALambda,treeGamma};
+TTree * trees[4]={0};
+TFile * calibrationFile=0;
+
+void InitTrees(const char * v0file= "/hera/alice/miranov/ExpertQA/data/LHC13c/pass1/V0Selected.root"){
+  //
+  //
+  //
+  //  const char * v0file = "/hera/alice/miranov/ExpertQA/data/LHC13c/pass1/V0Selected.root";
+  TFile * f = TFile::Open(v0file);
+  TTree * treeLambda=(TTree*)f->Get("treeLambda");
+  TTree * treeALambda=(TTree*)f->Get("treeALambda");
+  TTree * treeK0=(TTree*)f->Get("treeK0");
+  TTree * treeGamma=(TTree*)f->Get("treeGamma");
+  calibrationFile=TFile::Open("dEdxCalibration.root","update");
+  //
+  // register BetheBloch parameterization for each type of identified particles
+  //
+  AliTPCParam param;
+  param.RegisterBBParam(param.GetBetheBlochParamAlice(),1);
+  treeK0->SetAlias("dEdxExp0","AliTPCParam::BetheBlochAleph(track0.fIp.P()/massPion,1)");
+  treeK0->SetAlias("dEdxExp1","AliTPCParam::BetheBlochAleph(track1.fIp.P()/massPion,1)");
+  treeLambda->SetAlias("dEdxExp0","AliTPCParam::BetheBlochAleph(track0.fIp.P()/massProton,1)");
+  treeLambda->SetAlias("dEdxExp1","AliTPCParam::BetheBlochAleph(track1.fIp.P()/massPion,1)");
+  treeALambda->SetAlias("dEdxExp0","AliTPCParam::BetheBlochAleph(track0.fIp.P()/massPion,1)");
+  treeALambda->SetAlias("dEdxExp1","AliTPCParam::BetheBlochAleph(track1.fIp.P()/massProton,1)");
+  treeGamma->SetAlias("dEdxExp0","AliTPCParam::BetheBlochAleph(track0.fIp.P()/0.005,1)");
+  treeGamma->SetAlias("dEdxExp1","AliTPCParam::BetheBlochAleph(track1.fIp.P()/0.005,1)");
+  //
+  //
+  //
+  AliTPCParamSR paramSR;
+  TString rROC0=TString::Format("%2.2f", 0.5*(paramSR.GetInnerRadiusLow()+paramSR.GetInnerRadiusUp()));
+  TString rROC1=TString::Format("%2.2f", 0.5*(paramSR.GetPadRowRadii(36,0)+paramSR.GetPadRowRadii(36,paramSR.GetNRowUp1()-1)));
+  TString rROC2=TString::Format("%2.2f", 0.5*(paramSR.GetPadRowRadii(36,0)+paramSR.GetPadRowRadii(36,paramSR.GetNRowUp()-1)));
+  //
+  //
+  // 
+  Double_t bz=-5;
+  trees={treeK0, treeLambda,treeALambda,treeGamma};
+  for (Int_t itree=0; itree<4;itree++){
+    trees[itree]->SetAlias("bz","-5");
+    trees[itree]->SetAlias("phi0ROC0",TString::Format("track0.fIp.GetParameterAtRadius(%s+0,%2.2f,7)",rROC0.Data(),bz));
+    trees[itree]->SetAlias("phi0ROC1",TString::Format("track0.fIp.GetParameterAtRadius(%s+0,%2.2f,7)",rROC1.Data(),bz));
+    trees[itree]->SetAlias("phi0ROC2",TString::Format("track0.fIp.GetParameterAtRadius(%s+0,%2.2f,7)",rROC2.Data(),bz));
+    trees[itree]->SetAlias("phi1ROC0",TString::Format("track1.fIp.GetParameterAtRadius(%s+0,%2.2f,7)",rROC0.Data(),bz));
+    trees[itree]->SetAlias("phi1ROC1",TString::Format("track1.fIp.GetParameterAtRadius(%s+0,%2.2f,7)",rROC1.Data(),bz));
+    trees[itree]->SetAlias("phi1ROC2",TString::Format("track1.fIp.GetParameterAtRadius(%s+0,%2.2f,7)",rROC2.Data(),bz));
+    //
+    //
+    trees[itree]->SetAlias("side0","(track0.fIp.fP[3]>0&&track0.fIp.fP[1]>0)+2*(track0.fIp.fP[3]<0&&track0.fIp.fP[1]<0)");  // 0 - both sides, 1- A side, 2- C side
+    trees[itree]->SetAlias("side1","(track1.fIp.fP[3]>0&&track1.fIp.fP[1]>0)+2*(track1.fIp.fP[3]<0&&track1.fIp.fP[1]<0)");
+  }
+  /*
+    consistency check: 
+    // Phi position extrapolated to the IFC OK
+    treeK0->Draw("track0.GetParameterAtRadius(83.8,-5,7)-track0.fIp.fAlpha-track0.fIp.fP[0]/track0.fIp.fX>>his(100,-0.02,0.02)","abs(track0.GetParameterAtRadius(83.8,-5,7)-track0.fIp.fAlpha)<0.5","",100000);
+    // Phi angle extrapolated to the IFC
+    treeK0->Draw("track0.GetParameterAtRadius(83.8,-5,8)-track0.fIp.Phi()>>his(100,-0.02,0.02)","abs(track0.GetParameterAtRadius(83.8,-5,7)-track0.fIp.fAlpha)<0.5","",100000);
+    //
+    treeK0->Draw("track0.GetParameterAtRadius(103.8,-5,9)-(track0.fIp.GetParameterAtRadius(103.8,-5,8)-track0.fIp.GetParameterAtRadius(103.8,-5,7))>>his(100,-0.05,0.05)","abs(track0.GetParameterAtRadius(103.8,-5,8)-track0.GetParameterAtRadius(103.8,-5,7))<0.5","",10000);
+
+   */
+}
+
+void MakeSectorCalibration(){
+  //
+  // Get sector phi correction - separate for 
+  //
+  TCut cutASide0="side0>0";
+  TCut cutPt0="abs(track0.fIp.fP[4])<3";
+  TCut cutASide1="side1>0";
+  TCut cutPt1="abs(track0.fIp.fP[4])<3";
+  TObjArray * histoArray = new TObjArray(100);
+  TObjArray * graphArray = new TObjArray(100);
+  //
+  //
+  //
+  for (Int_t iregion=0; iregion<3; iregion++){
+    //    
+    TH2F *hisSectorROC=0;
+    TH2F *hisSectorROCP=0;
+    TH2F *hisSectorROCM=0;
+    TGraphErrors * graphs[3]={0};
+
+    for (Int_t itree=0; itree<3; itree++){
+      TString var0=TString::Format("track0.fTPCdEdxInfo.fTPCsignalRegion[%d]/dEdxExp0:18*(phi0ROC%d/pi+(side0-1))>>hisSectorROCPlus%d(36,0,36,60,20,80)",iregion,iregion,iregion);
+      TString var1=TString::Format("track1.fTPCdEdxInfo.fTPCsignalRegion[%d]/dEdxExp1:18*(phi1ROC%d/pi+(side1-1))>>hisSectorROCMinus%d(36,0,36,60,20,80)",iregion,iregion,iregion);
+      
+      trees[itree]->Draw(var0.Data(),cutASide0+cutPt0,"colzgoff");
+      if (hisSectorROCP==0) {
+       hisSectorROCP=(TH2F*)trees[itree]->GetHistogram()->Clone();
+      }
+      if (hisSectorROCP) hisSectorROCP->Add((TH2F*)trees[itree]->GetHistogram());
+      trees[itree]->Draw(var1.Data(),cutASide1+cutPt1,"colzgoff");
+      if (hisSectorROCM==0) hisSectorROCM=(TH2F*)trees[itree]->GetHistogram()->Clone();
+      if (hisSectorROCM) hisSectorROCM->Add((TH2F*)trees[itree]->GetHistogram());      
+    }
+    hisSectorROC=(TH2F*)hisSectorROCP->Clone();
+    hisSectorROC->SetName(TString::Format("hisSectorROCBoth%d(36,0,36,60,20,80)",iregion));
+    hisSectorROC->Add(hisSectorROCM);
+    //
+    graphs[0]=TStatToolkit::MakeStat1D(hisSectorROC, 0, 0.85,4,20,1);    
+    graphs[1]=TStatToolkit::MakeStat1D(hisSectorROCP, 0, 0.85,4,24,2);
+    graphs[2]=TStatToolkit::MakeStat1D(hisSectorROCM, 0, 0.85,4,25,4);    
+    graphs[0]->SetName(TString::Format("graphSectorROCBoth%d(36,0,36,60,20,80)",iregion));
+    graphs[1]->SetName(TString::Format("graphSectorROCPlus%d(36,0,36,60,20,80)",iregion));
+    graphs[2]->SetName(TString::Format("graphSectorROCMinus%d(36,0,36,60,20,80)",iregion));
+    graphs[0]->Draw("alp");
+    TStatToolkit::MakeStat1D(hisSectorROCP, 0, 0.85,4,24,2)->Draw("lp");
+    TStatToolkit::MakeStat1D(hisSectorROCM, 0, 0.85,4,25,4)->Draw("lp");
+    histoArray->AddLast(hisSectorROC);
+    histoArray->AddLast(hisSectorROCP);
+    histoArray->AddLast(hisSectorROCM); 
+    for (Int_t i=0; i<3; i++){
+      graphArray->AddLast(graphs[i]);
+    }
+  }
+  calibrationFile->mkdir("histos");
+  calibrationFile->cd("histos");
+  histoArray->Write();
+  calibrationFile->mkdir("graphs");
+  calibrationFile->cd("graphs");
+  graphArray->Write();
+  
+}
diff --git a/TPC/macros/data2011/makeBBFit.C b/TPC/macros/data2011/makeBBFit.C
new file mode 100644 (file)
index 0000000..15460e5
--- /dev/null
@@ -0,0 +1,630 @@
+/*
+   Macro to make the MC based dEdx fits, and study the influence of thre track selection to the PID.
+
+   Motivation:
+   In the ALICE Geant3 MC the input Bethe-Bloch parameterization of the primary ionization can be 
+   parameterized by user defined formula.
+
+   In detector Input dEdx(BG)_in} (more exact dNprim/dx) is transformed to the output reconstructed dEdx_{rec}. 
+   While original input function is just function of particle \beta\gama, random variable, reconstructed 
+   dEdx estimate, is influenced by detection processes and is sensitive to other aspects namily 
+   diffusion, track inclination angle (\phi,\theta), gain ...
+
+   In the following we will calibrate transform function:
+    dEdx_{BB}= f_{tr}(dEdx_{rec}, #phi,#eta)
+    //
+    // Example code for author:
+    //
+    .x $HOME/rootlogon.C
+    .x $HOME/NimStyle.C
+    .L $ALICE_ROOT/TPC/macros/data2011/makeBBFit.C+
+    Init();
+    MakeESDCutsPID();
+    makeBBfit(10000000);
+
+*/
+
+#include "TCut.h"
+#include "TFile.h"
+#include "TTree.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TH3.h"
+#include "TF1.h"
+#include "TCanvas.h"
+#include "TDatabasePDG.h"
+#include "TStatToolkit.h"
+#include "TGraphErrors.h"
+#include "TStopwatch.h"
+#include "TLegend.h"
+#include "TLatex.h"
+//
+#include "TTreeStream.h"
+#include "AliTPCParam.h"
+#include "AliTPCcalibBase.h"
+
+//
+// Global variables
+//
+
+TCut cutGeom, cutNcr, cutNcl;
+TCut cutFiducial;
+Int_t pdgs[4]={11,211,321,2212};
+Double_t massPDG[4]={0};
+const char *partName[4]={"Electron","Pion","Kaon","Proton"};
+const Int_t colors[5]={kGreen,kBlack,kRed,kBlue,5};
+const Int_t markers[5]={24,20,21,25,25};
+const Float_t markerSize[5]={1.2,1.2,1.0,1.2,1};
+TTree * treeFit=0;
+
+void Init();            // init (ALICE) BB parameterization
+
+//
+void FitTransferFunctionTheta(Bool_t isMax, Int_t dType, Int_t tgl, Bool_t skipKaon, Double_t maxP, TTreeSRedirector *pcstream, Bool_t doDraw);
+void FitTransferFunctionAll(Bool_t isMax, Int_t dType, Bool_t skipKaon, Double_t maxP, TTreeSRedirector *pcstream, Bool_t doDraw);
+
+void Init(){
+   //
+  // 1.) Register default ALICE parametrization
+  //
+  AliTPCParam param;
+  param.RegisterBBParam(param.GetBetheBlochParamAlice(),1);
+  for (Int_t ihis=0; ihis<4; ihis++)     massPDG [ihis]= TDatabasePDG::Instance()->GetParticle(pdgs[ihis])->Mass();
+}
+
+
+void MakeESDCutsPID(Double_t fgeom=1, Double_t fcr=0.85, Double_t fcl=0.7 ){
+  //
+  // Cuts to be used in the sequenece
+  // 1.)  cutGeom - stronger cut on geometry  - perfect agreement data-MC        
+  //              - Default length factor 1
+  // 2.)  cutNcr  - relativally stong cut on the number of crossed rows to gaurantee tracking performance 
+  //                relativally good agrement in the MC except of the week decay propability
+  //              - Default length factor 0.85
+  // 3.)  cutNcl  - very week cut on the numebr of clusters
+  //              - Default length factor 0.7
+  //  
+  // Combined cuts should be combination:
+  // cutGeom+cutNcr+cutNcl 
+  //  Default  factors 1, 0.85 and 0.7 should be suited for most of analysis
+  //  Modification can be expected for the Jet analysis and further tuning of the parameters for the 
+  //     relativistic PID analysis
+  //  
+  cutGeom=TString::Format("esdTrack.GetLengthInActiveZone(0,3,236, -5 ,0,0)> %f*(130-5*abs(esdTrack.fP[4]))",fgeom); 
+  //  Geomtrical cut in fiducial volume - proper description  in the MC
+  //  GetLengthInActiveZone(Int_t mode, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi = 0, TTreeSRedirector* pcstream = 0) const
+  //  mode   ==0     - inner param used
+  //  deltaY ==3     - cut on edges of sector 
+  //                   a.) to avoid dead zone - bias for tracking
+  //                   b.) zone with lower Q qualit
+  //                   c.) non homogenous Q sample - preferable IROC is skipped -bais in the dEdx
+  //  deltaZ ==236   - 
+  //  bz = 5 KG      - proper sign should be used ohterwise wrong calculation
+  cutNcr=TString::Format("esdTrack.GetTPCClusterInfo(3,1,0,159,1)>%f*(130-5*abs(esdTrack.fP[4]))",fcr);
+  //
+  // Cut on the number of crossed raws
+  // GetTPCClusterInfo(Int_t nNeighbours = 3, Int_t type = 0, Int_t row0 = 0, Int_t row1 = 159, Int_t bitType = 0) 
+  // pad row is decalared as crossed if some clusters was found in small neighborhood +- nNeighbours
+  //    nNeighbours =3  - +-3 padrows used to define the crossed rows
+  //    type = 0        - return number of rows (type==1 returns fraction of clusters)
+  //    row0-row1       - upper and lower part of integration
+  //  
+  cutNcl=TString::Format("esdTrack.fTPCncls>%f*(130-5*abs(esdTrack.fP[4]))",fcl);
+  //
+  // cut un the number of clusters
+  //
+  cutFiducial="abs(esdTrack.fP[3])<1&&abs(esdTrack.fD)<1";
+}
+
+void makeBBfit(Int_t ntracks=100000){
+  //
+  // Make dEdx  fits of indiviadual particle species in bins:
+  //  a.)  momenta
+  //  b.)  tan(theta) -tgl
+  //  c.)  per detector segmen
+  //  d.)  Qmax/Qtot
+  TFile * ff = TFile::Open("Filtered.root");
+  TTreeSRedirector *pcstream = new TTreeSRedirector("dedxFit.root","update");
+  TTree * treeMC = (TTree*)ff->Get("highPt");
+  //  treeMC->SetCacheSize(6000000000);
+  //
+  // 1.) Register default ALICE parametrization
+  //
+  AliTPCParam param;
+  param.RegisterBBParam(param.GetBetheBlochParamAlice(),1);
+  TH3D * hisdEdx3D[4]={0};
+  //
+  for (Int_t ihis=0; ihis<4; ihis++) {
+    massPDG [ihis]= TDatabasePDG::Instance()->GetParticle(pdgs[ihis])->Mass();
+    treeMC->SetAlias(TString::Format("cut%s",partName[ihis]), TString::Format("abs(particle.fPdgCode)==%d",pdgs[ihis]));
+    treeMC->SetAlias(TString::Format("dEdxp%s",partName[ihis]), TString::Format("AliTPCParam::BetheBlochAleph(esdTrack.fIp.P()/%f,1)",massPDG[ihis]));
+  }
+  //
+  // 2.) Fill dEdx histograms if not done before
+  //
+
+  if (pcstream->GetFile()->Get("RatioP_QMax0Pion3D")==0){    
+    //
+    TStopwatch timer;
+    for (Int_t iDetType=0; iDetType<9; iDetType++){
+      for (Int_t ihis=0; ihis<4; ihis++){
+       printf("%d\t%d\n",iDetType,ihis);
+       timer.Print();
+       TString detType="All";
+       TString dedx   ="esdTrack.fTPCsignal";
+       if (iDetType>0){
+         detType=TString::Format("Q%s%d",(iDetType-1)/4>0?"Max":"Tot",(iDetType-1)%4);
+         if (iDetType<5) dedx=TString::Format("esdTrack.fTPCdEdxInfo.GetSignalTot(%d)",(iDetType-1)%4);
+         if (iDetType>5) dedx=TString::Format("esdTrack.fTPCdEdxInfo.GetSignalMax(%d)",(iDetType-1)%4);
+       }  
+
+       TCut cutPDG=TString::Format("abs(particle.fPdgCode)==%d",pdgs[ihis]).Data();
+       TString hname= TString::Format("RatioP_%s%s3D",detType.Data(),partName[ihis]);  
+       TString query= TString::Format("%s/AliTPCParam::BetheBlochAleph(esdTrack.fIp.P()/%f,1):abs(esdTrack.fP[3]):esdTrack.fIp.P()>>%s",dedx.Data(), massPDG[ihis],hname.Data());
+       hisdEdx3D[ihis]  = new TH3D(hname.Data(),hname.Data(), 50, 0.2,25, 10,0,1, 100,20,80);
+       AliTPCcalibBase::BinLogX(hisdEdx3D[ihis]->GetXaxis());
+       treeMC->Draw(query,cutFiducial+cutGeom+cutNcr+cutNcl+cutPDG,"goff",ntracks);
+       
+       hisdEdx3D[ihis]->GetXaxis()->SetTitle("p (GeV/c)");
+       hisdEdx3D[ihis]->GetYaxis()->SetTitle("dEdx/dEdx_{BB} (a.u.)");
+       pcstream->GetFile()->cd();
+       hisdEdx3D[ihis]->Write(hname.Data());
+      }
+    }
+  }
+  delete pcstream;
+  //
+  // Fit histograms
+  //
+  pcstream = new TTreeSRedirector("dedxFit.root","update");
+  TF1 fg("fg","gaus");
+  //
+  for (Int_t iDetType=0; iDetType<9; iDetType++){
+    TString detType="All";
+    if (iDetType>0){
+      detType=TString::Format("Q%s%d",(iDetType-1)/4>0?"Max":"Tot",(iDetType-1)%4);
+    }    
+    for (Int_t ihis=0; ihis<4; ihis++){ 
+      TString hname= TString::Format("RatioP_%s%s3D",detType.Data(),partName[ihis]);   
+      hisdEdx3D[ihis] = (TH3D*)pcstream->GetFile()->Get(hname.Data()); 
+      Int_t nbinsP =  hisdEdx3D[0]->GetXaxis()->GetNbins();
+      Int_t nbinsTgl =  hisdEdx3D[0]->GetYaxis()->GetNbins();
+      //
+      for (Int_t ibinP=2; ibinP<nbinsP; ibinP++){
+       for (Int_t ibinTgl=2; ibinTgl<nbinsTgl; ibinTgl++){
+         //
+         Double_t pCenter =  hisdEdx3D[0]->GetXaxis()->GetBinCenter(ibinP);
+         Double_t tglCenter =  hisdEdx3D[0]->GetYaxis()->GetBinCenter(ibinTgl);
+         TH1D * hisProj =hisdEdx3D[ihis]->ProjectionZ("xxx", ibinP-1,ibinP+1, ibinTgl-1,ibinTgl+1);
+         Double_t entries = hisProj->GetEntries();
+         if (entries<10) continue;
+         Double_t mean = hisProj->GetMean();
+         Double_t rms = hisProj->GetRMS();
+         hisProj->Fit(&fg,"","");
+         TVectorD vecFit(3, fg.GetParameters());
+         TVectorD vecFitErr(3, fg.GetParErrors());
+         Double_t chi2=fg.GetChisquare();
+         Double_t mass    = massPDG[ihis];
+         Double_t dEdxExp =  AliTPCParam::BetheBlochAleph(pCenter/mass,1);
+         Bool_t isAll=(iDetType==0);
+         Bool_t isMax=(iDetType-1)/4>0;
+         Bool_t isTot=(iDetType-1)/4==0;
+         Int_t dType=(iDetType-1)%4;
+         Double_t dEdx = mean*dEdxExp;
+         //if (
+         (*pcstream)<<"fitdEdxG"<<
+           // dEdx type
+           "iDet="<<iDetType<<      // detector internal number
+           "isAll="<<isAll<<        // full TPC used?
+           "isMax="<<isMax<<        // Qmax charge used ?
+           "isTot="<<isTot<<        // Qtot charge used?
+           "dType="<<dType<<        // Detector region 0-IROC, 1- OROCmedium, 2- OROClong, 3- OROCboth
+           "pType="<<ihis<<         // particle type
+           //
+           "entries="<<entries<<      // entries in histogram
+           "ibinTgl="<<ibinTgl<<      //
+           "ibinP="<<ibinP<<          // 
+           "pCenter="<<pCenter<<      // momentum of center bin
+           "tglCenter="<<tglCenter<<  // tangent lambda
+           //
+           "mass="<<mass<<             // particle mass
+           "dEdxExp="<<dEdxExp<<       // mean expected dEdx in bin 
+           "dEdx="<<dEdx<<             // mean measured dEdx in bin
+           "mean="<<mean<<             // mean measured/expected
+           "rms="<<rms<<               // 
+           "chi2="<<chi2<<             // chi2 of the gausian fit
+           "vecFit.="<<&vecFit<<       // gaus fit param
+           "vecFitErr.="<<&vecFitErr<< // gaus fit error
+           "\n";
+       }
+      }
+    }
+  }
+  delete pcstream;
+  //
+  //
+  //
+}
+
+
+void FitTransferFunctionScanAll(){
+  //
+  // Make fit of transfer functions - parabolic in theta
+  //
+  TTreeSRedirector * pcstream = new TTreeSRedirector("dedxFit.root","update");
+  treeFit=(TTree*)pcstream->GetFile()->Get("fitdEdxG"); 
+  treeFit = (TTree*)pcstream->GetFile()->Get("fitdEdxG");
+  treeFit->SetMarkerStyle(25);
+  treeFit->SetCacheSize(200000000);
+  for (Int_t isMax=0; isMax<=1; isMax++){
+    for (Int_t dType=0; dType<4; dType++){      
+      for (Int_t skipKaon=0; skipKaon<=1; skipKaon++){
+       for (Float_t maxP=3; maxP<21; maxP+=3){
+         printf("%d\t%d\t%d\t%f\n",isMax,dType,skipKaon,maxP);
+         FitTransferFunctionAll(isMax,dType,skipKaon,maxP,pcstream,1);
+       }
+      }
+    }
+  }
+  delete pcstream;
+}
+
+
+void FitTransferFunctionScanTheta(){
+  //
+  // Make fit of transfer functions - bin by bin in Theta
+  //
+  TTreeSRedirector * pcstream = new TTreeSRedirector("dedxFit.root","update");
+  treeFit=(TTree*)pcstream->GetFile()->Get("fitdEdxG"); 
+  treeFit = (TTree*)pcstream->GetFile()->Get("fitdEdxG");
+  treeFit->SetMarkerStyle(25);
+  treeFit->SetCacheSize(200000000);
+  for (Int_t isMax=0; isMax<=1; isMax++){
+    for (Int_t dType=0; dType<4; dType++){
+      
+      for (Int_t tgl=2; tgl<10; tgl++){
+       for (Int_t skipKaon=0; skipKaon<=1; skipKaon++){
+         for (Float_t maxP=3; maxP<21; maxP+=3){
+           printf("%d\t%d\t%d\t%d\t%f\n",isMax,dType,tgl,skipKaon,maxP);
+           FitTransferFunctionTheta(isMax,dType,tgl,skipKaon,maxP,pcstream,1);
+         }
+       }
+      }
+    }
+  }
+  delete pcstream;
+}
+
+
+void FitTransferFunctionTheta(Bool_t isMax, Int_t dType, Int_t tgl, Bool_t skipKaon, Double_t maxP, TTreeSRedirector *pcstream, Bool_t doDraw){
+  //
+  // 
+  // dEdx_{BB}= f_{tr}(dEdx_{rec}, #phi,#eta)
+  //
+  // Fit the parematers of transfer function
+  // 4 models of transfer function used:
+  // 
+  //
+  // Example usage:
+  //    FitTransferFunctionTheta(1,3,8,1,5,0) 
+  //    isMax=1; dType=1; tgl=5; skipKaon=0; Double_t maxP=10
+  //
+  if (!pcstream)  pcstream = new TTreeSRedirector("dedxFit.root","update");
+  //
+  if (!treeFit){
+    treeFit = (TTree*)pcstream->GetFile()->Get("fitdEdxG");
+    treeFit->SetMarkerStyle(25);
+    treeFit->SetCacheSize(100000000);
+  }
+  const char *chfitType[4] = { "dEdx_{BB}=k(#theta)dEdx_{rec}", 
+                              "dEdx_{BB}=k(#theta)dEdx_{rec}+#Delta(#theta)", 
+                              "dEdx_{BB}=k(#theta,#phi)dEdx_{rec}+#Delta(#theta,#phi)",
+                              "dEdx_{BB}=k(#theta,#phi,1/Q)dEdx_{rec}+#Delta(#theta,#phi,1/Q)",
+  };
+  //
+  treeFit->SetAlias("isOK","entries>100&&chi2<80");
+  treeFit->SetAlias("dEdxM","(vecFit.fElements[1]*dEdxExp)/50.");
+  treeFit->SetAlias("dEdxMErr","(vecFitErr.fElements[1]*dEdxExp)/50.");
+  //
+  //
+  Int_t  npointsMax=30000000;
+  TStatToolkit toolkit;
+  Double_t chi20=0,chi21=0,chi22=0,chi23=0;
+  Int_t    npoints=0;
+  TVectorD param0,param1,param2,param3;
+  TMatrixD covar0,covar1,covar2,covar3;
+  TString fstringFast0="";
+  fstringFast0+="dEdxM++";
+  //
+  TString fstringFast="";
+  fstringFast+="dEdxM++";                  // 1
+  fstringFast+="(1/pCenter)++";            // 2
+  fstringFast+="(1/pCenter)^2++";          // 3
+  fstringFast+="(1/pCenter)*dEdxM++";      // 4
+  fstringFast+="((1/pCenter)^2)*dEdxM++";  // 5
+  //
+  //
+  TCut cutUse=TString::Format("isOK&&isMax==%d&&dType==%d&&ibinTgl==%d",isMax,dType,tgl).Data();
+  TCut cutFit=cutUse+TString::Format("pCenter<%f",maxP).Data();
+  if (skipKaon) cutFit+="pType!=3";
+  TCut cutDraw =  "(ibinP%2)==0";
+  TString *strDeltaFit0 = TStatToolkit::FitPlane(treeFit,"dEdxExp:dEdxMErr", fstringFast0.Data(),cutFit, chi20,npoints,param0,covar0,-1,0, npointsMax, 1);
+  TString *strDeltaFit1 = TStatToolkit::FitPlane(treeFit,"dEdxExp:dEdxMErr", fstringFast0.Data(),cutFit, chi21,npoints,param1,covar1,-1,0, npointsMax, 0);
+  TString *strDeltaFit2 = TStatToolkit::FitPlane(treeFit,"dEdxExp:dEdxMErr", fstringFast.Data(),cutFit, chi22,npoints,param2,covar2,-1,0, npointsMax, 0);
+  //
+  fstringFast+="(1/pCenter)/dEdxM++";       //6
+  fstringFast+="((1/pCenter)^2)/dEdxM++";   //7
+  TString *strDeltaFit3 = TStatToolkit::FitPlane(treeFit,"dEdxExp:dEdxMErr", fstringFast.Data(),cutFit, chi23,npoints,param3,covar3,-1,0, npointsMax, 0);
+
+  treeFit->SetAlias("fitdEdx0",strDeltaFit0->Data());
+  treeFit->SetAlias("fitdEdx1",strDeltaFit1->Data());
+  treeFit->SetAlias("fitdEdx2",strDeltaFit2->Data());
+  treeFit->SetAlias("fitdEdx3",strDeltaFit3->Data());
+  
+  strDeltaFit0->Tokenize("++")->Print();
+  strDeltaFit1->Tokenize("++")->Print();
+  strDeltaFit2->Tokenize("++")->Print();
+  strDeltaFit3->Tokenize("++")->Print();
+  //
+  (*pcstream)<<"fitTheta"<<
+    "isMax="<<isMax<<          // switch is Qmax/Qtot used
+    "dType="<<dType<<          // detector Type
+    "tgl="<<tgl<<              // tgl number 
+    "skipKaon="<<skipKaon<<    // Was kaon dEdx used in the calibration?
+    "maxP="<<maxP<<            // Maximal p used in the fit 
+    "npoints="<<npoints<<      // number of points for fit
+    // model 0
+    "chi20="<<chi20<<          // chi2
+    "param0.="<<&param0<<      // parameters
+    "covar0.="<<&covar0<<      // covariance
+    // model 1
+    "chi21="<<chi21<<          // chi2
+    "param1.="<<&param1<<      // parameters
+    "covar1.="<<&covar1<<      // covariance
+    // model 2
+    "chi22="<<chi22<<          // chi2
+    "param2.="<<&param2<<      // parameters
+    "covar2.="<<&covar2<<      // covariance
+    // model 3
+    "chi23="<<chi23<<          // chi2
+    "param3.="<<&param3<<      // parameters
+    "covar3.="<<&covar3<<      // covariance
+    "\n";
+  //
+  if (!doDraw) return;
+  TGraphErrors * graphs[4] ={0};
+  //  TCanvas *canvasdEdxFit = new TCanvas(TString::Format("canvasdEdxFit%d",fitType),"canvasdEdxFit",800,800);
+  TCanvas *canvasdEdxFit = new TCanvas("canvasdEdxFit","canvasdEdxFit",800,800);
+  canvasdEdxFit->SetLeftMargin(0.15);
+  canvasdEdxFit->SetRightMargin(0.1);
+  canvasdEdxFit->SetBottomMargin(0.15);
+  canvasdEdxFit->Divide(2,2,0,0);
+  for (Int_t fitType=0; fitType<4; fitType++){
+    canvasdEdxFit->cd(fitType+1);
+    TLegend * legendPart = new TLegend(0.16+0.1*(fitType%2==0),0.16-0.14*(fitType<2),0.89,0.4,TString::Format("%s",chfitType[fitType]));
+    legendPart->SetTextSize(0.05);
+    legendPart->SetBorderSize(0);
+    for (Int_t ihis=3; ihis>=0;ihis--){
+      gPad->SetLogx(1);
+      TString expr= TString::Format("100*(dEdxExp-fitdEdx%d)/dEdxExp:pCenter:100*dEdxMErr",fitType);
+      graphs[ihis]= TStatToolkit::MakeGraphErrors(treeFit,expr,cutUse+cutDraw+TString::Format("pType==%d",ihis).Data(), markers[ihis],colors[ihis],markerSize[ihis]);
+      graphs[ihis]->SetMinimum(-5);
+      graphs[ihis]->SetMaximum(5);
+      graphs[ihis]->GetXaxis()->SetTitle("#it{p} (GeV/c)");
+      graphs[ihis]->GetXaxis()->SetTitleSize(0.06);
+      graphs[ihis]->GetYaxis()->SetTitleSize(0.06);      
+      graphs[ihis]->GetYaxis()->SetTitle("#Delta(d#it{E}dx)/d#it{E}dx_{BB}(#beta#gamma) (%)");
+      if (ihis==3) graphs[ihis]->Draw("alp");
+      graphs[ihis]->Draw("lp");
+      legendPart->AddEntry(graphs[ihis],partName[ihis],"p");
+    }
+    legendPart->Draw();
+  }
+  TLatex  latexDraw;
+  latexDraw.SetTextSize(0.045);
+
+  const char *chDType[4]={"IROC","OROC medium","OROC long","OROC"};
+  {
+    if (isMax) latexDraw.DrawLatex(1,4,"Q_{Max}");
+    if (!isMax) latexDraw.DrawLatex(1,4,"Q_{tot}");
+    latexDraw.DrawLatex(1,3.5,chDType[dType%4]);
+    latexDraw.DrawLatex(1,3,TString::Format("#Theta=%1.1f",tgl/10.));
+    latexDraw.DrawLatex(1,2.5,TString::Format("Fit: p_{t}<%1.1f (GeV/c)",maxP));
+    latexDraw.DrawLatex(1,2.,TString::Format("Fit: Skip Kaon=%d",skipKaon));
+  }
+  //
+  //
+  canvasdEdxFit->SaveAs(TString::Format("fitTransfer_Max%d_Det_%dTheta%d_SkipKaon%d_MaxP%1.0f.pdf",isMax,dType,tgl, skipKaon,maxP));
+  canvasdEdxFit->SaveAs(TString::Format("fitTransfer_Max%d_Det_%dTheta%d_SkipKaon%d_MaxP%1.0f.png",isMax,dType,tgl, skipKaon,maxP));
+
+}
+//
+//
+//
+void FitTransferFunctionAll(Bool_t isMax, Int_t dType, Bool_t skipKaon, Double_t maxP, TTreeSRedirector *pcstream, Bool_t doDraw){
+  //
+  // 
+  // dEdx_{BB}= f_{tr}(dEdx_{rec}, #phi,#eta)
+  //
+  // Example usage:
+  //    FitTransferFunctionAll(1,1,1,15,0,1) 
+  //    isMax=1; dType=1; skipKaon=0; Double_t maxP=10
+  //
+  if (!pcstream)  pcstream = new TTreeSRedirector("dedxFit.root","update");
+  //
+  if (!treeFit){
+    treeFit = (TTree*)pcstream->GetFile()->Get("fitdEdxG");
+    treeFit->SetMarkerStyle(25);
+    treeFit->SetCacheSize(100000000);
+  }
+  const char *chfitType[4] = { "dEdx_{BB}=k(#theta)dEdx_{rec}", 
+                              "dEdx_{BB}=k(#theta)dEdx_{rec}+#Delta(#theta)", 
+                              "dEdx_{BB}=k(#theta,#phi)dEdx_{rec}+#Delta(#theta,#phi)",
+                              "dEdx_{BB}=k(#theta,#phi,1/Q)dEdx_{rec}+#Delta(#theta,#phi,1/Q)",
+  };
+  //
+  treeFit->SetAlias("isOK","entries>100&&chi2<80");
+  treeFit->SetAlias("dEdxM","(vecFit.fElements[1]*dEdxExp)/50.");
+  treeFit->SetAlias("dEdxMErr","(vecFitErr.fElements[1]*dEdxExp)/50.");
+  //
+  //
+  Int_t  npointsMax=30000000;
+  TStatToolkit toolkit;
+  Double_t chi20=0,chi21=0,chi22=0,chi23=0;
+  Int_t    npoints=0;
+  TVectorD param0,param1,param2,param3;
+  TMatrixD covar0,covar1,covar2,covar3;
+  //
+  //
+  //
+  TString fstringFast0="";
+  fstringFast0+="dEdxM++";
+  fstringFast0+="(tglCenter-0.5)++";
+  fstringFast0+="(tglCenter-0.5)*dEdxM++";
+  //
+  TString fstringFast1="";
+  fstringFast1+="dEdxM++";
+  fstringFast1+="(tglCenter-0.5)++";
+  fstringFast1+="(tglCenter-0.5)*dEdxM++";
+  fstringFast1+="(tglCenter-0.5)^2++";
+  fstringFast1+="((tglCenter-0.5)^2)*dEdxM++";
+  //
+  TString fstringFast2="";
+  fstringFast2+="dEdxM++";                  // 1
+  fstringFast2+="(1/pCenter)++";            // 2
+  fstringFast2+="(1/pCenter)^2++";          // 3
+  fstringFast2+="(1/pCenter)*dEdxM++";      // 4
+  fstringFast2+="((1/pCenter)^2)*dEdxM++";  // 5
+  //
+  fstringFast2+="(tglCenter-0.5)*dEdxM++";                  // 8
+  fstringFast2+="(tglCenter-0.5)*(1/pCenter)++";            // 9
+  fstringFast2+="(tglCenter-0.5)*(1/pCenter)^2++";          // 10
+  fstringFast2+="(tglCenter-0.5)*(1/pCenter)*dEdxM++";      // 11
+  fstringFast2+="(tglCenter-0.5)*((1/pCenter)^2)*dEdxM++";  // 12
+  //
+  //
+  fstringFast2+="((tglCenter-0.5)^2)*dEdxM++";                  // 15
+  fstringFast2+="((tglCenter-0.5)^2)*(1/pCenter)++";            // 16
+  fstringFast2+="((tglCenter-0.5)^2)*(1/pCenter)^2++";          // 17
+  fstringFast2+="((tglCenter-0.5)^2)*(1/pCenter)*dEdxM++";      // 18
+  fstringFast2+="((tglCenter-0.5)^2)*((1/pCenter)^2)*dEdxM++";  // 19
+  TString fstringFast3=fstringFast2;
+  //
+  fstringFast3+="(1/pCenter)/dEdxM++";       // 6
+  fstringFast3+="((1/pCenter)^2)/dEdxM++";   // 7
+  fstringFast3+="(tglCenter-0.5)*(1/pCenter)/dEdxM++";       // 13
+  fstringFast3+="(tglCenter-0.5)*((1/pCenter)^2)/dEdxM++";   // 14
+  fstringFast3+="((tglCenter-0.5)^2)*(1/pCenter)/dEdxM++";       // 20
+  fstringFast3+="((tglCenter-0.5)^2)*((1/pCenter)^2)/dEdxM++";   // 21
+  //
+  //
+  //
+  TCut cutUse=TString::Format("isOK&&isMax==%d&&dType==%d",isMax,dType).Data();
+  TCut cutFit=cutUse+TString::Format("pCenter<%f",maxP).Data();
+  if (skipKaon) cutFit+="pType!=3";
+  TCut cutDraw =  "(ibinP%2)==0";
+  TString *strDeltaFit0 = TStatToolkit::FitPlane(treeFit,"dEdxExp:dEdxMErr", fstringFast0.Data(),cutFit, chi20,npoints,param0,covar0,-1,0, npointsMax, 1);
+  TString *strDeltaFit1 = TStatToolkit::FitPlane(treeFit,"dEdxExp:dEdxMErr", fstringFast1.Data(),cutFit, chi21,npoints,param1,covar1,-1,0, npointsMax, 0);
+  TString *strDeltaFit2 = TStatToolkit::FitPlane(treeFit,"dEdxExp:dEdxMErr", fstringFast2.Data(),cutFit, chi22,npoints,param2,covar2,-1,0, npointsMax, 0);
+  //
+  TString *strDeltaFit3 = TStatToolkit::FitPlane(treeFit,"dEdxExp:dEdxMErr", fstringFast3.Data(),cutFit, chi23,npoints,param3,covar3,-1,0, npointsMax, 0);
+
+  treeFit->SetAlias("fitdEdx0",strDeltaFit0->Data());
+  treeFit->SetAlias("fitdEdx1",strDeltaFit1->Data());
+  treeFit->SetAlias("fitdEdx2",strDeltaFit2->Data());
+  treeFit->SetAlias("fitdEdx3",strDeltaFit3->Data());
+  
+  strDeltaFit0->Tokenize("++")->Print();
+  strDeltaFit1->Tokenize("++")->Print();
+  strDeltaFit2->Tokenize("++")->Print();
+  strDeltaFit3->Tokenize("++")->Print();
+  //
+  (*pcstream)<<"fitAll"<<
+    "isMax="<<isMax<<          // switch is Qmax/Qtot used
+    "dType="<<dType<<          // detector Type
+    "skipKaon="<<skipKaon<<    // Was kaon dEdx used in the calibration?
+    "maxP="<<maxP<<            // Maximal p used in the fit 
+    "npoints="<<npoints<<      // number of points for fit
+    // model 0
+    "chi20="<<chi20<<          // chi2
+    "param0.="<<&param0<<      // parameters
+    "covar0.="<<&covar0<<      // covariance
+    // model 1
+    "chi21="<<chi21<<          // chi2
+    "param1.="<<&param1<<      // parameters
+    "covar1.="<<&covar1<<      // covariance
+    // model 2
+    "chi22="<<chi22<<          // chi2
+    "param2.="<<&param2<<      // parameters
+    "covar2.="<<&covar2<<      // covariance
+    // model 3
+    "chi23="<<chi23<<          // chi2
+    "param3.="<<&param3<<      // parameters
+    "covar3.="<<&covar3<<      // covariance
+    "\n";
+  //
+  if (!doDraw) return;
+  TGraphErrors * graphs[4] ={0};
+  //  TCanvas *canvasdEdxFit = new TCanvas(TString::Format("canvasdEdxFit%d",fitType),"canvasdEdxFit",800,800);
+  TCanvas *canvasdEdxFit = new TCanvas("canvasdEdxFit","canvasdEdxFit",800,800);
+  canvasdEdxFit->SetLeftMargin(0.15);
+  canvasdEdxFit->SetRightMargin(0.1);
+  canvasdEdxFit->SetBottomMargin(0.15);
+  canvasdEdxFit->Divide(2,2,0,0);
+  for (Int_t fitType=0; fitType<4; fitType++){
+    canvasdEdxFit->cd(fitType+1);
+    TLegend * legendPart = new TLegend(0.16+0.1*(fitType%2==0),0.16-0.14*(fitType<2),0.89,0.4,TString::Format("%s",chfitType[fitType]));
+    legendPart->SetTextSize(0.05);
+    legendPart->SetBorderSize(0);
+    for (Int_t ihis=3; ihis>=0;ihis--){
+      gPad->SetLogx(1);
+      TString expr= TString::Format("100*(dEdxExp-fitdEdx%d)/dEdxExp:pCenter:100*dEdxMErr",fitType);
+      graphs[ihis]= TStatToolkit::MakeGraphErrors(treeFit,expr,cutUse+cutDraw+TString::Format("pType==%d",ihis).Data(), markers[ihis],colors[ihis],markerSize[ihis]);
+      graphs[ihis]->SetMinimum(-5);
+      graphs[ihis]->SetMaximum(5);
+      graphs[ihis]->GetXaxis()->SetTitle("#it{p} (GeV/c)");
+      graphs[ihis]->GetXaxis()->SetTitleSize(0.06);
+      graphs[ihis]->GetYaxis()->SetTitleSize(0.06);      
+      graphs[ihis]->GetYaxis()->SetTitle("#Delta(d#it{E}dx)/d#it{E}dx_{BB}(#beta#gamma) (%)");
+      if (ihis==3) graphs[ihis]->Draw("alp");
+      graphs[ihis]->Draw("lp");
+      legendPart->AddEntry(graphs[ihis],partName[ihis],"p");
+    }
+    legendPart->Draw();
+  }
+  TLatex  latexDraw;
+  latexDraw.SetTextSize(0.045);
+
+  const char *chDType[4]={"IROC","OROC medium","OROC long","OROC"};
+  {
+    if (isMax) latexDraw.DrawLatex(1,4,"Q_{Max}");
+    if (!isMax) latexDraw.DrawLatex(1,4,"Q_{tot}");
+    latexDraw.DrawLatex(1,3.5,chDType[dType%4]);
+    latexDraw.DrawLatex(1,2.5,TString::Format("Fit: p_{t}<%1.1f (GeV/c)",maxP));
+    latexDraw.DrawLatex(1,2.,TString::Format("Fit: Skip Kaon=%d",skipKaon));
+  }
+  //
+  //
+  canvasdEdxFit->SaveAs(TString::Format("fitTransfer_Max%d_Det_%dSkipKaon%d_MaxP%1.0f.pdf",isMax,dType, skipKaon,maxP));
+  canvasdEdxFit->SaveAs(TString::Format("fitTransfer_Max%d_Det_%dSkipKaon%d_MaxP%1.0f.png",isMax,dType, skipKaon,maxP));
+
+}
+
+
+void DrawFit(){
+  //
+  //
+  //
+  TTreeSRedirector * pcstream = new TTreeSRedirector("dedxFit.root","update");
+  TTree * treeTheta=(TTree*)pcstream->GetFile()->Get("fitTheta"); 
+  treeTheta->SetMarkerStyle(25);
+  TTree * treeAll=(TTree*)pcstream->GetFile()->Get("fitAll"); 
+  treeAll->SetMarkerStyle(25);
+  //
+  //
+  //
+  //treeFit->Draw("vecFit.fElements[2]/vecFit.fElements[1]*pow(dEdxExp*sqrt(1+tglCenter**2),0.25):dEdxExp:tglCenter","isTot&&dType==1&&entries>500","colz",1000000);
+
+}
diff --git a/TPC/macros/data2011/ocdbScan.C b/TPC/macros/data2011/ocdbScan.C
new file mode 100644 (file)
index 0000000..4b2deef
--- /dev/null
@@ -0,0 +1,21 @@
+TChain * chain0=0;
+TChain * chain1=0;
+
+void Init(){  
+  //  ls /hera/alice/local/benchmark/TestFor2011/r64765/000*/cpass1/dcsTime.root > /u/miranov/cpass1Calib.list
+  //  ls /hera/alice/local/benchmark/TestFor2011/r64765/000*/cpass0/dcsTime.root > /u/miranov/cpass0Calib.list
+  
+  chain0 = AliXRDPROOFtoolkit::MakeChain("/u/miranov/cpass0Calib.list","dcs",0,10000);
+  chain1 = AliXRDPROOFtoolkit::MakeChain("/u/miranov/cpass1Calib.list","dcs",0,10000);
+}
+
+
+void CheckHVCorrection(){
+  //
+  //
+  // 0.)
+  chain0->Draw("gainMIP:ptrel0","vdriftITS<0.01");
+  // 1.)
+  TStatToolkit::MakeGraphSparse(chain0,"gainMIP:ptrel0","vdriftITS<0.01",25,2)->Draw("alp");
+
+}
index 1c0400ec162a7d93f6abb734650299ebe1064acd..02344b25f99f254e654bfec2a6cef43c8250b661 100644 (file)
@@ -5,6 +5,9 @@ Content:
 stressTest.sh  - script to submit all scripts fromt $ALICE_ROOT/test directory
 
 To run stressTest:
-$ALICE_ROOT/test/stressTest/stressTest.sh <output dir prefix>  <batch command>
+$ALICE_ROOT/TPC/stressTest/stressTest.sh <output dir prefix>  <batch command>
 e.g:
-$ALICE_ROOT/test/stressTest/stressTest.sh /d/alice12/miranov/streeTest/ "bsub -q proof"
\ No newline at end of file
+
+
+$ALICE_ROOT/TPC/stressTest/stressTest.sh `pwd`  "qsub -V -cwd -o out.log"
+
index 9ac48bb13eaf98604be8165c9aba419ff6f16ed3..18978f5ddd937d4b2aa2eb9a6f1854a7bee7fa56 100755 (executable)
@@ -27,6 +27,8 @@ echo _____________________________________________________________
 #
 # Loop over all run*sh macros
 #
+svn status $ALICE_ROOT  > svn.status
+svn diff   $ALICE_ROOT  > svn.diff 
 for tmacro in `ls $ALICE_ROOT/test/*/run*.sh` ; do
 #
 dname=`dirname $tmacro`
@@ -37,8 +39,8 @@ mkdirhier $workdir
 cp $dname/* $workdir/
 cd $workdir
 rm *.root
-echo $submitcommand -oo $workdir/out.log --eo $workdir/err.log $tmacro
-$submitcommand -oo $workdir/out.log -eo $workdir/err.log $tmacro
+echo $submitcommand   $tmacro
+$submitcommand  $tmacro
 cd $outdir;
 done;