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;
gSystem->Load("libTENDER");
gSystem->Load("libPWGPP.so");
gSystem->Load("libAliHLTTrigger.so");
+ gSystem->Load("libPWGTools");
if (doEMCAL || doPHOS || doCALO) {
gSystem->Load("libEMCALUtils");
AliTaskCDBconnect(const AliTaskCDBconnect &other);
AliTaskCDBconnect& operator=(const AliTaskCDBconnect &other);
+
void InitGRP();
//
public:
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);
tpcRecoParam->SetUseMultiplicityCorrectionDedx(kFALSE);
tpcRecoParam->SetUseAlignmentTime(kFALSE);
tpcRecoParam->SetUseComposedCorrection(kTRUE);
+ //
+ tpcRecoParam->SetCorrectionHVandPTMode(1);
AliTPCcalibDB::Instance()->SetRun(run);
}
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();
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
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();
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..."
exit $exitcode
fi
-mv AliESDfriends_v1.root ../
mv syswatch.log ../syswatch_calib.log
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
--- /dev/null
+// 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;
+}
+
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");
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();
+ }
}
--- /dev/null
+/*
+ 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();
+
+}
#
# 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)
--- /dev/null
+/*
+ .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, ¶mLTM, 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");
+
+
+}
//
// Subset of matheamtical functions not included in the TMath
//
-
-///////////////////////////////////////////////////////////////////////////
+//
+/////////////////////////////////////////////////////////////////////////
#include "TMath.h"
#include "Riostream.h"
#include "TH1F.h"
#include "TCanvas.h"
#include "TLatex.h"
#include "TCut.h"
-
//
// includes neccessary for test functions
//
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);
}
}
+
+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 ¶ms , 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
// 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];
h1f[i]->FillRandom("myg");
}
- TStopwatch s;
+ TStopwatch s;
s.Start();
//standard gaus fit
for (Int_t i=0; i<nhistos; i++){
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];
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;
}
class TH1F;
class TH1;
+class TH2;
class TH3;
class TString;
class TTree;
// 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 ¶m , 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
//
#include "AliDCSSensor.h"
#include "TDatime.h"
+#include "TCanvas.h"
ClassImp(AliDCSSensor)
const Double_t kSecInHour = 3600.; // seconds in one hour
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
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; }
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)
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; }
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
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)
delete fESDTZEROfriend;
fESDTZEROfriend = new AliESDTZEROfriend(*esd.fESDTZEROfriend);
+ memcpy(fNclustersTPC,esd.fNclustersTPC,sizeof(fNclustersTPC));
+ memcpy(fNclustersTPCused,esd.fNclustersTPCused,sizeof(fNclustersTPCused));
return *this;
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
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
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()) {
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){
// 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;
}
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);
//
// "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) {
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);
}
//---------------------------------------------------------------------
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;
//---------------------------------------------------------------------
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;
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);
}
// 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]);
//
return kTRUE;
}
-
//_________________________________________________________
Bool_t AliExternalTrackParam::GetXYZatR(Double_t xr,Double_t bz, Double_t *xyz, Double_t* alpSect) const
{
return kTRUE;
//
}
-
#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
ResetMultiplicityCorrectionFunctions();
+ fgInstance=this;
}
/*TODO remove?
//_________________________________________________________________________
delete fCorrFuncSigmaMultiplicity;
fCorrFuncSigmaMultiplicity = 0x0;
+ if (fgInstance==this) fgInstance=0;
}
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);
+}
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,
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)
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
#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
//
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
//
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);
+}
#ifndef AliTPCdEdxInfo_H
#define AliTPCdEdxInfo_H
+class TGraphErrors;
+class TObjArray;
#include <TObject.h>
class AliTPCdEdxInfo : public TObject
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
// 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). //
#include <TCollection.h>
#include <TTimeStamp.h>
#include <TIterator.h>
+#include <TMath.h>
#include "AliLog.h"
#include "AliTPCComposedCorrection.h"
}
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;
}
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;
}
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;
}
class AliTPCComposedCorrection : public AliTPCCorrection {
public:
- enum CompositionType {kParallel,kQueue};
+ enum CompositionType {kParallel,kQueue, kQueueResidual};
AliTPCComposedCorrection();
AliTPCComposedCorrection(TCollection *corrections,CompositionType mode);
#include "AliTPCRecoParam.h"
#include "TLinearFitter.h"
-
+#include <AliSysInfo.h>
ClassImp(AliTPCCorrection)
-
+
TObjArray *AliTPCCorrection::fgVisualCorrection=0;
// instance of correction for visualization
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
}
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
// 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);
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:
// 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;
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)
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
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.
+ }
}
}
//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] ;
// 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
// 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
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
}
}
- } // end loop over phi
-
+ } // end loop over phi
+ AliSysInfo::AddStamp("IntegrateEz", 140,0,0);
for ( Int_t k = 0 ; k < phislices ; 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;
//
//
//
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]);
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]);
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]);
}
+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;
+}
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;
//
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:
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
void InitLookUpfulcrums(); // to initialize the grid of the look up table
- ClassDef(AliTPCCorrection,4);
+ ClassDef(AliTPCCorrection,5);
};
#endif
--- /dev/null
+/**************************************************************************
+ * 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];
+}
+
--- /dev/null
+/* 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
+};
+
+
#include "AliAlignObj.h"
#include "AliAlignObjParams.h"
#include "AliLog.h"
+#include "TGraphErrors.h"
+#include "AliTPCcalibDB.h"
+#include "AliMathBase.h"
+
+TObjArray *AliTPCParam::fBBParam = 0;
ClassImp(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.),
SetTitle("75x40_100x60_150x60");
SetDefault();
+ if (!fBBParam) fBBParam= new TObjArray(1000);
}
AliTPCParam::~AliTPCParam()
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
//
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
//
SetGateDelay(kGateDelay);
SetL1Delay(kL1Delay);
SetNTBinsBeforeL1(kNTBinsBeforeL1);
+ SetNominalGainSlopes();
}
}
}
+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);
+}
#include "TMath.h"
#include <TGeoMatrix.h>
-
+#include <TVectorD.h>
class TString;
+class TGraphErrors;
class AliTPCParam : public AliDetectorParam {
//////////////////////////////////////////////////////
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
//
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
//
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
//--------------------------------------------------------------------
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
};
// 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)
#include "TMath.h"
#include "AliTPCROC.h"
#include "AliTPCSpaceCharge3D.h"
+#include "AliSysInfo.h"
ClassImp(AliTPCSpaceCharge3D)
fSCLookUpPOCsFileNameRPhi(""),
fSCdensityInRZ(0),
fSCdensityInRPhiA(0),
- fSCdensityInRPhiC(0)
+ fSCdensityInRPhiC(0),
+ fSpaceChargeHistogram3D(0),
+ fSpaceChargeHistogramRPhi(0),
+ fSpaceChargeHistogramRZ(0)
{
//
// default constructor
delete fSCdensityInRZ;
delete fSCdensityInRPhiA;
delete fSCdensityInRPhiC;
-
+ delete fSpaceChargeHistogram3D;
+ delete fSpaceChargeHistogramRPhi;
+ delete fSpaceChargeHistogramRZ;
}
if (fInitLookUp) {
AliInfo("Lookup table was already initialized! Doing it again anyway ...");
- // return;
+ return;
}
// ------------------------------------------------------------------------------------------------------
// 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
// 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);
}
+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) {
//
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;
+
}
+
#include "AliTPCCorrection.h"
class TH3F;
+class TH3;
class AliTPCSpaceCharge3D : public AliTPCCorrection {
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);
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:
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);
};
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){
fCurrentRun,
sector%36>=18,
fCurrentRecoParam->GetUseDriftCorrectionTime());
+ //
+ deltaZcorrTime= AliTPCcalibDB::Instance()->
+ GetVDriftCorrectionDeltaZ(fCurrentTimeStamp,
+ fCurrentRun,
+ sector%36>=18,
+ 0);
+
}
//
if(fCurrentRecoParam->GetUseDriftCorrectionGY()>0) {
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 {
#include <AliSplineFit.h>
#include <AliCTPTimeParams.h>
+#include "TGraphErrors.h"
#include "AliTPCcalibDB.h"
#include "AliTPCdataQA.h"
#include "AliTPCcalibDButil.h"
//
// destructor
//
-
+ delete fIonTailArray;
delete fActiveChannelMap;
delete fGrRunState;
}
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){
}
+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)
{
}
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));
}
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
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;
+}
#include "AliSplineFit.h"
#include "TMap.h"
+class TGraphErrors;
class AliTPCSensorTempArray;
class AliDCSSensorArray;
class AliCDBEntry;
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;}
//
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
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);
Base/AliTPCROCVoltError3D.cxx
Base/AliTPCSpaceCharge.cxx
Base/AliTPCSpaceCharge3D.cxx
+ Base/AliTPCCorrectionLookupTable.cxx
Base/AliXRDPROOFtoolkit.cxx
Base/AliTPCExBEffective.cxx
Base/AliTPCExBEffectiveSector.cxx
--- /dev/null
+# -*- 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 )
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():
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);
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);
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)
// 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;
}
+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
//
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);
// 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;
return fCalibrationStatus;
}
+
+/*
+ Short sequence to acces the calbration entry:
+ TFile *f = TFile::Open("CalibObjects.root");
+ AliTPCcalibGainMult * fGainMult = (AliTPCcalibGainMult *)f->Get("TPCCalib/calibGainMult");
+
+
+*/
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)
// 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
- if (fStreamLevel>2 && streamCounter<20*fStreamLevel ){
+ if (fStreamLevel>2 && gRandom->Rndm()<0.1 ){
// dump debug info if required
TTreeSRedirector *cstream = GetDebugStreamer();
if (cstream){
"cl.="<<cluster<<
"cy="<<dy<<
"cz="<<dz<<
+ "ty="<<ty<<
+ "tz="<<tz<<
+ "vec.="<<&vec<< //track parameters
"\n";
}
}
"nclIn="<<nclIn<<
"nclOut="<<nclOut<<
"ncl="<<ncl<<
+ "seed.="<<seed<<
+ "track.="<<track<<
"TrIn0.="<<trackInOld<<
"TrOut0.="<<trackOutOld<<
"TrIn1.="<<&trackIn<<
#include "AliTracker.h"
#include "AliTPCTransform.h"
#include "AliTPCROC.h"
+#include "TStatToolkit.h"
ClassImp(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),
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),
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};
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++){
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};
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 -
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;
//
// 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");
}
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();
//
// 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);
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);
//
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;
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
//
// 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
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);
}
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(){
// //
#include "TH3F.h"
#include "TF1.h"
#include "THnSparse.h"
+#include "THn.h"
#include "TMatrixD.h"
#include "TVectorD.h"
class TH1F;
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);}
//
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
AliTPCcalibGainMult(const AliTPCcalibGainMult&);
AliTPCcalibGainMult& operator=(const AliTPCcalibGainMult&);
- ClassDef(AliTPCcalibGainMult, 2);
+ ClassDef(AliTPCcalibGainMult, 4);
};
#endif
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();
vGainGraphIROCErr.Zero();
vGainGraphOROCmedErr.Zero();
vGainGraphOROClongErr.Zero();
-
+ vGainQMaxGraphRegion.Zero();
+ vGainQTotGraphRegion.Zero();
TGraphErrors grDummy;
TObjArray * gainSplines = fCalibDB->GetTimeGainSplinesRun(irun);
if (gainSplines) {
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;
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);
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 <<
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),
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),
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;
// 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
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
}
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);
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;}
//
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%
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
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)
{
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;}
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
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
//
// 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)
};
#include "AliTPCclusterMI.h"
#include "AliTPCclusterInfo.h"
+#include "AliTrackPointArray.h"
#include "AliGeomManager.h"
#include "AliLog.h"
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);
+}
#include "AliCluster.h"
#include "TMath.h"
#include "AliTPCclusterInfo.h"
+#include <AliTrackPointArray.h>
+
//_____________________________________________________________________________
class AliTPCclusterMI : public AliCluster {
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
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"<<
#include "AliSplineFit.h"
#include "AliCDBManager.h"
#include "AliTPCcalibDButil.h"
+#include <AliCTPTimeParams.h>
ClassImp(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;
}
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];
}
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;
}
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;
}
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;
//
//
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];
//
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);
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;
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();
//
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
//
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) {
//
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]));
+ }
}
}
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
// 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++;
}
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 {
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
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)
};
//
// 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
}
if (AliTPCReconstructor::StreamLevel()>0) {
- fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
+ fDebugStreamer = new TTreeSRedirector("TPCdebug.root","recreate");
}
//
fSeedsPool = new TClonesArray("AliTPCseed",1000);
delete clrow;
LoadOuterSectors();
LoadInnerSectors();
- ApllyTailCancellation();
return 0;
}
static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
//
// TTree * tree = fClustersArray.GetTree();
+ AliInfo("LoadClusters()\n");
TTree * tree = fInput;
TBranch * br = tree->GetBranch("Segment");
clrow->Clear("C");
LoadOuterSectors();
LoadInnerSectors();
+ if (AliTPCReconstructor::GetRecoParam()->GetUseIonTailCorrection()) ApplyTailCancellation();
return 0;
}
}
}
-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 §or= (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 §or= (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 §or= (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() {
// 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
AliCosmicTracker::FindCosmic(event, kTRUE);
+ FillClusterOccupancyInfo();
+
return 0;
}
// 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
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));
+ }
+}
#include "AliTPCreco.h"
#include "AliTPCclusterMI.h"
#include "AliTPCtrackerSector.h"
+#include "AliESDfriend.h"
+
class TFile;
class AliTrackPoint;
class AliDCSSensorArray;
class AliDCSSensor;
-
+class TGraphErrors;
class AliTPCtracker : public AliTracker {
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();
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;
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);
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
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
//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;
return fPadLength[row];
}
-
+void AliTPCtracker::SetTPCtrackerSectors(AliTPCtrackerSector *innerSec, AliTPCtrackerSector *outerSec)
+{
+ //
+ fInnerSec = innerSec;
+ fOuterSec = outerSec;
+}
#endif
#include <TClonesArray.h>
#include "AliLog.h"
#include "AliComplexCluster.h"
+//#include "AliTPCcluster.h"
#include "AliTPCclusterMI.h"
#include "AliTPCClustersRow.h"
#include "AliTPCParam.h"
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;
}
}
+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
{
}
}
+//_________________________________________________________________________
+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;
+}
+
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;}
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;}
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
#include <TParameter.h>
#include "AliDigits.h"
+#include "AliHeader.h"
+
#include "AliMagF.h"
#include "AliRun.h"
#include "AliRunLoader.h"
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;
wmat[0]=0.2729;
wmat[1]=0.7271;
- density=0.001754609;
+ density=1.842e-3;
AliMixture(10,"CO2",amat,zmat,density,2,wmat);
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
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
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];
--- /dev/null
+#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
using std::ifstream;
using std::ios_base;
+extern "C"{
+ Gas gaspar_;
+};
ClassImp(AliTPCv2)
//_____________________________________________________________________________
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());
}
//_____________________________________________________________________________
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
//
// 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;
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
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();
#include "AliRun.h"
#include "AliTPCDigitsArray.h"
#include "TGeoManager.h"
+#include "AliTPCGen.h"
class AliTPCv2 : public AliTPC {
public:
using std::ifstream;
using std::ios_base;
+
+extern "C"{
+ Gas gaspar1_;
+};
ClassImp(AliTPCv4)
//_____________________________________________________________________________
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());
}
//_____________________________________________________________________________
//
// 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;
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);
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();
#include "AliRun.h"
#include "AliTPCDigitsArray.h"
#include "TGeoManager.h"
+#include "AliTPCGen.h"
class AliTPCv4 : public AliTPC {
public:
// + 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
--- /dev/null
+#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
,fX(-1000.)
,fY(-1000.)
,fZ(-1000.)
+ ,fSCscale(-1.)
+ ,fSCscaleChi2(0)
,fTracks("AliToyMCTrack")
{
fEventNumber = fgEvCounter;
,fX(event.fX)
,fY(event.fY)
,fZ(event.fZ)
+ ,fSCscale(event.fSCscale)
+ ,fSCscaleChi2(event.fSCscaleChi2)
,fTracks(event.fTracks)
{
//
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
};
#include <iostream>
+#include <fstream>
#include <TDatabasePDG.h>
#include <TRandom.h>
#include <TSpline.h>
#include <TObjString.h>
#include <TROOT.h>
+#include <TSystem.h>
+#include <TObjArray.h>
+#include <TLinearFitter.h>
#include <AliLog.h>
#include <AliTPCROC.h>
,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)
,fUseStepCorrection(kFALSE)
,fUseMaterialBudget(kFALSE)
,fIsLaser(kTRUE)
+ ,fPrereadSCList(kFALSE)
+ ,fCalculateScaling(kTRUE)
{
fTPCParam = AliTPCcalibDB::Instance()->GetParameters();
fTPCParam->ReadGeoMatrices();
,fEvent(0x0)
,fCurrentTrack(0)
,fTPCCorrection(gen.fTPCCorrection)
+ ,fTPCCorrectionAv(0x0)
+ ,fSCList(gen.fSCList)
+ ,fSCListFile(gen.fSCListFile)
,fCorrectionFile(gen.fCorrectionFile)
,fOutputFileName(gen.fOutputFileName)
,fOutFile(0x0)
,fUseStepCorrection(gen.fUseStepCorrection)
,fUseMaterialBudget(gen.fUseMaterialBudget)
,fIsLaser(gen.fIsLaser)
+ ,fPrereadSCList(gen.fPrereadSCList)
+ ,fCalculateScaling(gen.fCalculateScaling)
{
//
gRandom->SetSeed();
//________________________________________________________________
AliToyMCEventGenerator::~AliToyMCEventGenerator()
{
- delete fTPCCorrection;
+ if (HasSCList() &&!fPrereadSCList) delete fTPCCorrection;
+ delete fSCList;
}
//________________________________________________________________
case kNeCO2_9010:
fCorrectionFile.Append("_NeCO2");
break;
+ case kNeCO2N2_90105:
+ fCorrectionFile.Append("_NeCO2N2");
+ break;
}
switch (epsilon) {
case kEps5:
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:
// 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());
}
+
+
class TFile;
class TTree;
+class TObjArray;
class AliTPCParam;
class AliTPCCorrection;
class AliTrackPointArray;
+class AliTrackPoint;
+class AliTPCclusterMI;
class AliToyMCTrack;
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 {
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
#include <iostream>
+#include <TROOT.h>
#include <TDatabasePDG.h>
#include <TRandom.h>
#include <TF1.h>
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();
}
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);
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;
if(equalSpacing) {
printf("Generating event %3d (%.3g)\n",nGeneratedEvents,eventTime);
fEvent = Generate(eventTime);
+ SetSCScalingFactor();
nGeneratedEvents++;
FillTree();
delete fEvent;
for(Int_t iColl = 0; iColl<nCollsInCrossing; iColl++){
printf("Generating event %3d (%.3g)\n",nGeneratedEvents,eventTime);
fEvent = Generate(eventTime);
+ SetSCScalingFactor();
nGeneratedEvents++;
FillTree();
delete fEvent;
fInputIndex = 0;
- return fESDTree->GetEntries();
gRandom->SetSeed();
+ return fESDTree->GetEntries();
}
//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;
//
// 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);
#include <TROOT.h>
#include <TFile.h>
#include <TPRegexp.h>
+#include <TVectorF.h>
#include <AliExternalTrackParam.h>
#include <AliTPCcalibDB.h>
, fTime0(-1)
, fCreateT0seed(kFALSE)
, fLongT0seed(kTRUE)
+, fFillClusterRes(kFALSE)
+, fUseT0list(kFALSE)
+, fUseZ0list(kFALSE)
+, fForceAlpha(kFALSE)
+, fRecoInfo(-1)
, fStreamer(0x0)
, fInputFile(0x0)
, fTree(0x0)
, fAllClusters("AliTPCclusterMI",10000)
, fMapTrackEvent(10000)
, fMapTrackTrackInEvent(10000)
+, fHnDelta(0x0)
, fIsAC(kFALSE)
{
//
ConnectInputFile(file, nmaxEv);
if (!fTree) return;
+ Int_t maxev=fTree->GetEntries();
+ if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
+
InitStreamer(".debug");
gROOT->cd();
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
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;
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);
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);
//
// 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 <<
"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();
}
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);
}
}
}
//____________________________________________________________________________________
-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();
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){
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
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());
return track;
}
-
//____________________________________________________________________________________
AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeedAllClusters(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, Int_t &nClus)
{
// 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");
delete fEvent;
fEvent = 0x0;
-
+
+ delete fHnDelta;
+ fHnDelta=0x0;
// delete fTree;
fTree=0x0;
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];
+}
#include <TObject.h>
#include <TClonesArray.h>
#include <TExMap.h>
+#include <TVectorFfwd.h>
+#include <THn.h>
class TTree;
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);
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);
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
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
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)
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+#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()));
+
+}
+
+
--- /dev/null
+/*
+
+.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));
+}
+
#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);
// 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];
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);
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);
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");
}
--- /dev/null
+#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
--- /dev/null
+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();
+ //
+ //
+}
+
+
--- /dev/null
+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;
+}
--- /dev/null
+/*
+ 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");
+
+}
--- /dev/null
+
+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;
+
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();
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;
}
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");
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");
//
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};
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);
+
}
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()));
}
{
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);
--- /dev/null
+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);
+
+
+}
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");
--- /dev/null
+/*
+.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);
+ //
+}
+*/
--- /dev/null
+#
+# 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;
+}
+
--- /dev/null
+//
+// 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);
+
+
+}
+
+
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}
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\)
-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;
TString outputFile="toyMC";
//for simtype also below
- switch (simtype) {
+ switch (simtype%2) {
case 0:
outputFile.Append(Form("_fixed_%dkHz",rate));
break;
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));
//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());
+// }
}
#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
//
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){
//
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){
//
//
//
// 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
//
//
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
//
}
}
}
+ 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);
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;
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);
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));
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
+ }
+ }
+
+}
+
+
+
#
# shell scipt to
#
# 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
#
#
-# 4.) submit fluctuation code dist scan - 11 minutes
+# 4.) submit fluctuation code dist scan
#
rm dir*/SpaceCharg*root
rm dir*/filter*.log
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
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
//
//gStyle->SetOptStat(0);
-
+ st->SetTitleX(0.17);
+ st->SetTitleW(0.73);
+
// parameters
const Int_t nT0 = 2;
const Int_t nT02D = 2;
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"};
//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"};
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);
}
// 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);
}
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()));
#include "TVectorD.h"
#include "TMatrixD.h"
#include "TH1.h"
-#include "THnSparse.h"
#include "TClonesArray.h"
#include "TTreeStream.h"
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);
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
fAngleZ(0),
fN(0),
fCl(0),
- fInit(kFALSE),
- fHistoNtot(0),
- fHistoQtot(0),
- fHistoQNtot(0),
- fHistoDtot(0),
- fHistoDmax(0),
- fHistoDtotRaw(0),
- fHistoDmaxRaw(0)
+ fInit(kFALSE)
{
//
//
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(){
//
cluster->GenerElectrons();
cluster->Digitize();
}
- UpdatedEdxHisto();
}
Double_t AliTPCtrackFast::CookdEdxNtot(Double_t f0,Float_t f1){
//
//
AliTPCtrackFast fast;
- TTreeSRedirector cstream(fname);
+ TTreeSRedirector cstream(fname,"recreate");
for (Int_t itr=0; itr<ntracks; itr++){
//
fast.fMNprim=(5+50*gRandom->Rndm());
+#############################################################################################
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()
+
+
+
+
/*
-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){
//
//
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);
-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);
+ //
+ //
+ //
+
+
}
#!/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
--- /dev/null
+/*
+ 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();
+
+}
--- /dev/null
+/*
+ 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.="<<¶m0<< // parameters
+ "covar0.="<<&covar0<< // covariance
+ // model 1
+ "chi21="<<chi21<< // chi2
+ "param1.="<<¶m1<< // parameters
+ "covar1.="<<&covar1<< // covariance
+ // model 2
+ "chi22="<<chi22<< // chi2
+ "param2.="<<¶m2<< // parameters
+ "covar2.="<<&covar2<< // covariance
+ // model 3
+ "chi23="<<chi23<< // chi2
+ "param3.="<<¶m3<< // 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.="<<¶m0<< // parameters
+ "covar0.="<<&covar0<< // covariance
+ // model 1
+ "chi21="<<chi21<< // chi2
+ "param1.="<<¶m1<< // parameters
+ "covar1.="<<&covar1<< // covariance
+ // model 2
+ "chi22="<<chi22<< // chi2
+ "param2.="<<¶m2<< // parameters
+ "covar2.="<<&covar2<< // covariance
+ // model 3
+ "chi23="<<chi23<< // chi2
+ "param3.="<<¶m3<< // 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);
+
+}
--- /dev/null
+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");
+
+}
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"
+
#
# 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`
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;