--- /dev/null
+AliTrackletTaskUni* AddMultTaskRS(const char* outName="tracklet.root")
+{
+ // create manager
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) mgr = new AliAnalysisManager("My test train");
+ // create our task
+ AliTrackletTaskUni *task = new AliTrackletTaskUni("AliTrackletTaskUni");
+ // create output container
+ AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("clist", TList::Class(),AliAnalysisManager::kOutputContainer,outName);
+
+ // add our task to the manager
+ mgr->AddTask(task);
+
+ // finaly connect input and output
+ mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
+ mgr->ConnectOutput(task,1,coutput1);
+ //
+ return task;
+}
--- /dev/null
+AliTrackletTaskMulti* AddMultTaskTrackletMulti(const char* outName="tracklet.root")
+{
+ // create manager
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) mgr = new AliAnalysisManager("My test train");
+ // create our task
+ AliTrackletTaskMulti *task = new AliTrackletTaskMulti("AliTrackletTaskMulti");
+ // create output container
+ AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("clist", TList::Class(),AliAnalysisManager::kOutputContainer,outName);
+
+ // add our task to the manager
+ mgr->AddTask(task);
+
+ // finaly connect input and output
+ mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
+ mgr->ConnectOutput(task,1,coutput1);
+ //
+ return task;
+}
--- /dev/null
+AliTaskGlobVar* AddTaskGlobVar(const char* outName="tt.root")
+{
+ // create manager
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) mgr = new AliAnalysisManager("My test train");
+ // create our task
+ AliTaskGlobVar *task = new AliTaskGlobVar("AliTaskGlobVar");
+ // create output container
+ AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("clist", TList::Class(),AliAnalysisManager::kOutputContainer,outName);
+
+ // add our task to the manager
+ mgr->AddTask(task);
+
+ // finaly connect input and output
+ mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
+ mgr->ConnectOutput(task,1,coutput1);
+ //
+ return task;
+}
--- /dev/null
+#include "AliITSMultRecBg.h"
+#include "AliGeomManager.h"
+#include "AliMultiplicity.h"
+#include "../ITS/AliITSgeomTGeo.h"
+#include <TH2F.h>
+#include <TTree.h>
+#include <TRandom.h>
+#include <TBits.h>
+#include <TClonesArray.h>
+
+ClassImp(AliITSMultRecBg)
+
+//_________________________________________________________________
+AliITSMultRecBg::AliITSMultRecBg()
+: fRecType(kData),
+ fInjLr(0),
+ fInjStave(0),
+ fInjModule(0),
+ fInjModInStave(0),
+ fInjX(0),
+ fInjZ(0),
+ fInjHitsN(0),
+ fInjScale(1),
+ fInjCurrTrial(0),
+ fInjCluster(),
+ fInjBuffer(2*kTrNPar)
+ //
+{
+ // constructor
+ fCreateClustersCopy = kTRUE;
+ for (int i=0;i<2;i++) {
+ fAssociations[i] = 0;
+ fInjSPDOcc[i] = 0;
+ fInjSPDPatt[i] = 0;
+ fInjNTrials[i] = 0;
+ fInjNSuccess[i] = 0;
+ for (int s=4;s--;) fInjModuleClStart[i][s] = fInjModuleClN[i][s] = 0;
+ }
+ //
+}
+
+//_________________________________________________________________
+AliITSMultRecBg::~AliITSMultRecBg()
+{
+ // destructor
+ for (int i=0;i<2;i++) {
+ delete[] fAssociations[i];
+ delete fInjSPDOcc[i];
+ delete fInjSPDPatt[i];
+ for (int s=4;s--;) {
+ delete[] fInjModuleClStart[i][s];
+ delete[] fInjModuleClN[i][s];
+ }
+ }
+ //
+}
+
+//____________________________________________________________________
+void AliITSMultRecBg::CreateMultiplicityObject()
+{
+ // create AliMultiplicity object
+ //
+ if (fRecType==kData || fRecType==kBgRot || fRecType==kBgMix) {
+ AliITSMultReconstructor::CreateMultiplicityObject();
+ }
+ else if (fRecType==kBgInj) {
+ if (fMult) delete fMult;
+ int ntr = GetNInjSuccsess();
+ TBits fastOrFiredMap(0);
+ fMult = new AliMultiplicity(ntr,0,fNFiredChips[0],fNFiredChips[1],fastOrFiredMap);
+ fMult->SetMultTrackRefs(kTRUE);
+ fMult->SetScaleDThetaBySin2T(fScaleDTBySin2T);
+ fMult->SetDPhiWindow2(fDPhiWindow2);
+ fMult->SetDThetaWindow2(fDThetaWindow2);
+ fMult->SetDPhiShift(fDPhiShift);
+ fMult->SetNStdDev(fNStdDev);
+ //
+ for (int itr=ntr;itr--;) {
+ Float_t *tlInfo = fInjBuffer.GetArray() + itr*kTrNPar;
+ fMult->SetTrackletData(itr,tlInfo);
+ }
+ }
+ //
+
+}
+
+//_________________________________________________________________________
+void AliITSMultRecBg::Run(TTree* tree, Float_t* vtx, TTree* treeMix)
+{
+ // reconstruct with current settings
+ if (!tree) AliFatal("The RP Tree is missing");
+ if (fRecType==kBgMix && !treeMix) AliFatal("Mixed Mode requested but 2nd RP Tree is missing")
+ if (!vtx) return;
+ //
+ if (fRecType==kData) Reconstruct(tree, vtx);
+ else if (fRecType==kBgRot) Reconstruct(tree, vtx);
+ else if (fRecType==kBgMix) ReconstructMix(tree, treeMix, vtx);
+ else if (fRecType==kBgInj) GenInjBgSample(tree,vtx); // if needed, the reco will be done internally
+ else { AliError(Form("Unknown running mode %d",fRecType)); }
+ //
+ CreateMultiplicityObject();
+}
+
+//_________________________________________________________________________
+Bool_t AliITSMultRecBg::PrepareInjBgGenerator(Float_t *vtx)
+{
+ // prepare histograms/patterns for bg generation
+ //
+ if (!fRecoDone) Reconstruct(fTreeRP,vtx);
+ //
+ float xshift = fSPDSeg.Dx()/2, zshift = fSPDSeg.Dz()/2;
+ int maxRow1 = fSPDSeg.Npx(), maxCol1 = fSPDSeg.Npz();
+ int nChipsPerLadder = fSPDSeg.GetNumberOfChips();
+ //
+ fInjCluster.SetLabel(kInjFakeLabel,0);
+ fInjCluster.SetLabel(-2,1);
+ fInjCluster.SetLabel(-2,2);
+ //
+ for (int ilr=0;ilr<2;ilr++) {
+ int nLadPerStave = AliITSgeomTGeo::GetNDetectors(ilr+1);
+ int nStaves = AliITSgeomTGeo::GetNLadders(ilr+1);
+ for (int ild=nLadPerStave;ild--;) {
+ fInjModuleTotClN[ilr][ild] = 0;
+ for (int is=nStaves;is--;) {
+ fInjModuleClStart[ilr][ild][is] = -1;
+ fInjModuleClN[ilr][ild][is] = 0;
+ }
+ }
+ //
+ fInjSPDOcc[ilr]->Reset();
+ fInjSPDPatt[ilr]->ResetAllBits();
+ TClonesArray* clusters = fClArr[ilr];
+ Int_t nclus = fNClustersLay[ilr];
+ //
+ for (int icl=0;icl<nclus;icl++) {
+ AliITSRecPoint* clus = (AliITSRecPoint*)clusters->UncheckedAt(icl);
+ if (!clus) continue;
+ int ladder = clus->GetDetectorIndex(); // ladder id within the layer
+ int stave = ladder/nLadPerStave;
+ ladder = nLadPerStave-1 - ladder%nLadPerStave; // ladder id within the stave !!!! invert to get human readble histos
+ // the clusters are packed per modules, register the beginning and n.clusters of each module
+ if (fInjModuleClStart[ilr][ladder][stave]<0) fInjModuleClStart[ilr][ladder][stave] = icl;
+ fInjModuleClN[ilr][ladder][stave]++;
+ fInjModuleTotClN[ilr][ladder]++;
+ //
+ int chip = fSPDSeg.GetChipFromLocal(clus->GetDetLocalX(),clus->GetDetLocalZ()); // chip within the ladder
+ if (ilr==1) chip = nChipsPerLadder - 1 - chip; //!!!! invert to get human readble histos
+ chip += ladder*nChipsPerLadder; // chip within the stave
+ ladder %= nLadPerStave; // ladder id within the stave
+ fInjSPDOcc[ilr]->Fill(chip, stave); // register cluster for hit density profile
+ //
+ float xloc = clus->GetDetLocalX()*1e4+xshift;
+ float zloc = clus->GetDetLocalZ()*1e4+zshift;
+ int row,col;
+ fSPDSeg.GetPadIxz(xloc,zloc,row,col); // row,col here stats from 1
+ row--;
+ col--;
+ //
+ // generate bit pattern according to hit type
+ int npix = clus->GetType();
+ int nrows = clus->GetNy();
+ int ncols = clus->GetNz();
+ float cx=0,cz=0;
+ UInt_t *patt = GenClusterPattern(npix,nrows,ncols,cx,cz);
+ row = int(row - cx); if (row<0) row=0; else if (row+nrows>maxRow1) row = maxRow1-nrows;
+ col = int(col - cz); if (col<0) col=0; else if (col+ncols>maxCol1) col = maxCol1-ncols;
+ for (int icol=ncols;icol--;) {
+ UInt_t hcol = patt[icol];
+ for (int irow=nrows;irow--;) {
+ if (!(hcol&(1<<irow))) continue; // no hit here
+ int pbit = GetPixelBitL(stave,ladder,col+icol,row+irow);
+ fInjSPDPatt[ilr]->SetBitNumber( pbit );
+ }
+ }
+ //
+ } // loop over clusters of layer ilr
+ } // loop over layers
+ //
+ if (fNClustersLay[0]==0||fNClustersLay[1]==0) {
+ AliInfo(Form("Trackleting is impossible: Ncl1=%d Ncl2=%d",fNClustersLay[0],fNClustersLay[1]));
+ return kFALSE;
+ }
+ for (int i=0;i<2;i++) {
+ if (fAssociations[i]) delete[] fAssociations[i];
+ int* tmpi = fAssociations[i] = new Int_t[ fNClustersLay[i] ];
+ for (int ic=fNClustersLay[i];ic--;) tmpi[ic] = -1;
+ }
+ for (int itr=fNTracklets;itr--;) {
+ Float_t* tracklet = GetTracklet(itr);
+ int cll1 = (int)tracklet[kClID1];
+ int cll2 = (int)tracklet[kClID2];
+ fAssociations[0][cll1] = cll2;
+ fAssociations[1][cll2] = cll1;
+ }
+ //
+ fInjBuffer.Set(fNTracklets*kTrNPar);
+ //
+ return kTRUE;
+ //
+}
+
+//_________________________________________________________________________
+Bool_t AliITSMultRecBg::GenClusterToInject()
+{
+ // generate bg cluster on layer lr
+ //
+ int nLadPerStave = AliITSgeomTGeo::GetNDetectors(fInjLr+1);
+ int nChipsPerModule = fSPDSeg.GetNumberOfChips();
+ //
+ int clID;
+ //
+ //RRR printf("On Lr %d | %d %d\n",fInjLr,fNClustersLay[0],fNClustersLay[1]);
+ do {
+ fInjSPDOcc[fInjLr]->GetRandom2(fInjZ, fInjX);
+ // printf("raw: %f %f\n",fInjZ,fInjX);
+ fInjStave = int(fInjX);
+ int chipInStave = int(fInjZ); // chip in the stave
+ //
+ fInjX = (fInjX - fInjStave)*fSPDSeg.Dx(); // local x coordinate
+ fInjModInStave = chipInStave/nChipsPerModule;
+ fInjModInStave = nLadPerStave - 1 - fInjModInStave; //!!! go from human readable to formal one
+ fInjModule = fInjStave*nLadPerStave + fInjModInStave; // formal module number
+ //
+ fInjZ = (fInjZ-chipInStave)*fSPDSeg.Dz(); // local z coordinate
+ // printf("Z %e X %e | MinSt%d Mod%d\n",fInjZ, fInjX,fInjModInStave,fInjModule);
+ //
+ clID = PickClusterPrototype(fInjLr, fInjModInStave, fInjStave);
+ } while(clID<0);
+ //
+ // printf("clID: %d %d %d %d\n",clID,fNClustersLay[0],fNClustersLay[1],fInjLr);
+ AliITSRecPoint* rClus = (AliITSRecPoint*)fClArr[fInjLr]->UncheckedAt(clID);
+ fInjCluster.SetLayer(fInjLr);
+ fInjCluster.SetType(TMath::Min(kInjMaxNY*kInjMaxNZ,rClus->GetType()));
+ fInjCluster.SetNy(TMath::Min(kInjMaxNY,rClus->GetNy()));
+ fInjCluster.SetNz(TMath::Min(kInjMaxNZ,rClus->GetNz()));
+ fInjCluster.SetDetectorIndex(fInjModule);
+ fInjCluster.SetVolumeId(AliGeomManager::LayerToVolUID(AliGeomManager::kSPD1+fInjLr,fInjModule));
+ //
+ PlaceInjCluster();
+ return kTRUE;
+ //
+}
+
+//_________________________________________________________________________
+void AliITSMultRecBg::PlaceInjCluster()
+{
+ // place the injected cluster on the selected module,
+ // avoiding overlaps with real clusters
+ int npix = fInjCluster.GetType(), nrows = fInjCluster.GetNy(), ncols = fInjCluster.GetNz();
+ Float_t cx=0,cz=0;
+ UInt_t* pattern = GenClusterPattern(npix, nrows, ncols, cx,cz);
+ //
+ // try to embedd on top of real clusters
+ int maxRow1 = fSPDSeg.Npx(), maxCol1 = fSPDSeg.Npz();
+ int maxRow = maxRow1-1, maxCol = maxCol1-1;
+ TBits &bits = *fInjSPDPatt[fInjLr]; // hits pattern of selected layer
+ int row0=0,col0=0;
+ Bool_t failed;
+ do {
+ failed = kFALSE;
+ fSPDSeg.GetPadIxz(fInjX,fInjZ,row0,col0);
+ row0--; col0--; // row,col here start from 1
+ if (row0+nrows > maxRow1) row0 = maxRow1-nrows;
+ if (col0+ncols > maxCol1) col0 = maxCol1-ncols;
+ //
+ // printf("Cluster at %f %f: col:%d row:%d\n",fInjZ,fInjX,col0,row0);
+ //
+ // check if generated pattern is mergable with data clusters
+ fInjHitsN = 0;
+ for (int ic=ncols;ic--;) {
+ int colt = col0+ic;
+ for (int ir=nrows;ir--;) {
+ if ( !(pattern[ic]&(1<<ir)) ) continue; // not used
+ int rowt = row0+ir;
+ int bitID = GetPixelBitL(fInjStave,fInjModInStave,colt,rowt);
+ if ( bits.TestBitNumber(bitID) || // is pixel free?
+ (colt>0 && bits.TestBitNumber(bitID-maxRow1)) || // pixel 1 column below
+ (colt<maxCol && bits.TestBitNumber(bitID+maxRow1)) || // pixel 1 column above
+ (rowt>0 && bits.TestBitNumber(bitID-1)) || // pixel 1 row below
+ (rowt<maxRow && bits.TestBitNumber(bitID+1))) // pixel in 1 row above
+ {failed=kTRUE; break;}
+ // ok for this pixel
+ fInjHits[fInjHitsN++] = bitID;
+ }
+ if (failed) break;
+ }
+ if (failed) { // generate new x,z
+ // printf("Conflict found, retry\n");
+ fInjX = gRandom->Rndm()*fSPDSeg.Dx();
+ fInjZ = gRandom->Rndm()*fSPDSeg.Dz();
+ continue;
+ }
+ } while(failed);
+ //
+ // caclulate cluster coordinates
+ float x=0,z=0;
+ fInjX = fInjZ = 0;
+ for (int pix=fInjHitsN;pix--;) {
+ ExtractPixelL(fInjHits[pix], fInjStave, fInjModInStave, col0, row0);
+ fSPDSeg.GetPadCxz(row0+1,col0,x,z); // !!! Note: here row starts from 1 but col from 0!!!
+ fInjX += x;
+ fInjZ += z;
+ }
+ fInjX = (fInjX/fInjHitsN-fSPDSeg.Dx()/2)*1e-4;
+ fInjZ = (fInjZ/fInjHitsN-fSPDSeg.Dz()/2)*1e-4;
+ const TGeoHMatrix *mT2L = AliITSgeomTGeo::GetTracking2LocalMatrix(fInjLr+1,fInjStave+1,fInjModInStave+1);
+ Double_t loc[3]={fInjX,0.,fInjZ},trk[3]={0.,0.,0.};
+ mT2L->MasterToLocal(loc,trk);
+ //
+ fInjCluster.SetX(0);
+ fInjCluster.SetY(trk[1]);
+ fInjCluster.SetZ(trk[2]);
+ //
+ // printf("ClCoord: %+e %+e %+e\n",fInjCluster.GetX(),fInjCluster.GetY(),fInjCluster.GetZ());
+}
+
+//_________________________________________________________________________
+void AliITSMultRecBg::InitInjBg()
+{
+ // initialize data for bg injection
+ char buff[100];
+ for (int ilr=0;ilr<2;ilr++) {
+ sprintf(buff,"occL%d",ilr);
+ int nLaddersStave = AliITSgeomTGeo::GetNDetectors(ilr+1);
+ int nChipsStave = fSPDSeg.GetNumberOfChips()*nLaddersStave;
+ int nStaves = AliITSgeomTGeo::GetNLadders(ilr+1);
+ int nColsStave = fSPDSeg.Npz();
+ int nRowsStave = fSPDSeg.Npz();
+ fInjSPDOcc[ilr] = new TH2F(buff,buff,nChipsStave,0,nChipsStave, nStaves,0,nStaves);
+ fInjSPDPatt[ilr] = new TBits(nStaves*nLaddersStave*nColsStave*nRowsStave);
+ for (int is=0;is<nStaves;is++) {
+ for (int il=0;il<nLaddersStave;il++) {
+ fInjModuleClStart[ilr][il] = new Int_t[nStaves];
+ fInjModuleClN[ilr][il] = new Int_t[nStaves];
+ }
+ }
+ //
+ }
+}
+
+//_________________________________________________________________________
+UInt_t* AliITSMultRecBg::GenClusterPattern(Int_t &npix, Int_t &ny, Int_t &nz, Float_t cy,Float_t &cz)
+{
+ // generate random pattern for the cluster
+ static UInt_t hitPattern[160];
+ if (ny>kInjMaxNY) ny = kInjMaxNY;
+ if (nz>kInjMaxNZ) nz = kInjMaxNZ;
+ for (int iz=nz;iz--;) hitPattern[iz]=0;
+ //
+ // handle explicitly easy cases: () is for pixels in the same column ...
+ if (npix==1) hitPattern[0] = 0x1; // type (|)
+ else if (npix==2) {
+ if (nz==1) hitPattern[0] = 0x3; // tpye (||)
+ else hitPattern[0] = hitPattern[1] = 0x1; // tpye (|)(|)
+ }
+ else if (npix==3) {
+ if (nz==1) hitPattern[0] = 0x7; // tpye (|||)
+ else if (ny==1) hitPattern[0] = hitPattern[1] = hitPattern[2] = 0x1; // type (|)(|)(|)
+ else { hitPattern[0] = 0x3; hitPattern[1] = 0x1;} // type (||)(|)
+ }
+ else if (npix==4) {
+ if (nz==1) hitPattern[0] = 0xf; // type (||||)
+ else if (ny==1) hitPattern[0] = hitPattern[1] = hitPattern[2] = hitPattern[3] = 0x1; // type (|)(|)(|)(|)
+ else if (ny==2) {
+ if (nz==2) hitPattern[0] = hitPattern[1] = 0x3; // tpye (||)(||)
+ else {
+ hitPattern[0] = hitPattern[1] = hitPattern[2] = 0x1; // type (||)(|)(|) or (|)(||)(|)
+ hitPattern[gRandom->Rndm()>0.5 ? 0 : 1] |= 0x2;
+ }
+ }
+ else {
+ hitPattern[0] = 0x7;
+ hitPattern[1] = (gRandom->Rndm()>0.8) ? 0x1 : 0x2; // type (|||) + (_|_) or (|||) + (|__)
+ }
+ }
+ // more complex topologies
+ else {
+ UInt_t mask = 0xffffffff>>(32-ny);
+ for (int i=nz;i--;) hitPattern[i] = mask;
+ int toSup = ny*nz - npix;
+ int trial = toSup*5;
+ int colToTouch = nz-1; // at least 1 column should not be touched
+ while(toSup>0 && (trial--)>0) { // suppress random pixel until needed npix, ny and nz is obtained
+ int col = gRandom->Integer(nz);
+ if (hitPattern[col]==0x1) continue; // don't lose this column
+ if (hitPattern[col]==mask) {
+ if (!colToTouch) continue; // this is the only remaining column with ny rows hit
+ colToTouch--; // there are other columns of ny rows hit, may touch it
+ }
+ hitPattern[col] >>= 1;
+ toSup--;
+ }
+ if (toSup) npix += toSup; // failed to suppress exact number of pixels
+ }
+ //
+ cy = cz = 0; // get centroid
+ for (int col=nz;col--;) {
+ int npxr = 0;
+ for (int row=ny;row--;) if (hitPattern[col] & (0x1<<row)) {npxr++; cy+=(1+row);}
+ cz += npxr*(1+col);
+ }
+ cz = cz/npix - 0.5;
+ cy = cy/npix - 0.5;
+ //
+ return (UInt_t*)&hitPattern[0];
+}
+
+//_________________________________________________________________________
+Int_t AliITSMultRecBg::PickClusterPrototype(Int_t lr, Int_t ladInStave, Int_t stave2avoid)
+{
+ // pick random cluster to use as a prototype for injection. It should come
+ // from ladders at given Z belt and should not be from the stave2avoid
+ // pick random cluster to use as a prototype for injection. It should come
+ // from ladders at given Z belt and should not be from the stave2avoid
+ static int tried = 0;
+ static int ladInStaveOrig = 0;
+ //
+ int ncl = fInjModuleTotClN[lr][ladInStave];
+ if (stave2avoid>=0) ncl -= fInjModuleClN[lr][ladInStave][stave2avoid];
+ if (ncl<1) {
+ int totLad = AliITSgeomTGeo::GetNDetectors(lr+1);
+ if (!tried) ladInStaveOrig = ladInStave; // before starting the resque solution, save the orig.ladder
+ if (++tried >= totLad) { // failed to find cluster avoiding a stave2avoid
+ tried = 0;
+ return PickClusterPrototype(lr,ladInStaveOrig,-1);
+ }
+ int useLad = ladInStave+1;
+ if (useLad>=AliITSgeomTGeo::GetNDetectors(lr+1)) useLad = 0;
+ return PickClusterPrototype(lr,useLad,stave2avoid); // look in the neigbouring ladder
+ }
+ //
+ int pick = gRandom->Integer(ncl);
+ int nst = AliITSgeomTGeo::GetNLadders(lr+1);
+ int stave = 0;
+ for (stave=0;stave<nst;stave++) {
+ if (stave==stave2avoid) continue;
+ if (pick<fInjModuleClN[lr][ladInStave][stave]) break;
+ pick -= fInjModuleClN[lr][ladInStave][stave];
+ }
+ //
+ tried = 0;
+ return fInjModuleClStart[lr][ladInStave][stave]+pick;
+}
+
+//_________________________________________________________________________
+Int_t AliITSMultRecBg::SearchInjTracklet(const Float_t *vtx)
+{
+ // reconstruct tracklets which may involve injected cluster
+ // fake arrays to be used for injected cluster in MultReco
+ Float_t clustersLayInj[kClNPar];
+ Int_t detectorIndexClustersLayInj[1];
+ Bool_t overlapFlagClustersLayInj[1];
+ UInt_t usedClusLayInj[1];
+ //
+ Bool_t kUseOrig = kFALSE;//kTRUE;
+ if (kUseOrig) {
+ // to try with unused clusters
+ if ( fAssociations[fInjLr][fInjCurrTrial]>=0 ) return 0; // associated
+ float *origCl = GetClusterOfLayer(fInjLr,fInjCurrTrial);
+ for (int i=0;i<kClNPar;i++) clustersLayInj[i] = origCl[i];
+ }
+ else {
+ // >> fill cluster data: equivavlent of data fetched in AliITSMultReconstructor::LoadClusterArrays
+ detectorIndexClustersLayInj[0] = fInjCluster.GetDetectorIndex();
+ overlapFlagClustersLayInj[0] = kFALSE;
+ usedClusLayInj[0] = 0;
+ fInjCluster.GetGlobalXYZ( clustersLayInj );
+ for (int i=3;i--;) clustersLayInj[kClMC0+i] = fInjCluster.GetLabel(i);
+ ClusterPos2Angles(clustersLayInj, vtx); // convert to angles
+ }
+ //
+ // compare injected cluster with real ones
+ int partnerLr = 1 - fInjLr;
+
+ double bestChiUsed = fNStdDev*2, bestChiFree = fNStdDev*2;
+ int bestPartnerUsed=-1,bestPartnerFree=-1;
+ //
+ for (int icl=fNClustersLay[partnerLr];icl--;) {
+ Float_t *partnerCl = GetClusterOfLayer(partnerLr,icl);
+ Double_t dTheta = clustersLayInj[kClTh] - partnerCl[kClTh];
+ Double_t dPhi = clustersLayInj[kClPh] - partnerCl[kClPh];
+ if (dPhi>TMath::Pi()) dPhi=2.*TMath::Pi()-dPhi; // take into account boundary condition
+ Float_t d = CalcDist(dPhi,dTheta, fInjLr==0 ? clustersLayInj[kClTh]:partnerCl[kClTh]);
+ if (d>fNStdDev) continue;
+ //
+ int competitor = fAssociations[partnerLr][icl]; // is the cluster of partner layer already used by some tracklet?
+ if (competitor>=0) { if (d<bestChiUsed && d < fMinDists[ partnerLr==1 ? icl : competitor ]) { bestChiUsed = d; bestPartnerUsed = icl; } }
+ else { if (d<bestChiFree) { bestChiFree = d; bestPartnerFree = icl; } }
+ }
+ //
+ int winner = -1;
+ //
+ if (bestPartnerUsed>=0) {
+ if (bestPartnerFree>=0) { winner = bestChiFree<bestChiUsed ? bestPartnerFree : bestPartnerUsed;} // shall we subtract old real tracklet if the winner cluster is used one?
+ else { winner = bestPartnerUsed; }
+ }
+ else winner = bestPartnerFree;
+
+ // printf("%d\n",winner);
+
+ if (winner<0) return 0;
+ //
+ int nCurrTr = GetNInjSuccsess();
+ if (nCurrTr >= fInjBuffer.GetSize()/kTrNPar)
+ fInjBuffer.Set(nCurrTr*2*kTrNPar);
+ //
+ Float_t *tracklet = fInjBuffer.GetArray() + nCurrTr*kTrNPar;
+ Float_t *clPar1=0,*clPar2=0;
+ if (fInjLr) {
+ clPar1 = GetClusterOfLayer(partnerLr,winner);
+ clPar2 = clustersLayInj;
+ tracklet[kClID1] = winner;
+ tracklet[kClID2] = -1;
+ }
+ else {
+ clPar2 = GetClusterOfLayer(partnerLr,winner);
+ clPar1 = clustersLayInj;
+ tracklet[kClID1] = -1;
+ tracklet[kClID2] = winner;
+ }
+ tracklet[kTrTheta] = clPar1[kClTh]; // use the theta from the clusters in the first layer
+ tracklet[kTrPhi] = clPar1[kClPh]; // use the phi from the clusters in the first layer
+ tracklet[kTrDPhi] = clPar1[kClPh] - clPar2[kClPh]; // store the difference between phi1 and phi2
+ //
+ // define dphi in the range [0,pi] with proper sign (track charge correlated)
+ if (tracklet[kTrDPhi] > TMath::Pi()) tracklet[kTrDPhi] = tracklet[kTrDPhi]-2.*TMath::Pi();
+ if (tracklet[kTrDPhi] < -TMath::Pi()) tracklet[kTrDPhi] = tracklet[kTrDPhi]+2.*TMath::Pi();
+ tracklet[kTrDTheta] = clPar1[kClTh] - clPar2[kClTh]; // store the theta1-theta2
+ tracklet[kTrLab1] = clPar1[kClMC0];
+ tracklet[kTrLab2] = clPar2[kClMC0];
+ //
+ // printf("Got Tracklet from lr%d: %f %f\n",fInjLr,fInjNSuccess[0],fInjNSuccess[1]);
+ //
+ return 1;
+ //
+}
+
+//_________________________________________________________________________
+void AliITSMultRecBg::GenInjBgSample(TTree* treeRP, Float_t *vtx)
+{
+ // generate a sample of tracklets from injected bg
+ //
+ SetTreeRP(treeRP);
+ InitInjBg();
+ if (!PrepareInjBgGenerator(vtx)) return;
+ //
+ fInjNSuccess[0] = fInjNSuccess[1] = 0;
+ for (int i=0;i<2;i++) {
+ fInjLr = i;
+ fInjNTrials[i] = TMath::Max(1,int(fInjScale*fNClustersLay[i]));
+ for (fInjCurrTrial=0;fInjCurrTrial<fInjNTrials[i];fInjCurrTrial++) {
+ if (!GenClusterToInject()) break;
+ fInjNSuccess[i] += SearchInjTracklet(vtx);
+ }
+ }
+ printf("Successes/Trials: %d/%d %d/%d\n",fInjNSuccess[0],fInjNTrials[0],fInjNSuccess[1],fInjNTrials[1]);
+ //
+}
+
--- /dev/null
+#ifndef ALIITSMULTRECBG_H
+#define ALIITSMULTRECBG_H
+
+class TH2F;
+class TTree;
+#include <TArrayF.h>
+#include "../ITS/AliITSMultReconstructor.h"
+#include "../ITS/AliITSRecPoint.h"
+
+
+class AliITSMultRecBg : public AliITSMultReconstructor
+{
+ public:
+ enum {kData, // normal reconstruction
+ kBgRot, // bg with rotation
+ kBgInj, // bg with injection
+ kBgMix // bg with mixing
+ };
+ //
+ AliITSMultRecBg();
+ virtual ~AliITSMultRecBg();
+ //
+ void Run(TTree* tree, Float_t* vtx, TTree* treeMix=0);
+ //
+ void SetRecType(UInt_t m=kData) {fRecType = m;}
+ Int_t GetRecType() const {return fRecType;}
+ //
+ void SetInjScale(Float_t s=1.) {fInjScale = s>0? s:1.;}
+ Int_t GetNInjTrials(Int_t lr=-1) const {return lr<0 ? fInjNTrials[0]+fInjNTrials[1] : fInjNTrials[lr];}
+ Int_t GetNInjSuccsess(Int_t lr=-1) const {return lr<0 ? fInjNSuccess[0]+fInjNSuccess[1] : fInjNSuccess[lr];}
+ //
+ void Print(Option_t *opt=0) const {AliITSMultReconstructor::Print(opt);}
+ //
+ protected:
+ virtual void CreateMultiplicityObject();
+ //
+ // Injection stuff
+ void GenInjBgSample(TTree* treeRP, Float_t *vtx);
+ Bool_t PrepareInjBgGenerator(Float_t *vtx);
+ void InitInjBg();
+ Bool_t GenClusterToInject();
+ void PlaceInjCluster();
+ Int_t PickClusterPrototype(Int_t lr, Int_t ladInStave, Int_t stave2avoid);
+ UInt_t* GenClusterPattern(Int_t &npix, Int_t &ny, Int_t &nz, Float_t cy,Float_t &cz);
+ Int_t SearchInjTracklet(const Float_t *vtx);
+ Int_t GetPixelBitC(int stave, int chip, int col, int row) const {return row+((col+((chip+stave*20)<<5))<<8);} // row + (col+ (chip + stave*20)*32)*256;
+ Int_t GetPixelBitL(int stave, int ladder,int col, int row) const {return row+((col+(ladder+(stave<<2))*32*5)<<8);} // row + (col + (ladder + stave*4)*32*5)*256
+ void ExtractPixelL(int id, int &stave, int &ladder, int &col, int &row);
+
+
+ protected:
+ enum {kInjFakeLabel=-999};
+ enum {kInjMaxNY=10, kInjMaxNZ=8};
+ //
+ Int_t fRecType;
+ //
+ // method specific members
+ //
+ // injection
+ Int_t fInjLr; // injection layer
+ Int_t fInjStave; // injection stave (counted from layer)
+ Int_t fInjModule; // injection module (counted from layer)
+ Int_t fInjModInStave; // injection module (counted from stave)
+ Double_t fInjX; // injection local X
+ Double_t fInjZ; // injection local Z
+ Int_t fInjHitsN; // number of injected pixels
+ Int_t fInjHits[256]; // bit ids of injected pixels (GetPixelBitL/ExtractPixelL)
+ Int_t* fAssociations[2]; //! associations [0]: from L1 to L2, [1]: L2 to L1
+ Float_t fInjScale; // scaling factor for generation
+ Int_t fInjCurrTrial; // current trial id
+ Int_t fInjNTrials[2]; // number of injections per event for each layer
+ Int_t fInjNSuccess[2]; // number of successful injected tracklet generation
+ AliITSRecPoint fInjCluster; // fake cluster to inject
+ TH2F* fInjSPDOcc[2]; // occupancy in 2 SPD layers
+ TBits* fInjSPDPatt[2]; // occupancy pattern accounting for cluster types
+ Int_t* fInjModuleClStart[2][4]; //! start of clusters for modules in given Z belt of each stave
+ Int_t* fInjModuleClN[2][4]; //! number of clusters for modules in given Z belt of each stave
+ Int_t fInjModuleTotClN[2][4]; // total number of clusters for modules in given Z belt
+ TArrayF fInjBuffer; //! buffer for bg tracklets
+ //
+ ClassDef(AliITSMultRecBg,0)
+};
+
+
+inline void AliITSMultRecBg::ExtractPixelL(int id, int &stave, int &ladder, int &col, int &row)
+{
+ enum {kNRow=256,kNCol=32*5,kNLadd=4};
+ row = id%kNRow;
+ id /= kNRow;
+ col = id%kNCol;
+ id /= kNCol;
+ ladder = id%kNLadd;
+ stave = id/kNLadd;
+}
+
+
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2008, 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. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Analysis task to extract global variables to the tree //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TChain.h>
+#include <TFile.h>
+#include <TString.h>
+#include <TTree.h>
+#include <TList.h>
+#include <TObjArray.h>
+#include "AliAnalysisManager.h"
+#include "AliMultiplicity.h"
+#include "AliESDEvent.h"
+#include "AliESDInputHandler.h"
+#include "AliESDVZERO.h"
+#include "AliESDZDC.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliMCParticle.h"
+#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "AliLog.h"
+#include "AliPhysicsSelection.h"
+#include "AliESDCentrality.h"
+#include "AliESDtrackCuts.h"
+#include "AliTaskGlobVar.h"
+#include "AliGenEventHeader.h"
+#include "AliGenHijingEventHeader.h"
+#include "AliGenDPMjetEventHeader.h"
+
+
+ClassImp(AliTaskGlobVar)
+
+
+GloVars_t globVars;
+
+//________________________________________________________________________
+AliTaskGlobVar::AliTaskGlobVar(const char *name)
+ : AliAnalysisTaskSE(name),
+ //
+ fUseMC(kFALSE),
+ fOutput(0),
+ fOutTree(0),
+ fTrackCuts(0),
+ fTrackCuts1(0)
+{
+ // Constructor
+ DefineOutput(1, TList::Class());
+ //
+}
+
+//________________________________________________________________________
+AliTaskGlobVar::~AliTaskGlobVar()
+{
+ // Destructor
+ // histograms are in the output list and deleted when the output
+ // list is deleted by the TSelector dtor
+ if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) { //RRR
+ printf("Deleteing output\n");
+ delete fOutput;
+ fOutput = 0;
+ }
+ //
+}
+
+//________________________________________________________________________
+void AliTaskGlobVar::UserCreateOutputObjects()
+{
+ //
+ fOutput = new TList();
+ fOutput->SetOwner();
+ //
+ fOutTree = new TTree("globTree","globTree");
+ fOutTree->Branch("g",&globVars,"runID/I:timeStamp/i:zdcNA/F:zdcPA/F:zdcNC/F:zdcPC/F:zem1/F:zem2/F:zvSPD/F:zvTPC/F:chunk/S:flags/S"
+ ":spd1/S:spd2/S:ncontSPDV/S:ncontTPCV/S:nTrTPC/S:nTrTPCITS/S:nTracklets/S:v0A/S:v0C/S:v0Corr/S", 16777216);
+
+ if (fUseMC) {
+ fOutTree->Branch("gmc",&globVars.mcZV,"mcZV/F:mcdNdEta/S:mcNPart/S:mcNBColl/S", 16777216);
+ }
+ fOutput->Add(fOutTree);
+ //
+ // fTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+ fTrackCuts = CreatedNdPtTrackCuts(23);
+ fTrackCuts->SetEtaRange(-0.8,0.8);
+ fTrackCuts1 = CreatedNdPtTrackCuts(72);
+ fTrackCuts1->SetEtaRange(-0.8,0.8);
+ //
+ PostData(1, fOutput);
+ printf("CreatingXXX\n");
+ //
+}
+
+//________________________________________________________________________
+void AliTaskGlobVar::UserExec(Option_t *)
+{
+ // Main loop
+ //
+ AliAnalysisManager* anMan = AliAnalysisManager::GetAnalysisManager();
+ AliESDInputHandler *hand = (AliESDInputHandler*)anMan->GetInputEventHandler();
+ if (!hand) { printf("No ESD handler\n"); return; }
+ AliESDEvent *esd = hand->GetEvent();
+ if (!esd) { printf("No AliESDEvent\n"); return; }
+ //
+ if (!fUseMC && !ZDCTimeTrigger(esd)) return;
+ //
+ const AliESDVertex* vtxESD = esd->GetPrimaryVertexSPD();
+ Bool_t vtxOK = kTRUE;
+ if (vtxESD->GetNContributors()<1) vtxOK = kFALSE; //return;
+ if (vtxESD->GetDispersion()>0.04) vtxOK = kFALSE; //return;
+ if (vtxESD->GetZRes()>0.25) vtxOK = kFALSE; //return;
+ const AliMultiplicity* multESD = esd->GetMultiplicity();
+ const AliESDVertex* vtxESDTPC = esd->GetPrimaryVertexTPC();
+ // if (vtxESDTPC->GetNContributors()<1) return;
+ // if (vtxESDTPC->GetNContributors()<(-10.+0.25*multESD->GetNumberOfITSClusters(0))) return;
+ //
+ globVars.runID = esd->GetRunNumber();
+ TString rid = "";
+ rid += globVars.runID;
+ TString flname = hand->GetTree()->GetCurrentFile()->GetName();
+ globVars.chunk = 0;
+ int id = 0;
+ while ( (id=flname.Index(rid))>=0 ) flname = flname.Data()+id+rid.Length();
+ id = flname.First('.');
+ if (id>=0) {
+ flname = flname.Data() + id+1;
+ globVars.chunk = (Short_t)flname.Atoi();
+ }
+ // printf("%d %s\n",globVars.chunk,hand->GetTree()->GetCurrentFile()->GetName());
+ //
+ globVars.timeStamp = esd->GetTimeStamp();
+ globVars.timeStamp = esd->GetTimeStamp();
+ globVars.zvSPD = vtxESD->GetZ();
+ globVars.zvTPC = vtxESDTPC->GetZ();
+ globVars.ncontSPDV = (Short_t)vtxESD->GetNContributors();
+ globVars.ncontTPCV = (Short_t)vtxESDTPC->GetNContributors();
+ // globVars.nTrTPC = fTrackCuts ? (Short_t)fTrackCuts->GetReferenceMultiplicity(esd,kTRUE):-1;
+ globVars.nTrTPC = fTrackCuts ? (Short_t)fTrackCuts->CountAcceptedTracks(esd):-1;
+ globVars.nTrTPCITS = fTrackCuts1 ? (Short_t)fTrackCuts1->CountAcceptedTracks(esd):-1;
+ globVars.nTracklets = multESD->GetNumberOfTracklets();
+ //
+ AliESDVZERO* esdV0 = esd->GetVZEROData();
+ if (esdV0) {
+ globVars.v0A = (Short_t)esdV0->GetMTotV0A();
+ globVars.v0C = (Short_t)esdV0->GetMTotV0C();
+ }
+ else globVars.v0A = globVars.v0C = 0;
+ //
+ globVars.spd1 = (Short_t)multESD->GetNumberOfITSClusters(0);
+ globVars.spd2 = (Short_t)multESD->GetNumberOfITSClusters(1);
+ //
+ float v0Corr,v0CorrR;
+ v0Corr = GetCorrV0(esd,v0CorrR);
+ globVars.v0Corr = (Short_t)v0Corr;
+ // globVars.v0CorrResc = (Short_t)v0CorrR;
+
+ //---------------------------------------------
+ AliESDZDC *esdZDC = esd->GetESDZDC();
+ // --- ZDC offline trigger ---
+ // Returns if ZDC triggered, based on TDC information
+ Bool_t tdc[32] = {kFALSE};
+ for(Int_t itdc=0; itdc<32; itdc++){
+ for(Int_t i=0; i<4; i++){
+ if (0.025*esdZDC->GetZDCTDCData(itdc, i) != 0){
+ tdc[itdc] = kTRUE;
+ }
+ }
+ }
+ globVars.flags = 0;
+ if ( tdc[12] ) globVars.flags |= GloVars_t::kTDCNA; // Bool_t zdcNA = tdc[12];
+ if ( tdc[10] ) globVars.flags |= GloVars_t::kTDCNC; // Bool_t zdcNC = tdc[10];
+ if ( tdc[13] ) globVars.flags |= GloVars_t::kTDCPA; // Bool_t zdcPA = tdc[13];
+ if ( tdc[11] ) globVars.flags |= GloVars_t::kTDCPC; // Bool_t zdcPC = tdc[11];
+ if ( vtxOK ) globVars.flags |= GloVars_t::kSPDVTXOK;
+ //
+ globVars.zdcNC = (Float_t) (esdZDC->GetZDCN1Energy()) /8.;
+ globVars.zdcPC = (Float_t) (esdZDC->GetZDCP1Energy()) /8.;
+ globVars.zdcNA = (Float_t) (esdZDC->GetZDCN2Energy()) /8.;
+ globVars.zdcPA = (Float_t) (esdZDC->GetZDCP2Energy()) /8.;
+ globVars.zem1 = (Float_t) (esdZDC->GetZDCEMEnergy(0)) /8.;
+ globVars.zem2 = (Float_t) (esdZDC->GetZDCEMEnergy(1)) /8.;
+ //-----------------------------------------------
+ //
+ // ---------------------- MC ONLY -------------------------------
+ AliMCEventHandler* eventHandler = (AliMCEventHandler*)anMan->GetMCtruthEventHandler();
+ AliStack* stack=0;
+ AliMCEvent* mcEvent=0;
+ globVars.mcdNdEta = 0;
+ globVars.mcNPart = 0;
+ globVars.mcNBColl = 0;
+ if (fUseMC && eventHandler && (mcEvent=eventHandler->MCEvent()) && (stack=mcEvent->Stack())) {
+ int ntr = stack->GetNtrack();
+ for (int itr=ntr;itr--;) {
+ if (!stack->IsPhysicalPrimary(itr)) continue;
+ AliMCParticle *part = (AliMCParticle*)mcEvent->GetTrack(itr);
+ if (!part || !part->Charge()) continue;
+ Float_t eta = part->Eta();
+ if (TMath::Abs(eta)>0.5) continue;
+ globVars.mcdNdEta++;
+ }
+ //
+ AliGenEventHeader* mcGenH = mcEvent->GenEventHeader();
+ if (mcGenH->InheritsFrom(AliGenHijingEventHeader::Class())) {
+ AliGenHijingEventHeader* hHijing = (AliGenHijingEventHeader*)mcGenH;
+ globVars.mcNPart = (hHijing->ProjectileParticipants()+hHijing->TargetParticipants())/2.;
+ globVars.mcNBColl = hHijing->NN()+hHijing->NNw()+hHijing->NwN()+hHijing->NwNw();
+ }
+ else if (mcGenH->InheritsFrom(AliGenDPMjetEventHeader::Class())) {
+ AliGenDPMjetEventHeader* hDpmJet = (AliGenDPMjetEventHeader*)mcGenH;
+ globVars.mcNPart = (hDpmJet->ProjectileParticipants()+hDpmJet->TargetParticipants())/2.;
+ globVars.mcNBColl = hDpmJet->NN()+hDpmJet->NNw()+hDpmJet->NwN()+hDpmJet->NwNw();
+ }
+ else {} // unknown generator
+ //
+ TArrayF vtxMC;
+ mcGenH->PrimaryVertex(vtxMC);
+ globVars.mcZV = vtxMC[2];
+ }
+ //
+ fOutTree->Fill();
+ //
+}
+//________________________________________________________________________
+void AliTaskGlobVar::Terminate(Option_t *)
+{
+ Printf("Terminating...");
+ // AliAnalysisTaskSE::Terminate();
+}
+
+
+//________________________________________________________________________
+Float_t AliTaskGlobVar::GetCorrV0(const AliESDEvent* esd, float &v0CorrResc) const
+{
+ // correct V0 non-linearity, prepare a version rescaled to SPD2 corr
+ const Double_t par0[64] = { 6.71e-02 , 6.86e-02 , 7.06e-02 , 6.32e-02 ,
+ 5.91e-02 , 6.07e-02 , 5.78e-02 , 5.73e-02 , 5.91e-02 , 6.22e-02 ,
+ 5.90e-02 , 6.11e-02 , 5.55e-02 , 5.29e-02 , 5.19e-02 , 5.56e-02 ,
+ 6.25e-02 , 7.03e-02 , 5.64e-02 , 5.81e-02 , 4.57e-02 , 5.30e-02 ,
+ 5.13e-02 , 6.43e-02 , 6.27e-02 , 6.48e-02 , 6.07e-02 , 1.01e-01 ,
+ 6.68e-02 , 7.16e-02 , 6.36e-02 , 5.95e-02 , 2.52e-02 , 2.82e-02 ,
+ 2.56e-02 , 2.86e-02 , 2.82e-02 , 2.10e-02 , 2.13e-02 , 2.32e-02 ,
+ 2.75e-02 , 4.34e-02 , 3.78e-02 , 4.52e-02 , 4.11e-02 , 3.89e-02 ,
+ 4.10e-02 , 3.73e-02 , 4.51e-02 , 5.07e-02 , 5.42e-02 , 4.74e-02 ,
+ 4.33e-02 , 4.44e-02 , 4.64e-02 , 3.01e-02 , 6.38e-02 , 5.26e-02 ,
+ 4.99e-02 , 5.26e-02 , 5.47e-02 , 3.84e-02 , 5.00e-02 , 5.20e-02 };
+ const Double_t par1[64] = { -6.68e-05 , -7.78e-05 , -6.88e-05 , -5.92e-05 ,
+ -2.43e-05 , -3.54e-05 , -2.91e-05 , -1.99e-05 , -1.40e-05 , -4.01e-05 ,
+ -2.29e-05 , -3.68e-05 , -2.53e-05 , -2.44e-06 , -9.22e-06 , -1.51e-05 ,
+ -2.80e-05 , -2.34e-05 , -1.72e-05 , -1.81e-05 , -1.29e-05 , -2.65e-05 ,
+ -1.61e-05 , -2.86e-05 , -1.74e-05 , -4.23e-05 , -3.41e-05 , -1.05e-04 ,
+ -2.76e-05 , -4.71e-05 , -3.06e-05 , -2.32e-05 , -1.55e-06 , 2.15e-05 ,
+ 1.40e-05 , 2.16e-05 , 1.21e-05 , 3.05e-06 , 1.67e-05 , -3.84e-06 ,
+ 3.09e-06 , 1.50e-05 , 3.47e-06 , 4.87e-06 , -3.71e-07 , -1.75e-06 ,
+ -1.80e-06 , 9.99e-06 , -6.46e-06 , -4.91e-06 , 1.33e-05 , -2.52e-07 ,
+ -3.85e-06 , 4.94e-06 , -2.48e-07 , -1.20e-05 , 2.07e-06 , 6.12e-06 ,
+ -1.18e-06 , 4.54e-06 , -1.54e-05 , -1.25e-05 , 1.46e-06 , -6.67e-06 };
+ const Double_t par2[64] = { 1.29e-08 , 1.51e-08 , 1.43e-08 , 1.11e-08 ,
+ 5.04e-09 , 6.99e-09 , 5.58e-09 , 4.15e-09 , 4.00e-09 , 8.22e-09 ,
+ 4.97e-09 , 7.66e-09 , 4.91e-09 , 1.10e-09 , 2.64e-09 , 3.64e-09 ,
+ 5.76e-09 , 5.46e-09 , 3.38e-09 , 3.47e-09 , 2.43e-09 , 4.13e-09 ,
+ 2.80e-09 , 5.80e-09 , 3.86e-09 , 7.46e-09 , 5.98e-09 , 2.58e-08 ,
+ 5.50e-09 , 8.72e-09 , 5.23e-09 , 4.37e-09 , 2.33e-09 , -6.01e-10 ,
+ 3.99e-11 , -2.02e-10 , 7.67e-10 , 2.03e-09 , 1.17e-10 , 2.56e-09 ,
+ 1.16e-09 , -4.75e-10 , 1.28e-09 , 1.23e-09 , 1.62e-09 , 1.61e-09 ,
+ 1.93e-09 , 2.97e-10 , 2.21e-09 , 2.16e-09 , 5.22e-10 , 1.03e-09 ,
+ 1.56e-09 , 5.00e-10 , 1.01e-09 , 2.93e-09 , 1.05e-09 , 9.96e-11 ,
+ 1.21e-09 , 7.45e-10 , 3.07e-09 , 2.31e-09 , 6.70e-10 , 1.89e-09 };
+ //
+ Float_t multCorr = 0;
+ Float_t multCorr2 = 0;
+ Float_t multChCorr[64];
+ AliESDVZERO* esdV0 = esd->GetVZEROData();
+ for(Int_t i = 0; i < 64; ++i) {
+ Double_t b = (esdV0->GetMultiplicity(i)*par1[i]-par0[i]);
+ Double_t s = (b*b-4.*par2[i]*esdV0->GetMultiplicity(i)*esdV0->GetMultiplicity(i));
+ Double_t n;
+ if (s<0) {
+ printf("FPE %d %.2f %.2f %.2e\n",i,esdV0->GetMultiplicity(i),b,(b*b-4.*par2[i]*esdV0->GetMultiplicity(i)*esdV0->GetMultiplicity(i)));
+ n = -b;
+ }
+ else {
+ n = (-b + TMath::Sqrt(s));
+ }
+ multChCorr[i] = 2.*esdV0->GetMultiplicity(i)/n*par0[i];
+ multCorr += multChCorr[i];
+ multCorr2 += (multChCorr[i]/par0[i]/64.);
+ }
+ v0CorrResc = multCorr2;
+ return multCorr;
+}
+
+//_________________________________________________________________
+Bool_t AliTaskGlobVar::ZDCTimeTrigger(const AliESDEvent *aEsd) const
+{
+ // This method implements a selection
+ // based on the timing in both sides of zdcN
+ // It can be used in order to eliminate
+ // parasitic collisions
+ Bool_t zdcAccept = kFALSE;
+
+ AliESDZDC *esdZDC = aEsd->GetESDZDC();
+
+ const Float_t refSum = -568.5;
+ const Float_t refDelta = -2.1;
+ const Float_t sigmaSum = 3.25;
+ const Float_t sigmaDelta = 2.25;
+ for(Int_t i = 0; i < 4; ++i) {
+ if (esdZDC->GetZDCTDCData(10,i) != 0) {
+ Float_t tdcC = 0.025*(esdZDC->GetZDCTDCData(10,i)-esdZDC->GetZDCTDCData(14,i));
+ for(Int_t j = 0; j < 4; ++j) {
+ if (esdZDC->GetZDCTDCData(12,j) != 0) {
+ Float_t tdcA = 0.025*(esdZDC->GetZDCTDCData(12,j)-esdZDC->GetZDCTDCData(14,j));
+ if (((tdcC-tdcA-refDelta)*(tdcC-tdcA-refDelta)/(sigmaDelta*sigmaDelta) +
+ (tdcC+tdcA-refSum)*(tdcC+tdcA-refSum)/(sigmaSum*sigmaSum))< 1.0)
+ zdcAccept = kTRUE;
+ }
+ }
+ }
+ }
+ return zdcAccept;
+}
+
+
+AliESDtrackCuts* AliTaskGlobVar::CreatedNdPtTrackCuts(Int_t cutMode, Bool_t fieldOn)
+{
+ // copy of PWG0/dNdPt/macros/CreatedNdPtTrackCuts.C
+ //
+ AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts");
+
+
+ Double_t cov1, cov2, cov3, cov4, cov5;
+ Double_t nSigma;
+ Double_t maxDCAtoVertex, maxDCAtoVertexXY, maxDCAtoVertexZ;
+ Int_t minNClustersTPC;
+ Double_t maxChi2PerClusterTPC;
+ Double_t minPt, maxPt;
+ TString tag;
+
+ // default cuts for ITS+TPC
+ if (cutMode == 0)
+ {
+ cov1 = 2;
+ cov2 = 2;
+ cov3 = 0.5;
+ cov4 = 0.5;
+ cov5 = 2;
+ nSigma = 3;
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 3.5;
+
+ esdTrackCuts->SetMaxCovDiagonalElements(cov1, cov2, cov3, cov4, cov5);
+ // esdTrackCuts->SetMinNsigmaToVertex(nSigma);
+ esdTrackCuts->SetRequireSigmaToVertex(kTRUE);
+ esdTrackCuts->SetRequireTPCRefit(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "Global tracking";
+ }
+
+ // TPC-only cuts (vertex n sigma cut)
+ if (cutMode == 1)
+ {
+ // beta cuts (still under investigation)
+ //cov1 = 4;
+ //cov2 = 4;
+ cov1 = 2;
+ cov2 = 2;
+ cov3 = 0.5;
+ cov4 = 0.5;
+ cov5 = 2;
+ nSigma = 4;
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 3.5;
+
+ esdTrackCuts->SetMaxCovDiagonalElements(cov1, cov2, cov3, cov4, cov5);
+ // esdTrackCuts->SetMinNsigmaToVertex(nSigma);
+ esdTrackCuts->SetRequireSigmaToVertex(kTRUE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only cuts (vertex maxDCAtoVertex cut)
+ if (cutMode == 2)
+ {
+ // beta cuts (still under investigation)
+ maxDCAtoVertex = 3.0; // cm
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 3.5;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertex);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertex);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only no vertex cuts
+ if (cutMode == 3)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 3.5;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only no cuts at all
+ if (cutMode == 4)
+ {
+
+ // beta cuts (still under investigation)
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only no kink removal no chi2
+ if (cutMode == 5)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ //maxChi2PerClusterTPC = 3.5;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ //esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only no kink removal
+ if (cutMode == 6)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 3.5;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only no kink removal no minNClustersTPC
+ if (cutMode == 7)
+ {
+ // beta cuts (still under investigation)
+ //minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 3.5;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ //esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "TPC-only tracking";
+ }
+ // TPC-only no kink removal no minNClustersTPC
+ if (cutMode == 8)
+ {
+ // beta cuts (still under investigation)
+ //minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 3.5;
+ maxDCAtoVertex = 3.0; // cm
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertex);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertex);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ //esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only no kink removal no minNClustersTPC no maxChi2PerClusterTPC
+ if (cutMode == 9)
+ {
+ // beta cuts (still under investigation)
+ //minNClustersTPC = 50;
+ //maxChi2PerClusterTPC = 3.5;
+ maxDCAtoVertex = 3.0; // cm
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertex);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertex);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ //esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ //esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (loose cuts, absolute DCA cut)
+ if (cutMode == 10)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertex = 2.8; // cm
+ minPt=0.15;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertex);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertex);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+
+ // TPC-only (loose cuts, no DCA cut)
+ if (cutMode == 11)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 1.e10; // cm
+ maxDCAtoVertexZ = 1.e10; // cm
+ minPt=0.15;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (standard cuts, no DCA cut)
+ if (cutMode == 12)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 96;
+ maxChi2PerClusterTPC = 3.5;
+ maxDCAtoVertexXY = 1.e10; // cm
+ maxDCAtoVertexZ = 1.e10; // cm
+ minPt=0.2;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (tight cuts, no DCA cut)
+ if (cutMode == 13)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 120;
+ maxChi2PerClusterTPC = 3.5;
+ maxDCAtoVertexXY = 1.e10; // cm
+ maxDCAtoVertexZ = 1.e10; // cm
+ minPt=0.3;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (loose cuts, no pt cut)
+ if (cutMode == 14)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 1.e10; // cm
+ maxDCAtoVertexZ = 1.e10; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (standard cuts, no pt cut)
+ if (cutMode == 15)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 96;
+ maxChi2PerClusterTPC = 3.5;
+ maxDCAtoVertexXY = 1.e10; // cm
+ maxDCAtoVertexZ = 1.e10; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (tight cuts, no pt cuts)
+ if (cutMode == 16)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 120;
+ maxChi2PerClusterTPC = 3.5;
+ maxDCAtoVertexXY = 1.e10; // cm
+ maxDCAtoVertexZ = 1.e10; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+ // TPC-only (loose cuts)
+ if (cutMode == 17)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ //maxDCAtoVertexXY = 2.4; // cm
+ //maxDCAtoVertexZ = 3.2; // cm
+ maxDCAtoVertexXY = 1.6; // cm
+ maxDCAtoVertexZ = 2.1; // cm
+ minPt=0.15;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (standard cuts)
+ if (cutMode == 18)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 96;
+ maxChi2PerClusterTPC = 3.5;
+ //maxDCAtoVertexXY = 2.4; // cm
+ //maxDCAtoVertexZ = 3.2; // cm
+ maxDCAtoVertexXY = 1.4; // cm
+ maxDCAtoVertexZ = 1.8; // cm
+ minPt=0.2;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (tight cuts)
+ if (cutMode == 19)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 120;
+ maxChi2PerClusterTPC = 3.0;
+ //maxDCAtoVertexXY = 2.4; // cm
+ //maxDCAtoVertexZ = 3.2; // cm
+ maxDCAtoVertexXY = 1.4; // cm
+ maxDCAtoVertexZ = 1.8; // cm
+ minPt=0.3;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (arb. cuts, kink cuts included)
+ if (cutMode == 20)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 1.e10;
+ maxDCAtoVertexXY = 3.0; // cm
+ maxDCAtoVertexZ = 3.0; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (arb. cuts, kink cuts excluded)
+ if (cutMode == 21)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 1.e10;
+ maxDCAtoVertexXY = 3.0; // cm
+ maxDCAtoVertexZ = 3.0; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (arb. cuts, kink cuts excluded, no chi2, no DCA)
+ if (cutMode == 22)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 1.e10;
+ maxDCAtoVertexXY = 1.e10; // cm
+ maxDCAtoVertexZ = 1.e10; // cm
+ minPt=0.15;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only
+ if (cutMode == 23)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 70;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetRequireITSRefit(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ //esdTrackCuts->SetPtRange(minPt,maxPt);
+ //esdTrackCuts->SetEtaRange(minEta,maxEta);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only (no pt cut, no eta cut)
+ if (cutMode == 24)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ //
+ // systematic errors DCA cut studies
+ //
+ // TPC-only
+ if (cutMode == 25)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 1.4; // cm
+ maxDCAtoVertexZ = 2.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 26)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 1.6; // cm
+ maxDCAtoVertexZ = 2.4; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ //
+ // systematic errors cut studies
+ //
+ // TPC-only
+ if (cutMode == 27)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 1.8; // cm
+ maxDCAtoVertexZ = 2.6; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 28)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.0; // cm
+ maxDCAtoVertexZ = 2.8; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 29)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.2; // cm
+ maxDCAtoVertexZ = 3.0; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 30)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 31)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.6; // cm
+ maxDCAtoVertexZ = 3.4; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+
+ if (cutMode == 32)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.8; // cm
+ maxDCAtoVertexZ = 3.6; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 33)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 3.0; // cm
+ maxDCAtoVertexZ = 3.8; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 34)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 3.2; // cm
+ maxDCAtoVertexZ = 4.0; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 35)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 3.4; // cm
+ maxDCAtoVertexZ = 4.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+//
+// cut stability systematics
+//
+
+ if (cutMode == 36)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 70;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 37)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 90;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 38)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 3.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 39)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 5.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 40)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 1.4; // cm
+ maxDCAtoVertexZ = 2.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 41)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 3.4; // cm
+ maxDCAtoVertexZ = 4.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+
+ if (cutMode == 42)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+ minPt=0.0;
+ maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ //esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ esdTrackCuts->SetPtRange(minPt,maxPt);
+
+ tag = "TPC-only tracking";
+ }
+ // test
+ if (cutMode == 43)
+ {
+ // beta cuts (still under investigation)
+ minNClustersTPC = 50;
+ maxChi2PerClusterTPC = 4.0;
+ //maxDCAtoVertexXY = 2.4; // cm
+ //maxDCAtoVertexZ = 3.2; // cm
+ //minPt=0.15;
+ //maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ //esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ //esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ //esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ //esdTrackCuts->SetPtRange(minPt,maxPt);
+ //esdTrackCuts->SetEtaRange(minEta,maxEta);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-only + pt cut + eta cut
+ if (cutMode == 45)
+ {
+ // beta cuts (still under investigation)
+ //minNClustersTPC = 50;
+ //maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 2.4; // cm
+ maxDCAtoVertexZ = 3.2; // cm
+ //minPt=0.15;
+ //maxPt=1.e10;
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ //esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ //esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+ //esdTrackCuts->SetPtRange(minPt,maxPt);
+ //esdTrackCuts->SetEtaRange(minEta,maxEta);
+
+ tag = "TPC-only tracking";
+ }
+
+ // TPC-tracks + SPD point + ITS refit
+ if (cutMode == 50)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ //Double_t maxEtaInAcc=0.8;
+ Double_t maxdcaxyITSTPC=0.2;
+ Double_t maxdcazITSTPC=1.e9;
+
+ esdTrackCuts->SetMaxDCAToVertexXY(maxdcaxyITSTPC);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //esdTrackCuts->SetEtaRange(-maxEtaInAcc,maxEtaInAcc);
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster";
+ }
+
+ // TPC-tracks + SPD point + ITS refit
+ if (cutMode == 60)
+ {
+ Int_t minclsITS=4;
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcaxyITSTPC=0.2;
+ Double_t maxdcazITSTPC=1.e9;
+
+ esdTrackCuts->SetMaxDCAToVertexXY(maxdcaxyITSTPC);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetMinNClustersITS(minclsITS);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetRequireTPCRefit(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+
+ tag = "Global tracking: TPC refit + ITS refit + >3 ITS clusters + >=1 SPD cluster";
+ }
+
+ /*
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt)
+ if (cutMode == 70)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcaxyITSTPC=1.e9;
+ Double_t maxdcazITSTPC=1.e9;
+
+ esdTrackCuts->SetMaxDCAToVertexXY(maxdcaxyITSTPC);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt)";
+ }
+ */
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt)
+ if (cutMode == 70)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt)";
+ }
+
+ // TPC+ITS combine tracking + DCAr(pt) + DCAz(pt)
+ if (cutMode == 71)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCRefit(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // DCArphi parametrization (LHC10c pass2)
+ // 7*(0.0026+0.0050/pt^1.01)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
+
+ // DCArphi parametrization (LHC10c pass2)
+ // 7*(0.01+0.011/pt^0.72)
+ esdTrackCuts->SetMaxDCAToVertexZPtDep("0.07+0.077/pt^0.72");
+
+ tag = "TPC+ITS combine tracking + DCAr(pt) + DCAz(pt)";
+ }
+
+ // TPC+ITS combine tracking + DCAr(pt) (2010)
+ if (cutMode == 72)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=2.0;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCRefit(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // DCArphi parametrization (LHC10c pass2)
+ // 7*(0.0026+0.0050/pt^1.01)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
+
+ tag = "TPC+ITS combine tracking + DCAr(pt) (2010)";
+ }
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) 4-sigma
+ if (cutMode == 75)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 4*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.02+0.024/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) 4-sigma";
+ }
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) 10-sigma
+ if (cutMode == 80)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 10*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.05+0.06/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) 10 sigma";
+ }
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 60 TPCclust
+ if (cutMode == 85)
+ {
+ Int_t minclsTPC=60;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 60 TPCclust";
+ }
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 80 clusters
+ if (cutMode == 90)
+ {
+ Int_t minclsTPC=80;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 80 TPCclust";
+ }
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) + TPCchi2=3.5
+ if (cutMode == 95)
+ {
+ Int_t minclsTPC=80;
+ Double_t maxchi2perTPCcl=3.5;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + TPCchi2 3.5";
+ }
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) + TPCchi2=4.5
+ if (cutMode == 100)
+ {
+ Int_t minclsTPC=80;
+ Double_t maxchi2perTPCcl=4.5;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + TPCchi2 4.5";
+ }
+
+ // TPC-tracks
+ if (cutMode == 110)
+ {
+
+ minNClustersTPC = 70;
+ maxChi2PerClusterTPC = 4.0;
+ maxDCAtoVertexXY = 1.e9; // cm
+ maxDCAtoVertexZ = 1.e9; // cm
+
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+ esdTrackCuts->SetDCAToVertex2D(kTRUE);
+
+ tag = "TPC-tracks loose criteria";
+ }
+
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 50 TPCclust
+ if (cutMode == 120)
+ {
+ Int_t minclsTPC=50;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 60 TPCclust";
+ }
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 70 TPCclust + accept kink daughters
+ if (cutMode == 130)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 60 TPCclust";
+ }
+
+ // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 30 TPCclust + accept kink daughters
+ if (cutMode == 140)
+ {
+ Int_t minclsTPC=30;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=1.e9;
+
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 60 TPCclust";
+ }
+
+ // Adam Kisiel track selectiion
+ if (cutMode == 150)
+ {
+ Int_t minclsTPC=70;
+ Double_t maxchi2perTPCcl=4.;
+ Double_t maxdcazITSTPC=0.25;
+ Double_t maxdcaxyITSTPC=0.2;
+
+ //
+ // TPC
+ //
+ //esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+ esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+ // primary selection
+ //
+ //esdTrackCuts->SetDCAToVertex2D(kFALSE);
+ esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+ esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+ esdTrackCuts->SetMaxDCAToVertexXY(maxdcaxyITSTPC);
+
+ // 7*(0.0050+0.0060/pt^0.9)
+ //esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+ tag = "Adam Kisiel track selection";
+ }
+
+ // TPC+ITS refit
+ // for cut studies
+ if (cutMode == 151)
+ {
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCRefit(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ //
+ // ITS
+ //
+ esdTrackCuts->SetRequireITSRefit(kTRUE);
+ esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+
+ tag = "TPC+ITS refit required - for cut studies";
+ }
+
+ // TPC+ITS
+ // for cut studies
+ if (cutMode == 152)
+ {
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCRefit(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ //
+ // ITS
+ //
+ //esdTrackCuts->SetRequireITSRefit(kTRUE);
+ //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+
+ tag = "TPC refit required - for cut studies";
+ }
+
+ // TPC
+ // for cut studies
+ if (cutMode == 153)
+ {
+ //
+ // TPC
+ //
+ esdTrackCuts->SetRequireTPCRefit(kFALSE);
+ esdTrackCuts->SetRequireITSRefit(kFALSE);
+ esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+ esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+ //
+ // ITS
+ //
+ //esdTrackCuts->SetRequireITSRefit(kTRUE);
+ //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+ //
+
+ tag = "TPC stand alone - for cut studies";
+ }
+
+
+
+
+
+
+ // cuts for data without field
+ if (!fieldOn)
+ {
+ cov5 = 1e10;
+ tag += " without field";
+ }
+
+ Printf("Created track cuts for: %s", tag.Data());
+
+ return esdTrackCuts;
+}
--- /dev/null
+#ifndef ALIGLOBVAR_H
+#define ALIGLOBVAR_H
+
+///////////////////////////////////////////////////////////////////////////
+// Analysis task to extract global variables to the tree //
+///////////////////////////////////////////////////////////////////////////
+
+class AliESDEvent;
+class TList;
+class AliESDtrackCuts;
+#include "AliAnalysisTaskSE.h"
+#include "AliTriggerAnalysis.h"
+
+class AliTaskGlobVar : public AliAnalysisTaskSE {
+ //
+ public:
+ AliTaskGlobVar(const char *name = "AliTaskGlobVar");
+ virtual ~AliTaskGlobVar();
+ virtual void UserCreateOutputObjects();
+ virtual void UserExec(Option_t *option);
+ virtual void Terminate(Option_t *);
+ //
+ void SetUseMC(Bool_t mc=kTRUE) {fUseMC = mc;}
+ Float_t GetCorrV0(const AliESDEvent* esd, float &v0CorrResc) const;
+ Bool_t ZDCTimeTrigger(const AliESDEvent *aEsd) const;
+ AliESDtrackCuts* CreatedNdPtTrackCuts(Int_t cutMode, Bool_t fieldOn=kTRUE);
+ //
+ protected:
+ Bool_t fUseMC; // do we use MC info
+ TList* fOutput; // output list send on output slot 1
+ //
+ TTree* fOutTree; // output tree
+ AliESDtrackCuts* fTrackCuts; //! optional track cuts
+ AliESDtrackCuts* fTrackCuts1; //! optional track cuts
+ //
+ private:
+ AliTaskGlobVar(const AliTaskGlobVar&); // not implemented
+ AliTaskGlobVar& operator=(const AliTaskGlobVar&); // not implemented
+
+ ClassDef(AliTaskGlobVar, 1);
+};
+
+
+typedef struct {
+ enum {kTDCNA=0x1,kTDCPA=0x1<<1,kTDCNC=0x1<<2,kTDCPC=0x1<<3,kSPDVTXOK=0x1<<4};
+ Int_t runID;
+ UInt_t timeStamp;
+ Float_t zdcNA;
+ Float_t zdcPA;
+ Float_t zdcNC;
+ Float_t zdcPC;
+ Float_t zem1;
+ Float_t zem2;
+ //
+ Float_t zvSPD;
+ Float_t zvTPC;
+ Short_t chunk;
+ Short_t flags;
+ Short_t spd1;
+ Short_t spd2;
+ Short_t ncontSPDV;
+ Short_t ncontTPCV;
+ Short_t nTrTPC;
+ Short_t nTrTPCITS;
+ Short_t nTracklets;
+ Short_t v0A;
+ Short_t v0C;
+ Short_t v0Corr;
+ // Short_t v0CorrResc;
+ Float_t mcZV;
+ Short_t mcdNdEta;
+ Short_t mcNPart;
+ Short_t mcNBColl;
+} GloVars_t;
+
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2008, 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. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Class AliTrackletTaskMulti //
+// Analysis task to produce data and MC histos needed for tracklets //
+// dNdEta extraction in multiple bins in one go //
+// Author: ruben.shahoyan@cern.ch //
+///////////////////////////////////////////////////////////////////////////
+/*
+ Important parameters to set:
+ 1) make sure to initialize correct geometry in UserCreateOutputObjects
+ 2) The cut on signal selection variable (delta, dphi ...) should be decided beforehand
+...
+*/
+
+#include "TChain.h"
+#include "TTree.h"
+#include "TRandom.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "TH3F.h"
+#include "THnSparse.h"
+#include "TList.h"
+#include "TNtuple.h"
+#include "TObjArray.h"
+#include "TGeoGlobalMagField.h"
+
+#include "AliAnalysisManager.h"
+
+#include "AliMultiplicity.h"
+#include "AliESDEvent.h"
+#include "AliESDInputHandler.h"
+#include "AliESDInputHandlerRP.h"
+#include "../ANALYSIS/EventMixing/AliMixEventInputHandler.h"
+#include "AliCDBPath.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliCDBStorage.h"
+#include "AliGeomManager.h"
+#include "AliMagF.h"
+#include "AliESDVZERO.h"
+#include "AliESDZDC.h"
+#include "AliRunLoader.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliMCParticle.h"
+#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "../ITS/AliITSRecPoint.h"
+#include "../ITS/AliITSgeomTGeo.h"
+#include "../ITS/AliITSMultReconstructor.h"
+
+#include "AliLog.h"
+
+#include "AliPhysicsSelection.h"
+#include "AliESDCentrality.h"
+#include "AliTrackletTaskMulti.h"
+#include "AliITSMultRecBg.h"
+#include "AliGenEventHeader.h"
+#include "AliGenHijingEventHeader.h"
+#include "AliGenDPMjetEventHeader.h"
+#include "AliESDtrackCuts.h"
+
+ClassImp(AliTrackletTaskMulti)
+
+// centrality definition with SPD2corr
+const Float_t AliTrackletTaskMulti::fgkCentBinDefSPD2[] =
+{0,21,69,165,345,637,1069,1683,2511,3721,4585,6500}; // Alberica 2010-11-21 at 22:17
+//corresponding npart: {379.973,328.414,259.244,185.094,128.309,84.9333,52.7138,29.9245,15.3195,6.98915,3.16337};
+
+// special test with splitting upper 10% to 4 equidistant bins
+// {3721,4125,4584,5102,6500};
+
+
+// {0,29,85,191,385,687,1133,1743,2567,3765,4611,6500}; // before 21/11/10
+//corresponding npart: {3.14467,6.876,15.0519,29.0842,52.7315,84.8281,128.265,185.004,259.304,328.651,379.393};
+
+
+// centrality definition with V0 Rescaled
+const Float_t AliTrackletTaskMulti::fgkCentBinDefV0CR[] =
+{0,32.5,89.5,198.5,396.5,700.5,1140.5,1744.5,2562.5,3767.5,4647.5,6500.};
+// on V0 corrected and rescaled
+// corresponding npart: {3.23659,7.28226,15.9883,31.4739,54.7531,87.0497,130.454,185.996,260.318,329.655,379.114}
+
+
+const Float_t AliTrackletTaskMulti::fgkCentBinDefV0[] =
+ {12191,13529,15079,16815,21000}; // special test with splitting upper 10% to 4 equidistant bins for new baseline with ZDC timing cleanup, 11/29/2010 01:10:37 PM
+
+// {0,79,239,559,1165,2135,3555,5525,8213,12191,15079,21000}; // new baseline with ZDC timing cleanup, 11/29/2010 01:10:37 PM
+
+ // {12165,13527,15079,16801,21000}; // special test with splitting upper 10% to 4 equidistant bins for Alberica 2010-11-21 at 22:17
+// {0,79,247,577,1185,2155,3565,5527,8203,12167,15073,21000}; // Alberica 2010-11-21 at 22:17
+// corresponding npart: {379.112,323.171,253.417,183.054,129.116,86.9088,54.2474,30.2884,15.1553,6.7094,2.95315}
+
+// {0,107,297,659,1305,2301,3747,5715,8361,12307,15153,21000}; // before 21/11/10 on V0 corrected for non-linearity
+// corresponding npart: {2.93958,6.67109,15.0721,29.7634,52.6495,84.8531,128.160,185.197,259.314,328.781,381.040};
+
+//{0,105,291,644,1280,2269,3728,5704,8366,12111,14706,19540}; // after 18/11/10, V0 not corrected
+//{0,124.5,274.5,574.5,1224.5,2174.5,3624.5,5574.5,8274.5,12024.5,14674.5,20000}; // before 18/11/10
+
+
+// centrality selection with TPC tracls only
+const Float_t AliTrackletTaskMulti::fgkCentBinDefTrTPC[] =
+ {0,13,37,85,171,307,507,783,1157,1685,2055,2900};
+//corresponding npart: {3.22604,6.98597,15.1032,29.7764,52.6338,84.7075,128.221,185.129,259.17,329.234,378.667};
+
+//------------------------- 2D boundaries ---------------------------------------
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0X[] =
+ {0.,150.0,310.0,610.0,1190.0,2170.0,3570.0,5530.0,8210.0,12150.0,15070.0,21000.};
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0Y[] =
+ {0.0,1224.6,1999.4,2665.2,3106.0,3312.4,3343.0,3238.1,2758.1,1697.8,978.7,0.00};
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0S[] =
+ {-1.,-0.1225,-0.3001,-0.9252,-2.0376,-10.1909,62.0849,9.1496,4.1895,3.6557,4.7364,1.};
+
+/*
+// 80% of ZDC&V0 set to 247 as 80% of 1D V0
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0X[] =
+ {0.,130.,247.,490.,1010.0,1950.,3310.,5270.,7930.,11930.,14930.,21000.};
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0Y[] =
+ {0.00,1061.35,1732.80,2459.06,3017.64,3288.97,3346.46,3264.99,2822.64,1758.14,1008.61,0.00};
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0S[] =
+ {-1.,0.1225,-0.3001,-0.5631,-2.0376,-7.3697,125.8992,10.2539,4.4412,3.6288,4.6181,1.};
+*/
+
+const Float_t *fkCentBinDef = 0;
+const Float_t *fkCentBinDef2DY = 0;
+const Float_t *fkCentBinDef2DS = 0;
+
+const char* AliTrackletTaskMulti::fgkPDGNames[] = {
+"#pi^{+}",
+"p",
+"K^{+}",
+"K^{*+}",
+"e^{-}",
+"#mu^{-}",
+"#rho^{+}",
+"D^{+}",
+"D^{*+}",
+"D_{s}^{+}",
+"D_{s}^{*+}",
+"#Delta^{-}",
+"#Delta^{+}",
+"#Delta^{++}",
+"#Sigma^{-}",
+"#Sigma^{+}",
+"#Sigma^{*-}",
+"#Sigma^{*+}",
+"#Sigma^{*+}_{c}",
+"#Sigma^{*++}_{c}",
+"#Xi^{-}",
+"#Xi^{*-}",
+"#Lambda^{+}_{c}",
+"n",
+"#Delta^{0}",
+"#gamma",
+"K^{0}_{S}",
+"K^{0}_{L}",
+"K^{0}",
+"K^{*}",
+"#eta",
+"#pi^{0}",
+"#rho^{0}",
+"#varphi",
+"#eta'",
+"#omega",
+"#Lambda",
+"#Sigma^{0}",
+"#Sigma^{*0}_{c}",
+"#Sigma^{*0}",
+"D^{0}",
+"D^{*0}",
+"#Xi_{0}",
+"#Xi^{*0}",
+"#Xi^{0}_{c}",
+"#Xi^{*0}_{c}",
+"Nuclei",
+"Others"
+};
+
+const int AliTrackletTaskMulti::fgkPDGCodes[] = {
+ 211,
+ 2212,
+ 321,
+ 323,
+ 11,
+ 13,
+ 213,
+ 411,
+ 413,
+ 431,
+ 433,
+ 1114,
+ 2214,
+ 2224,
+ 3112,
+ 3222,
+ 3114,
+ 3224,
+ 4214,
+ 4224,
+ 3312,
+ 3314,
+ 4122,
+ 2112,
+ 2114,
+ 22,
+ 310,
+ 130,
+ 311,
+ 313,
+ 221,
+ 111,
+ 113,
+ 333,
+ 331,
+ 223,
+ 3122,
+ 3212,
+ 4114,
+ 3214,
+ 421,
+ 423,
+ 3322,
+ 3324,
+ 4132,
+ 4314
+// nuclei
+// unknown
+};
+
+//________________________________________________________________________
+/*//Default constructor
+AliTrackletTaskMulti::AliTrackletTaskMulti(const char *name)
+ : AliAnalysisTaskSE(name),
+*/
+//________________________________________________________________________
+AliTrackletTaskMulti::AliTrackletTaskMulti(const char *name)
+ : AliAnalysisTaskSE(name),
+//
+ fOutput(0),
+//
+ fDoNormalReco(kFALSE),
+ fDoInjection(kFALSE),
+ fDoRotation(kFALSE),
+ fDoMixing(kFALSE),
+ //
+ fUseMC(kFALSE),
+ fCheckReconstructables(kFALSE),
+//
+ fHistosTrData(0),
+ fHistosTrInj(0),
+ fHistosTrRot(0),
+ fHistosTrMix(0),
+//
+ fHistosTrPrim(0),
+ fHistosTrSec(0),
+ fHistosTrComb(0),
+ fHistosTrCombU(0),
+//
+ fHistosTrRcblPrim(0),
+ fHistosTrRcblSec(0),
+ fHistosCustom(0),
+//
+ fEtaCut(3.0),
+ fZVertexMin(-20),
+ fZVertexMax( 20),
+//
+ fScaleDTBySin2T(kFALSE),
+ fCutOnDThetaX(kFALSE),
+ fNStdDev(1.),
+ fDPhiWindow(0.08),
+ fDThetaWindow(0.025),
+ fDPhiShift(0.0045),
+ fPhiOverlapCut(0.005),
+ fZetaOverlap(0.05),
+ fPhiRot(0.),
+ fInjScale(1.),
+ fRemoveOverlaps(kFALSE),
+//
+ fDPhiSCut(0.06),
+ fNStdCut(1.),
+ fMCV0Scale(0.7520),
+//
+ fMultReco(0),
+ fRPTree(0),
+ fRPTreeMix(0),
+ fStack(0),
+ fMCEvent(0),
+ fTrackCuts(0),
+ //
+ fNPart(0),
+ fNBColl(0),
+ fCurrCentBin(-1),
+ fNCentBins(0),
+ fUseCentralityVar(kCentV0)
+ /*
+ ,
+ fTrigger(AliTriggerAnalysis::kAcceptAll),
+ fMCCentralityBin(AliAnalysisTaskSPDdNdEta::kall),
+ fCentrLowLim(0),
+ fCentrUpLim(0),
+ fCentrEst("")
+ */
+{
+ // Constructor
+
+ DefineOutput(1, TList::Class());
+ //
+ SetScaleDThetaBySin2T();
+ SetNStdDev();
+ SetPhiWindow();
+ SetThetaWindow();
+ SetPhiShift();
+ SetPhiOverlapCut();
+ SetZetaOverlapCut();
+ SetPhiRot();
+ SetRemoveOverlaps();
+ //
+}
+
+//________________________________________________________________________
+AliTrackletTaskMulti::~AliTrackletTaskMulti()
+{
+ // Destructor
+ // histograms are in the output list and deleted when the output
+ // list is deleted by the TSelector dtor
+ if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) { //RRR
+ printf("Deleteing output\n");
+ delete fOutput;
+ fOutput = 0;
+ }
+ //
+ delete fMultReco;
+ delete fTrackCuts;
+ //
+ delete fHistosTrData;
+ delete fHistosTrPrim;
+ delete fHistosTrSec;
+ delete fHistosTrComb;
+ delete fHistosTrCombU;
+ delete fHistosTrInj;
+ delete fHistosTrRot;
+ delete fHistosTrMix;
+ delete fHistosTrRcblPrim;
+ delete fHistosTrRcblSec;
+ delete fHistosCustom;
+ //
+}
+
+//________________________________________________________________________
+void AliTrackletTaskMulti::UserCreateOutputObjects()
+{
+ //
+ fOutput = new TList();
+ fOutput->SetOwner();
+ //
+ if (fUseCentralityVar == kCentV0) {
+ fNCentBins = sizeof(fgkCentBinDefV0)/sizeof(Float_t) - 1;
+ fkCentBinDef = fgkCentBinDefV0;
+ }
+ else if (fUseCentralityVar == kCentV0CR) {
+ fNCentBins = sizeof(fgkCentBinDefV0CR)/sizeof(Float_t) - 1;
+ fkCentBinDef = fgkCentBinDefV0CR;
+ }
+ else if (fUseCentralityVar == kCentSPD2) {
+ fNCentBins = sizeof(fgkCentBinDefSPD2)/sizeof(Float_t) - 1;
+ fkCentBinDef = fgkCentBinDefSPD2;
+ }
+ else if (fUseCentralityVar == kCentTrTPC) {
+ fNCentBins = sizeof(fgkCentBinDefTrTPC)/sizeof(Float_t) - 1;
+ fkCentBinDef = fgkCentBinDefTrTPC;
+ }
+ else if (fUseCentralityVar == kCentZDCV0) {
+ fNCentBins = sizeof(fgkCentBinDefZDCV0X)/sizeof(Float_t) - 1;
+ fkCentBinDef = fgkCentBinDefZDCV0X;
+ fkCentBinDef2DY = fgkCentBinDefZDCV0Y;
+ fkCentBinDef2DS = fgkCentBinDefZDCV0S;
+ }
+ else {
+ AliFatal(Form("Unknown cenrality parameter %d",fUseCentralityVar));
+ }
+ //
+ AliCDBManager *man = AliCDBManager::Instance();
+ if (fUseMC) {
+ Bool_t newGeom = kTRUE;
+ man->SetDefaultStorage("alien://Folder=/alice/simulation/2008/v4-15-Release/Residual");
+ if (newGeom) {
+ // new geom
+ AliCDBEntry* obj = man->Get("GRP/Geometry/Data",130844,8);
+ AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+ if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",130844,6,-1)) AliFatal("Failed to misalign geometry");
+ }
+ else {
+ // old geom
+ AliCDBEntry* obj = man->Get("GRP/Geometry/Data",130845,7);
+ AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+ if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",130845,5,-1)) AliFatal("Failed to misalign geometry");
+ }
+ }
+ else {
+ man->SetDefaultStorage("raw://"); man->SetRun(137045);
+ AliCDBEntry* obj = man->Get("GRP/Geometry/Data",137045,3);
+ AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+ if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",137045,8,-1)) AliFatal("Failed to misalign geometry");
+ }
+ //
+ fTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+ //
+ // Create histograms
+ //---------------------------------------------Standard histos per tracklet type--->>
+ UInt_t hPattern = 0xffffffff;
+ fHistosTrData = BookHistosSet("TrData",hPattern);
+ if (GetDoInjection()) fHistosTrInj = BookHistosSet("TrInj",hPattern);
+ if (GetDoRotation()) fHistosTrRot = BookHistosSet("TrRot",hPattern);
+ if (GetDoMixing()) fHistosTrMix = BookHistosSet("TrMix",hPattern);
+ if (fUseMC) {
+ fHistosTrPrim = BookHistosSet("TrPrim",hPattern);
+ fHistosTrSec = BookHistosSet("TrSec",hPattern);
+ fHistosTrComb = BookHistosSet("TrComb",hPattern);
+ fHistosTrCombU = BookHistosSet("TrCombU",hPattern);
+ if (fCheckReconstructables) {
+ fHistosTrRcblPrim = BookHistosSet("TrRcblPrim",hPattern);
+ fHistosTrRcblSec = BookHistosSet("TrRcblSec",hPattern);
+ }
+ }
+ //---------------------------------------------Standard histos per tracklet type---<<
+ //
+ //---------------------------------------------Custom Histos----------------------->>
+ // put here any non standard histos
+ fHistosCustom = BookCustomHistos();
+ //
+ //---------------------------------------------Custom Histos-----------------------<<
+ int nhist = fOutput->GetEntries();
+ for (int i=0;i<nhist;i++) {
+ TObject* hst = fOutput->At(i);
+ if (!hst || !(hst->InheritsFrom(TH1::Class()))) continue;
+ ((TH1*)hst)->Sumw2();
+ }
+ //
+ PostData(1, fOutput);
+ //
+}
+
+//________________________________________________________________________
+void AliTrackletTaskMulti::UserExec(Option_t *)
+{
+ // Main loop
+ //
+ AliAnalysisManager* anMan = AliAnalysisManager::GetAnalysisManager();
+ fRPTree = fRPTreeMix = 0;
+ AliESDInputHandlerRP *handRP = (AliESDInputHandlerRP*)anMan->GetInputEventHandler();
+ if (!handRP) { printf("No RP handler\n"); return; }
+ AliESDEvent *esd = handRP->GetEvent();
+ if (!esd) { printf("No AliESDEvent\n"); return; }
+ //
+ // do we need to initialize the field?
+ AliMagF* field = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
+ if (!field && !esd->InitMagneticField()) {printf("Failed to initialize the B field\n");return;}
+ //
+ /* // RS to be clarified
+ // Trigger selection
+ static AliTriggerAnalysis* triggerAnalysis = 0;
+ Bool_t eventTriggered = triggerAnalysis->IsTriggerFired(esd, fTrigger);
+ if (!eventTriggered) {printf("No trigger\n"); return;}
+ //
+ // Centrality selection
+ Bool_t eventInCentralityBin = kFALSE;
+ // Centrality selection
+ AliESDCentrality *centrality = esd->GetCentrality();
+ if (fCentrEst=="") eventInCentralityBin = kTRUE;
+ else {
+ if(!centrality) {
+ AliError("Centrality object not available");
+ } else {
+ if (centrality->IsEventInCentralityClass(fCentrLowLim,fCentrUpLim,fCentrEst.Data())) eventInCentralityBin = kTRUE;
+ }
+ }
+ */
+ // if (!fUseMC && !ZDCTimeTrigger(esd)) return;
+ //
+ const AliESDVertex* vtxESD = esd->GetPrimaryVertexSPD();
+ if (vtxESD->GetNContributors()<1) return;
+ if (vtxESD->GetDispersion()>0.04) return;
+ if (vtxESD->GetZRes()>0.25) return;
+ const AliMultiplicity* multESD = esd->GetMultiplicity();
+ const AliESDVertex* vtxESDTPC = esd->GetPrimaryVertexTPC();
+ float nSPD1 = multESD->GetNumberOfITSClusters(0);
+ float nSPD2 = multESD->GetNumberOfITSClusters(1);
+ //
+ /*
+ if (vtxESDTPC->GetNContributors()<1 ||
+ vtxESDTPC->GetNContributors()<(-10.+0.25*nSPD1)) return;
+ */
+ //
+ TH1* hstat = (TH1*)fHistosCustom->UncheckedAt(kHStat);
+ //
+ hstat->Fill(kEvTot); // RS
+ //
+ Double_t esdvtx[3];
+ vtxESD->GetXYZ(esdvtx);
+ for (int i=3;i--;) fESDVtx[i] = esdvtx[i];
+ //
+ float vtxf[3] = {vtxESD->GetX(),vtxESD->GetY(),vtxESD->GetZ()};
+ //
+ //------------------------------------------------------
+ // ZDC cut
+ AliESDZDC *esdZDC = esd->GetESDZDC();
+ // --- ZDC offline trigger ---
+ // Returns if ZDC triggered, based on TDC information
+ Bool_t tdc[32] = {kFALSE};
+ for(Int_t itdc=0; itdc<32; itdc++){
+ for(Int_t i=0; i<4; i++){
+ if (0.025*esdZDC->GetZDCTDCData(itdc, i) != 0){
+ tdc[itdc] = kTRUE;
+ }
+ }
+ }
+ Bool_t zdcNA = tdc[12];
+ Bool_t zdcNC = tdc[10];
+ Bool_t zdcPA = tdc[13];
+ Bool_t zdcPC = tdc[11];
+ //
+ Bool_t zdcA= ((zdcPA) || (zdcNA));
+ Bool_t zdcC= ((zdcPC) || (zdcNC));
+ // if (!fUseMC && !(zdcA&&zdcC)) return;
+ if (!fUseMC && !(zdcNA&&zdcNC)) return;
+ float zdcEnergy = esdZDC->GetZDCN1Energy() + esdZDC->GetZDCP1Energy() + esdZDC->GetZDCN2Energy()+ esdZDC->GetZDCP2Energy();
+ zdcEnergy /= 8.;
+ //
+ //-----------------------------------------------------
+ Float_t multV0A=0,multV0C=0,multV0=0,multV0Corr=0,multV0CorrResc=0;
+ AliESDVZERO* esdV0 = esd->GetVZEROData();
+ if (esdV0) {
+ multV0A = esdV0->GetMTotV0A();
+ multV0C = esdV0->GetMTotV0C();
+ }
+ if (fUseMC) {
+ multV0A *= fMCV0Scale;
+ multV0C *= fMCV0Scale;
+ }
+ multV0 = multV0A + multV0C;
+ if (!fUseMC) multV0Corr = GetCorrV0(esd, multV0CorrResc);
+ else {
+ multV0Corr = multV0;
+ multV0CorrResc = multV0;
+ }
+ //
+ // correct nSPD2 for Zv dependence
+ float nSPD2Corr = GetCorrSPD2(nSPD2,esdvtx[2]);
+ //
+ float multTPC = fTrackCuts->GetReferenceMultiplicity(esd,kTRUE);
+ //
+ // registed Ntracklets and ZVertex of the event
+ ((TH1*)fHistosCustom->UncheckedAt(kHZVtxNoSel))->Fill(esdvtx[2]);
+ ((TH1*)fHistosCustom->UncheckedAt(kHNTrackletsNoSel))->Fill(multESD->GetNumberOfTracklets());
+ ((TH1*)fHistosCustom->UncheckedAt(kHNClSPD1NoSel))->Fill(nSPD1);
+ ((TH1*)fHistosCustom->UncheckedAt(kHNClSPD2NoSel))->Fill(nSPD2);
+ ((TH1*)fHistosCustom->UncheckedAt(kHV0NoSel))->Fill(multV0Corr);
+ ((TH1*)fHistosCustom->UncheckedAt(kHV0CCNoSel))->Fill(multV0CorrResc);
+ ((TH1*)fHistosCustom->UncheckedAt(kHMultTPCNoSel))->Fill(multTPC);
+ //
+ // ((TH2F*)fHistosCustom->UncheckedAt(kHV0NClSPD2NoSel))->Fill(multV0A+multV0C,multESD->GetNumberOfITSClusters(1));
+ //
+ // printf("ESD vertex! %f %f %f, %d contributors\n",esdvtx[0],esdvtx[1],esdvtx[2],vtxESD->GetNContributors());
+
+ if(vtxf[2] < fZVertexMin || vtxf[2] > fZVertexMax) return;
+ ((TH2F*)fHistosCustom->UncheckedAt(kHV0NClSPD2NoSel))->Fill(multV0Corr,nSPD2);
+ ((TH2F*)fHistosCustom->UncheckedAt(kHV0CCNClSPD2NoSel))->Fill(multV0CorrResc,nSPD2);
+ //
+ /// double mltTst = fUseMC ? multESD->GetNumberOfITSClusters(1) : multV0A+multV0C;
+ // double mltTst = multESD->GetNumberOfITSClusters(1); //RRR
+ float mltTst = -1;
+ float mltTst2 = -1;
+ if (fUseCentralityVar == kCentSPD2) mltTst = nSPD2Corr;
+ else if (fUseCentralityVar == kCentV0) mltTst = multV0Corr; // Cvetan's corrected V0
+ else if (fUseCentralityVar == kCentV0CR) mltTst = multV0CorrResc; // Cvetan's rescaled V0
+ else if (fUseCentralityVar == kCentTrTPC) mltTst = multTPC; // TPC Mult
+ else if (fUseCentralityVar == kCentZDCV0) {
+ mltTst = multV0Corr;
+ mltTst2 = zdcEnergy;
+ }
+ else AliFatal(Form("Unknown cenrality parameter %d",fUseCentralityVar));
+ //
+ fCurrCentBin = GetCentralityBin(mltTst,mltTst2);
+ if (fCurrCentBin<0) {
+ printf("Reject: %.1f : V0:%.1f V0Cor:%.1f V0CR:%.1f SPD2c:%.1f\n",mltTst, multV0,multV0Corr,multV0CorrResc,nSPD2Corr);
+ return;
+ }
+ //
+ ((TH1*)fHistosCustom->UncheckedAt(kHStatCent))->Fill(mltTst);
+ ((TH1*)fHistosCustom->UncheckedAt(kHStatCentBin))->Fill(fCurrCentBin);
+ printf("Bin %d (mlt=%f) Multiplicity from ESD:\n",fCurrCentBin,mltTst);
+ // multESD->Print();
+ //
+ AliMCEventHandler* eventHandler = 0;
+ fMCEvent = 0;
+ fStack = 0;
+ //
+ if (fUseMC) {
+ eventHandler = (AliMCEventHandler*)anMan->GetMCtruthEventHandler();
+ if (!eventHandler) { printf("ERROR: Could not retrieve MC event handler\n"); return; }
+ fMCEvent = eventHandler->MCEvent();
+ if (!fMCEvent) { printf("ERROR: Could not retrieve MC event\n"); return; }
+ fStack = fMCEvent->Stack();
+ if (!fStack) { printf("Stack not available\n"); return; }
+ }
+ //
+ fRPTree = handRP->GetTreeR("ITS");
+ if (!fRPTree) { AliError(" Invalid ITS cluster tree !\n"); return; }
+ //
+ // =============================================================================>>>
+ // MC Generator info
+ AliGenEventHeader* mcGenH = 0;
+ fNPart = 0;
+ fNBColl = 0;
+ if (fUseMC) {
+ mcGenH = fMCEvent->GenEventHeader();
+ if (mcGenH->InheritsFrom(AliGenHijingEventHeader::Class())) {
+ AliGenHijingEventHeader* hHijing = (AliGenHijingEventHeader*)mcGenH;
+ fNPart = (hHijing->ProjectileParticipants()+hHijing->TargetParticipants())/2.;
+ fNBColl = hHijing->NN()+hHijing->NNw()+hHijing->NwN()+hHijing->NwNw();
+ }
+ else if (mcGenH->InheritsFrom(AliGenDPMjetEventHeader::Class())) {
+ AliGenDPMjetEventHeader* hDpmJet = (AliGenDPMjetEventHeader*)mcGenH;
+ fNPart = (hDpmJet->ProjectileParticipants()+hDpmJet->TargetParticipants())/2.;
+ fNBColl = hDpmJet->NN()+hDpmJet->NNw()+hDpmJet->NwN()+hDpmJet->NwNw();
+ }
+ else {} // unknown generator
+ }
+ //
+ // register Ntracklets and ZVertex of the event
+ ((TH2*)fHistosCustom->UncheckedAt(kHZVtx))->Fill(esdvtx[2],fCurrCentBin);
+ ((TH2*)fHistosCustom->UncheckedAt(kHNTracklets))->Fill(multESD->GetNumberOfTracklets(),fCurrCentBin);
+ //
+ if (fUseMC) FillMCPrimaries();
+ // fill N clusters
+ ((TH2*)fHistosCustom->UncheckedAt(kHNClSPD1))->Fill(nSPD1,fCurrCentBin);
+ ((TH2*)fHistosCustom->UncheckedAt(kHNClSPD2))->Fill(nSPD2,fCurrCentBin);
+ ((TH2*)fHistosCustom->UncheckedAt(kHV0))->Fill(multV0Corr,fCurrCentBin);
+ ((TH2*)fHistosCustom->UncheckedAt(kHV0CC))->Fill(multV0CorrResc,fCurrCentBin);
+ ((TH2*)fHistosCustom->UncheckedAt(kHMultTPC))->Fill(multTPC,fCurrCentBin);
+ //
+ // normal reconstruction
+ hstat->Fill(kBinEntries+kEvProcData + kEntriesPerBin*fCurrCentBin);
+ //
+ if (GetDoNormalReco() || GetDoInjection()) { // for the injection the normal reco should be done
+ InitMultReco();
+ fMultReco->Run(fRPTree, vtxf);
+ printf("Multiplicity Reconstructed:\n");
+ AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+ if (mlt) mlt->Print();
+ if (GetDoNormalReco()) FillHistos(kData,mlt);
+ FillClusterInfo();
+ //
+ }
+ if (!GetDoNormalReco()) FillHistos(kData,multESD); // fill data histos from ESD
+ //
+ // Injection: it must come right after the normal reco since needs its results
+ if (GetDoInjection()) {
+ if (!fMultReco) InitMultReco(); // in principle, not needed, the reco is created above
+ fMultReco->SetRecType(AliITSMultRecBg::kBgInj);
+ fMultReco->Run(fRPTree, vtxf);
+ printf("Multiplicity from Injection:\n");
+ AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+ if (mlt) mlt->Print();
+ hstat->Fill(kBinEntries + kEvProcInj + kEntriesPerBin*fCurrCentBin);
+ FillHistos(kBgInj,mlt);
+ }
+ //
+ // Rotation
+ if (GetDoRotation()) {
+ InitMultReco();
+ fMultReco->SetRecType(AliITSMultRecBg::kBgRot);
+ fMultReco->SetPhiRotationAngle(fPhiRot);
+ fMultReco->Run(fRPTree, vtxf);
+ printf("Multiplicity from Rotation:\n");
+ AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+ if (mlt) mlt->Print();
+ hstat->Fill(kBinEntries + kEvProcRot + kEntriesPerBin*fCurrCentBin);
+ FillHistos(kBgRot,mlt);
+ }
+ //
+ if (GetDoMixing()) {
+ AliMixEventInputHandler* handToMix = (AliMixEventInputHandler*)handRP->MixingHandler();
+ if (!handToMix) { printf("No Mixing handler\n"); return; }
+ handToMix->GetEntry();
+ if(handToMix->MixedEventNumber()<1) {printf("Mixing: No enough events in pool\n"); return;}
+ AliESDInputHandlerRP* handRPMix = (AliESDInputHandlerRP*) handToMix->InputEventHandler(0);
+
+ if (!handRPMix) { printf("No Mixing RP handler\n"); return; }
+ fRPTreeMix = handRPMix->GetTreeR("ITS");
+ if (!fRPTreeMix) { AliError(" Invalid ITS cluster tree of the 2nd event!\n"); return; }
+ //
+ AliESDEvent *esdMix = handRPMix->GetEvent();
+ const AliESDVertex* vtxESDmix = esdMix->GetVertex();
+ ((TH2*)fHistosCustom->UncheckedAt(kHZVtxMixDiff))->Fill(vtxESDmix->GetZ()-esdvtx[2],fCurrCentBin);
+ ((TH2*)fHistosCustom->UncheckedAt(kHNTrMixDiff) )->
+ Fill(esdMix->GetMultiplicity()->GetNumberOfTracklets() - multESD->GetNumberOfTracklets(),fCurrCentBin);
+ //
+ InitMultReco();
+ fMultReco->SetRecType(AliITSMultRecBg::kBgMix);
+ fMultReco->Run(fRPTree, vtxf,fRPTreeMix);
+ printf("Multiplicity from Mixing:\n");
+ AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+ if (mlt) mlt->Print();
+ hstat->Fill(kBinEntries + kEvProcMix + kEntriesPerBin*fCurrCentBin);
+ FillHistos(kBgMix,mlt);
+ //
+ }
+ // =============================================================================<<<
+ //
+ delete fMultReco;
+ fMultReco = 0;
+ //
+}
+
+//________________________________________________________________________
+Float_t AliTrackletTaskMulti::GetCorrSPD2(Float_t spd2raw,Float_t zv) const
+{
+ //renormalize N spd2 clusters at given Zv to acceptance at Zv=0
+ const double pars[] = {8.10030e-01,-2.80364e-03,-7.19504e-04};
+ zv -= pars[0];
+ float corr = 1 + zv*(pars[1] + zv*pars[2]);
+ return corr>0 ? spd2raw/corr : -1;
+}
+
+//________________________________________________________________________
+Float_t AliTrackletTaskMulti::GetCorrV0(const AliESDEvent* esd, float &v0CorrResc) const
+{
+ // correct V0 non-linearity, prepare a version rescaled to SPD2 corr
+ const Double_t par0[64] = { 6.71e-02 , 6.86e-02 , 7.06e-02 , 6.32e-02 ,
+ 5.91e-02 , 6.07e-02 , 5.78e-02 , 5.73e-02 , 5.91e-02 , 6.22e-02 ,
+ 5.90e-02 , 6.11e-02 , 5.55e-02 , 5.29e-02 , 5.19e-02 , 5.56e-02 ,
+ 6.25e-02 , 7.03e-02 , 5.64e-02 , 5.81e-02 , 4.57e-02 , 5.30e-02 ,
+ 5.13e-02 , 6.43e-02 , 6.27e-02 , 6.48e-02 , 6.07e-02 , 1.01e-01 ,
+ 6.68e-02 , 7.16e-02 , 6.36e-02 , 5.95e-02 , 2.52e-02 , 2.82e-02 ,
+ 2.56e-02 , 2.86e-02 , 2.82e-02 , 2.10e-02 , 2.13e-02 , 2.32e-02 ,
+ 2.75e-02 , 4.34e-02 , 3.78e-02 , 4.52e-02 , 4.11e-02 , 3.89e-02 ,
+ 4.10e-02 , 3.73e-02 , 4.51e-02 , 5.07e-02 , 5.42e-02 , 4.74e-02 ,
+ 4.33e-02 , 4.44e-02 , 4.64e-02 , 3.01e-02 , 6.38e-02 , 5.26e-02 ,
+ 4.99e-02 , 5.26e-02 , 5.47e-02 , 3.84e-02 , 5.00e-02 , 5.20e-02 };
+ const Double_t par1[64] = { -6.68e-05 , -7.78e-05 , -6.88e-05 , -5.92e-05 ,
+ -2.43e-05 , -3.54e-05 , -2.91e-05 , -1.99e-05 , -1.40e-05 , -4.01e-05 ,
+ -2.29e-05 , -3.68e-05 , -2.53e-05 , -2.44e-06 , -9.22e-06 , -1.51e-05 ,
+ -2.80e-05 , -2.34e-05 , -1.72e-05 , -1.81e-05 , -1.29e-05 , -2.65e-05 ,
+ -1.61e-05 , -2.86e-05 , -1.74e-05 , -4.23e-05 , -3.41e-05 , -1.05e-04 ,
+ -2.76e-05 , -4.71e-05 , -3.06e-05 , -2.32e-05 , -1.55e-06 , 2.15e-05 ,
+ 1.40e-05 , 2.16e-05 , 1.21e-05 , 3.05e-06 , 1.67e-05 , -3.84e-06 ,
+ 3.09e-06 , 1.50e-05 , 3.47e-06 , 4.87e-06 , -3.71e-07 , -1.75e-06 ,
+ -1.80e-06 , 9.99e-06 , -6.46e-06 , -4.91e-06 , 1.33e-05 , -2.52e-07 ,
+ -3.85e-06 , 4.94e-06 , -2.48e-07 , -1.20e-05 , 2.07e-06 , 6.12e-06 ,
+ -1.18e-06 , 4.54e-06 , -1.54e-05 , -1.25e-05 , 1.46e-06 , -6.67e-06 };
+ const Double_t par2[64] = { 1.29e-08 , 1.51e-08 , 1.43e-08 , 1.11e-08 ,
+ 5.04e-09 , 6.99e-09 , 5.58e-09 , 4.15e-09 , 4.00e-09 , 8.22e-09 ,
+ 4.97e-09 , 7.66e-09 , 4.91e-09 , 1.10e-09 , 2.64e-09 , 3.64e-09 ,
+ 5.76e-09 , 5.46e-09 , 3.38e-09 , 3.47e-09 , 2.43e-09 , 4.13e-09 ,
+ 2.80e-09 , 5.80e-09 , 3.86e-09 , 7.46e-09 , 5.98e-09 , 2.58e-08 ,
+ 5.50e-09 , 8.72e-09 , 5.23e-09 , 4.37e-09 , 2.33e-09 , -6.01e-10 ,
+ 3.99e-11 , -2.02e-10 , 7.67e-10 , 2.03e-09 , 1.17e-10 , 2.56e-09 ,
+ 1.16e-09 , -4.75e-10 , 1.28e-09 , 1.23e-09 , 1.62e-09 , 1.61e-09 ,
+ 1.93e-09 , 2.97e-10 , 2.21e-09 , 2.16e-09 , 5.22e-10 , 1.03e-09 ,
+ 1.56e-09 , 5.00e-10 , 1.01e-09 , 2.93e-09 , 1.05e-09 , 9.96e-11 ,
+ 1.21e-09 , 7.45e-10 , 3.07e-09 , 2.31e-09 , 6.70e-10 , 1.89e-09 };
+ //
+ Float_t multCorr = 0;
+ Float_t multCorr2 = 0;
+ Float_t multChCorr[64];
+ AliESDVZERO* esdV0 = esd->GetVZEROData();
+ for(Int_t i = 0; i < 64; ++i) {
+ Double_t b = (esdV0->GetMultiplicity(i)*par1[i]-par0[i]);
+ Double_t s = (b*b-4.*par2[i]*esdV0->GetMultiplicity(i)*esdV0->GetMultiplicity(i));
+ Double_t n;
+ if (s<0) {
+ printf("FPE %d %.2f %.2f %.2e\n",i,esdV0->GetMultiplicity(i),b,(b*b-4.*par2[i]*esdV0->GetMultiplicity(i)*esdV0->GetMultiplicity(i)));
+ n = -b;
+ }
+ else {
+ n = (-b + TMath::Sqrt(s));
+ }
+ multChCorr[i] = 2.*esdV0->GetMultiplicity(i)/n*par0[i];
+ multCorr += multChCorr[i];
+ multCorr2 += (multChCorr[i]/par0[i]/64.);
+ }
+ v0CorrResc = multCorr2;
+ return multCorr;
+}
+
+
+//________________________________________________________________________
+void AliTrackletTaskMulti::Terminate(Option_t *)
+{
+ Printf("Terminating...");
+ TH1* hstat;
+ TList *lst = dynamic_cast<TList*>(GetOutputData(1));
+ printf("Term: %p %p %p\n",fOutput,lst,fHistosCustom);
+ if (lst && (hstat=(TH1*)lst->FindObject("hStat"))) {
+ Info("Terminate","Registering used settings");
+ // fill used settings
+ hstat->Fill(kOneUnit,1.);
+ hstat->Fill(kDPhi,fDPhiWindow);
+ hstat->Fill(kDTht,fDThetaWindow);
+ hstat->Fill(kNStd,fNStdDev);
+ hstat->Fill(kPhiShift,fDPhiShift);
+ hstat->Fill(kThtS2,fScaleDTBySin2T);
+ hstat->Fill(kThtCW,fCutOnDThetaX);
+ hstat->Fill(kPhiOvl,fPhiOverlapCut);
+ hstat->Fill(kZEtaOvl,fZetaOverlap);
+ hstat->Fill(kNoOvl,fRemoveOverlaps);
+ //
+ hstat->Fill(kPhiRot,fPhiRot);
+ hstat->Fill(kInjScl,fInjScale);
+ hstat->Fill(kEtaCut,fEtaCut);
+ hstat->Fill(kZVMin,fZVertexMin);
+ hstat->Fill(kZVMax,fZVertexMax);
+ //
+ hstat->Fill(kDPiSCut,fDPhiSCut);
+ hstat->Fill(kNStdCut,fNStdCut);
+ hstat->Fill(kMCV0Scale, fMCV0Scale);
+ //
+ }
+ //
+ // AliAnalysisTaskSE::Terminate();
+}
+
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::InitMultReco()
+{
+ // create mult reconstructor
+ if (fMultReco) delete fMultReco;
+ fMultReco = new AliITSMultRecBg();
+ fMultReco->SetCreateClustersCopy(kTRUE);
+ fMultReco->SetScaleDThetaBySin2T(fScaleDTBySin2T);
+ fMultReco->SetNStdDev(fNStdDev);
+ fMultReco->SetPhiWindow( fDPhiWindow );
+ fMultReco->SetThetaWindow( fDThetaWindow );
+ fMultReco->SetPhiShift( fDPhiShift );
+ fMultReco->SetRemoveClustersFromOverlaps(fRemoveOverlaps);
+ fMultReco->SetPhiOverlapCut(fPhiOverlapCut);
+ fMultReco->SetZetaOverlapCut(fZetaOverlap);
+ fMultReco->SetHistOn(kFALSE);
+ fMultReco->SetRecType( AliITSMultRecBg::kData );
+}
+
+//_________________________________________________________________________
+TObjArray* AliTrackletTaskMulti::BookCustomHistos()
+{
+ // book custom histos, not related to specific tracklet type
+ TObjArray* histos = new TObjArray();
+ TH1F* hstat;
+ //
+ // ------------ job parameters, statistics ------------------------------>>>
+ int nbs = kBinEntries + fNCentBins*kEntriesPerBin;
+ hstat = new TH1F("hStat","Run statistics",nbs,0.5,nbs+0.5);
+ //
+ hstat->GetXaxis()->SetBinLabel(kEvTot, "Ev.Tot");
+ hstat->GetXaxis()->SetBinLabel(kOneUnit,"ScaleMerge");
+ hstat->GetXaxis()->SetBinLabel(kNWorkers,"Workers");
+ //
+ hstat->GetXaxis()->SetBinLabel(kDPhi, "#Delta#varphi");
+ hstat->GetXaxis()->SetBinLabel(kDTht, "#Delta#theta");
+ hstat->GetXaxis()->SetBinLabel(kNStd, "N.std");
+ hstat->GetXaxis()->SetBinLabel(kPhiShift,"#delta#varphi");
+ hstat->GetXaxis()->SetBinLabel(kThtS2,"scale #Delta#theta");
+ hstat->GetXaxis()->SetBinLabel(kPhiOvl,"#varpho_{Ovl}");
+ hstat->GetXaxis()->SetBinLabel(kZEtaOvl,"#z_{Ovl}");
+ hstat->GetXaxis()->SetBinLabel(kNoOvl, "rem.ovl");
+ //
+ hstat->GetXaxis()->SetBinLabel(kPhiRot,"#varphi_{rot}");
+ hstat->GetXaxis()->SetBinLabel(kInjScl,"inj");
+ hstat->GetXaxis()->SetBinLabel(kEtaCut,"#eta cut");
+ hstat->GetXaxis()->SetBinLabel(kZVMin,"ZV_{min} cut");
+ hstat->GetXaxis()->SetBinLabel(kZVMax,"ZV_{max} cut");
+ //
+ hstat->GetXaxis()->SetBinLabel(kDPiSCut,"#Delta#varphi-#delta_{#phi} cut");
+ hstat->GetXaxis()->SetBinLabel(kNStdCut,"#Delta cut");
+ //
+ hstat->GetXaxis()->SetBinLabel(kMCV0Scale,"MC V0 scale");
+ //
+ for (int i=0;i<fNCentBins;i++) {
+ TString bnt = "b"; bnt+= i;
+ int offs = kBinEntries + i*kEntriesPerBin;
+ hstat->GetXaxis()->SetBinLabel(offs + kEvProcData, bnt+" Ev.ProcData");
+ hstat->GetXaxis()->SetBinLabel(offs + kEvProcInj, bnt+" Ev.ProcInj");
+ hstat->GetXaxis()->SetBinLabel(offs + kEvProcRot, bnt+" Ev.ProcRot");
+ hstat->GetXaxis()->SetBinLabel(offs + kEvProcMix, bnt+" Ev.ProcMix");
+ //
+ }
+ //
+ hstat->Fill(kNWorkers);
+ //
+ AddHisto(histos,hstat,kHStat);
+ //
+ // ------------------------ events per centrality bin ----------------------
+ TH1D* hCentAx = new TH1D("EvCentr","Events per centrality",fNCentBins,fkCentBinDef);
+ hCentAx->GetXaxis()->SetTitle("Centrality parameter");
+ AddHisto(histos,hCentAx,kHStatCent);
+ //
+ TH1D* hCentBin = new TH1D("EvCentrBin","Events per centrality bin",fNCentBins,-0.5,fNCentBins-0.5);
+ hCentBin->GetXaxis()->SetTitle("Centrality Bin");
+ AddHisto(histos,hCentBin,kHStatCentBin);
+ //
+ // ------------ job parameters, statistics ------------------------------<<<
+ //
+ double etaMn=-3,etaMx=3;
+ double zMn=-30, zMx=30;
+ int nEtaBins = int((etaMx-etaMn)/0.1);
+ if (nEtaBins<1) nEtaBins = 1;
+ //
+ int nZVBins = int(zMx-zMn);
+ if (nZVBins<1) nZVBins = 1;
+ //
+ // Z vertex distribution for events before selection
+ TH1F* hzvns = new TH1F("zvNoSel","Z vertex before selection",nZVBins,zMn,zMx);
+ hzvns->GetXaxis()->SetTitle("Zvertex");
+ AddHisto(histos,hzvns,kHZVtxNoSel);
+ //
+ int nbmltSPD2 = 700;
+ double maxmltSPD2 = 7000;
+ int nbmltV0 = 1000;
+ double maxmltV0 = 20000;
+ // N tracklets for processed events
+ TH1F* hntns = new TH1F("NtrackletsNoSel","N Tracklets Before Selection",nbmltSPD2,0,maxmltSPD2);
+ hntns->GetXaxis()->SetTitle("N tracklets");
+ AddHisto(histos,hntns,kHNTrackletsNoSel);
+ //
+ // N SPD1 clusters
+ TH1F* hncl1ns = new TH1F("NClustersSPD1NoSel","N Clusters on SPD1 Before Selection",nbmltSPD2,0,maxmltSPD2);
+ hncl1ns->GetXaxis()->SetTitle("N Clus SPD1");
+ AddHisto(histos,hncl1ns,kHNClSPD1NoSel);
+ //
+ // N SPD2 clusters
+ TH1F* hncl2ns = new TH1F("NClustersSPD2NoSel","N Clusters on SPD2 Before Selection",nbmltSPD2,0,maxmltSPD2);
+ hncl2ns->GetXaxis()->SetTitle("N Clus SPD2");
+ AddHisto(histos,hncl2ns,kHNClSPD2NoSel);
+ //
+ // V0
+ TH1F* hnV0ns = new TH1F("V0NoSel","V0 signal Before Selection",nbmltV0,0,maxmltV0);
+ hnV0ns->GetXaxis()->SetTitle("V0 signal");
+ AddHisto(histos,hnV0ns,kHV0NoSel);
+ //
+ // V0 Corr
+ TH1F* hnV0CCns = new TH1F("V0CorrNoSel","V0 Corr signal Before Selection",nbmltSPD2,0,maxmltSPD2); //!!! Same scale as SPD2
+ hnV0ns->GetXaxis()->SetTitle("V0 Corr signal");
+ AddHisto(histos,hnV0CCns,kHV0CCNoSel);
+ //
+ // V0
+ //TH2F* hnV0SPD2ns = new TH2F("V0NDP2NoSel","NSPD2 vs V0 signal Before Selection",2500,0,20000,1400,0,maxmltSPD2);
+ TH2F* hnV0SPD2ns = new TH2F("V0NDP2NoMltSel","NSPD2 vs V0 signal Before Mlt Selection",100,0,maxmltV0,100,0,maxmltSPD2);
+ hnV0SPD2ns->GetXaxis()->SetTitle("V0 signal");
+ hnV0SPD2ns->GetYaxis()->SetTitle("N Clus SPD2 ");
+ AddHisto(histos,hnV0SPD2ns,kHV0NClSPD2NoSel);
+ //
+ // V0 corr
+ //TH2F* hnV0SPD2ns = new TH2F("V0SPD2NoSel","NSPD2 vs V0 signal Before Selection",2500,0,20000,1400,0,maxmltSPD2);
+ TH2F* hnV0CCSPD2ns = new TH2F("V0CCSPD2NoMltSel","NSPD2 vs V0 Corr signal Before Mlt Selection",100,0,maxmltV0,100,0,maxmltSPD2);
+ hnV0CCSPD2ns->GetXaxis()->SetTitle("V0 Corr signal");
+ hnV0CCSPD2ns->GetYaxis()->SetTitle("N Clus SPD2 ");
+ AddHisto(histos,hnV0CCSPD2ns,kHV0CCNClSPD2NoSel);
+ //
+ // TPC ref mult before selection
+ TH1F* hntpc = new TH1F("TPCMultNoSel","TPC Multipliplicity Before Selection",300,0,3000);
+ hntpc->GetXaxis()->SetTitle("N TPC tracks");
+ AddHisto(histos,hntpc,kHMultTPCNoSel);
+ //
+
+ TH2F* hzv = new TH2F("zv","Z vertex after Selection per Cent.Bin",nZVBins,zMn,zMx, fNCentBins, -0.5,fNCentBins-0.5);
+ hzv->GetXaxis()->SetTitle("Zvertex");
+ hzv->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hzv,kHZVtx);
+ //
+ // N tracklets for processed events
+ TH2F* hnt = new TH2F("Ntracklets","N Tracklets per Cent.Bin",nbmltSPD2,0,maxmltSPD2, fNCentBins, -0.5,fNCentBins-0.5);
+ hnt->GetXaxis()->SetTitle("N tracklets");
+ hnt->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnt,kHNTracklets);
+ //
+ // N SPD1 clusters
+ TH2F* hncl1 = new TH2F("NClustersSPD1","N Clusters on SPD1 per Cent.Bin",nbmltSPD2,0,maxmltSPD2, fNCentBins, -0.5,fNCentBins-0.5);
+ hncl1->GetXaxis()->SetTitle("N Clus SPD1");
+ hncl1->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hncl1,kHNClSPD1);
+ //
+ // N SPD2 clusters
+ TH2F* hncl2 = new TH2F("NClustersSPD2","N Clusters on SPD2 per Cent.Bin",nbmltSPD2,0,maxmltSPD2, fNCentBins, -0.5,fNCentBins-0.5);
+ hncl2->GetXaxis()->SetTitle("N Clus SPD2");
+ hncl2->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hncl2,kHNClSPD2);
+ //
+ // V0
+ TH2F* hnV0 = new TH2F("V0","V0 signalper Cent.Bin ",nbmltV0,0,maxmltV0, fNCentBins, -0.5,fNCentBins-0.5);
+ hnV0->GetXaxis()->SetTitle("V0 signal");
+ hnV0->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnV0,kHV0);
+ //
+ // V0 corr
+ TH2F* hnV0CC = new TH2F("V0Corr","V0 Corr signal per Cent.Bin ",nbmltSPD2,0,maxmltSPD2, fNCentBins, -0.5,fNCentBins-0.5);
+ hnV0CC->GetXaxis()->SetTitle("V0 Corr signal");
+ hnV0CC->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnV0CC,kHV0CC);
+ //
+ // TPC
+ TH2F* hnTPC = new TH2F("TPCMult","TPC Mult Cent.Bin ",300,0,3000, fNCentBins, -0.5,fNCentBins-0.5);
+ hnTPC->GetXaxis()->SetTitle("TPC Mult");
+ hnTPC->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnTPC,kHMultTPC);
+ //
+ //----------------------------------------------------------------------
+ int nEtaBinsS = int(2*fEtaCut/0.1);
+ if (nEtaBinsS<1) nEtaBins = 1;
+ //
+ int nZVBinsS = int(fZVertexMax-fZVertexMin);
+ if (nZVBinsS<1) nZVBinsS = 1;
+
+ if (fUseMC) {
+ // Z vertex vs Eta distribution for primaries
+ char buffn[100],bufft[500];
+ for (int ib=0;ib<fNCentBins;ib++) {
+ sprintf(buffn,"b%d_zvEtaPrimMC",ib);
+ sprintf(bufft,"bin%d Zvertex vs #eta PrimMC",ib);
+ TH2F* hzvetap = new TH2F(buffn,bufft, nEtaBinsS,-fEtaCut,fEtaCut,nZVBinsS,fZVertexMin,fZVertexMax);
+ hzvetap->GetXaxis()->SetTitle("#eta");
+ hzvetap->GetYaxis()->SetTitle("Zvertex");
+ AddHisto(histos,hzvetap,kHZVEtaPrimMC+ib);
+ }
+ //
+ // <n> primaries according to MC generator
+ TH1F* hnprimM = new TH1F("nPrimMean","<N> primaries",fNCentBins, -0.5,fNCentBins-0.5);
+ hnprimM->GetXaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnprimM,kHNPrimMeanMC);
+ //
+ // <n> primaries per part.pair according to MC generator
+ TH1F* hnprim2partM = new TH1F("nPrim2Part","<N> primaries per part.pair",fNCentBins, -0.5,fNCentBins-0.5);
+ hnprim2partM->GetXaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnprim2partM,kHNPrim2PartMC);
+ //
+ // <n> primaries per part.pair vs npart.pair according to MC generator
+ TH2F* hnprim2partNp = new TH2F("nPrim2Part_vs_NPart","<N> primaries per part.pair vs N part.pairs",105,0,210,200,0,40);
+ hnprim2partNp->GetXaxis()->SetTitle("N.part.pairs");
+ hnprim2partNp->GetYaxis()->SetTitle("N.prim/N.part.pairs");
+ AddHisto(histos,hnprim2partNp,kHNPrim2PartNpMC);
+ //
+ // <n> primaries per b.coll vs npart.pair according to MC generator
+ TH2F* hnprim2BCollNp = new TH2F("nPrim2BColl_vs_NPart","<N> primaries per bin.coll vs N part.pairs",105,0,210,200,0,40);
+ hnprim2BCollNp->GetXaxis()->SetTitle("N.part.pairs");
+ hnprim2BCollNp->GetYaxis()->SetTitle("N.prim/N.bin.coll.");
+ AddHisto(histos,hnprim2BCollNp,kHNPrim2BCollNpMC);
+ //
+ // <n> primaries per bin.coll. according to MC generator
+ TH1F* hnprim2BCollM = new TH1F("nPrim2BColl","<N> primaries per bin.coll",fNCentBins, -0.5,fNCentBins-0.5);
+ hnprim2BCollM->GetXaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnprim2BCollM,kHNPrim2BCollMC);
+ //
+ // n participants according to MC generator
+ TH2F* hnpart = new TH2F("nPart","N participant pairs",210,0,210,fNCentBins, -0.5,fNCentBins-0.5);
+ hnpart->GetXaxis()->SetTitle("N part. pairs");
+ hnpart->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnpart,kHNPartMC);
+ //
+ // <n> participants according to MC generator
+ TH1F* hnpartM = new TH1F("nPartMean","<N> participant pairs",fNCentBins, -0.5,fNCentBins-0.5);
+ hnpartM->GetXaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnpartM,kHNPartMeanMC);
+ //
+ // n bin coll. according to MC generator
+ TH2F* hnbcoll = new TH2F("nBColl","N bin. coll",2000,0,2000,fNCentBins, -0.5,fNCentBins-0.5);
+ hnbcoll->GetXaxis()->SetTitle("N bin. coll");
+ hnbcoll->GetYaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnbcoll,kHNBCollMC);
+ //
+ // <n> bin col according to MC generator
+ TH1F* hnbcollM = new TH1F("nBCollMean","<N> bin.colls",fNCentBins, -0.5,fNCentBins-0.5);
+ hnbcollM->GetXaxis()->SetTitle("Cent.Bin ID");
+ AddHisto(histos,hnbcollM,kHNBCollMeanMC);
+ //
+ }
+ //
+ if (GetDoMixing()) {
+ //
+ // Difference in Z vertex for mixed events
+ TH2F* hzdiff = new TH2F("MixSPDVertexDiff","SPD #Delta Z Vertex distribution per mult bin ",100,-5,5, fNCentBins, -0.5,fNCentBins-0.5);
+ hzdiff->GetXaxis()->SetTitle("#Delta Z Vertex [cm]");
+ hzdiff->GetYaxis()->SetTitle(Form("Entries / %1.2f [cm] per mult bin",10./100.));
+ AddHisto(histos,hzdiff,kHZVtxMixDiff);
+ //
+ // Difference in N tracklets for mixed events
+ TH2F* hntdiff = new TH2F("MixNTrackletsDiff"," SPD tracklets Diff ",200,-1000,1000, fNCentBins, -0.5,fNCentBins-0.5);
+ hntdiff->GetXaxis()->SetTitle("# tracklet diff");
+ AddHisto(histos,hntdiff,kHNTrMixDiff);
+ }
+ //
+ // --------------------------------------------------
+ if (fUseMC) {
+ int npdg = sizeof(fgkPDGNames)/sizeof(char*);
+ TH2F* hpdgP = new TH2F("pdgPrim","primary PDG",npdg,0,npdg,fNCentBins, -0.5,fNCentBins-0.5);
+ AddHisto(histos,hpdgP,kHPrimPDG);
+ TH2F* hpdgS = new TH2F("pdgSec","secondary PDG",npdg,0,npdg,fNCentBins, -0.5,fNCentBins-0.5);
+ AddHisto(histos,hpdgS,kHSecPDG);
+ TH2F* hpdgPP = new TH2F("pdgPrimPar","primary parent PDG ",npdg,0,npdg,fNCentBins, -0.5,fNCentBins-0.5);
+ AddHisto(histos,hpdgPP,kHPrimParPDG);
+ TH2F* hpdgSP = new TH2F("pdgSecPar","secondary parent PDG",npdg,0,npdg,fNCentBins, -0.5,fNCentBins-0.5);
+ AddHisto(histos,hpdgSP,kHSecParPDG);
+ for (int i=0;i<npdg;i++) {
+ hpdgP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+ hpdgS->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+ hpdgPP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+ hpdgSP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+ }
+ }
+ //
+ // -------------------------------------------------
+ TH2F* hclinf=0;
+ hclinf = new TH2F("cl0InfoUsed","#phi vs Z of used clusters, Lr0",60,-15,15, 80,0,2*TMath::Pi());
+ AddHisto(histos,hclinf,kHClUsedInfoL0);
+ hclinf = new TH2F("cl1InfoUsed","#phi vs Z of used clusters, Lr1",60,-15,15, 2*80,0,2*TMath::Pi());
+ AddHisto(histos,hclinf,kHClUsedInfoL1);
+ hclinf = new TH2F("cl0InfoAll","#phi vs Z of all clusters, Lr0",60,-15,15, 80,0,2*TMath::Pi());
+ AddHisto(histos,hclinf,kHClAllInfoL0);
+ hclinf = new TH2F("cl1InfoAll","#phi vs Z of all clusters, Lr1",60,-15,15, 2*80,0,2*TMath::Pi());
+ AddHisto(histos,hclinf,kHClAllInfoL1);
+ //
+ // -------------------------------------------------
+ histos->SetOwner(kFALSE);
+ //
+ return histos;
+}
+
+//_________________________________________________________________________
+TObjArray* AliTrackletTaskMulti::BookHistosSet(const char* pref, UInt_t selHistos)
+{
+ // book standard set of histos attaching the pref in front of the name/title
+ //
+ const int kNDPhiBins = 100;
+ const int kNDThtBins = 100;
+ int nDistBins = int(fNStdDev)*5;
+ //
+ int nEtaBins = int(2*fEtaCut/0.1);
+ if (nEtaBins<1) nEtaBins = 1;
+ //
+ int nZVBins = int(fZVertexMax-fZVertexMin);
+ if (nZVBins<1) nZVBins = 1;
+ float dphir = fDPhiWindow*TMath::Sqrt(fNStdDev);
+ float dthtr = fDThetaWindow*TMath::Sqrt(fNStdDev);
+ //
+ TObjArray* histos = new TObjArray();
+ TH2F* h2;
+ TH1F* h1;
+ char buffn[100],bufft[500];
+ //
+ for (int ib=0;ib<fNCentBins;ib++) {
+ //
+ int offs = ib*kNStandardH;
+ if (selHistos & (0x1<<kHEtaZvCut) ) {
+ sprintf(buffn,"b%d_%s_ZvEtaCutT",ib,pref);
+ sprintf(bufft,"bin%d (%s) Zv vs Eta with tracklet cut",ib,pref);
+ h2 = new TH2F(buffn,bufft,nEtaBins,-fEtaCut,fEtaCut, nZVBins, fZVertexMin,fZVertexMax);
+ h2->GetXaxis()->SetTitle("#eta");
+ h2->GetYaxis()->SetTitle("Zv");
+ AddHisto(histos,h2,offs+kHEtaZvCut);
+ }
+ //
+ if (selHistos & (0x1<<kHDPhiDTheta) ) {
+ sprintf(buffn,"b%d_%s_dPhidTheta",ib,pref);
+ sprintf(bufft,"bin%d (%s) #Delta#theta vs #Delta#varphi",ib,pref);
+ h2 = new TH2F(buffn,bufft,kNDPhiBins,-dphir,dphir,kNDThtBins,-dthtr,dthtr);
+ h2->GetXaxis()->SetTitle("#Delta#varphi [rad]");
+ h2->GetYaxis()->SetTitle("#Delta#theta [rad]");
+ AddHisto(histos,h2,offs+kHDPhiDTheta);
+ }
+ //
+ if (selHistos & (0x1<<kHDPhiSDThetaX) ) {
+ sprintf(buffn,"b%d_%s_dPhiSdThetaX",ib,pref);
+ sprintf(bufft,"bin%d (%s) #Delta#theta%s vs #Delta#varphi-#delta_{#varphi}",ib,pref,fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+ h2 = new TH2F(buffn,bufft,kNDPhiBins,-dphir,dphir,kNDThtBins,-dthtr,dthtr);
+ h2->GetXaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+ sprintf(bufft,"#Delta#theta%s",fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+ h2->GetYaxis()->SetTitle(bufft);
+ AddHisto(histos,h2,offs+kHDPhiSDThetaX);
+ }
+ //
+ if (selHistos & (0x1<<kHWDist) ) {
+ sprintf(buffn,"b%d_%s_WDist",ib,pref);
+ sprintf(bufft,"bin%d #Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+ "[#Delta#theta%s/#sigma#theta]^{2}",ib,fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+ h1 = new TH1F(buffn,bufft,nDistBins,0,fNStdDev);
+ sprintf(bufft,"#Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+ "[#Delta#theta%s/#sigma#theta]^{2}",fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+ h1->GetXaxis()->SetTitle(bufft);
+ AddHisto(histos,h1,offs+kHWDist);
+ }
+ //
+ }
+ //
+ histos->SetOwner(kFALSE);
+ return histos;
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::AddHisto(TObjArray* histos, TObject* h, Int_t at)
+{
+ // add single histo to the set
+ if (at>=0) histos->AddAtAndExpand(h,at);
+ else histos->Add(h);
+ fOutput->Add(h);
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::FillHistos(Int_t type, const AliMultiplicity* mlt)
+{
+ // fill histos of given type
+ if (!mlt) return;
+ //
+ TObjArray* histos = 0;
+ if (type == kData) histos = fHistosTrData;
+ else if (type == kBgInj) histos = fHistosTrInj;
+ else if (type == kBgRot) histos = fHistosTrRot;
+ else if (type == kBgMix) histos = fHistosTrMix;
+ //
+ Bool_t fillMC = (type==kData) && fUseMC && fStack;
+ //
+ //
+ //---------------------------------------- CHECK ------------------------------>>>
+ TArrayF vtxMC;
+ AliGenHijingEventHeader* pyHeader = 0;
+ //
+ if (fUseMC) {
+ pyHeader = (AliGenHijingEventHeader*) fMCEvent->GenEventHeader();//header->GenEventHeader();
+ pyHeader->PrimaryVertex(vtxMC);
+ }
+ //---------------------------------------- CHECK ------------------------------<<<
+ //
+ if (!histos) return;
+ int ntr = mlt->GetNumberOfTracklets();
+ for (int itr=ntr;itr--;) {
+ //
+ //---------------------------------------- CHECK ------------------------------>>>
+ /*
+ if (fUseMC) {
+ Bool_t reject = kFALSE;
+ while(1) {
+ int lab0 = mlt->GetLabel(itr,0);
+ int lab1 = mlt->GetLabel(itr,1);
+ if (lab0!=lab1) break;
+ if (!fStack->IsPhysicalPrimary(lab0)) break;
+ //
+ TParticle* part = fStack->Particle(lab0);
+ Float_t dz = part->Vz() - vtxMC[2];
+ if (TMath::Abs(dz)<1e-6) break;
+ reject = kTRUE;
+ break;
+ }
+ if (reject) continue;
+ }
+ */
+ //---------------------------------------- CHECK ------------------------------<<<
+ //
+ double theta = mlt->GetTheta(itr);
+ double eta = -TMath::Log(TMath::Tan(theta/2));
+ if (TMath::Abs(eta)>fEtaCut) continue;
+ //
+ double dtheta = mlt->GetDeltaTheta(itr);
+ double dThetaX = dtheta;
+ if (fScaleDTBySin2T) {
+ double sint = TMath::Sin(theta);
+ dThetaX /= (sint*sint);
+ }
+ if (fCutOnDThetaX && TMath::Abs(dThetaX)>fDThetaWindow) continue;
+ // double phi = mlt->GetPhi(itr);
+ double dphi = mlt->GetDeltaPhi(itr);
+ double dist = mlt->CalcDist(itr);
+ //
+ FillHistosSet(histos,eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist);
+ // special handling for mc info
+ if (fillMC && fStack) {
+ int lab0 = mlt->GetLabel(itr,0);
+ int lab1 = mlt->GetLabel(itr,1);
+ int typeMC = 2; // comb.bg.
+ if (lab0 == lab1) typeMC = fStack->IsPhysicalPrimary(lab0) ? 0:1; // prim or sec
+ if (typeMC==0) FillHistosSet(fHistosTrPrim,eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist); // primary
+ else if (typeMC==1) FillHistosSet(fHistosTrSec, eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist); // secondary
+ else {
+ FillHistosSet(fHistosTrComb,eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist); // comb
+ // for combinatorals fill also the uncorrelated part
+ if (fMultReco) {
+ float *trl = fMultReco->GetTracklet(itr);
+ int clId0 = (int)trl[AliITSMultReconstructor::kClID1];
+ int clId1 = (int)trl[AliITSMultReconstructor::kClID2];
+ float *clLabs0 = fMultReco->GetClusterOfLayer(0,clId0) + AliITSMultReconstructor::kClMC0;
+ float *clLabs1 = fMultReco->GetClusterOfLayer(1,clId1) + AliITSMultReconstructor::kClMC0;
+ if (!HaveCommonParent(clLabs0,clLabs1))
+ FillHistosSet(fHistosTrCombU,eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist);
+ }
+ } // combinatorials
+
+ if (dist<fNStdCut) {
+ double dphiS = TMath::Abs(dphi) - fDPhiShift; if (dphi<0) dphiS = -dphiS;
+ if (dphiS<fDPhiSCut) FillSpecies(typeMC, lab0);
+ }
+ if (fCheckReconstructables) CheckReconstructables();
+ }
+ }
+ //
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::FillMCPrimaries()
+{
+ // fill all MC primaries Zv vs Eta
+ if (!fStack || !fMCEvent) return;
+
+ //---------------------------------------- CHECK ------------------------------>>>
+ TArrayF vtxMC;
+ AliGenHijingEventHeader* pyHeader = 0;
+ //
+ if (fUseMC) {
+ pyHeader = (AliGenHijingEventHeader*) fMCEvent->GenEventHeader();//header->GenEventHeader();
+ pyHeader->PrimaryVertex(vtxMC);
+ }
+ //---------------------------------------- CHECK ------------------------------<<<
+ //
+ int ntr = fStack->GetNtrack();
+ TH2* hprimEtaZ = (TH2F*)fHistosCustom->UncheckedAt(kHZVEtaPrimMC+fCurrCentBin);
+ int nprim = 0;
+ for (int itr=ntr;itr--;) {
+ if (!fStack->IsPhysicalPrimary(itr)) continue;
+ AliMCParticle *part = (AliMCParticle*)fMCEvent->GetTrack(itr);
+ if (!part->Charge()) continue;
+ //
+ //---------------------------------------- CHECK ------------------------------>>>
+ /*
+ Float_t dz = part->Zv() - vtxMC[2];
+ if (TMath::Abs(dz)>1e-6) continue; // reject
+ */
+ //---------------------------------------- CHECK ------------------------------<<<
+ //
+ Float_t theta = part->Theta();
+ if (theta<1e-6 || theta>TMath::Pi()-1e-6) continue;
+ Float_t eta = part->Eta();
+ if (TMath::Abs(eta)>fEtaCut) continue;
+ hprimEtaZ->Fill(eta, fESDVtx[2]);
+ nprim++;
+ }
+ //
+ ((TH1*)fHistosCustom->UncheckedAt(kHNPrimMeanMC))->Fill(fCurrCentBin,nprim);
+ if (fNPart>0) {
+ ((TH1*)fHistosCustom->UncheckedAt(kHNPrim2PartMC))->Fill(fCurrCentBin,nprim/fNPart);
+ ((TH2*)fHistosCustom->UncheckedAt(kHNPrim2PartNpMC))->Fill(fNPart,nprim/fNPart);
+ ((TH2*)fHistosCustom->UncheckedAt(kHNPartMC))->Fill(fNPart,fCurrCentBin);
+ ((TH1*)fHistosCustom->UncheckedAt(kHNPartMeanMC))->Fill(fCurrCentBin,fNPart);
+ }
+ if (fNBColl>0) {
+ ((TH1*)fHistosCustom->UncheckedAt(kHNPrim2BCollMC))->Fill(fCurrCentBin,nprim/fNBColl);
+ ((TH2*)fHistosCustom->UncheckedAt(kHNPrim2BCollNpMC))->Fill(fNPart,nprim/fNBColl);
+ ((TH2*)fHistosCustom->UncheckedAt(kHNBCollMC))->Fill(fNBColl,fCurrCentBin);
+ ((TH1*)fHistosCustom->UncheckedAt(kHNBCollMeanMC))->Fill(fCurrCentBin,fNBColl);
+ }
+ //
+}
+
+//_________________________________________________________________________
+ void AliTrackletTaskMulti::FillHistosSet(TObjArray* histos, double eta,
+ //double /*phi*/,double /*theta*/,
+ double dphi,double dtheta,double dThetaX,
+ double dist)
+{
+ // fill standard set of histos
+ if (dist>fNStdDev) return;
+ //
+ double dphiS = TMath::Abs(dphi) - fDPhiShift;
+ if (dphi<0) dphiS = -dphiS;
+ //
+ int offs = fCurrCentBin*kNStandardH;
+ //
+ if (histos->UncheckedAt(offs+kHDPhiSDThetaX))
+ ((TH2*)histos->UncheckedAt(offs+kHDPhiSDThetaX))->Fill(dphiS,dThetaX);
+ //
+ if (histos->UncheckedAt(offs+kHDPhiDTheta))
+ ((TH2*)histos->UncheckedAt(offs+kHDPhiDTheta))->Fill(dphi,dtheta);
+ //
+ if (histos->UncheckedAt(kHWDist))
+ ((TH2*)histos->UncheckedAt(offs+kHWDist))->Fill(dist);
+ //
+ if (dist<fNStdCut && dphiS<fDPhiSCut && histos->UncheckedAt(offs+kHEtaZvCut))
+ ((TH2*)histos->UncheckedAt(offs+kHEtaZvCut))->Fill(eta,fESDVtx[2]);
+ //
+}
+
+//__________________________________________________________________
+void AliTrackletTaskMulti::FillSpecies(Int_t primsec, Int_t id)
+{
+ // fill PDGcode
+ TH1 *hPart=0,*hParent=0;
+ if (primsec==0) {
+ hPart = (TH1*)fHistosCustom->UncheckedAt(kHPrimPDG);
+ hParent = (TH1*)fHistosCustom->UncheckedAt(kHPrimParPDG);
+ }
+ else if (primsec==1) {
+ hPart = (TH1*)fHistosCustom->UncheckedAt(kHSecPDG);
+ hParent = (TH1*)fHistosCustom->UncheckedAt(kHSecParPDG);
+ }
+ else return;
+ int ntr = fStack->GetNtrack();
+ TParticle* part = fStack->Particle(id);
+ int pdgCode = TMath::Abs(part->GetPdgCode());
+ int pdgBin = GetPdgBin(pdgCode);
+ int parID = part->GetFirstMother();
+ int pdgCodePar = -1;
+ int pdgBinPar = -1;
+ while (parID>=0 && parID<ntr) {
+ part = fStack->Particle(parID);
+ pdgCodePar = TMath::Abs(part->GetPdgCode());
+ parID = part->GetFirstMother();
+ }
+ if (pdgCodePar>0) pdgBinPar = GetPdgBin(pdgCodePar);
+ //
+ hPart->Fill(pdgBin,fCurrCentBin);
+ hParent->Fill(pdgBinPar,fCurrCentBin);
+ //
+}
+
+//_________________________________________________________________________
+Int_t AliTrackletTaskMulti::GetCentralityBin(Float_t multX, Float_t multY)
+{
+ // calculate centrality bin
+ if (fUseCentralityVar<kCent2D) { // 1D bins
+ for (int i=0;i<fNCentBins;i++) if (multX>=fkCentBinDef[i] && multX<fkCentBinDef[i+1]) return i;
+ }
+ else {
+ for (int i=fNCentBins;i--;) {
+ // X on boundary corresponding to multY
+ float xOnLineUp = (multY-fkCentBinDef2DY[i+1])/fkCentBinDef2DS[i+1] + fkCentBinDef[i+1];
+ float xOnLineLw = (multY-fkCentBinDef2DY[i]) / fkCentBinDef2DS[i] + fkCentBinDef[i];
+ if (multX>=xOnLineLw && multX<xOnLineUp) return i;
+ }
+ }
+ return -1;
+}
+
+//_________________________________________________________________________
+Int_t AliTrackletTaskMulti::GetPdgBin(Int_t pdgCode)
+{
+ // return my pdg bin
+ int ncodes = sizeof(fgkPDGCodes)/sizeof(int);
+ int pdgBin=0;
+ for (pdgBin=0;pdgBin<ncodes;pdgBin++) if (pdgCode==fgkPDGCodes[pdgBin]) break;
+ if (pdgBin>=ncodes) {
+ if (float(pdgCode)>1e9) pdgBin = ncodes; // nuclei
+ else pdgBin = ncodes+1; // unknown
+ }
+ return pdgBin;
+}
+
+//_________________________________________________________________________
+Bool_t AliTrackletTaskMulti::HaveCommonParent(const float* clLabs0,const float* clLabs1)
+{
+ // do 2 clusters have common parrent
+ const int kMaxPar = 50;
+ static int pars[2][50];
+ int npars[2]={0,0};
+ const float *labs[2] = {clLabs0,clLabs1};
+ int ntr = fStack->GetNtrack();
+ for (int il=0;il<2;il++) {
+ for (int ilb=0;ilb<3;ilb++) {
+ int lbl = (int)labs[il][ilb];
+ if (lbl<0 || lbl>=ntr) continue;
+ //
+ while (npars[il]<kMaxPar-1) {
+ pars[il][ npars[il]++ ] = lbl;
+ TParticle* part = fStack->Particle(lbl);
+ if (!part) break;
+ lbl = part->GetFirstMother();
+ if (lbl<1 || lbl>=ntr) break;
+ }
+ }
+ }
+ // compare array of parents
+ for (int i0=npars[0];i0--;) for (int i1=npars[1];i1--;) if (pars[0][i0]==pars[1][i1]) return kTRUE;
+ return kFALSE;
+}
+
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::CheckReconstructables()
+{
+ // fill reconstructable tracklets hitsos
+ static TArrayI trInd;
+ static TBits isPrimArr;
+ //
+ if (!fMultReco || !fMultReco->IsRecoDone()) {AliInfo("To check reconstructables the reco had to be requested"); return;}
+ if (!fStack) {AliInfo("MC Stack is not availalble"); return;}
+ const double kPtMin = 0.05;
+ //
+ TClonesArray *clArr[2];
+ for (int ilr=0;ilr<2;ilr++) {
+ clArr[ilr] = fMultReco->GetClustersOfLayer(ilr);
+ if (!clArr[ilr]) {AliInfo("Clusters are not available"); return;}
+ }
+ //
+ int ntr = fStack->GetNtrack();
+ if (!ntr) return;
+ trInd.Reset();
+ if (trInd.GetSize()<ntr) trInd.Set(ntr);
+ isPrimArr.ResetAllBits();
+ // count track wich may be reconstructable
+ //
+ int ntrStore=0,ntrStorePrim=0;
+ Int_t *trIndArr = trInd.GetArray();
+ for (Int_t it=0; it<ntr; it++) {
+ TParticle* part = fStack->Particle(it);
+ if (TMath::Abs(part->Eta())>2.2) continue;
+ if (TMath::Abs(part->Pt())<kPtMin) continue;
+ if (fStack->IsPhysicalPrimary(it)) {
+ isPrimArr.SetBitNumber(it);
+ ntrStorePrim++;
+ }
+ else { // check if secondary is worth cheking
+ TParticlePDG* pdgPart = part->GetPDG();
+ if (TMath::Abs(pdgPart->Charge())!=3) continue;
+ if (part->R()>5.) continue;
+ }
+ trIndArr[it] = ++ntrStore;
+ }
+ //
+ AliInfo(Form("Selected %d MC particles (%d prim) out of %d in the stack\n",ntrStore,ntrStorePrim,ntr));
+ //
+ const int kMaxCl=3;
+ AliITSRecPoint **clIndL[2];
+ clIndL[0] = new AliITSRecPoint*[kMaxCl*ntrStore]; // max 2 clusters per layer
+ clIndL[1] = new AliITSRecPoint*[kMaxCl*ntrStore]; // max 2 clusters per layer
+ memset(clIndL[0],0,kMaxCl*ntrStore*sizeof(AliITSRecPoint*));
+ memset(clIndL[1],0,kMaxCl*ntrStore*sizeof(AliITSRecPoint*));
+ //
+ for (int ilr=0;ilr<2;ilr++) {
+ TClonesArray *clusters = clArr[ilr];
+ int ncl = clusters->GetEntriesFast();
+ for (int icl=ncl;icl--;) {
+ AliITSRecPoint *cl = (AliITSRecPoint*)clusters->UncheckedAt(icl);
+ for (int ilb=3;ilb--;) {
+ int lbl = cl->GetLabel(ilb); if (lbl<0 || lbl>=ntr) continue;
+ int lblI = trIndArr[lbl];
+ if (--lblI<0) continue; // not kept
+ for (int icc=0;icc<kMaxCl;icc++) if (!clIndL[ilr][lblI+icc*ntrStore]) {clIndL[ilr][lblI+ntrStore*icc] = cl; break;} // first empty one
+ }
+ }
+ }
+ //
+ Float_t clusterLay[2][AliITSMultReconstructor::kClNPar];
+ double trComp[6][kMaxCl*kMaxCl];
+ int indQual[kMaxCl*kMaxCl];
+ //
+ for (int itr=ntr;itr--;) {
+ int lblI = trIndArr[itr];
+ if (--lblI<0) continue; // discarded
+ int ntrCand = 0; // number of tracklet candidates (including overlaps)
+ for (int icl0=0;icl0<kMaxCl;icl0++) {
+ AliITSRecPoint *cl0 = clIndL[0][lblI+icl0*ntrStore];
+ if (!cl0 || !clIndL[1][lblI]) break;
+ cl0->GetGlobalXYZ( clusterLay[0] );
+ fMultReco->ClusterPos2Angles(clusterLay[0], fESDVtx);
+ for (int icl1=0;icl1<kMaxCl;icl1++) {
+ AliITSRecPoint *cl1 = clIndL[1][lblI+icl1*ntrStore];
+ if (!cl1) break;
+ cl1->GetGlobalXYZ( clusterLay[1] );
+ fMultReco->ClusterPos2Angles(clusterLay[1], fESDVtx);
+ trComp[AliITSMultReconstructor::kTrPhi][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClPh];
+ trComp[AliITSMultReconstructor::kTrTheta][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClTh];
+ trComp[AliITSMultReconstructor::kTrDTheta][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClTh] - clusterLay[1][AliITSMultReconstructor::kClTh];
+ trComp[AliITSMultReconstructor::kTrDPhi][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClPh] - clusterLay[1][AliITSMultReconstructor::kClPh];
+ trComp[AliITSMultReconstructor::kTrLab1][ntrCand] = icl1*10 + icl0;
+ double &dphi = trComp[ntrCand][3];
+ if (dphi>TMath::Pi()) dphi=2.*TMath::Pi()-dphi; // take into account boundary condition
+ trComp[5][ntrCand] = fMultReco->CalcDist(trComp[AliITSMultReconstructor::kTrDPhi][ntrCand],
+ trComp[AliITSMultReconstructor::kTrDTheta][ntrCand],
+ trComp[AliITSMultReconstructor::kTrTheta][ntrCand]);
+ ntrCand++;
+ }
+ }
+ if (!ntrCand) continue; // no tracklets
+ if (ntrCand>1) TMath::Sort(ntrCand,trComp[5],indQual,kFALSE); else indQual[0] = 0; // sort in weighted distance
+ if (fRemoveOverlaps) ntrCand = 1; // select the best
+ //
+ // disable worst tracklet with shared cluster
+ for (int itc=0;itc<ntrCand;itc++) {
+ int ind = indQual[itc];
+ if (trComp[AliITSMultReconstructor::kTrLab1][ind]<0) continue; // already disabled
+ for (int jtc=itc+1;jtc<ntrCand;jtc++) {
+ int jnd = indQual[jtc];
+ if (trComp[AliITSMultReconstructor::kTrLab1][jnd]<0) continue; // already disabled
+ if ( int(trComp[AliITSMultReconstructor::kTrLab1][ind])/10 == int(trComp[AliITSMultReconstructor::kTrLab1][jnd])/10 ||
+ int(trComp[AliITSMultReconstructor::kTrLab1][ind])%10 == int(trComp[AliITSMultReconstructor::kTrLab1][jnd])%10) trComp[AliITSMultReconstructor::kTrLab1][jnd] = -1;
+ }
+ }
+ //
+ // store, but forbid cluster reusing
+ TObjArray* histos = isPrimArr.TestBitNumber(itr) ? fHistosTrRcblPrim : fHistosTrRcblSec;
+ for (int itc=0;itc<ntrCand;itc++) {
+ int ind = indQual[itc];
+ if (trComp[4][ind]<0) continue; // discarded
+ double eta = -TMath::Log(TMath::Tan(trComp[AliITSMultReconstructor::kTrTheta][ind]/2));
+ if (TMath::Abs(eta)>fEtaCut) continue;
+ double dThetaX = trComp[AliITSMultReconstructor::kTrTheta][ind];
+ if (fScaleDTBySin2T) {
+ double sint = TMath::Sin(trComp[AliITSMultReconstructor::kTrTheta][ind]);
+ dThetaX /= (sint*sint);
+ }
+ FillHistosSet(histos,eta,
+ //trComp[AliITSMultReconstructor::kTrPhi][ind],trComp[AliITSMultReconstructor::kTrTheta][ind],
+ trComp[AliITSMultReconstructor::kTrDPhi][ind],trComp[AliITSMultReconstructor::kTrDTheta][ind],
+ dThetaX,trComp[5][ind]);
+ }
+ }
+ //
+ delete[] clIndL[0];
+ delete[] clIndL[1];
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::FillClusterInfo()
+{
+ // fill info on clusters associated to good tracklets
+ if (!fMultReco) return;
+ int ntr = fMultReco->GetNTracklets();
+ int clID[2];
+ TH2F *hclU[2] = {(TH2F*)fHistosCustom->UncheckedAt(kHClUsedInfoL0),(TH2F*)fHistosCustom->UncheckedAt(kHClUsedInfoL1)};
+ TH2F *hclA[2] = {(TH2F*)fHistosCustom->UncheckedAt(kHClAllInfoL0),(TH2F*)fHistosCustom->UncheckedAt(kHClAllInfoL1)};
+ for (int itr=ntr;itr--;) {
+ Float_t *trc = fMultReco->GetTracklet(itr);
+ if (TMath::Abs(TMath::Abs(trc[AliITSMultReconstructor::kTrDPhi])-fDPhiShift)>fDPhiSCut) continue;
+ if (fMultReco->CalcDist(trc[AliITSMultReconstructor::kTrDPhi],
+ trc[AliITSMultReconstructor::kTrDTheta],
+ trc[AliITSMultReconstructor::kTrTheta]) > fNStdCut) continue;
+ clID[0] = (int)trc[AliITSMultReconstructor::kClID1];
+ clID[1] = (int)trc[AliITSMultReconstructor::kClID2];
+ for (int il=0;il<2;il++) {
+ Float_t *clinf = fMultReco->GetClusterOfLayer(il,clID[il]);
+ hclU[il]->Fill( clinf[AliITSMultReconstructor::kClZ], clinf[AliITSMultReconstructor::kClPh]);
+ }
+ }
+ //
+ for (int il=0;il<2;il++) for (int ic=fMultReco->GetNClustersLayer(il);ic--;) {
+ Float_t *clinf = fMultReco->GetClusterOfLayer(il,ic);
+ hclA[il]->Fill( clinf[AliITSMultReconstructor::kClZ], clinf[AliITSMultReconstructor::kClPh]);
+ }
+ //
+}
+
+
+//_________________________________________________________________
+Bool_t AliTrackletTaskMulti::ZDCTimeTrigger(const AliESDEvent *aEsd) const
+{
+ // This method implements a selection
+ // based on the timing in both sides of zdcN
+ // It can be used in order to eliminate
+ // parasitic collisions
+ Bool_t zdcAccept = kFALSE;
+
+ AliESDZDC *esdZDC = aEsd->GetESDZDC();
+
+ const Float_t refSum = -568.5;
+ const Float_t refDelta = -2.1;
+ const Float_t sigmaSum = 3.25;
+ const Float_t sigmaDelta = 2.25;
+ for(Int_t i = 0; i < 4; ++i) {
+ if (esdZDC->GetZDCTDCData(10,i) != 0) {
+ Float_t tdcC = 0.025*(esdZDC->GetZDCTDCData(10,i)-esdZDC->GetZDCTDCData(14,i));
+ for(Int_t j = 0; j < 4; ++j) {
+ if (esdZDC->GetZDCTDCData(12,j) != 0) {
+ Float_t tdcA = 0.025*(esdZDC->GetZDCTDCData(12,j)-esdZDC->GetZDCTDCData(14,j));
+ if (((tdcC-tdcA-refDelta)*(tdcC-tdcA-refDelta)/(sigmaDelta*sigmaDelta) +
+ (tdcC+tdcA-refSum)*(tdcC+tdcA-refSum)/(sigmaSum*sigmaSum))< 1.0)
+ zdcAccept = kTRUE;
+ }
+ }
+ }
+ }
+ return zdcAccept;
+}
--- /dev/null
+#ifndef ALITRACKLETTASKMULTI_H
+#define ALITRACKLETTASKMULTI_H
+
+///////////////////////////////////////////////////////////////////////////
+// Class AliTrackletTaskMulti //
+// Analysis task to produce data and MC histos needed for tracklets //
+// dNdEta extraction in multiple bins in one go //
+// Author: ruben.shahoyan@cern.ch //
+///////////////////////////////////////////////////////////////////////////
+
+class TH1F;
+class TH2F;
+class AliESDEvent;
+class TList;
+class TNtuple;
+
+class AliMCParticle;
+class AliITSMultRecBg;
+class AliESDTrackCuts;
+
+#include "../ITS/AliITSsegmentationSPD.h"
+#include "AliAnalysisTaskSE.h"
+#include "AliTriggerAnalysis.h"
+
+class AliTrackletTaskMulti : public AliAnalysisTaskSE {
+ public:
+ enum {kData,kBgInj,kBgRot,kBgMix,kMC};
+ enum {kCentSPD2, kCentV0, kCentV0CR, kCentTrTPC,
+ kCent2D=9, // just a separator between 1D and 2D bins
+ kCentZDCV0}; // what is used to define centrality
+ //
+ enum { // define here id's of the standard histos in corresponding TObjArray* fHistosTr...
+ kHEtaZvCut, // histo zv vs eta for tracklets passing final selection (dist<1 or |dPhi|<narrowWindow ...)
+ kHDPhiDTheta, // measured dTheta vs dPhi
+ kHDPhiSDThetaX, // dTheta (1/sin^2 scaled if needed) vs dPhi (bending subtracted)
+ kHWDist, // Weighted distance
+ kNStandardH // number of standard histos per centrality bin
+ };
+ enum { // define here id's of any custom histos to be added to fHistosCustom
+ kHStat, // job info (meaning of bins defined in the enum below)
+ //
+ kHStatCent, // events per centrality bin with real values on the axis
+ kHStatCentBin, // events per centrality bin
+ //
+ kHNPrimMeanMC, // <n> primaries per mult bin
+ kHNPrim2PartMC, // <n> prim per part.pair per mult bin
+ kHNPrim2BCollMC, // <n> prim per bin.coll per mult bin
+ kHNPrim2PartNpMC, // <n> prim per n part vs npart
+ kHNPrim2BCollNpMC, // <n> prim per n part vs npart
+ kHNPartMC, // n.part.pairs according to MC
+ kHNPartMeanMC, // <n> part pairs per mult bin
+ kHNBCollMC, // n.bin.colls according to MC
+ kHNBCollMeanMC,
+ //
+ kHZVtxNoSel, // Z vertex distribution before event selection
+ kHNTrackletsNoSel, // N tracklets before event selection
+ kHNClSPD1NoSel, // N clusters on SPD1 before event selection
+ kHNClSPD2NoSel, // N clusters on SPD2 before event selection
+ kHV0NoSel, // V0 mult before selection
+ kHV0CCNoSel, // V0 corr (Cvetan) mult before selection
+ kHV0NClSPD2NoSel, // V0 - nspd2 correlation
+ kHV0CCNClSPD2NoSel,// V0 corr - nspd2 correlation
+ kHMultTPCNoSel, // TPC ref.mult
+ //
+ kHZVtx, // Z vertex distribution
+ kHNTracklets, // N tracklets
+ kHNClSPD1, // N clusters on SPD1
+ kHNClSPD2, // N clusters on SPD2
+ kHV0, // V0 mult after selection
+ kHV0CC, // V0 corr mult after selection
+ kHMultTPC, // TPC ref.mult
+ //
+ kHZVtxMixDiff, // difference in Z vtx of mixed events
+ kHNTrMixDiff, // difference in N tracklets of mixed events
+ //
+ kHPrimPDG, // PDG code of prim tracklet
+ kHSecPDG, // PDG code of sec tracklet
+ kHPrimParPDG, // PDG code of prim tracklet parent
+ kHSecParPDG, // PDG code of sec tracklet parent
+ //
+ kHClUsedInfoL0, // used clusters of lr0
+ kHClUsedInfoL1, // used clusters of lr1
+ kHClAllInfoL0, // all clusters of lr0
+ kHClAllInfoL1, // all clusters of lr1
+ //
+ // This MUST be last one: this is just beginning of many histos (one per bin)
+ kHZVEtaPrimMC // Zv vs eta for all primary tracks (true MC multiplicity)
+ }; // custom histos
+
+ // bins for saved parameters
+ enum {kDummyBin,
+ kEvTot, // events read
+ kOneUnit, // just 1 to track primate merges
+ kNWorkers, // n workers
+ //
+ kDPhi, // dphi window
+ kDTht, // dtheta window
+ kNStd, // N.standard deviations to keep
+ kPhiShift, // bending shift
+ kThtS2, // is dtheta scaled by 1/sin^2
+ kThtCW, // on top of w.dist cut cut also on 1 sigma dThetaX
+ kPhiOvl, // overlap params
+ kZEtaOvl, // overlap params
+ kNoOvl, // flag that overlap are suppressed
+ //
+ kPhiRot, // rotation phi
+ kInjScl, // injection scaling
+ kEtaCut, // eta cut
+ kZVMin, // min ZVertex to process
+ kZVMax, // max ZVertex to process
+ //
+ kDPiSCut, // cut on dphi used to extract signal (when WDist is used in analysis, put it equal to kDPhi
+ kNStdCut, // cut on weighted distance (~1) used to extract signal
+ //
+ kMCV0Scale, // scaling value for V0 in MC
+ //
+ // here we put entries for each mult.bin
+ kBinEntries = 50,
+ kEvProcData, // events with data mult.object (ESD or reco)
+ kEvProcInj, // events Injected, total
+ kEvProcRot, // events Rotated
+ kEvProcMix, // events Mixed
+ kEntriesPerBin
+ };
+
+ //
+ AliTrackletTaskMulti(const char *name = "AliTrackletTaskMulti");
+ virtual ~AliTrackletTaskMulti();
+
+ virtual void UserCreateOutputObjects();
+ virtual void UserExec(Option_t *option);
+ virtual void Terminate(Option_t *);
+
+ void SetUseCentralityVar(Int_t v=kCentV0) {fUseCentralityVar = v;}
+ void SetUseMC(Bool_t mc = kFALSE) {fUseMC = mc;}
+ void SetCheckReconstructables(Bool_t c=kFALSE) {fCheckReconstructables = c;}
+ TObjArray* BookHistosSet(const char* pref, UInt_t selHistos=0xffffffff);
+ TObjArray* BookCustomHistos();
+ void AddHisto(TObjArray* histos, TObject* h, Int_t at=-1);
+ void FillHistosSet(TObjArray* histos, double eta, /*double phi,double theta,*/double dphi,double dtheta,double dthetaX,double dist);
+ // RS
+ void SetNStdDev(Float_t f=1.) {fNStdDev = f<1e-5 ? 1e-5:f;}
+ void SetScaleDThetaBySin2T(Bool_t v=kFALSE) {fScaleDTBySin2T = v;}
+ void SetCutOnDThetaX(Bool_t v=kFALSE) {fCutOnDThetaX = v;}
+ void SetPhiWindow(float w=0.08) {fDPhiWindow = w<1e-5 ? 1e-5:w;}
+ void SetThetaWindow(float w=0.025) {if (w<0) fCutOnDThetaX=kTRUE; fDThetaWindow = TMath::Abs(w)<1e-5 ? 1e-5:TMath::Abs(w);}
+ void SetPhiShift(float w=0.0045) {fDPhiShift = w;}
+ void SetPhiOverlapCut(float w=0.005) {fPhiOverlapCut = w;}
+ void SetZetaOverlapCut(float w=0.05) {fZetaOverlap = w;}
+ void SetPhiRot(float w=0) {fPhiRot = w;}
+ void SetInjScale(Float_t s=1.) {fInjScale = s>0? s:1.;}
+ void SetRemoveOverlaps(Bool_t w=kFALSE) {fRemoveOverlaps = w;}
+ //
+ void SetDPhiSCut(Float_t c=0.06) {fDPhiSCut = c;}
+ void SetNStdCut(Float_t c=1.0) {fNStdCut = c;}
+ void SetScaleMCV0(Float_t s=1.0) {fMCV0Scale = s;}
+ //
+ void SetEtaCut(Float_t eta) {fEtaCut = eta;}
+ void SetZVertexMin(Float_t z) {fZVertexMin = z;}
+ void SetZVertexMax(Float_t z) {fZVertexMax = z;}
+ //
+ Bool_t GetDoNormalReco() const {return fDoNormalReco;}
+ Bool_t GetDoInjection() const {return fDoInjection;}
+ Bool_t GetDoRotation() const {return fDoRotation;}
+ Bool_t GetDoMixing() const {return fDoMixing;}
+ //
+ void SetDoNormalReco(Bool_t v=kTRUE) {fDoNormalReco = v;}
+ void SetDoInjection(Bool_t v=kTRUE) {fDoInjection = v;}
+ void SetDoRotation(Bool_t v=kTRUE) {fDoRotation = v;}
+ void SetDoMixing(Bool_t v=kTRUE) {fDoMixing = v;}
+ //
+ /*
+ void SetTrigger(AliTriggerAnalysis::Trigger trigger) { fTrigger = trigger; }
+ void SetMCCentralityBin(MCCentralityBin mccentrbin) { fMCCentralityBin = mccentrbin;}
+ void SetCentralityLowLim(Float_t centrlowlim) { fCentrLowLim = centrlowlim;}
+ void SetCentralityUpLim(Float_t centruplim) { fCentrUpLim = centruplim;}
+ void SetCentralityEst(TString centrest) { fCentrEst = centrest;}
+ */
+ //
+ protected:
+ void InitMultReco();
+ Bool_t HaveCommonParent(const float* clLabs0,const float* clLabs1);
+ void FillHistos(Int_t type, const AliMultiplicity* mlt);
+ void FillMCPrimaries();
+ void FillSpecies(Int_t primsec, Int_t id);
+ void FillClusterInfo();
+ Int_t GetPdgBin(Int_t pdgCode);
+ void CheckReconstructables();
+ Int_t GetCentralityBin(Float_t multX, Float_t multY=-1);
+ Float_t GetCorrSPD2(Float_t spd2raw,Float_t zv) const;
+ Float_t GetCorrV0(const AliESDEvent* esd, float &v0CorrResc) const;
+ Bool_t ZDCTimeTrigger(const AliESDEvent *aEsd) const;
+ //
+ protected:
+ TList* fOutput; // output list send on output slot 1
+ //
+ Bool_t fDoNormalReco; // do normal reco
+ Bool_t fDoInjection; // do injection
+ Bool_t fDoRotation; // do rotation
+ Bool_t fDoMixing; // do mixing
+ //
+ Bool_t fUseMC;
+ Bool_t fCheckReconstructables;
+ //
+ TObjArray* fHistosTrData; //! all tracklets in data
+ TObjArray* fHistosTrInj; //! injected
+ TObjArray* fHistosTrRot; //! rotated
+ TObjArray* fHistosTrMix; //! mixed
+ //
+ TObjArray* fHistosTrPrim; //! primary
+ TObjArray* fHistosTrSec; //! secondary
+ TObjArray* fHistosTrComb; //! combinatorials
+ TObjArray* fHistosTrCombU; //! combinatorials uncorrelated
+ //
+ TObjArray* fHistosTrRcblPrim; //! Primary Reconstructable
+ TObjArray* fHistosTrRcblSec; //! Secondary Reconstructable
+ TObjArray* fHistosCustom; //! custom histos
+ //
+ // Settings for the reconstruction
+ // tracklet reco settings
+ Float_t fEtaCut; // histos filled only for this eta range
+ Float_t fZVertexMin; // min Z vtx to process
+ Float_t fZVertexMax; // max Z vtx to process
+ //
+ Bool_t fScaleDTBySin2T; // request dTheta scaling by 1/sin^2(theta)
+ Bool_t fCutOnDThetaX; // if true, apart from NStdDev cut apply also the cut on dThetaX
+ Float_t fNStdDev; // cut on weighted distance
+ Float_t fDPhiWindow; // max dPhi
+ Float_t fDThetaWindow; // max dTheta
+ Float_t fDPhiShift; // mean bend
+ Float_t fPhiOverlapCut; // overlaps cut in phi
+ Float_t fZetaOverlap; // overlaps cut in Z
+ Float_t fPhiRot; // rotate L1 wrt L2
+ Float_t fInjScale; // scaling factor for injection
+ Bool_t fRemoveOverlaps; // request overlaps removal
+ //
+ Float_t fDPhiSCut; // cut on signal dphiS
+ Float_t fNStdCut; // cut on signal weighted distance
+ Float_t fMCV0Scale; // scaling factor for V0 in MC
+ //
+ AliITSMultRecBg *fMultReco; //! mult.reco object
+ TTree* fRPTree; //! tree of recpoints
+ TTree* fRPTreeMix; //! tree of recpoints for mixing
+ AliStack* fStack; //! MC stack
+ AliMCEvent* fMCEvent; //! MC Event
+ Float_t fESDVtx[3]; // ESD vertex
+ AliESDtrackCuts* fTrackCuts; //! optional track cuts
+ //
+ //
+ /*
+ AliTriggerAnalysis::Trigger fTrigger; // requested trigger
+ MCCentralityBin fMCCentralityBin; // to select MC centrality bin in which corrections are calculated
+ Float_t fCentrLowLim; // to select centrality bin on data
+ Float_t fCentrUpLim; // to select centrality bin on data
+ TString fCentrEst; // to select centrality estimator
+ */
+ Float_t fNPart; // number of participant pairs from MC
+ Float_t fNBColl; // number of bin. collision from MC
+ Int_t fCurrCentBin; // current centrality bin
+ Int_t fNCentBins; // N of mult bins
+ Int_t fUseCentralityVar; // what is used to determine the centrality
+ const Float_t* fkCentBinDef; //! selected binning in centrality
+ const Float_t* fkCentBinDef2DY; //! Y point of 2D bin
+ const Float_t* fkCentBinDef2DS; //! slope of 2D bin
+ static const Float_t fgkCentBinDefV0[]; //!definition of mult bin (with lower and upper cuts)
+ static const Float_t fgkCentBinDefV0CR[]; //!definition of mult bin (with lower and upper cuts)
+ static const Float_t fgkCentBinDefSPD2[]; //!definition of mult bin (with lower and upper cuts)
+ static const Float_t fgkCentBinDefTrTPC[]; //!definition of mult bin (with lower and upper cuts)
+ //
+ static const Float_t fgkCentBinDefZDCV0X[]; //! ZDC vs V0Corr X
+ static const Float_t fgkCentBinDefZDCV0Y[]; //! ZDC vs V0Corr Y
+ static const Float_t fgkCentBinDefZDCV0S[]; //! ZDC vs V0Corr Slope
+ //
+ static const char* fgkPDGNames[]; //!pdg names
+ static const Int_t fgkPDGCodes[]; //!pdg codes
+ //
+ private:
+ AliTrackletTaskMulti(const AliTrackletTaskMulti&); // not implemented
+ AliTrackletTaskMulti& operator=(const AliTrackletTaskMulti&); // not implemented
+
+ ClassDef(AliTrackletTaskMulti, 1);
+};
+
+
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2008, 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. *
+**************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+// Class AliTrackletTaskUni //
+// Analysis task to study performance and combinatorial background //
+// in tracklet reconstruction //
+// Author: M. Nicassio (INFN Bari) //
+// Contact: Maria.Nicassio@ba.infn.it, Domenico.Elia@ba.infn.it //
+//////////////////////////////////////////////////////////////////////////
+
+#include "TChain.h"
+#include "TTree.h"
+#include "TRandom.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "TH3F.h"
+#include "THnSparse.h"
+#include "TList.h"
+#include "TNtuple.h"
+#include "TObjArray.h"
+#include "TGeoGlobalMagField.h"
+
+#include "AliAnalysisManager.h"
+
+#include "AliMultiplicity.h"
+#include "AliESDEvent.h"
+#include "AliESDInputHandler.h"
+#include "AliESDInputHandlerRP.h"
+#include "../ANALYSIS/EventMixing/AliMixEventInputHandler.h"
+#include "AliCDBPath.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliCDBStorage.h"
+#include "AliGeomManager.h"
+#include "AliMagF.h"
+#include "AliESDVZERO.h"
+#include "AliESDZDC.h"
+#include "AliRunLoader.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliMCParticle.h"
+#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "../ITS/AliITSRecPoint.h"
+#include "../ITS/AliITSgeomTGeo.h"
+#include "../ITS/AliITSMultReconstructor.h"
+
+#include "AliLog.h"
+
+#include "AliPhysicsSelection.h"
+#include "AliESDCentrality.h"
+#include "AliTrackletTaskUni.h"
+#include "AliITSMultRecBg.h"
+#include "AliGenEventHeader.h"
+#include "AliGenHijingEventHeader.h"
+#include "AliGenDPMjetEventHeader.h"
+
+ClassImp(AliTrackletTaskUni)
+
+const char* AliTrackletTaskUni::fgkPDGNames[] = {
+"#pi^{+}",
+"p",
+"K^{+}",
+"K^{*+}",
+"e^{-}",
+"#mu^{-}",
+"#rho^{+}",
+"D^{+}",
+"D^{*+}",
+"D_{s}^{+}",
+"D_{s}^{*+}",
+"#Delta^{-}",
+"#Delta^{+}",
+"#Delta^{++}",
+"#Sigma^{-}",
+"#Sigma^{+}",
+"#Sigma^{*-}",
+"#Sigma^{*+}",
+"#Sigma^{*+}_{c}",
+"#Sigma^{*++}_{c}",
+"#Xi^{-}",
+"#Xi^{*-}",
+"#Lambda^{+}_{c}",
+"n",
+"#Delta^{0}",
+"#gamma",
+"K^{0}_{S}",
+"K^{0}_{L}",
+"K^{0}",
+"K^{*}",
+"#eta",
+"#pi^{0}",
+"#rho^{0}",
+"#varphi",
+"#eta'",
+"#omega",
+"#Lambda",
+"#Sigma^{0}",
+"#Sigma^{*0}_{c}",
+"#Sigma^{*0}",
+"D^{0}",
+"D^{*0}",
+"#Xi_{0}",
+"#Xi^{*0}",
+"#Xi^{0}_{c}",
+"#Xi^{*0}_{c}",
+"Nuclei",
+"Others"
+};
+
+const int AliTrackletTaskUni::fgkPDGCodes[] = {
+ 211,
+ 2212,
+ 321,
+ 323,
+ 11,
+ 13,
+ 213,
+ 411,
+ 413,
+ 431,
+ 433,
+ 1114,
+ 2214,
+ 2224,
+ 3112,
+ 3222,
+ 3114,
+ 3224,
+ 4214,
+ 4224,
+ 3312,
+ 3314,
+ 4122,
+ 2112,
+ 2114,
+ 22,
+ 310,
+ 130,
+ 311,
+ 313,
+ 221,
+ 111,
+ 113,
+ 333,
+ 331,
+ 223,
+ 3122,
+ 3212,
+ 4114,
+ 3214,
+ 421,
+ 423,
+ 3322,
+ 3324,
+ 4132,
+ 4314
+// nuclei
+// unknown
+};
+
+//________________________________________________________________________
+/*//Default constructor
+AliTrackletTaskUni::AliTrackletTaskUni(const char *name)
+ : AliAnalysisTaskSE(name),
+*/
+//________________________________________________________________________
+AliTrackletTaskUni::AliTrackletTaskUni(const char *name)
+ : AliAnalysisTaskSE(name),
+//
+ fOutput(0),
+//
+ fDoNormalReco(kFALSE),
+ fDoInjection(kFALSE),
+ fDoRotation(kFALSE),
+ fDoMixing(kFALSE),
+ //
+ fUseMC(kFALSE),
+ fCheckReconstructables(kFALSE),
+//
+ fHistosTrData(0),
+ fHistosTrInj(0),
+ fHistosTrRot(0),
+ fHistosTrMix(0),
+//
+ fHistosTrPrim(0),
+ fHistosTrSec(0),
+ fHistosTrComb(0),
+ fHistosTrCombU(0),
+//
+ fHistosTrRcblPrim(0),
+ fHistosTrRcblSec(0),
+ fHistosCustom(0),
+//
+ fEtaCut(3.0),
+ fZVertexMin(-20),
+ fZVertexMax( 20),
+ fMultCutMin(0),
+ fMultCutMax(99999),
+//
+ fScaleDTBySin2T(kFALSE),
+ fCutOnDThetaX(kFALSE),
+ fNStdDev(1.),
+ fDPhiWindow(0.08),
+ fDThetaWindow(0.025),
+ fDPhiShift(0.0045),
+ fPhiOverlapCut(0.005),
+ fZetaOverlap(0.05),
+ fPhiRot(0.),
+ fInjScale(1.),
+ fRemoveOverlaps(kFALSE),
+//
+ fMultReco(0),
+ fRPTree(0),
+ fRPTreeMix(0),
+ fStack(0),
+ fMCEvent(0)
+ /*
+ ,
+ fTrigger(AliTriggerAnalysis::kAcceptAll),
+ fMCCentralityBin(AliAnalysisTaskSPDdNdEta::kall),
+ fCentrLowLim(0),
+ fCentrUpLim(0),
+ fCentrEst("")
+ */
+{
+ // Constructor
+
+ DefineOutput(1, TList::Class());
+ //
+ SetScaleDThetaBySin2T();
+ SetNStdDev();
+ SetPhiWindow();
+ SetThetaWindow();
+ SetPhiShift();
+ SetPhiOverlapCut();
+ SetZetaOverlapCut();
+ SetPhiRot();
+ SetRemoveOverlaps();
+ //
+}
+//________________________________________________________________________
+AliTrackletTaskUni::~AliTrackletTaskUni()
+{
+ // Destructor
+ // histograms are in the output list and deleted when the output
+ // list is deleted by the TSelector dtor
+ if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) { //RRR
+ printf("Deleteing output\n");
+ delete fOutput;
+ fOutput = 0;
+ }
+ //
+ delete fMultReco;
+ //
+ delete fHistosTrData;
+ delete fHistosTrPrim;
+ delete fHistosTrSec;
+ delete fHistosTrComb;
+ delete fHistosTrCombU;
+ delete fHistosTrInj;
+ delete fHistosTrRot;
+ delete fHistosTrMix;
+ delete fHistosTrRcblPrim;
+ delete fHistosTrRcblSec;
+ delete fHistosCustom;
+ //
+}
+
+//________________________________________________________________________
+void AliTrackletTaskUni::UserCreateOutputObjects()
+{
+ //
+ fOutput = new TList();
+ fOutput->SetOwner();
+ //
+ AliCDBManager *man = AliCDBManager::Instance();
+ if (fUseMC) {
+ Bool_t newGeom = kTRUE;
+ man->SetDefaultStorage("alien://Folder=/alice/simulation/2008/v4-15-Release/Residual");
+ if (newGeom) {
+ // new geom
+ AliCDBEntry* obj = man->Get("GRP/Geometry/Data",130844,8);
+ AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+ if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",130844,6,-1)) AliFatal("Failed to misalign geometry");
+ }
+ else {
+ // old geom
+ AliCDBEntry* obj = man->Get("GRP/Geometry/Data",130845,7);
+ AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+ if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",130845,5,-1)) AliFatal("Failed to misalign geometry");
+ }
+ }
+ else {
+ man->SetDefaultStorage("raw://"); man->SetRun(137045);
+ AliCDBEntry* obj = man->Get("GRP/Geometry/Data",137045,3);
+ AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+ if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",137045,8,-1)) AliFatal("Failed to misalign geometry");
+ }
+ //
+ // Create histograms
+ //---------------------------------------------Standard histos per tracklet type--->>
+ UInt_t hPattern = 0xffffffff;
+ hPattern &= ~(BIT(kHEtaZvDPhiS)); // pattern of histos to fill
+ fHistosTrData = BookHistosSet("TrData",hPattern);
+ if (GetDoInjection()) fHistosTrInj = BookHistosSet("TrInj",hPattern);
+ if (GetDoRotation()) fHistosTrRot = BookHistosSet("TrRot",hPattern);
+ if (GetDoMixing()) fHistosTrMix = BookHistosSet("TrMix",hPattern);
+ if (fUseMC) {
+ hPattern = 0xffffffff; hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+ fHistosTrPrim = BookHistosSet("TrPrim",hPattern);
+ //
+ hPattern = 0xffffffff; hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+ fHistosTrSec = BookHistosSet("TrSec",hPattern);
+ //
+ hPattern = 0xffffffff;
+ fHistosTrComb = BookHistosSet("TrComb",hPattern);
+ //
+ hPattern = 0xffffffff; hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+ fHistosTrCombU = BookHistosSet("TrCombU",hPattern);
+ //
+ if (fCheckReconstructables) {
+ hPattern = 0xffffffff; hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+ fHistosTrRcblPrim = BookHistosSet("TrRcblPrim",hPattern);
+ //
+ hPattern = 0xffffffff; hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+ fHistosTrRcblSec = BookHistosSet("TrRcblSec",hPattern);
+ }
+ }
+ //---------------------------------------------Standard histos per tracklet type---<<
+ //
+ //---------------------------------------------Custom Histos----------------------->>
+ // put here any non standard histos
+ fHistosCustom = BookCustomHistos();
+ //
+ //---------------------------------------------Custom Histos-----------------------<<
+ int nhist = fOutput->GetEntries();
+ for (int i=0;i<nhist;i++) {
+ TObject* hst = fOutput->At(i);
+ if (!hst || !(hst->InheritsFrom(TH1::Class()))) continue;
+ ((TH1*)hst)->Sumw2();
+ }
+ //
+ PostData(1, fOutput);
+ //
+}
+
+//________________________________________________________________________
+void AliTrackletTaskUni::UserExec(Option_t *)
+{
+ // Main loop
+ //
+ AliAnalysisManager* anMan = AliAnalysisManager::GetAnalysisManager();
+ fRPTree = fRPTreeMix = 0;
+ AliESDInputHandlerRP *handRP = (AliESDInputHandlerRP*)anMan->GetInputEventHandler();
+ if (!handRP) { printf("No RP handler\n"); return; }
+ AliESDEvent *esd = handRP->GetEvent();
+ if (!esd) { printf("No AliESDEvent\n"); return; }
+ //
+ // do we need to initialize the field?
+ AliMagF* field = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
+ if (!field && !esd->InitMagneticField()) {printf("Failed to initialize the B field\n");return;}
+ //
+ /* // RS to be clarified
+ // Trigger selection
+ static AliTriggerAnalysis* triggerAnalysis = 0;
+ Bool_t eventTriggered = triggerAnalysis->IsTriggerFired(esd, fTrigger);
+ if (!eventTriggered) {printf("No trigger\n"); return;}
+ //
+ // Centrality selection
+ Bool_t eventInCentralityBin = kFALSE;
+ // Centrality selection
+ AliESDCentrality *centrality = esd->GetCentrality();
+ if (fCentrEst=="") eventInCentralityBin = kTRUE;
+ else {
+ if(!centrality) {
+ AliError("Centrality object not available");
+ } else {
+ if (centrality->IsEventInCentralityClass(fCentrLowLim,fCentrUpLim,fCentrEst.Data())) eventInCentralityBin = kTRUE;
+ }
+ }
+ */
+
+ const AliESDVertex* vtxESD = esd->GetPrimaryVertexSPD();
+ if (vtxESD->GetNContributors()<1) return;
+ if (vtxESD->GetDispersion()>0.04) return;
+ if (vtxESD->GetZRes()>0.25) return;
+ const AliMultiplicity* multESD = esd->GetMultiplicity();
+ const AliESDVertex* vtxESDTPC = esd->GetPrimaryVertexTPC();
+ if (vtxESDTPC->GetNContributors()<1 ||
+ vtxESDTPC->GetNContributors()<(-10.+0.25*multESD->GetNumberOfITSClusters(0))) return;
+ //
+ TH1F* hstat = (TH1F*)fHistosCustom->UncheckedAt(kHStat);
+ //
+ hstat->Fill(kEvTot); // RS
+ //
+ Double_t esdvtx[3];
+ vtxESD->GetXYZ(esdvtx);
+ for (int i=3;i--;) fESDVtx[i] = esdvtx[i];
+ //
+ float vtxf[3] = {vtxESD->GetX(),vtxESD->GetY(),vtxESD->GetZ()};
+ //
+ //------------------------------------------------------
+ // ZDC cut
+ AliESDZDC *esdZDC = esd->GetESDZDC();
+ // --- ZDC offline trigger ---
+ // Returns if ZDC triggered, based on TDC information
+ Bool_t tdc[32] = {kFALSE};
+ for(Int_t itdc=0; itdc<32; itdc++){
+ for(Int_t i=0; i<4; i++){
+ if (0.025*esdZDC->GetZDCTDCData(itdc, i) != 0){
+ tdc[itdc] = kTRUE;
+ }
+ }
+ }
+ Bool_t zdcNA = tdc[12];
+ Bool_t zdcNC = tdc[10];
+ Bool_t zdcPA = tdc[13];
+ Bool_t zdcPC = tdc[11];
+ //
+ Bool_t zdcC= ((zdcPA) || (zdcNA));
+ Bool_t zdcA= ((zdcPC) || (zdcNC));
+ if (!zdcC || !zdcA) return;
+ //-----------------------------------------------------
+ Float_t multV0A=0,multV0C=0;
+ AliESDVZERO* esdV0 = esd->GetVZEROData();
+ if (esdV0) {
+ multV0A = esdV0->GetMTotV0A();
+ multV0C = esdV0->GetMTotV0C();
+ }
+ if (fUseMC) {
+ const double v0Scale = 0.75108;
+ multV0A *= v0Scale;
+ multV0C *= v0Scale;
+ }
+ // registed Ntracklets and ZVertex of the event
+ ((TH1F*)fHistosCustom->UncheckedAt(kHZVtxNoSel))->Fill(esdvtx[2]);
+ ((TH1F*)fHistosCustom->UncheckedAt(kHNTrackletsNoSel))->Fill(multESD->GetNumberOfTracklets());
+ ((TH1F*)fHistosCustom->UncheckedAt(kHNClSPD1NoSel))->Fill(multESD->GetNumberOfITSClusters(0));
+ ((TH1F*)fHistosCustom->UncheckedAt(kHNClSPD2NoSel))->Fill(multESD->GetNumberOfITSClusters(1));
+ ((TH1F*)fHistosCustom->UncheckedAt(kHV0NoSel))->Fill(multV0A+multV0C);
+ // ((TH2F*)fHistosCustom->UncheckedAt(kHV0NClSPD2NoSel))->Fill(multV0A+multV0C,multESD->GetNumberOfITSClusters(1));
+ //
+ // printf("ESD vertex! %f %f %f, %d contributors\n",esdvtx[0],esdvtx[1],esdvtx[2],vtxESD->GetNContributors());
+
+ if(vtxf[2] < fZVertexMin || vtxf[2] > fZVertexMax) return;
+ ((TH2F*)fHistosCustom->UncheckedAt(kHV0NClSPD2NoSel))->Fill(multV0A+multV0C,multESD->GetNumberOfITSClusters(1));
+ //
+ /// double mltTst = fUseMC ? multESD->GetNumberOfITSClusters(1) : multV0A+multV0C;
+ // double mltTst = multESD->GetNumberOfITSClusters(1); //RRR
+ double mltTst = multV0A+multV0C; //RRR
+
+ if ((mltTst<fMultCutMin) || (mltTst>fMultCutMax)) return;
+ //
+ // if((multESD->GetNumberOfTracklets() < fMultCutMin) || (multESD->GetNumberOfTracklets() > fMultCutMax)) return;
+ //
+ printf("Multiplicity from ESD:\n");
+ // multESD->Print();
+ //
+ AliMCEventHandler* eventHandler = 0;
+ fMCEvent = 0;
+ fStack = 0;
+ //
+ if (fUseMC) {
+ eventHandler = (AliMCEventHandler*)anMan->GetMCtruthEventHandler();
+ if (!eventHandler) { printf("ERROR: Could not retrieve MC event handler\n"); return; }
+ fMCEvent = eventHandler->MCEvent();
+ if (!fMCEvent) { printf("ERROR: Could not retrieve MC event\n"); return; }
+ fStack = fMCEvent->Stack();
+ if (!fStack) { printf("Stack not available\n"); return; }
+ }
+ //
+ fRPTree = handRP->GetTreeR("ITS");
+ if (!fRPTree) { AliError(" Invalid ITS cluster tree !\n"); return; }
+ //
+ //
+ // registed Ntracklets and ZVertex of the event
+ ((TH1F*)fHistosCustom->UncheckedAt(kHZVtx))->Fill(esdvtx[2]);
+ ((TH1F*)fHistosCustom->UncheckedAt(kHNTracklets))->Fill(multESD->GetNumberOfTracklets());
+ //
+ if (fUseMC) FillMCPrimaries( ((TH2F*)fHistosCustom->UncheckedAt(kHZVEtaPrimMC)) );
+ // fill N clusters
+ ((TH1F*)fHistosCustom->UncheckedAt(kHNClSPD1))->Fill(multESD->GetNumberOfITSClusters(0));
+ ((TH1F*)fHistosCustom->UncheckedAt(kHNClSPD2))->Fill(multESD->GetNumberOfITSClusters(1));
+ ((TH1F*)fHistosCustom->UncheckedAt(kHV0))->Fill(multV0A+multV0C);
+ //
+ // normal reconstruction
+ hstat->Fill(kEvProcData);
+ if (GetDoNormalReco() || GetDoInjection()) { // for the injection the normal reco should be done
+ InitMultReco();
+ fMultReco->Run(fRPTree, vtxf);
+ printf("Multiplicity Reconstructed:\n");
+ AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+ if (mlt) mlt->Print();
+ if (GetDoNormalReco()) FillHistos(kData,mlt);
+ //
+ }
+ if (!GetDoNormalReco()) FillHistos(kData,multESD); // fill data histos from ESD
+ //
+ // Injection: it must come right after the normal reco since needs its results
+ if (GetDoInjection()) {
+ if (!fMultReco) InitMultReco(); // in principle, not needed, the reco is created above
+ fMultReco->SetRecType(AliITSMultRecBg::kBgInj);
+ fMultReco->Run(fRPTree, vtxf);
+ printf("Multiplicity from Injection:\n");
+ AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+ if (mlt) mlt->Print();
+ hstat->Fill(kEvProcInj);
+ FillHistos(kBgInj,mlt);
+ }
+ //
+ // Rotation
+ if (GetDoRotation()) {
+ InitMultReco();
+ fMultReco->SetRecType(AliITSMultRecBg::kBgRot);
+ fMultReco->SetPhiRotationAngle(fPhiRot);
+ fMultReco->Run(fRPTree, vtxf);
+ printf("Multiplicity from Rotation:\n");
+ AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+ if (mlt) mlt->Print();
+ hstat->Fill(kEvProcRot);
+ FillHistos(kBgRot,mlt);
+ }
+ //
+ if (GetDoMixing()) {
+ AliMixEventInputHandler* handToMix = (AliMixEventInputHandler*)handRP->MixingHandler();
+ if (!handToMix) { printf("No Mixing handler\n"); return; }
+ handToMix->GetEntry();
+ if(handToMix->MixedEventNumber()<1) {printf("Mixing: No enough events in pool\n"); return;}
+ AliESDInputHandlerRP* handRPMix = (AliESDInputHandlerRP*) handToMix->InputEventHandler(0);
+
+ if (!handRPMix) { printf("No Mixing RP handler\n"); return; }
+ fRPTreeMix = handRPMix->GetTreeR("ITS");
+ if (!fRPTreeMix) { AliError(" Invalid ITS cluster tree of the 2nd event!\n"); return; }
+ //
+ AliESDEvent *esdMix = handRPMix->GetEvent();
+ const AliESDVertex* vtxESDmix = esdMix->GetVertex();
+ ((TH1F*)fHistosCustom->UncheckedAt(kHZVtxMixDiff))->Fill(vtxESDmix->GetZ()-esdvtx[2]);
+ ((TH1F*)fHistosCustom->UncheckedAt(kHNTrMixDiff) )->
+ Fill(esdMix->GetMultiplicity()->GetNumberOfTracklets() - multESD->GetNumberOfTracklets());
+ //
+ InitMultReco();
+ fMultReco->SetRecType(AliITSMultRecBg::kBgMix);
+ fMultReco->Run(fRPTree, vtxf,fRPTreeMix);
+ printf("Multiplicity from Mixing:\n");
+ AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+ if (mlt) mlt->Print();
+ hstat->Fill(kEvProcMix);
+ FillHistos(kBgMix,mlt);
+ //
+ }
+ // =============================================================================<<<
+ //
+ delete fMultReco;
+ fMultReco = 0;
+ //
+}
+//________________________________________________________________________
+void AliTrackletTaskUni::Terminate(Option_t *)
+{
+ Printf("Terminating...");
+ TH1* hstat;
+ TList *lst = dynamic_cast<TList*>(GetOutputData(1));
+ printf("Term: %p %p %p\n",fOutput,lst,fHistosCustom);
+ if (lst && (hstat=(TH1*)lst->FindObject("hStat"))) {
+ Info("Terminate","Registering used settings");
+ // fill used settings
+ hstat->Fill(kDPhi,fDPhiWindow);
+ hstat->Fill(kDTht,fDThetaWindow);
+ hstat->Fill(kNStd,fNStdDev);
+ hstat->Fill(kPhiShift,fDPhiShift);
+ hstat->Fill(kThtS2,fScaleDTBySin2T);
+ hstat->Fill(kThtCW,fCutOnDThetaX);
+ hstat->Fill(kPhiOvl,fPhiOverlapCut);
+ hstat->Fill(kZEtaOvl,fZetaOverlap);
+ hstat->Fill(kNoOvl,fRemoveOverlaps);
+ //
+ hstat->Fill(kPhiRot,fPhiRot);
+ hstat->Fill(kInjScl,fInjScale);
+ hstat->Fill(kEtaCut,fEtaCut);
+ hstat->Fill(kZVMin,fZVertexMin);
+ hstat->Fill(kZVMax,fZVertexMax);
+ hstat->Fill(kTrcMin,fMultCutMin);
+ hstat->Fill(kTrcMax,fMultCutMax);
+ //
+ hstat->Fill(kOneUnit,1.);
+ }
+ //
+
+ // AliAnalysisTaskSE::Terminate();
+}
+
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::InitMultReco()
+{
+ // create mult reconstructor
+ if (fMultReco) delete fMultReco;
+ fMultReco = new AliITSMultRecBg();
+ fMultReco->SetCreateClustersCopy(kTRUE);
+ fMultReco->SetScaleDThetaBySin2T(fScaleDTBySin2T);
+ fMultReco->SetNStdDev(fNStdDev);
+ fMultReco->SetPhiWindow( fDPhiWindow );
+ fMultReco->SetThetaWindow( fDThetaWindow );
+ fMultReco->SetPhiShift( fDPhiShift );
+ fMultReco->SetRemoveClustersFromOverlaps(fRemoveOverlaps);
+ fMultReco->SetPhiOverlapCut(fPhiOverlapCut);
+ fMultReco->SetZetaOverlapCut(fZetaOverlap);
+ fMultReco->SetHistOn(kFALSE);
+ fMultReco->SetRecType( AliITSMultRecBg::kData );
+}
+
+//_________________________________________________________________________
+TObjArray* AliTrackletTaskUni::BookCustomHistos()
+{
+ // book custom histos, not related to specific tracklet type
+ TObjArray* histos = new TObjArray();
+ TH1F* hstat;
+ //
+ // ------------ job parameters, statistics ------------------------------>>>
+ hstat = new TH1F("hStat","Run statistics",kNStatBins,0.5,kNStatBins-0.5);
+ //
+ hstat->GetXaxis()->SetBinLabel(kEvTot, "Ev.Tot");
+ hstat->GetXaxis()->SetBinLabel(kEvProcData,"Ev.ProcData");
+ hstat->GetXaxis()->SetBinLabel(kEvProcInj,"Ev.ProcInj");
+ hstat->GetXaxis()->SetBinLabel(kEvProcRot,"Ev.ProcRot");
+ hstat->GetXaxis()->SetBinLabel(kEvProcMix,"Ev.ProcMix");
+ //
+ hstat->GetXaxis()->SetBinLabel(kDPhi, "#Delta#varphi");
+ hstat->GetXaxis()->SetBinLabel(kDTht, "#Delta#theta");
+ hstat->GetXaxis()->SetBinLabel(kNStd, "N.std");
+ hstat->GetXaxis()->SetBinLabel(kPhiShift,"#delta#varphi");
+ hstat->GetXaxis()->SetBinLabel(kThtS2,"scale #Delta#theta");
+ hstat->GetXaxis()->SetBinLabel(kPhiOvl,"#varpho_{Ovl}");
+ hstat->GetXaxis()->SetBinLabel(kZEtaOvl,"#z_{Ovl}");
+ hstat->GetXaxis()->SetBinLabel(kNoOvl, "rem.ovl");
+ //
+ hstat->GetXaxis()->SetBinLabel(kPhiRot,"#varphi_{rot}");
+ hstat->GetXaxis()->SetBinLabel(kInjScl,"inj");
+ hstat->GetXaxis()->SetBinLabel(kEtaCut,"#eta cut");
+ hstat->GetXaxis()->SetBinLabel(kZVMin,"ZV_{min} cut");
+ hstat->GetXaxis()->SetBinLabel(kZVMax,"ZV_{max} cut");
+ hstat->GetXaxis()->SetBinLabel(kTrcMin,"Mult_{min} cut");
+ hstat->GetXaxis()->SetBinLabel(kTrcMax,"Mult_{max} cut");
+ //
+ hstat->GetXaxis()->SetBinLabel(kOneUnit,"ScaleMerge");
+ hstat->GetXaxis()->SetBinLabel(kNWorkers,"Workers");
+ hstat->Fill(kNWorkers);
+ //
+ AddHisto(histos,hstat,kHStat);
+ // ------------ job parameters, statistics ------------------------------<<<
+ //
+ double etaMn=-3,etaMx=3;
+ double zMn=-30, zMx=30;
+ int nEtaBins = int((etaMx-etaMn)/0.1);
+ if (nEtaBins<1) nEtaBins = 1;
+ //
+ int nZVBins = int(zMx-zMn);
+ if (nZVBins<1) nZVBins = 1;
+ //
+ // Z vertex distribution for events before selection
+ TH1F* hzvns = new TH1F("zvNoSel","Z vertex Before Selection",nZVBins,zMn,zMx);
+ hzvns->GetXaxis()->SetTitle("Zvertex");
+ AddHisto(histos,hzvns,kHZVtxNoSel);
+ //
+ int nbmltSPD2 = 700;
+ double maxmltSPD2 = 7000;
+ int nbmltV0 = 1000;
+ double maxmltV0 = 20000;
+ // N tracklets for processed events
+ TH1F* hntns = new TH1F("NtrackletsNoSel","N Tracklets Before Selection",nbmltSPD2,0,maxmltSPD2);
+ hntns->GetXaxis()->SetTitle("N tracklets");
+ AddHisto(histos,hntns,kHNTrackletsNoSel);
+ //
+ // N SPD1 clusters
+ TH1F* hncl1ns = new TH1F("NClustersSPD1NoSel","N Clusters on SPD1 Before Selection",nbmltSPD2,0,maxmltSPD2);
+ hncl1ns->GetXaxis()->SetTitle("N Clus SPD1");
+ AddHisto(histos,hncl1ns,kHNClSPD1NoSel);
+ //
+ // N SPD2 clusters
+ TH1F* hncl2ns = new TH1F("NClustersSPD2NoSel","N Clusters on SPD2 Before Selection",nbmltSPD2,0,maxmltSPD2);
+ hncl2ns->GetXaxis()->SetTitle("N Clus SPD2");
+ AddHisto(histos,hncl2ns,kHNClSPD2NoSel);
+ //
+ // V0
+ TH1F* hnV0ns = new TH1F("V0NoSel","V0 signal Before Selection",nbmltV0,0,maxmltV0);
+ hnV0ns->GetXaxis()->SetTitle("V0 signal");
+ AddHisto(histos,hnV0ns,kHV0NoSel);
+ //
+ // V0
+ //TH2F* hnV0SPD2ns = new TH2F("V0NDP2NoSel","NSPD2 vs V0 signal Before Selection",2500,0,20000,1400,0,maxmltSPD2);
+ TH2F* hnV0SPD2ns = new TH2F("V0NDP2NoMltSel","NSPD2 vs V0 signal Before Mlt Selection",100,0,maxmltV0,100,0,maxmltSPD2);
+ hnV0SPD2ns->GetXaxis()->SetTitle("V0 signal");
+ hnV0SPD2ns->GetYaxis()->SetTitle("N Clus SPD2 ");
+ AddHisto(histos,hnV0SPD2ns,kHV0NClSPD2NoSel);
+ //
+ //
+ // Z vertex distribution for selected events
+ TH1F* hzv = new TH1F("zv","Z vertex",nZVBins,zMn,zMx);
+ hzv->GetXaxis()->SetTitle("Zvertex");
+ AddHisto(histos,hzv,kHZVtx);
+ //
+ // N tracklets for processed events
+ TH1F* hnt = new TH1F("Ntracklets","N Tracklets",nbmltSPD2,0,maxmltSPD2);
+ hnt->GetXaxis()->SetTitle("N tracklets");
+ AddHisto(histos,hnt,kHNTracklets);
+ //
+ // N SPD1 clusters
+ TH1F* hncl1 = new TH1F("NClustersSPD1","N Clusters on SPD1",nbmltSPD2,0,maxmltSPD2);
+ hncl1->GetXaxis()->SetTitle("N Clus SPD1");
+ AddHisto(histos,hncl1,kHNClSPD1);
+ //
+ // N SPD2 clusters
+ TH1F* hncl2 = new TH1F("NClustersSPD2","N Clusters on SPD2",nbmltSPD2,0,maxmltSPD2);
+ hncl2->GetXaxis()->SetTitle("N Clus SPD2");
+ AddHisto(histos,hncl2,kHNClSPD2);
+ //
+ // V0
+ TH1F* hnV0 = new TH1F("V0","V0 signal",nbmltV0,0,maxmltV0);
+ hnV0->GetXaxis()->SetTitle("V0 signal");
+ AddHisto(histos,hnV0,kHV0);
+ //
+ //----------------------------------------------------------------------
+ int nEtaBinsS = int(2*fEtaCut/0.1);
+ if (nEtaBinsS<1) nEtaBins = 1;
+ //
+ int nZVBinsS = int(fZVertexMax-fZVertexMin);
+ if (nZVBinsS<1) nZVBinsS = 1;
+
+ if (fUseMC) {
+ // Z vertex vs Eta distribution for primaries
+ TH2F* hzvetap = new TH2F("zvEtaPrimMC","Z vertex vs eta PrimMC",nEtaBinsS,-fEtaCut,fEtaCut,nZVBinsS,fZVertexMin,fZVertexMax);
+ hzvetap->GetXaxis()->SetTitle("#eta");
+ hzvetap->GetYaxis()->SetTitle("Zvertex");
+ AddHisto(histos,hzvetap,kHZVEtaPrimMC);
+ }
+ //
+ if (GetDoMixing()) {
+ //
+ // Difference in Z vertex for mixed events
+ TH1F* hzdiff = new TH1F("MixSPDVertexDiff","SPD #Delta Z Vertex distribution ",100,-5,5);
+ hzdiff->GetXaxis()->SetTitle("#Delta Z Vertex [cm]");
+ hzdiff->GetYaxis()->SetTitle(Form("Entries / %1.2f [cm]",10./100.));
+ AddHisto(histos,hzdiff,kHZVtxMixDiff);
+ //
+ // Difference in N tracklets for mixed events
+ TH1F* hntdiff = new TH1F("MixNTrackletsDiff"," SPD tracklets Diff ",2000,-3000,3000);
+ hntdiff->GetXaxis()->SetTitle("# tracklet diff");
+ AddHisto(histos,hntdiff,kHNTrMixDiff);
+ }
+ //
+ // --------------------------------------------------
+ int nDistBins = int(fNStdDev)*2;
+ int npdg = sizeof(fgkPDGNames)/sizeof(char*);
+ TH2F* hpdgP = new TH2F("pdgPrim","primary PDG",npdg,0,npdg,nDistBins,0,fNStdDev);
+ AddHisto(histos,hpdgP,kHPrimPDG);
+ TH2F* hpdgS = new TH2F("pdgSec","secondary PDG",npdg,0,npdg,nDistBins,0,fNStdDev);
+ AddHisto(histos,hpdgS,kHSecPDG);
+ TH2F* hpdgPP = new TH2F("pdgPrimPar","primary parent PDG ",npdg,0,npdg,nDistBins,0,fNStdDev);
+ AddHisto(histos,hpdgPP,kHPrimParPDG);
+ TH2F* hpdgSP = new TH2F("pdgSecPar","secondary parent PDG",npdg,0,npdg,nDistBins,0,fNStdDev);
+ AddHisto(histos,hpdgSP,kHSecParPDG);
+ for (int i=0;i<npdg;i++) {
+ hpdgP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+ hpdgS->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+ hpdgPP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+ hpdgSP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+ }
+ //
+ // -------------------------------------------------
+ histos->SetOwner(kFALSE);
+
+ return histos;
+}
+
+//_________________________________________________________________________
+TObjArray* AliTrackletTaskUni::BookHistosSet(const char* pref, UInt_t selHistos)
+{
+ // book standard set of histos attaching the pref in front of the name/title
+ //
+ const int kNDPhiBins = 100;
+ const int kNDThtBins = 100;
+ int nDistBins = int(fNStdDev)*2;
+
+ int nEtaBins = int(2*fEtaCut/0.1);
+ if (nEtaBins<1) nEtaBins = 1;
+ //
+ int nZVBins = int(fZVertexMax-fZVertexMin);
+ if (nZVBins<1) nZVBins = 1;
+ float dphir = fDPhiWindow*TMath::Sqrt(fNStdDev);
+ float dthtr = fDThetaWindow*TMath::Sqrt(fNStdDev);
+ //
+ TObjArray* histos = new TObjArray();
+ TH2F* h2;
+ THnSparseF* hsp;
+ char buffn[100],bufft[500];
+ //
+ if (selHistos & (0x1<<kHEtaZvDist) ) {
+ // sparse 3d histo for w.dist vs zv vs eta
+ sprintf(buffn,"%s_DistZvEta",pref);
+ sprintf(bufft,"(%s)Weighted Dist.(#Delta) vs Zv vs Eta",pref);
+ int nbnEZD[3] = {nEtaBins,nZVBins,nDistBins};
+ double xmnEZD[3] = {-fEtaCut,fZVertexMin,0};
+ double xmxEZD[3] = { fEtaCut,fZVertexMax,fNStdDev};
+ hsp = new THnSparseF(buffn,bufft,3,nbnEZD,xmnEZD,xmxEZD);
+ hsp->GetAxis(0)->SetTitle("#eta");
+ hsp->GetAxis(1)->SetTitle("Zv");
+ sprintf(bufft,"#Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+ "[#Delta#theta%s/#sigma#theta]^{2}",fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+ hsp->GetAxis(2)->SetTitle(bufft);
+ AddHisto(histos,hsp,kHEtaZvDist);
+ }
+ //
+ if (selHistos & (0x1<<kHEtaZvDPhiS) ) {
+ // sparse 3d histo for dphi vs zv vs eta
+ sprintf(buffn,"%s_DistZvDPhiS",pref);
+ sprintf(bufft,"(%s) #Delta#varphi-#delta_{#varphi} vs Zv vs Eta",pref);
+ int nbnEZP[3] = {nEtaBins,nZVBins, int(dphir*2/0.005)};
+ double xmnEZP[3] = {-fEtaCut,fZVertexMin,-dphir};
+ double xmxEZP[3] = { fEtaCut,fZVertexMax, dphir};
+ hsp = new THnSparseF(buffn,bufft,3,nbnEZP,xmnEZP,xmxEZP);
+ hsp->GetAxis(0)->SetTitle("#eta");
+ hsp->GetAxis(1)->SetTitle("Zv");
+ hsp->GetAxis(2)->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+ AddHisto(histos,hsp,kHEtaZvDPhiS);
+ }
+ //
+ if (selHistos & (0x1<<kHEtaZvCut) ) {
+ sprintf(buffn,"%s_ZvEtaCutT",pref);
+ sprintf(bufft,"(%s) Zv vs Eta with tracklet cut",pref);
+ h2 = new TH2F(buffn,bufft,nEtaBins,-fEtaCut,fEtaCut, nZVBins, fZVertexMin,fZVertexMax);
+ h2->GetXaxis()->SetTitle("#eta");
+ h2->GetYaxis()->SetTitle("Zv");
+ AddHisto(histos,h2,kHEtaZvCut);
+ }
+ //
+ if (selHistos & (0x1<<kHDPhiDTheta) ) {
+ sprintf(buffn,"%s_dPhidTheta",pref);
+ sprintf(bufft,"(%s) #Delta#theta vs #Delta#varphi",pref);
+ h2 = new TH2F(buffn,bufft,kNDPhiBins,-dphir,dphir,kNDThtBins,-dthtr,dthtr);
+ h2->GetXaxis()->SetTitle("#Delta#varphi [rad]");
+ h2->GetYaxis()->SetTitle("#Delta#theta [rad]");
+ AddHisto(histos,h2,kHDPhiDTheta);
+ }
+ //
+ if (selHistos & (0x1<<kHDPhiSDThetaX) ) {
+ sprintf(buffn,"%s_dPhiSdThetaX",pref);
+ sprintf(bufft,"(%s) #Delta#theta%s vs #Delta#varphi-#delta_{#varphi}",pref,fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+ h2 = new TH2F(buffn,bufft,kNDPhiBins,-dphir,dphir,kNDThtBins,-dthtr,dthtr);
+ h2->GetXaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+ sprintf(bufft,"#Delta#theta%s",fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+ h2->GetYaxis()->SetTitle(bufft);
+ AddHisto(histos,h2,kHDPhiSDThetaX);
+ }
+ //
+ if (selHistos & (0x1<<kHEtaDPhiS) ) {
+ sprintf(buffn,"%s_EtaDPhiS",pref);
+ sprintf(bufft,"(%s) #Delta#varphi-#delta_{#varphi} vs #eta",pref);
+ h2 = new TH2F(buffn,bufft,nEtaBins, -fEtaCut,fEtaCut,kNDPhiBins,-dphir,dphir);
+ h2->GetXaxis()->SetTitle("#eta");
+ h2->GetYaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+ AddHisto(histos,h2,kHEtaDPhiS);
+ }
+ //
+ if (selHistos & (0x1<<kHEtaDThetaX) ) {
+ sprintf(buffn,"%s_EtaDThetaX",pref);
+ sprintf(bufft,"(%s) #Delta#theta%s vs #eta",pref,fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+ h2 = new TH2F(buffn,bufft,nEtaBins, -fEtaCut,fEtaCut,kNDThtBins,-dthtr,dthtr);
+ h2->GetXaxis()->SetTitle("#eta");
+ sprintf(bufft,"#Delta#theta%s",fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+ h2->GetYaxis()->SetTitle(bufft);
+ AddHisto(histos,h2,kHEtaDThetaX);
+ }
+ //
+ if (selHistos & (0x1<<kHEtaDist) ) {
+ sprintf(buffn,"%s_EtaDist",pref);
+ sprintf(bufft,"(%s) Weighted Dist.(#Delta) vs #eta",pref);
+ h2 = new TH2F(buffn,bufft,nEtaBins, -fEtaCut,fEtaCut,nDistBins,0,fNStdDev);
+ h2->GetXaxis()->SetTitle("#eta");
+ sprintf(bufft,"#Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+ "[#Delta#theta%s/#sigma#theta]^{2}",fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+ h2->GetYaxis()->SetTitle(bufft);
+ AddHisto(histos,h2,kHEtaDist);
+ }
+ //
+ if (selHistos & (0x1<<kHZvDPhiS) ) {
+ sprintf(buffn,"%s_ZvDPhiS",pref);
+ sprintf(bufft,"(%s) #Delta#varphi-#delta_{#varphi} vs Zv",pref);
+ h2 = new TH2F(buffn,bufft, nZVBins, fZVertexMin,fZVertexMax, kNDPhiBins,-dphir,dphir);
+ h2->GetXaxis()->SetTitle("Zv");
+ h2->GetYaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+ AddHisto(histos,h2,kHZvDPhiS);
+ }
+ //
+ if (selHistos & (0x1<<kHZvDThetaX) ) {
+ sprintf(buffn,"%s_ZvDThetaX",pref);
+ sprintf(bufft,"(%s) #Delta#theta%s vs Zv",pref,fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+ h2 = new TH2F(buffn,bufft, nZVBins, fZVertexMin,fZVertexMax, kNDThtBins,-dthtr,dthtr);
+ h2->GetXaxis()->SetTitle("Zv");
+ h2->GetYaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+ AddHisto(histos,h2,kHZvDThetaX);
+ }
+ //
+ if (selHistos & (0x1<<kHZvDist) ) {
+ sprintf(buffn,"%s_ZvDist",pref);
+ sprintf(bufft,"(%s) Weighted Dist.(#Delta) vs Zv",pref);
+ h2 = new TH2F(buffn,bufft, nZVBins, fZVertexMin,fZVertexMax, nDistBins,0,fNStdDev);
+ h2->GetXaxis()->SetTitle("Zv");
+ sprintf(bufft,"#Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+ "[#Delta#theta%s/#sigma#theta]^{2}",fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+ h2->GetYaxis()->SetTitle(bufft);
+ AddHisto(histos,h2,kHZvDist);
+ }
+ //
+ histos->SetOwner(kFALSE);
+ return histos;
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::AddHisto(TObjArray* histos, TObject* h, Int_t at)
+{
+ // add single histo to the set
+ if (at>=0) histos->AddAtAndExpand(h,at);
+ else histos->Add(h);
+ fOutput->Add(h);
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::FillHistos(Int_t type, const AliMultiplicity* mlt)
+{
+ // fill histos of given type
+ if (!mlt) return;
+ //
+ TObjArray* histos = 0;
+ if (type == kData) histos = fHistosTrData;
+ else if (type == kBgInj) histos = fHistosTrInj;
+ else if (type == kBgRot) histos = fHistosTrRot;
+ else if (type == kBgMix) histos = fHistosTrMix;
+ //
+ Bool_t fillMC = (type==kData) && fUseMC && fStack;
+ //
+ //---------------------------------------- CHECK ------------------------------>>>
+ TArrayF vtxMC;
+ AliGenHijingEventHeader* pyHeader = 0;
+ //
+ if (fUseMC) {
+ pyHeader = (AliGenHijingEventHeader*) fMCEvent->GenEventHeader();//header->GenEventHeader();
+ pyHeader->PrimaryVertex(vtxMC);
+ }
+ //---------------------------------------- CHECK ------------------------------<<<
+ //
+ if (!histos) return;
+ int ntr = mlt->GetNumberOfTracklets();
+ //
+ for (int itr=ntr;itr--;) {
+ //
+ //---------------------------------------- CHECK ------------------------------>>>
+ if (fUseMC) {
+ Bool_t reject = kFALSE;
+ while(1) {
+ int lab0 = mlt->GetLabel(itr,0);
+ int lab1 = mlt->GetLabel(itr,1);
+ if (lab0!=lab1) break;
+ if (!fStack->IsPhysicalPrimary(lab0)) break;
+ //
+ TParticle* part = fStack->Particle(lab0);
+ Float_t dz = part->Vz() - vtxMC[2];
+ if (TMath::Abs(dz)<1e-6) break;
+ reject = kTRUE;
+ break;
+ }
+ if (reject) continue;
+ }
+ //---------------------------------------- CHECK ------------------------------<<<
+ //
+ double theta = mlt->GetTheta(itr);
+ double phi = mlt->GetPhi(itr);
+ double dtheta = mlt->GetDeltaTheta(itr);
+ double dphi = mlt->GetDeltaPhi(itr);
+ double dist = mlt->CalcDist(itr);
+ //
+ FillHistosSet(histos,phi,theta,dphi,dtheta,dist);
+ // special handling for mc info
+ if (fillMC && fStack) {
+ int lab0 = mlt->GetLabel(itr,0);
+ int lab1 = mlt->GetLabel(itr,1);
+ int typeMC = 2; // comb.bg.
+ if (lab0 == lab1) typeMC = fStack->IsPhysicalPrimary(lab0) ? 0:1; // prim or sec
+ if (typeMC==0) FillHistosSet(fHistosTrPrim,phi,theta,dphi,dtheta,dist); // primary
+ else if (typeMC==1) FillHistosSet(fHistosTrSec, phi,theta,dphi,dtheta,dist); // secondary
+ else {
+ FillHistosSet(fHistosTrComb,phi,theta,dphi,dtheta,dist); // comb
+ // for combinatorals fill also the uncorrelated part
+ if (fMultReco) {
+ float *trl = fMultReco->GetTracklet(itr);
+ int clId0 = (int)trl[AliITSMultReconstructor::kClID1];
+ int clId1 = (int)trl[AliITSMultReconstructor::kClID2];
+ float *clLabs0 = fMultReco->GetClusterOfLayer(0,clId0) + AliITSMultReconstructor::kClMC0;
+ float *clLabs1 = fMultReco->GetClusterOfLayer(1,clId1) + AliITSMultReconstructor::kClMC0;
+ if (!HaveCommonParent(clLabs0,clLabs1))
+ FillHistosSet(fHistosTrCombU,phi,theta,dphi,dtheta,dist);
+ }
+ } // combinatorials
+ FillSpecies(typeMC, lab0, dist);
+ if (fCheckReconstructables) CheckReconstructables();
+ }
+ }
+ //
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::FillMCPrimaries(TH2F* hetaz)
+{
+ // fill all MC primaries Zv vs Eta
+ if (!fStack || !fMCEvent) return;
+
+ //---------------------------------------- CHECK ------------------------------>>>
+ TArrayF vtxMC;
+ AliGenHijingEventHeader* pyHeader = 0;
+ //
+ if (fUseMC) {
+ pyHeader = (AliGenHijingEventHeader*) fMCEvent->GenEventHeader();//header->GenEventHeader();
+ pyHeader->PrimaryVertex(vtxMC);
+ }
+ //---------------------------------------- CHECK ------------------------------<<<
+ //
+
+
+ int ntr = fStack->GetNtrack();
+ for (int itr=ntr;itr--;) {
+ if (!fStack->IsPhysicalPrimary(itr)) continue;
+ AliMCParticle *part = (AliMCParticle*)fMCEvent->GetTrack(itr);
+ if (!part->Charge()) continue;
+ //
+ //---------------------------------------- CHECK ------------------------------>>>
+ Float_t dz = part->Zv() - vtxMC[2];
+ if (TMath::Abs(dz)>1e-6) continue; // reject
+ //---------------------------------------- CHECK ------------------------------<<<
+ //
+
+ Float_t theta = part->Theta();
+ if (theta<1e-6 || theta>TMath::Pi()-1e-6) continue;
+ Float_t eta = part->Eta();
+ hetaz->Fill(eta, fESDVtx[2]);
+ }
+ //
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::FillHistosSet(TObjArray* histos, double /*phi*/,double theta,
+ double dphi,double dtheta,double dist)
+{
+ // fill standard set of histos
+ if (dist>fNStdDev) return;
+ //
+ double dphiS = TMath::Abs(dphi) - fDPhiShift;
+ if (dphi<0) dphiS = -dphiS;
+ double eta = -TMath::Log(TMath::Tan(theta/2));
+ if (TMath::Abs(eta)>fEtaCut) return;
+ //
+ double dThetaX = dtheta;
+ if (fScaleDTBySin2T) {
+ double sint = TMath::Sin(theta);
+ dThetaX /= (sint*sint);
+ }
+ //
+ if (fCutOnDThetaX && TMath::Abs(dThetaX)>fDThetaWindow) return;
+ //
+ if (histos->UncheckedAt(kHEtaZvDist)) {
+ double ezd[3] = {eta,fESDVtx[2],dist};
+ ((THnSparseF*)histos->UncheckedAt(kHEtaZvDist))->Fill(ezd);
+ }
+ //
+ if (histos->UncheckedAt(kHEtaZvDPhiS)) {
+ double ezp[3] = {eta,fESDVtx[2],dphiS};
+ ((THnSparseF*)histos->UncheckedAt(kHEtaZvDPhiS))->Fill(ezp);
+ }
+ //
+ if (histos->UncheckedAt(kHDPhiSDThetaX))
+ ((TH2F*)histos->UncheckedAt(kHDPhiSDThetaX))->Fill(dphiS,dThetaX);
+ //
+ if (histos->UncheckedAt(kHEtaDPhiS))
+ ((TH2F*)histos->UncheckedAt(kHEtaDPhiS))->Fill(eta,dphiS);
+ //
+ if (histos->UncheckedAt(kHEtaDThetaX))
+ ((TH2F*)histos->UncheckedAt(kHEtaDThetaX))->Fill(eta,dThetaX);
+ //
+ if (histos->UncheckedAt(kHEtaDist))
+ ((TH2F*)histos->UncheckedAt(kHEtaDist))->Fill(eta,dist);
+ //
+ if (histos->UncheckedAt(kHZvDPhiS))
+ ((TH2F*)histos->UncheckedAt(kHZvDPhiS))->Fill(fESDVtx[2],dphiS);
+ //
+ if (histos->UncheckedAt(kHZvDThetaX))
+ ((TH2F*)histos->UncheckedAt(kHZvDThetaX))->Fill(fESDVtx[2],dThetaX);
+ //
+ if (histos->UncheckedAt(kHZvDist))
+ ((TH2F*)histos->UncheckedAt(kHZvDist))->Fill(fESDVtx[2],dist);
+ //
+ if (dist<=1 && histos->UncheckedAt(kHEtaZvCut))
+ ((TH2F*)histos->UncheckedAt(kHEtaZvCut))->Fill(eta,fESDVtx[2]);
+ //
+}
+
+//__________________________________________________________________
+void AliTrackletTaskUni::FillSpecies(Int_t primsec, Int_t id, double dist)
+{
+ // fill PDGcode
+ TH1 *hPart=0,*hParent=0;
+ if (primsec==0) {
+ hPart = (TH1F*)fHistosCustom->UncheckedAt(kHPrimPDG);
+ hParent = (TH1F*)fHistosCustom->UncheckedAt(kHPrimParPDG);
+ }
+ else if (primsec==1) {
+ hPart = (TH1F*)fHistosCustom->UncheckedAt(kHSecPDG);
+ hParent = (TH1F*)fHistosCustom->UncheckedAt(kHSecParPDG);
+ }
+ else return;
+ int ntr = fStack->GetNtrack();
+ TParticle* part = fStack->Particle(id);
+ int pdgCode = TMath::Abs(part->GetPdgCode());
+ int pdgBin = GetPdgBin(pdgCode);
+ int parID = part->GetFirstMother();
+ int pdgCodePar = -1;
+ int pdgBinPar = -1;
+ while (parID>=0 && parID<ntr) {
+ part = fStack->Particle(parID);
+ pdgCodePar = TMath::Abs(part->GetPdgCode());
+ parID = part->GetFirstMother();
+ }
+ if (pdgCodePar>0) pdgBinPar = GetPdgBin(pdgCodePar);
+ //
+ hPart->Fill(pdgBin,dist);
+ hParent->Fill(pdgBinPar,dist);
+ //
+}
+
+//_________________________________________________________________________
+Int_t AliTrackletTaskUni::GetPdgBin(Int_t pdgCode)
+{
+ // return my pdg bin
+ int ncodes = sizeof(fgkPDGCodes)/sizeof(int);
+ int pdgBin=0;
+ for (pdgBin=0;pdgBin<ncodes;pdgBin++) if (pdgCode==fgkPDGCodes[pdgBin]) break;
+ if (pdgBin>=ncodes) {
+ if (float(pdgCode)>1e9) pdgBin = ncodes; // nuclei
+ else pdgBin = ncodes+1; // unknown
+ }
+ return pdgBin;
+}
+
+//_________________________________________________________________________
+Bool_t AliTrackletTaskUni::HaveCommonParent(const float* clLabs0,const float* clLabs1)
+{
+ // do 2 clusters have common parrent
+ const int kMaxPar = 50;
+ static int pars[2][50];
+ int npars[2]={0,0};
+ const float *labs[2] = {clLabs0,clLabs1};
+ int ntr = fStack->GetNtrack();
+ for (int il=0;il<2;il++) {
+ for (int ilb=0;ilb<3;ilb++) {
+ int lbl = (int)labs[il][ilb];
+ if (lbl<0 || lbl>=ntr) continue;
+ //
+ while (npars[il]<kMaxPar-1) {
+ pars[il][ npars[il]++ ] = lbl;
+ TParticle* part = fStack->Particle(lbl);
+ if (!part) break;
+ lbl = part->GetFirstMother();
+ if (lbl<1 || lbl>=ntr) break;
+ }
+ }
+ }
+ // compare array of parents
+ for (int i0=npars[0];i0--;) for (int i1=npars[1];i1--;) if (pars[0][i0]==pars[1][i1]) return kTRUE;
+ return kFALSE;
+}
+
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::CheckReconstructables()
+{
+ // fill reconstructable tracklets hitsos
+ static TArrayI trInd;
+ static TBits isPrimArr;
+ //
+ if (!fMultReco || !fMultReco->IsRecoDone()) {AliInfo("To check reconstructables the reco had to be requested"); return;}
+ if (!fStack) {AliInfo("MC Stack is not availalble"); return;}
+ const double kPtMin = 0.05;
+ //
+ TClonesArray *clArr[2];
+ for (int ilr=0;ilr<2;ilr++) {
+ clArr[ilr] = fMultReco->GetClustersOfLayer(ilr);
+ if (!clArr[ilr]) {AliInfo("Clusters are not available"); return;}
+ }
+ //
+ int ntr = fStack->GetNtrack();
+ if (!ntr) return;
+ trInd.Reset();
+ if (trInd.GetSize()<ntr) trInd.Set(ntr);
+ isPrimArr.ResetAllBits();
+ // count track wich may be reconstructable
+ //
+ int ntrStore=0,ntrStorePrim=0;
+ Int_t *trIndArr = trInd.GetArray();
+ for (Int_t it=0; it<ntr; it++) {
+ TParticle* part = fStack->Particle(it);
+ if (TMath::Abs(part->Eta())>2.2) continue;
+ if (TMath::Abs(part->Pt())<kPtMin) continue;
+ if (fStack->IsPhysicalPrimary(it)) {
+ isPrimArr.SetBitNumber(it);
+ ntrStorePrim++;
+ }
+ else { // check if secondary is worth cheking
+ TParticlePDG* pdgPart = part->GetPDG();
+ if (TMath::Abs(pdgPart->Charge())!=3) continue;
+ if (part->R()>5.) continue;
+ }
+ trIndArr[it] = ++ntrStore;
+ }
+ //
+ AliInfo(Form("Selected %d MC particles (%d prim) out of %d in the stack\n",ntrStore,ntrStorePrim,ntr));
+ //
+ const int kMaxCl=3;
+ AliITSRecPoint **clIndL[2];
+ clIndL[0] = new AliITSRecPoint*[kMaxCl*ntrStore]; // max 2 clusters per layer
+ clIndL[1] = new AliITSRecPoint*[kMaxCl*ntrStore]; // max 2 clusters per layer
+ memset(clIndL[0],0,kMaxCl*ntrStore*sizeof(AliITSRecPoint*));
+ memset(clIndL[1],0,kMaxCl*ntrStore*sizeof(AliITSRecPoint*));
+ //
+ for (int ilr=0;ilr<2;ilr++) {
+ TClonesArray *clusters = clArr[ilr];
+ int ncl = clusters->GetEntriesFast();
+ for (int icl=ncl;icl--;) {
+ AliITSRecPoint *cl = (AliITSRecPoint*)clusters->UncheckedAt(icl);
+ for (int ilb=3;ilb--;) {
+ int lbl = cl->GetLabel(ilb); if (lbl<0 || lbl>=ntr) continue;
+ int lblI = trIndArr[lbl];
+ if (--lblI<0) continue; // not kept
+ for (int icc=0;icc<kMaxCl;icc++) if (!clIndL[ilr][lblI+icc*ntrStore]) {clIndL[ilr][lblI+ntrStore*icc] = cl; break;} // first empty one
+ }
+ }
+ }
+ //
+ Float_t clusterLay[2][AliITSMultReconstructor::kClNPar];
+ double trComp[6][kMaxCl*kMaxCl];
+ int indQual[kMaxCl*kMaxCl];
+ //
+ for (int itr=ntr;itr--;) {
+ int lblI = trIndArr[itr];
+ if (--lblI<0) continue; // discarded
+ int ntrCand = 0; // number of tracklet candidates (including overlaps)
+ for (int icl0=0;icl0<kMaxCl;icl0++) {
+ AliITSRecPoint *cl0 = clIndL[0][lblI+icl0*ntrStore];
+ if (!cl0 || !clIndL[1][lblI]) break;
+ cl0->GetGlobalXYZ( clusterLay[0] );
+ fMultReco->ClusterPos2Angles(clusterLay[0], fESDVtx);
+ for (int icl1=0;icl1<kMaxCl;icl1++) {
+ AliITSRecPoint *cl1 = clIndL[1][lblI+icl1*ntrStore];
+ if (!cl1) break;
+ cl1->GetGlobalXYZ( clusterLay[1] );
+ fMultReco->ClusterPos2Angles(clusterLay[1], fESDVtx);
+ trComp[AliITSMultReconstructor::kTrPhi][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClPh];
+ trComp[AliITSMultReconstructor::kTrTheta][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClTh];
+ trComp[AliITSMultReconstructor::kTrDTheta][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClTh] - clusterLay[1][AliITSMultReconstructor::kClTh];
+ trComp[AliITSMultReconstructor::kTrDPhi][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClPh] - clusterLay[1][AliITSMultReconstructor::kClPh];
+ trComp[AliITSMultReconstructor::kTrLab1][ntrCand] = icl1*10 + icl0;
+ double &dphi = trComp[ntrCand][3];
+ if (dphi>TMath::Pi()) dphi=2.*TMath::Pi()-dphi; // take into account boundary condition
+ trComp[5][ntrCand] = fMultReco->CalcDist(trComp[AliITSMultReconstructor::kTrDPhi][ntrCand],
+ trComp[AliITSMultReconstructor::kTrDTheta][ntrCand],
+ trComp[AliITSMultReconstructor::kTrTheta][ntrCand]);
+ ntrCand++;
+ }
+ }
+ if (!ntrCand) continue; // no tracklets
+ if (ntrCand>1) TMath::Sort(ntrCand,trComp[5],indQual,kFALSE); else indQual[0] = 0; // sort in weighted distance
+ if (fRemoveOverlaps) ntrCand = 1; // select the best
+ //
+ // disable worst tracklet with shared cluster
+ for (int itc=0;itc<ntrCand;itc++) {
+ int ind = indQual[itc];
+ if (trComp[AliITSMultReconstructor::kTrLab1][ind]<0) continue; // already disabled
+ for (int jtc=itc+1;jtc<ntrCand;jtc++) {
+ int jnd = indQual[jtc];
+ if (trComp[AliITSMultReconstructor::kTrLab1][jnd]<0) continue; // already disabled
+ if ( int(trComp[AliITSMultReconstructor::kTrLab1][ind])/10 == int(trComp[AliITSMultReconstructor::kTrLab1][jnd])/10 ||
+ int(trComp[AliITSMultReconstructor::kTrLab1][ind])%10 == int(trComp[AliITSMultReconstructor::kTrLab1][jnd])%10) trComp[AliITSMultReconstructor::kTrLab1][jnd] = -1;
+ }
+ }
+ //
+ // store, but forbid cluster reusing
+ TObjArray* histos = isPrimArr.TestBitNumber(itr) ? fHistosTrRcblPrim : fHistosTrRcblSec;
+ for (int itc=0;itc<ntrCand;itc++) {
+ int ind = indQual[itc];
+ if (trComp[4][ind]<0) continue; // discarded
+ FillHistosSet(histos,
+ trComp[AliITSMultReconstructor::kTrPhi][ind],trComp[AliITSMultReconstructor::kTrTheta][ind],
+ trComp[AliITSMultReconstructor::kTrDPhi][ind],trComp[AliITSMultReconstructor::kTrDTheta][ind],
+ trComp[5][ind]);
+ }
+ }
+ //
+ delete[] clIndL[0];
+ delete[] clIndL[1];
+}
+
--- /dev/null
+#ifndef ALITRACKLETTASKUNI_H
+#define ALITRACKLETTASKUNI_H
+
+///////////////////////////////////////////////////////////////////////////
+// Class AliTrackletTask //
+// Analysis task to study performance of tracklet reconstruction //
+// algorithm and combinatorial background //
+// Author: M. Nicassio (INFN Bari) //
+// Contact: Maria.Nicassio@ba.infn.it, Domenico.Elia@ba.infn.it //
+///////////////////////////////////////////////////////////////////////////
+
+class TH1F;
+class TH2F;
+class AliESDEvent;
+class TList;
+class TNtuple;
+
+class AliMCParticle;
+class AliITSMultRecBg;
+
+#include "../ITS/AliITSsegmentationSPD.h"
+#include "AliAnalysisTaskSE.h"
+#include "AliTriggerAnalysis.h"
+
+class AliTrackletTaskUni : public AliAnalysisTaskSE {
+ public:
+ enum {kData,kBgInj,kBgRot,kBgMix,kMC};
+ //
+ enum { // define here id's of the standard histos in corresponding TObjArray* fHistosTr...
+ kHEtaZvDist, // 3 d sparse histo with dist (uncut) vs zv vs eta
+ kHEtaZvDPhiS, // 3 d sparse histo with dphiS (uncut) vs zv vs eta
+ kHEtaZvCut, // zv vs eta with strict cut on tracklets applied (dist<1 or |dPhi|<narrowWindow)
+ kHDPhiDTheta, // measured dTheta vs dPhi
+ kHDPhiSDThetaX, // dTheta (1/sin^2 scaled if needed) vs dPhi (bending subtracted)
+ kHEtaDPhiS, // dPhi (bending subtracted) vs eta
+ kHEtaDThetaX, // dTheta (1/sin^2 scaled if needed) vs eta
+ kHEtaDist, // Weighted distance vs eta
+ kHZvDPhiS, // dPhi (bending subtracted) vs Zv
+ kHZvDThetaX, // dTheta (1/sin^2 scaled if needed) vs Zv
+ kHZvDist // Weighted distance vs Zv
+ };
+ enum { // define here id's of any custom histos to be added to fHistosCustom
+ kHStat, // job info (meaning of bins defined in the enum below)
+ kHZVEtaPrimMC, // Zv vs eta for all primary tracks (true MC multiplicity)
+ //
+ kHZVtxNoSel, // Z vertex distribution before event selection
+ kHNTrackletsNoSel, // N tracklets before event selection
+ kHNClSPD1NoSel, // N clusters on SPD1 before event selection
+ kHNClSPD2NoSel, // N clusters on SPD2 before event selection
+ kHV0NoSel, // V0 mult before selection
+ kHV0NClSPD2NoSel, // V0 - nspd2 correlation
+ //
+ kHZVtx, // Z vertex distribution
+ kHNTracklets, // N tracklets
+ kHNClSPD1, // N clusters on SPD1
+ kHNClSPD2, // N clusters on SPD2
+ kHV0, // V0 mult after selection
+ //
+ kHZVtxMixDiff, // difference in Z vtx of mixed events
+ kHNTrMixDiff, // difference in N tracklets of mixed events
+ //
+ kHPrimPDG, // PDG code of prim tracklet
+ kHSecPDG, // PDG code of sec tracklet
+ kHPrimParPDG, // PDG code of prim tracklet parent
+ kHSecParPDG // PDG code of sec tracklet parent
+ }; // custom histos
+
+ // bins for saved parameters
+ enum {kDummyBin,
+ kEvTot, // events read
+ kEvProcData, // events with data mult.object (ESD or reco)
+ kEvProcInj, // events Injected
+ kEvProcRot, // events Rotated
+ kEvProcMix, // events Mixed
+ //
+ kDPhi, // dphi window
+ kDTht, // dtheta window
+ kNStd, // N.standard deviations to keep
+ kPhiShift, // bending shift
+ kThtS2, // is dtheta scaled by 1/sin^2
+ kThtCW, // on top of w.dist cut cut also on 1 sigma dThetaX
+ kPhiOvl, // overlap params
+ kZEtaOvl, // overlap params
+ kNoOvl, // flag that overlap are suppressed
+ //
+ kPhiRot, // rotation phi
+ kInjScl, // injection scaling
+ kEtaCut, // eta cut
+ kZVMin, // min ZVertex to process
+ kZVMax, // max ZVertex to process
+ kTrcMin, // min mult to process
+ kTrcMax, // max mult to process
+ //
+ kOneUnit=49, // just 1 to track mergings
+ kNWorkers=50, // n workers
+ kNStatBins
+ };
+
+ //
+ AliTrackletTaskUni(const char *name = "AliTrackletTaskUni");
+ virtual ~AliTrackletTaskUni();
+
+ virtual void UserCreateOutputObjects();
+ virtual void UserExec(Option_t *option);
+ virtual void Terminate(Option_t *);
+
+ void SetUseMC(Bool_t mc = kFALSE) {fUseMC = mc;}
+ void SetCheckReconstructables(Bool_t c=kFALSE) {fCheckReconstructables = c;}
+ TObjArray* BookHistosSet(const char* pref, UInt_t selHistos=0xffffffff);
+ TObjArray* BookCustomHistos();
+ void AddHisto(TObjArray* histos, TObject* h, Int_t at=-1);
+ void FillHistosSet(TObjArray* histos, double phi,double theta,double dphi,double dtheta,double dist);
+ // RS
+ void SetNStdDev(Float_t f=1.) {fNStdDev = f<1e-5 ? 1e-5:f;}
+ void SetScaleDThetaBySin2T(Bool_t v=kFALSE) {fScaleDTBySin2T = v;}
+ void SetCutOnDThetaX(Bool_t v=kFALSE) {fCutOnDThetaX = v;}
+ void SetPhiWindow(float w=0.08) {fDPhiWindow = w<1e-5 ? 1e-5:w;}
+ void SetThetaWindow(float w=0.025) {if (w<0) fCutOnDThetaX=kTRUE; fDThetaWindow = TMath::Abs(w)<1e-5 ? 1e-5:TMath::Abs(w);}
+ void SetPhiShift(float w=0.0045) {fDPhiShift = w;}
+ void SetPhiOverlapCut(float w=0.005) {fPhiOverlapCut = w;}
+ void SetZetaOverlapCut(float w=0.05) {fZetaOverlap = w;}
+ void SetPhiRot(float w=0) {fPhiRot = w;}
+ void SetInjScale(Float_t s=1.) {fInjScale = s>0? s:1.;}
+ void SetRemoveOverlaps(Bool_t w=kFALSE) {fRemoveOverlaps = w;}
+ //
+ void SetEtaCut(Float_t eta) {fEtaCut = eta;}
+ void SetZVertexMin(Float_t z) {fZVertexMin = z;}
+ void SetZVertexMax(Float_t z) {fZVertexMax = z;}
+ void SetMultCutMin(Int_t n=0) {fMultCutMin = n;}
+ void SetMultCutMax(Int_t n=99999) {fMultCutMax = n;}
+ //
+ Bool_t GetDoNormalReco() const {return fDoNormalReco;}
+ Bool_t GetDoInjection() const {return fDoInjection;}
+ Bool_t GetDoRotation() const {return fDoRotation;}
+ Bool_t GetDoMixing() const {return fDoMixing;}
+ //
+ void SetDoNormalReco(Bool_t v=kTRUE) {fDoNormalReco = v;}
+ void SetDoInjection(Bool_t v=kTRUE) {fDoInjection = v;}
+ void SetDoRotation(Bool_t v=kTRUE) {fDoRotation = v;}
+ void SetDoMixing(Bool_t v=kTRUE) {fDoMixing = v;}
+ //
+ /*
+ void SetTrigger(AliTriggerAnalysis::Trigger trigger) { fTrigger = trigger; }
+ void SetMCCentralityBin(MCCentralityBin mccentrbin) { fMCCentralityBin = mccentrbin;}
+ void SetCentralityLowLim(Float_t centrlowlim) { fCentrLowLim = centrlowlim;}
+ void SetCentralityUpLim(Float_t centruplim) { fCentrUpLim = centruplim;}
+ void SetCentralityEst(TString centrest) { fCentrEst = centrest;}
+ */
+ //
+ protected:
+ void InitMultReco();
+ Bool_t HaveCommonParent(const float* clLabs0,const float* clLabs1);
+ void FillHistos(Int_t type, const AliMultiplicity* mlt);
+ void FillMCPrimaries(TH2F* hetaz);
+ void FillSpecies(Int_t primsec, Int_t id, Double_t dist);
+ Int_t GetPdgBin(Int_t pdgCode);
+ void CheckReconstructables();
+ //
+ protected:
+ TList* fOutput; // output list send on output slot 1
+ //
+ Bool_t fDoNormalReco; // do normal reco
+ Bool_t fDoInjection; // do injection
+ Bool_t fDoRotation; // do rotation
+ Bool_t fDoMixing; // do mixing
+ //
+ Bool_t fUseMC;
+ Bool_t fCheckReconstructables;
+ //
+ TObjArray* fHistosTrData; //! all tracklets in data
+ TObjArray* fHistosTrInj; //! injected
+ TObjArray* fHistosTrRot; //! rotated
+ TObjArray* fHistosTrMix; //! mixed
+ //
+ TObjArray* fHistosTrPrim; //! primary
+ TObjArray* fHistosTrSec; //! secondary
+ TObjArray* fHistosTrComb; //! combinatorials
+ TObjArray* fHistosTrCombU; //! combinatorials uncorrelated
+ //
+ TObjArray* fHistosTrRcblPrim; //! Primary Reconstructable
+ TObjArray* fHistosTrRcblSec; //! Secondary Reconstructable
+ TObjArray* fHistosCustom; //! custom histos
+ //
+ // Settings for the reconstruction
+ // tracklet reco settings
+ Float_t fEtaCut; // histos filled only for this eta range
+ Float_t fZVertexMin; // min Z vtx to process
+ Float_t fZVertexMax; // max Z vtx to process
+ Int_t fMultCutMin; // min mult in ESD to process?
+ Int_t fMultCutMax; // max mult in ESD to process?
+ //
+ Bool_t fScaleDTBySin2T; // request dTheta scaling by 1/sin^2(theta)
+ Bool_t fCutOnDThetaX; // if true, apart from NStdDev cut apply also the cut on dThetaX
+ Float_t fNStdDev; // cut on weighted distance
+ Float_t fDPhiWindow; // max dPhi
+ Float_t fDThetaWindow; // max dTheta
+ Float_t fDPhiShift; // mean bend
+ Float_t fPhiOverlapCut; // overlaps cut in phi
+ Float_t fZetaOverlap; // overlaps cut in Z
+ Float_t fPhiRot; // rotate L1 wrt L2
+ Float_t fInjScale; // scaling factor for injection
+ Bool_t fRemoveOverlaps; // request overlaps removal
+ //
+ AliITSMultRecBg *fMultReco; //! mult.reco object
+ TTree* fRPTree; //! tree of recpoints
+ TTree* fRPTreeMix; //! tree of recpoints for mixing
+ AliStack* fStack; //! MC stack
+ AliMCEvent* fMCEvent; //! MC Event
+ Float_t fESDVtx[3]; // ESD vertex
+ //
+ /*
+ AliTriggerAnalysis::Trigger fTrigger; // requested trigger
+ MCCentralityBin fMCCentralityBin; // to select MC centrality bin in which corrections are calculated
+ Float_t fCentrLowLim; // to select centrality bin on data
+ Float_t fCentrUpLim; // to select centrality bin on data
+ TString fCentrEst; // to select centrality estimator
+ */
+ static const char* fgkPDGNames[]; //!pdg names
+ static const Int_t fgkPDGCodes[]; //!pdg codes
+ //
+ private:
+ AliTrackletTaskUni(const AliTrackletTaskUni&); // not implemented
+ AliTrackletTaskUni& operator=(const AliTrackletTaskUni&); // not implemented
+
+ ClassDef(AliTrackletTaskUni, 1);
+};
+
+
+#endif
--- /dev/null
+void AnalysisMacroGlob(TString dataset="/alice/sim/LHC10f8f_130844",
+ TString outFName="glovar.root",
+ Int_t nEvents = 5000,
+ Int_t nEventsSkip = 0)
+{
+ //
+ TString format = GetFormatFromDataSet(dataset);
+ //
+ // ALICE stuff
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) mgr = new AliAnalysisManager("Test train");
+ //
+ Bool_t isMC = dataset.Contains("sim");
+ InputHandlerSetup(format,kFALSE,isMC);
+ gProof->Load("AliTaskGlobVar.cxx++g");
+ //
+ /*
+ gROOT->LoadMacro("AddTaskGlobVar.C");
+ AliTaskGlobVar *task = AddTaskGlobVar(outFName.Data());
+ */
+ AliTaskGlobVar *task = new AliTaskGlobVar("AliTaskGlobVar");
+ // create output container
+ AliAnalysisDataContainer *coutput1 =
+ mgr->CreateContainer("clist", TList::Class(),AliAnalysisManager::kOutputContainer,outFName.Data());
+ // add our task to the manager
+ mgr->AddTask(task);
+ //
+ // finaly connect input and output
+ mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
+ mgr->ConnectOutput(task,1,coutput1);
+ //
+ if (!isMC) {
+ AddPhysicsSelection();
+ task->SelectCollisionCandidates( AliVEvent::kUserDefined );
+ task->SetUseMC(kFALSE);
+ }
+ else task->SetUseMC(kTRUE);
+ // else task->SelectCollisionCandidates( AliVEvent::kMB);
+ //
+ // Run analysis
+ mgr->InitAnalysis();
+ // process dataset
+ mgr->StartAnalysis("proof", dataset.Data(), nEvents, nEventsSkip);
+ //
+ TString evstCmd = "if [ -e event_stat.root ]; then \nmv event_stat.root evstat_";
+ evstCmd += outFName; evstCmd += " \nfi";
+ gSystem->Exec( evstCmd.Data() );
+
+}
+
+
+TString GetFormatFromDataSet(TString dataset) {
+
+// Info("runAAF.C","Detecting format from dataset (may take while, depends on network connection)...");
+ TString dsTreeName;
+ if (dataset.Contains("#")) {
+ Info("runAAF.C",Form("Detecting format from dataset name '%s' ...",dataset.Data()));
+ dsTreeName=dataset(dataset.Last('#'),dataset.Length());
+ } else {
+ Info("runAAF.C",Form("Detecting format from dataset '%s' (may take while, depends on network connection) ...",dataset.Data()));
+ TFileCollection *ds = gProof->GetDataSet(dataset.Data());
+ if (!ds) {
+ Error(Form("Dataset %s doesn't exist on proof cluster!!!!",dataset.Data()));
+ return "";
+ }
+ dsTreeName = ds->GetDefaultTreeName();
+ }
+
+ if (dsTreeName.Contains("esdTree")) {
+ Info("runAAF.C","ESD input format detected ...");
+ return "ESD";
+ } else if (dsTreeName.Contains("aodTree")) {
+ Info("runAAF.C","AOD input format detected ...");
+ return "AOD";
+ } else {
+ Error("runAAF.C",Form("Tree %s is not supported !!!",dsTreeName.Data()));
+ Error("runAAF.C",Form("Maybe set your DS to %s#esdTree or %s#aodTree",dataset.Data(),dataset.Data()));
+ }
+
+ return "";
+}
+
+Bool_t InputHandlerSetup(TString format = "esd", Bool_t useRP=kFALSE, Bool_t useKine = kFALSE)
+{
+ format.ToLower();
+
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+
+ AliAnalysisDataContainer *cin = mgr->GetCommonInputContainer();
+
+ if (cin) return;
+
+ if (!format.CompareTo("esd"))
+ {
+ AliESDInputHandler *esdInputHandler = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+ if (!esdInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating esdInputHandler ...");
+ if (useRP) esdInputHandler = new AliESDInputHandlerRP();
+ else esdInputHandler = new AliESDInputHandler();
+ mgr->SetInputEventHandler(esdInputHandler);
+ }
+
+ if (useKine)
+ {
+ AliMCEventHandler* mcInputHandler = dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+
+ if (!mcInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating mcInputHandler ...");
+ AliMCEventHandler* mcInputHandler = new AliMCEventHandler();
+ mgr->SetMCtruthEventHandler(mcInputHandler);
+ }
+ }
+
+ }
+ else if (!format.CompareTo("aod"))
+ {
+ AliAODInputHandler *aodInputHandler = dynamic_cast<AliAODInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+ if (!aodInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating aodInputHandler ...");
+ aodInputHandler = new AliAODInputHandler();
+ mgr->SetInputEventHandler(aodInputHandler);
+ }
+ }
+ else
+ {
+ Info("Wrong input format!!! Only ESD and AOD are supported. Skipping Task ...");
+ return kFALSE;
+ }
+
+ return kTRUE;
+}
+
+void AddPhysicsSelection(Bool_t isMC=kFALSE)
+{
+ // physics selection a la Michele
+ printf("Requesting physics selection in %s mode\n",isMC ? "MC":"Data");
+ gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+ //isMC is true when processing monte carlo, the second 0 disables the cluster vs tracklets
+ AliPhysicsSelectionTask* physicsSelectionTask = AddTaskPhysicsSelection(isMC,0);
+ if(!isMC) {
+ AliPhysicsSelection * physSel = physicsSelectionTask->GetPhysicsSelection();
+ physSel->AddCollisionTriggerClass("+CMBAC-B-NOPF-ALL");
+ /*
+ physSel->AddCollisionTriggerClass("+CMBS1C-B-NOPF-ALL");
+ physSel->AddCollisionTriggerClass("+CMBS1A-B-NOPF-ALL");
+ */
+ //
+ physSel->AddCollisionTriggerClass("+CMBS2C-B-NOPF-ALL");
+ physSel->AddCollisionTriggerClass("+CMBS2A-B-NOPF-ALL");
+ //
+ // This are needed only to fill the statistics tables
+ physSel->AddBGTriggerClass("+CMBAC-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBAC-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBAC-E-NOPF-ALL");
+ //
+ /*
+ physSel->AddBGTriggerClass("+CMBS1C-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1C-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1C-E-NOPF-ALL");
+ //
+ physSel->AddBGTriggerClass("+CMBS1A-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1A-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1A-E-NOPF-ALL");
+ //
+ */
+ /*
+ //
+ physSel->AddBGTriggerClass("+CMBS2C-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2C-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2C-E-NOPF-ALL");
+ //
+ physSel->AddBGTriggerClass("+CMBS2A-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2A-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2A-E-NOPF-ALL");
+ */
+ }
+ // if you use the following line, your task only gets the selected events
+ // task->SelectCollisionCandidates(AliVEvent::kUserDefined);
+ //
+ //Alternatively, in the UserExec of your task:
+ //Bool_t isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kUserDefined);
+ //
+}
--- /dev/null
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "TList.h"
+#include "TFile.h"
+#include "TStyle.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "THnSparse.h"
+#include "TLegend.h"
+#include "TSystem.h"
+#include "TMath.h"
+#include "TCanvas.h"
+#include "TLegend.h"
+#include "TLatex.h"
+#include "TF1.h"
+#include "TLine.h"
+#include "TPaletteAxis.h"
+//
+//
+#endif
+#include "/home/shahoian/ALICE/mymacros/SaveCanvas.h"
+
+
+
+const char kHStatName[]="hStat";
+double kEps = 1e-6;
+//
+double kdPhiBgTailMin = 0.1; // lower limit of dphi tail to use for bg normalization
+double kdPhiBgTailMax = 0.3; // upper limit of dphi tail to use for bg normalization
+//
+double kWDistBgTailMin = 5.; // lower limit of wgh.distance tail to use for bg normalization
+double kWDistBgTailMax = 25.; // upper limit of wgh.distance tail to use for bg normalization
+
+double kdPhiSgCut = 0.06; // cut in dphi-bent used to extract the signal, extracted from stat histo
+double kWDistSgCut = 1.5; // cut in w.distance used to extract the signal, extracted from stat histo
+//
+enum { kNormShapeDist, // normalize bg tails usig weighted distance shape
+ kNormShapeDPhi, // normalize bg tails usig dPhi-bend shape
+ kNormShapes};
+
+enum { kSclWghMean, // normalize bg tails to data using weighted mean of bin-by-bin ratios
+ kSclIntegral, // normalize bg tails to data using integral
+ kSclTypes};
+
+// histograms to be used for bg nomalization for each of NormShapes used
+const char* kNormShapeH[kNormShapes] = {
+ "EtaDist", // Weighted distance vs Eta
+ "EtaDPhiS" // Dphi-bent vs distance
+};
+
+const char* figDir = "fig161110";
+TString useBgType = "Inj";
+Int_t useShapeType = kNormShapeDist; // which distribution to use for bg normalization
+Bool_t useMCLB = 0;//kFALSE; // use Comb MC Labels as a template for Bg.
+Int_t useScaleType = kSclIntegral;//kSclWghMean; // which type of tails normalization to use
+Double_t useEtaCut = 1.; // cut on eta
+Double_t useZvMin = -5.; // cut on Z vertex
+Double_t useZvMax = 5.; // cut on Z vertex
+Int_t useBinGrEta = -1; // for bg fits group eta bins
+Int_t useBinGrZv = -1; // for bg fits group Zv bins
+
+enum {kBitNormPerEvent=BIT(14)};
+ // bins for saved parameters in the hStat histo
+enum {kDummyBin,
+ kEvTot, // events read
+ kEvProcData, // events with data mult.object (ESD or reco)
+ kEvProcInj, // events Injected
+ kEvProcRot, // events Rotated
+ kEvProcMix, // events Mixed
+ //
+ kDPhi, // dphi window
+ kDTht, // dtheta window
+ kNStd, // N.standard deviations to keep
+ kPhiShift, // bending shift
+ kThtS2, // is dtheta scaled by 1/sin^2
+ kPhiOvl, // overlap params
+ kZEtaOvl, // overlap params
+ kNoOvl, // flag that overlap are suppressed
+ //
+ kPhiRot, // rotation phi
+ kInjScl, // injection scaling
+ kEtaCut, // eta cut
+ kZVMin, // min ZVertex to process
+ kZVMax, // max ZVertex to process
+ kTrcMin, // min mult to process
+ kTrcMax, // max mult to process
+ //
+ kOneUnit=49, // just 1 to track mergings
+ kNWorkers=50, // n workers
+ kNStatBins
+};
+
+
+enum {kSigCorr,kMCPrim,kRawDtCut,kSignalEst,kSignalEstMC,kBgEst,k1MBeta,k1MBetaMC,kAlpha,kAlphaMC,kBgMC,kBgRescFc,kDataDist,kBgDist,kBgMCDist, kNHistos, kMCShift=20};
+
+void CorrectSpectra(const char* flNameData, const char* flNameMC,const char* unique="");
+void PrepareHistos(TList* lst, Bool_t isMC, TObjArray* outArray);
+void ProcessHistos(TObjArray* outArray);
+TH1* NormalizeBg(TH1* dataH, TH1* bgH, double &scl, double &scle);
+TObject* FindObject(const char* nameH, const TList* lst, Bool_t normPerEvent=kTRUE);
+TList* LoadList(const char* flName, const char* addPref, const char* nameL="clist");
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate);
+Int_t CheckStat(const TList* lst,const char* dtType);
+void Integrate(TH1* hist, double xmn,double xmx, double &val, double& err);
+void CropHisto(TH1* histo, int b00, int b01, int b10=-1, int b11=-1);
+void CropHisto(TH1* histo, double b00, double b01, double b10=-1, double b11=-1);
+void GetRealMinMax(TH1* h, double &vmn, double &vmx);
+const char* HName(const char* prefix,const char* htype);
+
+void ProjDZE(THnSparseF* hrawd, THnSparseF* hgenb, THnSparseF* hmcComb, TObjArray* res, int bstep0=-1,int bstep1=-1);
+
+void PlotResults();
+void PlotDNDEta();
+void PlotDist();
+void PlotAlphaBeta();
+void PlotSpecies();
+
+TList *listDt=0, *listMC=0;
+TObjArray resArr;
+char outStr[1000];
+char outTitle[1000];
+TString uniqueName="";
+
+void CorrectSpectra(const char* flNameData, const char* flNameMC, const char* uniqueNm)
+{
+ //
+ uniqueName = uniqueNm;
+ listDt = LoadList(flNameData,"dt_");
+ listMC = LoadList(flNameMC,"mc_");
+ //
+ resArr.Clear();
+ PrepareHistos(listMC, kTRUE, &resArr);
+ PrepareHistos(listDt, kFALSE, &resArr);
+ //
+ ProcessHistos(&resArr);
+ //
+ sprintf(outStr,"CutEta%.1f_Zv%.1f_%.1f_bg%s_Shape_%s_mcLB%d_cutSig%.1f_cutBg%.1f",useEtaCut,useZvMin,useZvMax,useBgType.Data(),
+ useShapeType==kNormShapeDist ? "wdst":"dphi",
+ useMCLB,
+ useShapeType==kNormShapeDist ? kWDistSgCut:kdPhiSgCut,
+ useShapeType==kNormShapeDist ? kWDistBgTailMin:kdPhiBgTailMin);
+ sprintf(outTitle,"%s, |#eta|<%.1f, %.1f<Z_{V}<%.1f, Bg.:%s, UseMCLB=%d, CutVar:%s, |sig|<%.2f, %.2f<|bg.nrm|<%.2f",
+ uniqueName.Data(),
+ useEtaCut,useZvMin,useZvMax,useBgType.Data(),
+ useMCLB,
+ useShapeType==kNormShapeDist ? "#Delta":"#Delta#varphi-#delta_{#varphi}",
+ useShapeType==kNormShapeDist ? kWDistSgCut:kdPhiSgCut,
+ useShapeType==kNormShapeDist ? kWDistBgTailMin : kdPhiBgTailMin,
+ useShapeType==kNormShapeDist ? kWDistBgTailMax : kdPhiBgTailMax
+ );
+ PlotResults();
+}
+
+//_____________________________________________________________________
+void PrepareHistos(TList* lst, Bool_t isMC, TObjArray* outArray)
+{
+ // params:
+ //
+ int shift = isMC ? kMCShift : 0;
+ //
+ const char* xxZvEta;
+ if (useShapeType==kNormShapeDist) xxZvEta = "DistZvEta";
+ else xxZvEta = "DistZvDPhiS";
+
+ printf("PrepareBg : (%4s) of type %s from %s with shape %d\n",isMC?" MC ":"Data",useBgType.Data(),lst->GetName(),useShapeType);
+ if (!CheckStat(lst,useBgType.Data())) {printf("Bg of type %s is absent in list %s\n",useBgType.Data(),lst->GetName()); return;}
+ //
+ THnSparseF* hD = (THnSparseF*) FindObject(HName("Data",xxZvEta),lst);
+ THnSparseF* hB = (THnSparseF*) FindObject(HName(useBgType.Data(),xxZvEta),lst);
+ //
+ // special feature: use MC Labels bg as a shape instead of generated bg
+ if (useMCLB/* && !isMC*/) {
+ TString nm = hB->GetName(); nm += "_MCLB";
+ TString tit = hB->GetTitle(); tit += "_MCLB";
+ THnSparseF* hBMCLB = (THnSparseF*) FindObject(HName("Comb",xxZvEta),listMC)->Clone(nm.Data());
+ hBMCLB->SetTitle(tit.Data());
+ hB = hBMCLB;
+ }
+ THnSparseF* hBmc = 0;
+ if (isMC) hBmc = (THnSparseF*) FindObject(HName("Comb",xxZvEta),lst);
+ //
+ ProjDZE(hD,hB,hBmc, outArray, useBinGrEta, useBinGrZv);
+ //
+ if (!isMC) return;
+ //
+ // prepare MC primary signal histo
+ TH2F* mcPrim = (TH2F*)FindObject( "zvEtaPrimMC", lst );
+ mcPrim = (TH2F*) mcPrim->Clone("mcTrueSignal");
+ CropHisto(mcPrim,-useEtaCut,useEtaCut,useZvMin,useZvMax);
+ outArray->AddAtAndExpand(mcPrim, kMCPrim + shift);
+ //
+}
+
+//_____________________________________________________________________
+void ProcessHistos(TObjArray* outArray)
+{
+ //
+ // build alpha matrix
+ TH2* halp = (TH2*)outArray->At(kMCShift + kMCPrim);
+ halp = (TH2*) halp->Clone("Alpha");
+ halp->SetTitle("#alpha");
+ halp->Divide( (TH2*)outArray->At(kMCShift + k1MBeta) );
+ halp->Divide( (TH2*)outArray->At(kMCShift + kRawDtCut) );
+ halp->SetMinimum(1.5);
+ halp->SetMaximum(4.);
+ outArray->AddAtAndExpand(halp, kAlpha);
+ //
+ // build alpha matrix with MC labels bg
+ TH2* halpMC = (TH2*)outArray->At(kMCShift + kMCPrim);
+ halpMC = (TH2*) halpMC->Clone("AlphaMC");
+ halpMC->SetTitle("#alpha MC labels");
+ halpMC->Divide( (TH2*)outArray->At(kMCShift + k1MBetaMC) );
+ halpMC->Divide( (TH2*)outArray->At(kMCShift + kRawDtCut) );
+ halpMC->SetMinimum(1.5);
+ halpMC->SetMaximum(4.);
+ outArray->AddAtAndExpand(halpMC, kAlphaMC);
+ //
+ // build corrected signal
+ TH2* hsigCorr = (TH2*)outArray->At(kSignalEst);
+ hsigCorr = (TH2*) hsigCorr->Clone("SignalEstCorr");
+ hsigCorr->SetTitle("Corrected Signal");
+ hsigCorr->Multiply( halp );
+ outArray->AddAtAndExpand(hsigCorr, kSigCorr);
+ //
+}
+
+TCanvas *canvFin=0;
+TCanvas *canvAlp=0;
+TCanvas *canvBet=0;
+TCanvas* canvDst=0;
+TCanvas* canvSpec=0;
+
+void PlotResults()
+{
+ PlotDist();
+ PlotAlphaBeta();
+ PlotSpecies();
+ PlotDNDEta();
+
+}
+
+void PlotDNDEta()
+{
+ //
+ TObjArray *res = &resArr;
+ char buff[1000];
+ // eta range
+ double plEta = useEtaCut*1.1;
+ gStyle->SetOptFit(0);
+ gStyle->SetOptStat(0);
+ gStyle->SetOptTitle(0);
+ double mn = 1e6,mx = -1e6;
+ canvFin = new TCanvas("canvFin", "canvFin",0,50,700,550);
+ canvFin->SetLeftMargin(0.15);
+ // canvFin->ToggleEventStatus();
+ //
+ // corrected data
+ TH1* hsigCorr = ((TH2F*)res->At(kSigCorr))->ProjectionX("DataCorrSignal");
+ SetHStyle(hsigCorr,kRed,20,1.0);
+ hsigCorr->GetXaxis()->SetRangeUser(-plEta+kEps,plEta-kEps);
+ hsigCorr->Scale(1./hsigCorr->GetBinWidth(1));
+ hsigCorr->Draw();
+ mx = TMath::Max(mx, hsigCorr->GetMaximum());
+ mn = TMath::Min(mn, hsigCorr->GetMinimum());
+ TF1* pl0 = new TF1("pl0","pol0");
+ pl0->SetParameter(0,hsigCorr->GetMinimum());
+ hsigCorr->Fit(pl0,"q0","",-0.5,.5);
+ double fval = pl0->GetParameter(0);
+ double ferr = pl0->GetParError(0);
+ char ftres[1000];
+ sprintf(ftres,"dN/d#eta_{|#eta|<0.5} = %d #pm %d",int(fval),int(ferr));
+ printf("dN/d#eta_{|#eta|<0.5} = %.2f %.2f\n",fval,ferr);
+ TLatex *txfit = new TLatex(-0.2,hsigCorr->GetMinimum()*0.9, ftres);
+ txfit->SetTextSize(0.04);
+ txfit->Draw();
+ //
+ // raw data
+ TH1* hraw = ((TH2F*)res->At(kRawDtCut))->ProjectionX("DataRaw");
+ SetHStyle(hraw,kRed,21,1.0);
+ hraw->GetXaxis()->SetRangeUser(-plEta,plEta);
+ hraw->Scale(1./hraw->GetBinWidth(1));
+ hraw->Draw("same");
+ mn = TMath::Min(mn, hraw->GetMinimum());
+ mx = TMath::Max(mx, hraw->GetMaximum());
+ //
+ // raw data bg sub
+ TH1* hraws = ((TH2F*)res->At(kSignalEst))->ProjectionX("DataRawSub");
+ SetHStyle(hraws,kRed,23,1.0);
+ hraws->GetXaxis()->SetRangeUser(-plEta,plEta);
+ hraws->Scale(1./hraw->GetBinWidth(1));
+ hraws->Draw("same");
+ mn = TMath::Min(mn, hraw->GetMinimum());
+ mx = TMath::Max(mx, hraw->GetMaximum());
+ //
+ // bg
+ TH1* hbg = ((TH2F*)res->At(kBgEst))->ProjectionX("BgEst");
+ SetHStyle(hbg,kMagenta,22,1.0);
+ hbg->GetXaxis()->SetRangeUser(-plEta,plEta);
+ hbg->Scale(1./hbg->GetBinWidth(1));
+ hbg->Draw("same");
+ mn = TMath::Min(mn, hbg->GetMinimum());
+ mx = TMath::Max(mx, hbg->GetMaximum());
+ //
+ // mc part ----------------------------
+ // raw data
+ TH1* hrawMC = ((TH2F*)res->At(kRawDtCut+kMCShift))->ProjectionX("DataRawMC");
+ SetHStyle(hrawMC,kBlue,24,1.0);
+ hrawMC->GetXaxis()->SetRangeUser(-plEta,plEta);
+ hrawMC->Scale(1./hrawMC->GetBinWidth(1));
+ hrawMC->Draw("same");
+ mn = TMath::Min(mn, hrawMC->GetMinimum());
+ mx = TMath::Max(mx, hrawMC->GetMaximum());
+ //
+ // raw data bg sub
+ TH1* hrawsMC = ((TH2F*)res->At(kSignalEst+kMCShift))->ProjectionX("DataRawSubMC");
+ SetHStyle(hrawsMC,kBlue,26,1.0);
+ hrawsMC->GetXaxis()->SetRangeUser(-plEta,plEta);
+ hrawsMC->Scale(1./hrawMC->GetBinWidth(1));
+ hrawsMC->Draw("same");
+ mn = TMath::Min(mn, hrawMC->GetMinimum());
+ mx = TMath::Max(mx, hrawMC->GetMaximum());
+ //
+ // raw data bgMClabels sub
+ TH1* hrawsMCLB = ((TH2F*)res->At(kSignalEstMC+kMCShift))->ProjectionX("DataRawSubMCLB");
+ SetHStyle(hrawsMCLB,kGreen+2,30,1.0);
+ hrawsMCLB->GetXaxis()->SetRangeUser(-plEta,plEta);
+ hrawsMCLB->Scale(1./hrawsMCLB->GetBinWidth(1));
+ hrawsMCLB->Draw("same");
+ mn = TMath::Min(mn, hrawsMCLB->GetMinimum());
+ mx = TMath::Max(mx, hrawsMCLB->GetMaximum());
+ //
+ // bg est
+ TH1* hbgMCEst = ((TH2F*)res->At(kBgEst+kMCShift))->ProjectionX("BgEstMC");
+ SetHStyle(hbgMCEst,kBlue,26,1.0);
+ hbgMCEst->GetXaxis()->SetRangeUser(-plEta,plEta);
+ hbgMCEst->Scale(1./hbgMCEst->GetBinWidth(1));
+ hbgMCEst->Draw("same");
+ mn = TMath::Min(mn, hbgMCEst->GetMinimum());
+ mx = TMath::Max(mx, hbgMCEst->GetMaximum());
+ //
+ // bg MC
+ TH1* hbgMC = ((TH2F*)res->At(kBgMC+kMCShift))->ProjectionX("BgMC");
+ SetHStyle(hbgMC,kGreen+2,25,1.0);
+ hbgMC->GetXaxis()->SetRangeUser(-plEta,plEta);
+ hbgMC->Scale(1./hbgMC->GetBinWidth(1));
+ hbgMC->Draw("same");
+ mn = TMath::Min(mn, hbgMC->GetMinimum());
+ mx = TMath::Max(mx, hbgMC->GetMaximum());
+ //
+ mn = 0;
+ hsigCorr->SetMinimum(mn);
+ hsigCorr->SetMaximum(mx + 0.4*(mx-mn));
+ gPad->Modified();
+ //
+ TLegend *legDnDeta = new TLegend(0.15,0.75, 0.45,0.95);
+ legDnDeta->SetFillColor(kWhite);
+ legDnDeta->SetHeader("Data");
+ legDnDeta->AddEntry(hsigCorr,"Corrected","pl");
+ legDnDeta->AddEntry(hraw, "Reconstructed","pl");
+ sprintf(buff,"Reconstructed - Bckg.%s.",useBgType.Data());
+ legDnDeta->AddEntry(hraws, buff,"pl");
+ sprintf(buff,"Background %s.",useBgType.Data());
+ legDnDeta->AddEntry(hbg, buff,"pl");
+ legDnDeta->Draw();
+ //
+ TLegend *legDnDetaMC = new TLegend(0.60,0.72, 0.95,0.95);
+ legDnDetaMC->SetFillColor(kWhite);
+ legDnDetaMC->SetHeader("MC");
+ legDnDetaMC->AddEntry(hrawMC, "Reconstructed","pl");
+ sprintf(buff,"Reconstructed - Bckg.%s.",useBgType.Data());
+ legDnDetaMC->AddEntry(hrawsMC, buff,"pl");
+ sprintf(buff,"Reconstructed - Bckg.%s.","MC.Labels");
+ legDnDetaMC->AddEntry(hrawsMCLB, buff,"pl");
+ sprintf(buff,"Background %s.",useBgType.Data());
+ legDnDetaMC->AddEntry(hbgMCEst, buff,"pl");
+ sprintf(buff,"Background %s.","MC Labels");
+ legDnDetaMC->AddEntry(hbgMC, buff,"pl");
+
+ legDnDetaMC->Draw();
+ //
+ gPad->SetGrid(1.1);
+ gPad->Modified();
+ canvFin->cd();
+ AddLabel(outTitle,0.1,0.97, kBlack,0.025);
+ sprintf(buff,"%s/%sdNdEta_%s",figDir,uniqueName.Data(),outStr);
+ SaveCanvas(canvFin,buff,"cg");
+ //
+}
+//
+void PlotAlphaBeta()
+{
+ char buff[1000];
+ gStyle->SetOptFit(0);
+ gStyle->SetOptStat(0);
+ gStyle->SetOptTitle(0);
+ TObjArray* res = &resArr;
+ //------------------------------------------------------
+ canvBet = new TCanvas("canvBet","canvBet",10,10,1000,400);
+ canvBet->Divide(3,1,0.01,0.06);
+ canvBet->cd(1);
+ TH1* dtBet = (TH1*)res->At(k1MBeta);
+ TH1* mcBet = (TH1*)res->At(k1MBeta+kMCShift);
+ TH1* mcBetLB = (TH1*)res->At(k1MBetaMC+kMCShift);
+ double mn,mx,mnt,mxt;
+ GetRealMinMax(dtBet,mn,mx);
+ GetRealMinMax(mcBet,mnt,mxt);
+ if (mnt<mn) mn = mnt;
+ if (mxt>mx) mx = mxt;
+ GetRealMinMax(mcBetLB,mnt,mxt);
+ if (mnt<mn) mn = mnt;
+ if (mxt>mx) mx = mxt;
+ //
+ dtBet->SetMinimum(mn - 0.05*(mx-mn));
+ dtBet->SetMaximum(mx + 0.05*(mx-mn));
+ mcBet->SetMinimum(mn - 0.05*(mx-mn));
+ mcBet->SetMaximum(mx + 0.05*(mx-mn));
+ mcBetLB->SetMinimum(mn - 0.05*(mx-mn));
+ mcBetLB->SetMaximum(mx + 0.05*(mx-mn));
+ //
+ canvBet->cd(1);
+ gPad->SetRightMargin(0.15);
+ dtBet->Draw("colz");
+ AddLabel("#beta Data",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ dtBet->GetYaxis()->SetTitleOffset(1.4);
+ TPaletteAxis *p = (TPaletteAxis*)dtBet->FindObject("palette");
+ if (p) p->SetX1NDC(0.85);
+ canvBet->cd(2);
+ gPad->SetRightMargin(0.15);
+ mcBet->Draw("colz");
+ AddLabel("#beta MC (bckg.estimated)",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ mcBet->GetYaxis()->SetTitleOffset(1.4);
+ p = (TPaletteAxis*)mcBet->FindObject("palette");
+ if (p) p->SetX1NDC(0.85);
+ canvBet->cd(3);
+ gPad->SetRightMargin(0.15);
+ mcBetLB->Draw("colz");
+ AddLabel("#beta MC (bckg.from MC labels)",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ mcBetLB->GetYaxis()->SetTitleOffset(1.4);
+ p = (TPaletteAxis*)mcBetLB->FindObject("palette");
+ if (p) p->SetX1NDC(0.85);
+ //
+ canvBet->cd();
+ AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+ //
+ sprintf(buff,"%s/%sBeta_%s",figDir,uniqueName.Data(),outStr);
+ SaveCanvas(canvBet,buff,"cg");
+
+ //------------------------------------------------------
+ canvAlp = new TCanvas("canvAlp","canvAlp",10,10,900,400);
+ canvAlp->Divide(2,1,0.01,0.06);
+ canvAlp->cd(1);
+ TH1* dtAlp = (TH1*)res->At(kAlpha);
+ TH1* mcAlp = (TH1*)res->At(kAlphaMC);
+ GetRealMinMax(dtAlp,mn,mx);
+ GetRealMinMax(mcAlp,mnt,mxt);
+ if (mnt<mn) mn = mnt;
+ if (mxt>mx) mx = mxt;
+ dtAlp->SetMinimum(mn - 0.05*(mx-mn));
+ dtAlp->SetMaximum(mx + 0.05*(mx-mn));
+ mcAlp->SetMinimum(mn - 0.05*(mx-mn));
+ mcAlp->SetMaximum(mx + 0.05*(mx-mn));
+ //
+ canvAlp->cd(1);
+ gPad->SetRightMargin(0.15);
+ dtAlp->Draw("colz");
+ AddLabel("#alpha (bckg.estimated)",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ dtAlp->GetYaxis()->SetTitleOffset(1.4);
+ TPaletteAxis *pa = (TPaletteAxis*)dtBet->FindObject("palette");
+ if (pa) pa->SetX1NDC(0.85);
+ canvAlp->cd(2);
+ gPad->SetRightMargin(0.15);
+ mcAlp->Draw("colz");
+ AddLabel("#alpha (bckg.from MC labels)",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ mcAlp->GetYaxis()->SetTitleOffset(1.4);
+ pa = (TPaletteAxis*)mcBet->FindObject("palette");
+ if (pa) pa->SetX1NDC(0.85);
+ gPad->Modified();
+ canvAlp->cd();
+ AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+ //
+ sprintf(buff,"%s/%sAlpha_%s",figDir,uniqueName.Data(),outStr);
+ SaveCanvas(canvAlp,buff,"cg");
+
+}
+
+void PlotSpecies()
+{
+ char buff[1000];
+ gStyle->SetOptFit(0);
+ gStyle->SetOptStat(0);
+ gStyle->SetOptTitle(0);
+ //------------------------------------------------------
+ TH2F* hSpecPrim = (TH2F*)FindObject( "pdgPrim", listMC,kFALSE);
+ TH2F* hSpecSec = (TH2F*)FindObject( "pdgSec", listMC,kFALSE);
+ TH2F* hSpecPrimP = (TH2F*)FindObject( "pdgPrimPar", listMC,kFALSE);
+ TH2F* hSpecSecP = (TH2F*)FindObject( "pdgSecPar", listMC,kFALSE);
+ int nbd = hSpecPrim->GetXaxis()->GetNbins();
+ //
+ TH1* hSpecPrimAll = hSpecPrim->ProjectionX("specPrimAll",1,nbd+1,"e");
+ hSpecPrimAll->Scale(100./hSpecPrimAll->Integral());
+ hSpecPrimAll->GetYaxis()->SetTitle("Fraction,%");
+ hSpecPrimAll->GetXaxis()->SetLabelSize(0.06);
+ hSpecPrimAll->GetXaxis()->LabelsOption("v");
+ //
+ TH1* hSpecSecAll = hSpecSec->ProjectionX("specSecAll",1,nbd+1,"e");
+ hSpecSecAll->Scale(100./hSpecSecAll->Integral());
+ hSpecSecAll->GetYaxis()->SetTitle("Fraction,%");
+ hSpecSecAll->GetXaxis()->SetLabelSize(0.05);
+ //
+ TH1* hSpecPrimPAll = hSpecPrimP->ProjectionX("specPrimPAll",1,nbd+1,"e");
+ hSpecPrimPAll->Scale(100./hSpecPrimPAll->Integral());
+ hSpecPrimPAll->GetYaxis()->SetTitle("Fraction,%");
+ hSpecPrimPAll->GetXaxis()->SetLabelSize(0.06);
+ hSpecPrimPAll->GetXaxis()->LabelsOption("v");
+
+ //
+ TH1* hSpecSecPAll = hSpecSecP->ProjectionX("specSecPAll",1,nbd+1,"e");
+ hSpecSecPAll->Scale(100./hSpecSecPAll->Integral());
+ hSpecSecPAll->GetYaxis()->SetTitle("Fraction,%");
+ hSpecSecPAll->GetXaxis()->SetLabelSize(0.05);
+ //
+ int binCut = hSpecPrim->GetXaxis()->FindBin(kWDistSgCut-kEps);
+ TH1* hSpecPrimSel = hSpecPrim->ProjectionX("specPrimSel",1,binCut,"e");
+ hSpecPrimSel->Scale(100./hSpecPrimSel->Integral());
+ hSpecPrimSel->GetYaxis()->SetTitle("Fraction,%");
+ hSpecPrimSel->GetXaxis()->SetLabelSize(0.05);
+ //
+ TH1* hSpecSecSel = hSpecSec->ProjectionX("specSecSel",1,binCut,"e");
+ hSpecSecSel->Scale(100./hSpecSecSel->Integral());
+ hSpecSecSel->GetYaxis()->SetTitle("Fraction,%");
+ hSpecSecSel->GetXaxis()->SetLabelSize(0.05);
+ //
+ TH1* hSpecPrimPSel = hSpecPrimP->ProjectionX("specPrimPSel",1,binCut,"e");
+ hSpecPrimPSel->Scale(100./hSpecPrimPSel->Integral());
+ hSpecPrimPSel->GetYaxis()->SetTitle("Fraction,%");
+ hSpecPrimPSel->GetXaxis()->SetLabelSize(0.05);
+ //
+ TH1* hSpecSecPSel = hSpecSecP->ProjectionX("specSecPSel",1,binCut,"e");
+ hSpecSecPSel->Scale(100./hSpecSecPSel->Integral());
+ hSpecSecPSel->GetYaxis()->SetTitle("Fraction,%");
+ hSpecSecPSel->GetXaxis()->SetLabelSize(0.05);
+
+
+ canvSpec = new TCanvas("canvSpec","canvSpec",10,10,1100,800);
+ canvSpec->Divide(1,2,0.01,0.01);
+ canvSpec->cd(1);
+ hSpecPrimAll->Draw();
+ SetHStyle(hSpecPrimAll,kBlue,25,1.1);
+ hSpecPrimSel->Draw("same");
+ SetHStyle(hSpecPrimSel,kRed,20,1);
+ //
+ hSpecSecAll->Draw("same");
+ SetHStyle(hSpecSecAll,kGreen,32,1.1);
+ hSpecSecSel->Draw("same");
+ SetHStyle(hSpecSecSel,kBlack,22,1);
+ //
+ TLegend *legPart = new TLegend(0.8,0.72, 0.999,0.999);
+ legPart->SetFillColor(kWhite);
+ legPart->SetHeader("Tracklet PDG");
+ //
+ legPart->AddEntry(hSpecPrimAll, "Prim., before #Delta cut","pl");
+ legPart->AddEntry(hSpecPrimSel, "Prim., after #Delta cut","pl");
+ legPart->AddEntry(hSpecSecAll, "Sec., before #Delta cut","pl");
+ legPart->AddEntry(hSpecSecSel, "Sec., after #Delta cut","pl");
+ //
+ legPart->Draw();
+ gPad->SetLogy();
+ gPad->SetGrid(1,1);
+ gPad->Modified();
+ //
+ canvSpec->cd(2);
+ hSpecPrimPAll->Draw();
+ SetHStyle(hSpecPrimPAll,kBlue,25,1.1);
+ hSpecPrimPSel->Draw("same");
+ SetHStyle(hSpecPrimPSel,kRed,20,1);
+ //
+ hSpecSecPAll->Draw("same");
+ SetHStyle(hSpecSecPAll,kGreen,32,1.1);
+ hSpecSecPSel->Draw("same");
+ SetHStyle(hSpecSecPSel,kBlack,22,1);
+ //
+ TLegend *legPartP = new TLegend(0.8,0.72, 0.999,0.999);
+ legPartP->SetFillColor(kWhite);
+ legPartP->SetHeader("Tracklet Parents PDG");
+ //
+ legPartP->AddEntry(hSpecPrimPAll, "Prim., before #Delta cut","pl");
+ legPartP->AddEntry(hSpecPrimPSel, "Prim., after #Delta cut","pl");
+ legPartP->AddEntry(hSpecSecPAll, "Sec., before #Delta cut","pl");
+ legPartP->AddEntry(hSpecSecPSel, "Sec., after #Delta cut","pl");
+ //
+ legPartP->Draw();
+ gPad->SetLogy();
+ gPad->SetGrid(1,1);
+ gPad->Modified();
+ //
+ canvSpec->cd(1);
+ AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+ canvSpec->cd();
+ //
+ sprintf(buff,"%s/%sSpecies_%s",figDir,uniqueName.Data(),outStr);
+ SaveCanvas(canvSpec,buff,"cg");
+}
+
+void PlotDist()
+{
+ TObjArray* res = &resArr;
+ char buff[1000];
+ canvDst = new TCanvas("canvDst","canvDst",10,10,700,500);
+ TH1* mcdst = (TH1*)res->At(kDataDist+kMCShift);
+ TH1* mcdstbg = (TH1*)res->At(kBgDist+kMCShift);
+ TH1* mcdstbgLB = (TH1*)res->At(kBgMCDist+kMCShift);
+ TH1* dtdst = (TH1*)res->At(kDataDist);
+ TH1* dtdstbg = (TH1*)res->At(kBgDist);
+ //
+ TH2* mcDstZN = (TH2*)FindObject(useShapeType==kNormShapeDist ? "TrData_ZvDist":"TrData_ZvDPhiS", listMC );
+ TH2* mcDstZSec = (TH2*)FindObject(useShapeType==kNormShapeDist ? "TrSec_ZvDist":"TrSec_ZvDPhiS", listMC );
+ TH2* mcDstZCombU = (TH2*)FindObject(useShapeType==kNormShapeDist ? "TrCombU_ZvDist":"TrCombU_ZvDPhiS", listMC );
+ TH2* mcDstZCombC = (TH2*)FindObject(useShapeType==kNormShapeDist ? "TrComb_ZvDist":"TrComb_ZvDPhiS", listMC );
+ //
+ mcDstZN->GetXaxis()->SetRangeUser(useZvMin+kEps,useZvMax-kEps);
+ mcDstZSec->GetXaxis()->SetRangeUser(useZvMin+kEps,useZvMax-kEps);
+ mcDstZCombU->GetXaxis()->SetRangeUser(useZvMin+kEps,useZvMax-kEps);
+ mcDstZCombC->GetXaxis()->SetRangeUser(useZvMin+kEps,useZvMax-kEps);
+ //
+ TH1* mcDstN = mcDstZN->ProjectionY("mcDstN");
+ TH1* mcDstSec = mcDstZSec->ProjectionY("mcDstSec");
+ TH1* mcDstCombU = mcDstZCombU->ProjectionY("mcDstCombU");
+ TH1* mcDstCombC = mcDstZCombC->ProjectionY("mcDstCombC");
+ //
+ double scl,sclE;
+ mcDstN = NormalizeBg(mcdst,mcDstN,scl,sclE);
+ mcDstSec->Scale(scl);
+ mcDstCombU->Scale(scl);
+ mcDstCombC->Scale(scl);
+ mcDstCombC->Add(mcDstCombU,-1);
+ //
+ dtdst->Draw("");
+ gPad->Modified();
+ dtdst->GetXaxis()->SetLabelSize(0.03);
+ dtdst->GetXaxis()->SetTitleSize(0.03);
+ dtdst->GetXaxis()->SetTitleOffset(2);
+ dtdstbg->Draw("same");
+
+ mcdst->Draw("same");
+ mcDstSec->Draw("same");
+ mcdstbgLB->Draw("same");
+ mcdstbg->Draw("same");
+ mcDstCombC->Draw("same");
+ //
+
+ SetHStyle(mcdst,kBlue, 25,0.7);
+ SetHStyle(mcdstbgLB,kGreen, 7/*32*/,0.5);
+ SetHStyle(mcdstbg,kCyan, 7/*26*/,0.5);
+ SetHStyle(mcDstCombC,kGreen+2, 21,0.7);
+ SetHStyle(mcDstSec,kBlue+2, 22,0.7);
+ //
+ SetHStyle(dtdst,kRed, 20,0.7);
+ SetHStyle(dtdstbg,kBlue, 34,0.7);
+ //
+ double vmcTot,vmcTotE;
+ double vmcSec,vmcSecE, ratSec,ratSecE;
+ double vmcCmbEst,vmcCmbEstE, ratCmbEst,ratCmbEstE;
+ double vmcCmb,vmcCmbE, ratCmb,ratCmbE;
+ double vmcCmbC,vmcCmbCE, ratCmbC,ratCmbCE;
+ double cutSgMin,cutSgMax;
+ double cutBgMin,cutBgMax;
+ if (useShapeType==kNormShapeDist) {
+ cutSgMin = 0;
+ cutSgMax = kWDistSgCut;
+ cutBgMin = kWDistBgTailMin;
+ cutBgMax = kWDistBgTailMax;
+ }
+ else {
+ cutSgMin = 0;
+ cutSgMax = kdPhiSgCut;
+ cutBgMin = kdPhiBgTailMin;
+ cutBgMax = kdPhiBgTailMax;
+ }
+ Integrate(mcdst, cutSgMin,cutSgMax, vmcTot,vmcTotE);
+ Integrate(mcDstSec, cutSgMin,cutSgMax, vmcSec,vmcSecE);
+ GetRatE(vmcSec,vmcSecE, vmcTot,vmcTotE, ratSec,ratSecE);
+ //
+ Integrate(mcdstbgLB, cutSgMin,cutSgMax, vmcCmb,vmcCmbE);
+ GetRatE(vmcCmb,vmcCmbE, vmcTot,vmcTotE, ratCmb,ratCmbE);
+ //
+ Integrate(mcdstbg, cutSgMin,cutSgMax, vmcCmbEst,vmcCmbEstE);
+ GetRatE(vmcCmbEst,vmcCmbEstE, vmcTot,vmcTotE, ratCmbEst,ratCmbEstE);
+ //
+ Integrate(mcDstCombC, cutSgMin,cutSgMax, vmcCmbC,vmcCmbCE);
+ GetRatE(vmcCmbC,vmcCmbCE, vmcTot,vmcTotE, ratCmbC,ratCmbCE);
+ //
+ double vdtTot,vdtTotE;
+ double vdtBg,vdtBgE, ratdtBg,ratdtBgE;
+ //
+ Integrate(dtdst, cutSgMin,cutSgMax, vdtTot,vdtTotE);
+ Integrate(dtdstbg, cutSgMin,cutSgMax, vdtBg,vdtBgE);
+ GetRatE( vdtBg,vdtBgE, vdtTot,vdtTotE, ratdtBg,ratdtBgE);
+ //
+ //
+ double dmn = mcdst->GetMinimum();
+ double dmx = mcdst->GetMaximum();
+ TLine *ln = new TLine(cutSgMax, dmn, cutSgMax, dmx);
+ ln->SetLineColor(kBlack);
+ ln->Draw();
+ TLine *lnc = new TLine(cutBgMin, dmn, cutBgMin, dmx);
+ lnc->SetLineColor(kRed);
+ lnc->Draw();
+ if (useShapeType==kNormShapeDPhi) {
+ ln = new TLine(-cutSgMax, dmn, -cutSgMax, dmx);
+ ln->SetLineColor(kBlack);
+ ln->Draw();
+ //
+ lnc = new TLine(-cutBgMin, dmn, -cutBgMin, dmx);
+ lnc->SetLineColor(kRed);
+ lnc->Draw();
+ }
+ //
+ TLegend *legDstMC1 = new TLegend(0.60,0.72, 0.95,0.95);
+ legDstMC1->SetFillColor(kWhite);
+
+ //
+ legDstMC1->AddEntry(dtdst, "Data raw","pl");
+ sprintf(buff,"Data Comb. %s. : %.1f%%",useBgType.Data(),ratdtBg*100);
+ legDstMC1->AddEntry(dtdstbg, buff,"pl");
+ //
+
+
+ legDstMC1->AddEntry(mcdst, "MC raw","pl");
+ sprintf(buff,"MC Comb. %s. : %.1f%%",useBgType.Data(),ratCmbEst*100);
+ legDstMC1->AddEntry(mcdstbg, buff,"pl");
+ //
+ sprintf(buff,"MC Comb. %s. : %.1f%%","MC Lbl.",ratCmb*100);
+ legDstMC1->AddEntry(mcdstbgLB, buff,"pl");
+
+ sprintf(buff,"MC Comb.Uncorr %s. : %.1f%%","MC Lbl.",ratCmbC*100);
+ legDstMC1->AddEntry(mcDstCombC, buff,"pl");
+
+ sprintf(buff,"MC Sec. : %.1f%%",ratSec*100);
+ legDstMC1->AddEntry(mcDstSec, buff,"pl");
+
+ legDstMC1->Draw();
+
+ if (useShapeType==kNormShapeDist) gPad->SetLogx();
+ gPad->SetLogy();
+ gPad->SetGrid(1,1);
+ gPad->Modified();
+ //
+ canvDst->cd();
+ AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+ //
+ sprintf(buff,"%s/%sDst_%s",figDir,uniqueName.Data(),outStr);
+ SaveCanvas(canvDst,buff,"cg");
+ //
+}
+
+
+//______________________________________________________________________
+void CropHisto(TH1* histo, int bx0, int bx1, int by0, int by1)
+{
+ // fill 0 to all bins outside defined range
+ TAxis *xax = histo->GetXaxis();
+ int nbx = xax->GetNbins();
+ double vmn=1e16,vmx=-1e16;
+ if (histo->InheritsFrom(TH2::Class())) {
+ TAxis *yax = histo->GetYaxis();
+ int nby = yax->GetNbins();
+ for (int ix=nbx+2;ix--;) {
+ for (int iy=nby+2;iy--;) {
+ if ((ix<bx0||ix>bx1)||(iy<by0||iy>by1)) {
+ histo->SetBinContent(ix,iy,0);
+ histo->SetBinError(ix,iy,0);
+ }
+ else {
+ double vl = histo->GetBinContent(ix,iy);
+ if (vl<vmn) vmn = vl;
+ if (vl>vmx) vmx = vl;
+ }
+ }
+ }
+ }
+ else {
+ for (int ix=nbx+2;ix--;) {
+ if ((ix<bx0||ix>bx1)) {
+ histo->SetBinContent(ix,0);
+ histo->SetBinError(ix,0);
+ }
+ else {
+ double vl = histo->GetBinContent(ix);
+ if (vl<vmn) vmn = vl;
+ if (vl>vmx) vmx = vl;
+ }
+ }
+ }
+ //
+ if (vmn==vmx) {
+ vmn = 0.95*vmn;
+ vmx = 1.05*vmx;
+ }
+ histo->SetMaximum(vmx);
+ histo->SetMinimum(vmn);
+}
+
+//______________________________________________________________________
+void CropHisto(TH1* histo, double vx0, double vx1, double vy0, double vy1)
+{
+ // fill 0 to all bins outside defined range
+ TAxis *xax = histo->GetXaxis();
+ int bx0,bx1,by0=-1,by1=-1;
+ bx0 = xax->FindBin(vx0+kEps);
+ bx1 = xax->FindBin(vx1-kEps);
+ if (histo->InheritsFrom(TH2::Class())) {
+ TAxis *yax = histo->GetYaxis();
+ by0 = yax->FindBin(vy0+kEps);
+ by1 = yax->FindBin(vy1-kEps);
+ }
+ CropHisto(histo,bx0,bx1,by0,by1);
+}
+
+//______________________________________________________________________
+TH1* NormalizeBg(TH1* dataH, TH1* bgH, double &scl, double &sclE)
+{
+ // match generated bg and data tails, calculate normalization, return normalized bg copy
+ //
+ TAxis* xax = dataH->GetXaxis();
+ int nbtot = xax->GetNbins();
+ int bgBins[2][2] = {{0}}; // limiting bins for tails integration
+ Int_t ntails; // 0 for dphi plot, 1 for weighted dist plot
+ if (useShapeType == kNormShapeDist) { // only positive tail
+ bgBins[0][0] = xax->FindBin(kWDistBgTailMin+kEps); // positive tail min bin
+ bgBins[0][1] = xax->FindBin(kWDistBgTailMax-kEps); // positive tail max bin
+ ntails = 1;
+ }
+ else if (useShapeType == kNormShapeDPhi) { // both tails
+ bgBins[0][0] = xax->FindBin( kdPhiBgTailMin+kEps); // positive tail min bin
+ bgBins[0][1] = xax->FindBin( kdPhiBgTailMax-kEps); // positive tail max bin
+ bgBins[1][0] = xax->FindBin(-kdPhiBgTailMax+kEps); // negative tail min bin
+ bgBins[1][1] = xax->FindBin(-kdPhiBgTailMin-kEps); // positive tail max bin
+ ntails = 2;
+ }
+ else {printf("NormalizeBg: unknown shape type %d\n",useShapeType);exit(1);}
+ printf("NormalizeBg: bins for tails: right: %d:%d / left: %d:%d\n",bgBins[0][0],bgBins[0][1],bgBins[1][0],bgBins[1][1]);
+ //
+ double meanR=0,meanRE=0,meanRE2=0;
+ double meanD=0,meanDE2=0;
+ double meanB=0,meanBE2=0;
+ double meanRI=0,meanRIE=0;
+ for (int itp=0;itp<=ntails;itp++) {
+ for (int ib=bgBins[itp][0];ib<=bgBins[itp][1];ib++) {
+ if (ib<1||ib>nbtot) continue;
+ double vD = dataH->GetBinContent(ib);
+ double vB = bgH->GetBinContent(ib);
+ double eD = dataH->GetBinError(ib);
+ double eB = bgH->GetBinError(ib);
+ meanD += vD; meanDE2 += eD*eD;
+ meanB += vB; meanBE2 += eB*eB;
+ if (vD<=0 || vB<=0 || eD<=0 || eB<=0) continue;
+ double rat = vD/vB;
+ double ratE2 = rat*rat*(eD*eD/vD/vD + eB*eB/vB/vB);
+ meanR += rat/ratE2; meanRE2 += 1.0/ratE2;
+ }
+ }
+ //
+ if (meanRE2>0) {
+ meanR /= meanRE2;
+ meanRE2 = 1./meanRE2;
+ meanRE = TMath::Sqrt(meanRE2);
+ }
+ if (meanDE2>0 && meanBE2>0) {
+ meanRI = meanD/meanB;
+ meanRIE = meanRI*TMath::Sqrt(meanDE2/meanD/meanD + meanBE2/meanB/meanB);
+ }
+ printf("NormalizeBg: Tails scaling %s wrt %s: Wgh.Mean:%.4f(%.4f) / Integral:%.4f(%.4f)\n",
+ bgH->GetName(),dataH->GetName(), meanR,meanRE, meanRI,meanRIE);
+ printf("NormalizeBg: Select scaling type %s\n",useScaleType==kSclWghMean ? "Wgh.Mean":"Integral");
+ //
+ scl = useScaleType==kSclWghMean ? meanR : meanRI;
+ sclE = useScaleType==kSclWghMean ? meanRE : meanRIE;
+ //
+ // rescaled bg
+ char buff[1000];
+ sprintf(buff,"%s_bgNorm",bgH->GetName());
+ bgH = (TH1*)bgH->Clone(buff);
+ sprintf(buff,"%s bgNorm%d %.4f+-%.4f",bgH->GetName(),useScaleType,scl,sclE);
+ TH1* dumH = (TH1*)bgH->Clone("dummySCL$"); dumH->Reset();
+ for (int i=1;i<=nbtot;i++) {
+ dumH->SetBinContent(i,scl);
+ dumH->SetBinError(i,sclE);
+ }
+ bgH->Multiply(dumH);
+ delete dumH;
+ return bgH;
+}
+
+//______________________________________________________________________
+TObject* FindObject(const char* nameH, const TList* lst, Bool_t normPerEvent)
+{
+ // get histo, optionally normalizing it per processed event
+ if (!lst) {printf("FindObject %s: No list provided\n",nameH); exit(1);}
+ int nent = lst->GetEntries();
+ TString nm;
+ TObject *hst = 0;
+ for (int i=nent;i--;) {
+ nm = lst->At(i)->GetName();
+ if (nm.EndsWith(nameH)) {hst = lst->At(i); break;}
+ }
+ if (!hst) {printf("FindObject: No %s histo in list %s\n",nameH,lst->GetName()); exit(1);}
+ if (!normPerEvent || hst->TestBit(kBitNormPerEvent)) return hst; // already normalized
+ TString nameHS = nameH;
+ if (nameHS==kHStatName) return hst; // never scale stat. histo
+ //
+ TH1* hstat = (TH1*)FindObject(kHStatName,lst,kFALSE);
+ double nrm = hstat->GetBinContent(kEvProcData);
+ if (nrm<1) {printf("FindObject: Anomaluous %d number of events processed in list %p\n",int(nrm),lst); exit(1);}
+ //
+ // account for eventual cut in Z
+ TH1* hzv = (TH1*)FindObject("zv",lst,kFALSE);
+ int nbz = hzv->GetNbinsX();
+ double zvTot = hzv->Integral(1,nbz);
+ int zb0 = hzv->FindBin( useZvMin+kEps); if (zb0<1) zb0 = 1;
+ int zb1 = hzv->FindBin( useZvMax-kEps); if (zb1>nbz) zb1 = nbz;
+ double zvSel = hzv->Integral(zb0,zb1);
+ if (zvTot<1 || zvSel<1) {printf("No statistics: NzvTot: %.1f NzvSel:%.f\n",zvTot,zvSel); return 0;}
+ else printf("%f fraction of selected events is used with current Zv cut %.1f:%.1f\n",zvSel/zvTot,useZvMin,useZvMax);
+ nrm *= zvSel/zvTot;
+ //
+ if (hst->InheritsFrom(TH1::Class())) ((TH1*)hst)->Scale(1./nrm);
+ else if (hst->InheritsFrom(THnSparse::Class())) {
+ THnSparse* spr = (THnSparse*) hst;
+ spr->Sumw2();
+ int coord[3] = {0,0,0};
+ for (Long64_t i = 0; i < spr->GetNbins(); ++i) {
+ // Get the content of the bin from the current histogram
+ Double_t v = spr->GetBinContent(i, coord);
+ spr->SetBinContent(coord, v/nrm);
+ spr->SetBinError(coord,TMath::Sqrt(v)/nrm);
+ }
+ }
+ //
+ hst->SetBit(kBitNormPerEvent);
+ return hst;
+}
+
+//______________________________________________________________________
+TList* LoadList(const char* flName, const char* addPref, const char* nameL)
+{
+ // load list with histos
+ TString nms = flName;
+ gSystem->ExpandPathName(nms);
+ TFile* fl = TFile::Open(nms.Data());
+ if (!fl) {printf("LoadList: No file %s\n",nms.Data()); exit(1);}
+ TList* lst = (TList*)fl->Get(nameL);
+ if (!lst) {printf("LoadList: No list %s in file %s\n",nameL,nms.Data()); exit(1);}
+ lst->SetName(flName);
+ //
+ int nEnt = lst->GetSize();
+ TString nm;
+ for (int i=0;i<nEnt;i++) {
+ TNamed* ob = (TNamed*)lst->At(i);
+ nm = addPref;
+ nm += ob->GetName();
+ ob->SetName(nm.Data());
+ }
+ //
+ return lst;
+}
+
+//____________________________________________________________________________
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate)
+{
+ rat = 0; rate = 0;
+ if (TMath::Abs(y)<1e-16 || TMath::Abs(x)<1e-16) return;
+ rat = x/y;
+ rate = rat*TMath::Sqrt( xe*xe/(x*x) + ye*ye/(y*y));
+}
+
+//____________________________________________________________________________
+void Integrate(TH1* hist, double xmn,double xmx, double &val, double& err)
+{
+ // integrate 1d histo within given limits
+ TAxis* xax = hist->GetXaxis();
+ int bmn = xax->FindBin(xmn+kEps); if (bmn<1) bmn = 0; // include
+ int bmx = xax->FindBin(xmx-kEps);
+ val = hist->IntegralAndError(bmn,bmx,err);
+ // is this histo with symmetric axis ? then integrate also negative half axis
+ if (TMath::Abs( xax->GetXmin() + xax->GetXmax() )<1e-6) {
+ bmn = xax->FindBin(-xmx+kEps);
+ bmx = xax->FindBin(-xmn-kEps);
+ double errn;
+ val += hist->IntegralAndError(bmn,bmx,errn);
+ err = TMath::Sqrt(err*err + errn*errn);
+ }
+}
+
+
+//____________________________________________________________________________
+const char* HName(const char* prefix,const char* htype)
+{
+ // compose the name of histo in the clist
+ static TString strh;
+ strh = "Tr"; strh += prefix; strh += "_"; strh += htype;
+ return strh.Data();
+}
+
+//____________________________________________________________________________
+Int_t CheckStat(const TList* lst, const char* dtType)
+{
+ // check if needed bg was generated
+ TH1* hstat = (TH1*)FindObject(kHStatName,lst);
+ TString dts = dtType;
+ if (dts=="Data") return int( hstat->GetBinContent(kEvProcData) );
+ if (dts=="Mix") return int( hstat->GetBinContent(kEvProcMix) );
+ if (dts=="Inj") return int( hstat->GetBinContent(kEvProcInj) );
+ if (dts=="Rot") return int( hstat->GetBinContent(kEvProcRot) );
+ printf("Unknown process %s statistics is checked. Alowed: Data,Mix,Inj,Rot",dtType);
+ return 0;
+}
+
+//____________________________________________________________________________
+void ProjDZE(THnSparseF* hrawd, THnSparseF* hgenb, THnSparseF* hmcComb, TObjArray* res, int bStepEta,int bStepZv)
+{
+ // project 3d histo of Dist vs Zv vs Eta to Zv vs Eta with all cuts
+ int shift = hmcComb ? kMCShift : 0; // is this mc?
+ //
+ // determine boundaries for zv and eta cuts
+ //
+ double cutDstMin,cutDstMax;
+ double cutBgMin,cutBgMax;
+ double cutSgMin,cutSgMax;
+ if (useShapeType==kNormShapeDist) {
+ cutDstMin = 0;
+ cutDstMax = kWDistBgTailMax;
+ //
+ cutBgMin = kWDistBgTailMin;
+ cutBgMax = kWDistBgTailMax;
+ //
+ cutSgMin = 0;
+ cutSgMax = kWDistSgCut;
+ }
+ else {
+ cutDstMin = -kdPhiBgTailMax;
+ cutDstMax = kdPhiBgTailMax;
+ //
+ cutBgMin = kdPhiBgTailMin;
+ cutBgMax = kdPhiBgTailMax;
+ //
+ cutSgMin = 0;
+ cutSgMax = kdPhiSgCut;
+ }
+ //
+ int bn0[3] = {0}; // 1st bin to count
+ int bn1[3] = {0}; // last bin to count
+ // eta
+ TAxis* axEta = hrawd->GetAxis(0);
+ bn0[0] = axEta->FindBin(-useEtaCut+kEps);
+ bn1[0] = axEta->FindBin( useEtaCut-kEps);
+ // Zv
+ TAxis* axZv = hrawd->GetAxis(1);
+ bn0[1] = axZv->FindBin( useZvMin+kEps);
+ bn1[1] = axZv->FindBin( useZvMax-kEps);
+ // W.dist
+ TAxis* axDst = hrawd->GetAxis(2);
+ bn0[2] = axDst->FindBin( cutDstMin + kEps);
+ bn1[2] = axDst->FindBin( cutDstMax - kEps);
+ //
+ //
+ int nb[3] = { bn1[0]-bn0[0]+1, bn1[1]-bn0[1]+1, bn1[2]-bn0[2]+1}; // number of bins to count
+ int nbTot[3] = {axEta->GetNbins(), axZv->GetNbins(), axDst->GetNbins() }; // total bins
+ //
+ if (bStepEta<1 || bStepEta>nb[0]) bStepEta = nb[0];
+ if (bStepZv<1 || bStepEta>nb[1]) bStepZv = nb[1];
+ //
+ for (int i=3;i--;) { // set default axis range
+ hrawd->GetAxis(i)->SetRange(1,nbTot[i]);
+ hgenb->GetAxis(i)->SetRange(1,nbTot[i]);
+ if (hmcComb) hmcComb->GetAxis(i)->SetRange(1,nbTot[i]);
+ }
+ //
+ char grpTit[100];
+ sprintf(grpTit,"grp_eta%d_zv%d",bStepEta,bStepZv);
+ //
+ TString pref = hmcComb ? "mc" : "dt";
+ //
+ // "Data" histo with cut on tails where we look for signal
+ hrawd->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+ TH2* hRawDtCut = hrawd->Projection(1,0,"e");
+ hrawd->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+ hRawDtCut->SetName(pref+"_RawWithCut");
+ hRawDtCut->SetTitle(pref+" Raw with cut on tracklets");
+ res->AddAtAndExpand(hRawDtCut, kRawDtCut+shift);
+ //
+ // "Data - Est.Bg" histo with cut on tails where we look for signal
+ hrawd->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+ TH2* hSignalEst = hrawd->Projection(1,0,"e");
+ hrawd->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+ hSignalEst->SetName(pref+"_SignalCut_"+grpTit);
+ hSignalEst->SetTitle(pref+" Signal (raw-bg) with cut on tracklets "+grpTit);
+ res->AddAtAndExpand(hSignalEst, kSignalEst+shift);
+ //
+ // "Data - MC.Bg" histo with cut on tails where we look for signal
+ TH2* hSignalEstMC = 0;
+ if (hmcComb) {
+ hrawd->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+ hSignalEstMC = hrawd->Projection(1,0,"e");
+ hrawd->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+ hSignalEstMC->SetName(pref+"_SignalCut_bgMCLabels_"+grpTit);
+ hSignalEstMC->SetTitle(pref+" Signal (raw-bg_MCLabels) with cut on tracklets "+grpTit);
+ res->AddAtAndExpand(hSignalEstMC, kSignalEstMC+shift);
+ }
+ //
+ // Estimated background in the cut range
+ hgenb->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+ TH2* hBgEst = hgenb->Projection(1,0,"e");
+ hgenb->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+ hBgEst->SetName(pref+"_BgEst_"+grpTit);
+ hBgEst->SetTitle(pref+" Estimated Bg "+grpTit);
+ res->AddAtAndExpand(hBgEst, kBgEst+shift);
+ //
+ // 1-beta for "data" = (Data_cut - Bg_cut) / Data_cut
+ TH2* h1mBeta = hrawd->Projection(1,0,"e");
+ h1mBeta->Reset();
+ h1mBeta->SetName(pref+"_h1mBeta_"+grpTit);
+ h1mBeta->SetTitle(pref+" 1-#beta with gen.bg. "+grpTit);
+ res->AddAtAndExpand(h1mBeta, k1MBeta+shift);
+ //
+ // If MC labels info is provided
+ TH2* h1mBetaMC = 0; // 1-beta for MC with bg from labels
+ TH2* hBgMC = 0; // bg from MC labels
+ if (hmcComb) {
+ hmcComb->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+ h1mBetaMC = hmcComb->Projection(1,0,"e");
+ h1mBetaMC->SetName(pref+"_h1mBetaMC");
+ h1mBetaMC->SetTitle(pref+" 1-#beta with bg. from MC labels");
+ h1mBetaMC->Divide(hRawDtCut);
+ res->AddAtAndExpand(h1mBetaMC, k1MBetaMC+shift);
+ for (int ib0=1;ib0<=nbTot[0];ib0++)
+ for (int ib1=1;ib1<=nbTot[1];ib1++)
+ h1mBetaMC->SetBinContent(ib0,ib1, 1.- h1mBetaMC->GetBinContent(ib0,ib1));
+ //
+ hBgMC = hmcComb->Projection(1,0,"e");
+ hBgMC->SetName(pref+"_Bg_MClab");
+ hBgMC->SetTitle(pref+" Bg from MC labels");
+ res->AddAtAndExpand(hBgMC, kBgMC+shift);
+ //
+ // finalize estimated signal with bg from MC labels
+ hSignalEstMC->Add(hBgMC,-1);
+ //
+ hmcComb->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+ }
+ //
+ // rescaling factors for generated bg
+ TH2* hBgRescFc = hrawd->Projection(1,0,"e"); hBgRescFc->Reset();
+ hBgRescFc->SetName(pref+"_hBgRescFactors_"+grpTit);
+ hBgRescFc->SetTitle(pref+" Scale.factor for gen.bg. "+grpTit);
+ res->AddAtAndExpand(hBgRescFc, kBgRescFc+shift);
+ //
+ int nbint = bStepEta*bStepZv;
+ float nbinstsq = TMath::Sqrt(nbint);
+ hrawd->GetAxis(0)->SetRange(bn0[0],bn1[0]);
+ hrawd->GetAxis(1)->SetRange(bn0[1],bn1[1]);
+ TH1* hDstDt = hrawd->Projection(2,"e");
+ hrawd->GetAxis(0)->SetRange(1,nbTot[0]);
+ hrawd->GetAxis(1)->SetRange(1,nbTot[1]);
+ hDstDt->SetName(pref+"_DistRaw_"+grpTit); // "Data" projection on tracklet quality (w.distance) axis to check the tails
+ hDstDt->SetTitle(pref+" DistRaw "+grpTit);
+ double nrmDst,dumErr = 0;
+ Integrate(hDstDt, cutBgMin,cutBgMax, nrmDst, dumErr);
+ hDstDt->Scale(1./nrmDst);
+ res->AddAtAndExpand(hDstDt, kDataDist+shift);
+ //
+ hgenb->GetAxis(0)->SetRange(bn0[0],bn1[0]);
+ hgenb->GetAxis(1)->SetRange(bn0[1],bn1[1]);
+ TH1* hDstBg = hgenb->Projection(2,"e"); hDstBg->Reset();
+ hgenb->GetAxis(0)->SetRange(1,nbTot[0]);
+ hgenb->GetAxis(1)->SetRange(1,nbTot[1]);
+ hDstBg->SetName(pref+"_DistBgNorm_"+grpTit); // Gen.Bg projection on tracklet quality (w.distance) axis to check the tails
+ hDstBg->SetTitle(pref+" DistBgNorm "+grpTit); // Gen.Bg projection on tracklet quality (w.distance) axis to check the tails
+ res->AddAtAndExpand(hDstBg, kBgDist+shift);
+ TH1* hDstBgMC = 0;
+ if (hmcComb) {
+ hmcComb->GetAxis(0)->SetRange(bn0[0],bn1[0]);
+ hmcComb->GetAxis(1)->SetRange(bn0[1],bn1[1]);
+ hDstBgMC = hmcComb->Projection(2,"e");
+ hmcComb->GetAxis(0)->SetRange(1,nbTot[0]);
+ hmcComb->GetAxis(1)->SetRange(1,nbTot[1]);
+ hDstBgMC->SetName(pref+"_DistBgMC");
+ hDstBgMC->SetTitle(pref+" Bg. Distance from MC labels");
+ hDstBgMC->Scale(1./nrmDst);
+ res->AddAtAndExpand(hDstBgMC, kBgMCDist+shift);
+ }
+ //
+ // fill 1-beta matrix
+ for (int ib0=bn0[0];ib0<=bn1[0];ib0+=bStepEta) { // eta
+ hrawd->GetAxis(0)->SetRange(ib0,ib0+bStepEta-1);
+ hgenb->GetAxis(0)->SetRange(ib0,ib0+bStepEta-1);
+ for (int ib1=bn0[1];ib1<=bn1[1];ib1+=bStepZv) { // zv
+ hrawd->GetAxis(1)->SetRange(ib1,ib1+bStepZv-1);
+ hgenb->GetAxis(1)->SetRange(ib1,ib1+bStepZv-1);
+ //
+ TH1D* dstD = hrawd->Projection(2,"e"); // data "qaulity" for given eta:zv bin
+ TH1D* dstB = hgenb->Projection(2,"e"); // data "qaulity" for given eta:zv bin
+ double scl,sclE;
+ TH1* nrmB = NormalizeBg(dstD,dstB,scl,sclE); // get rescaling factor for bg. from tails comparison
+ double bgVal,bgErr;
+ double dtVal,dtErr;
+ // integral in the range where we look for signal
+ Integrate(nrmB, cutSgMin, cutSgMax, bgVal, bgErr);
+ Integrate(dstD, cutSgMin, cutSgMax, dtVal, dtErr);
+ double beta,betaErr;
+ GetRatE(bgVal,bgErr, dtVal, dtErr,beta,betaErr);
+ // betaErr*=nbinstsq; // ??? RS
+ for (int i=ib0;i<ib0+bStepEta;i++) {
+ for (int j=ib1;j<ib1+bStepZv;j++) {
+ hBgRescFc->SetBinContent(i,j, scl);
+ hBgRescFc->SetBinError(i,j, sclE);
+ }
+ }
+ hDstBg->Add(nrmB);
+ delete dstD;
+ delete dstB;
+ delete nrmB;
+ //
+ }
+ }
+ hDstBg->Scale(1./nrmDst);
+ //
+ // finalize estimated bg and signal matrices
+ hBgEst->Multiply(hBgRescFc);
+ hSignalEst->Add(hBgEst,-1);
+ //
+ // finalize 1-beta
+ for (int ib0=bn0[0];ib0<=bn1[0];ib0++) { // eta
+ for (int ib1=bn0[1];ib1<=bn1[1];ib1++) { // zv
+ // printf("Bin %d %d\n",ib0,ib1);
+ double bg = hBgEst->GetBinContent(ib0,ib1);
+ double bgE = hBgEst->GetBinError(ib0,ib1);
+ double dt = hRawDtCut->GetBinContent(ib0,ib1);
+ double dtE = hRawDtCut->GetBinError(ib0,ib1);
+ double beta,betaE;
+ GetRatE(bg,bgE,dt,dtE, beta,betaE );
+ h1mBeta->SetBinContent(ib0,ib1,1.-beta);
+ h1mBeta->SetBinError(ib0,ib1,betaE);
+ //
+ }
+ }
+ //
+ // crop to needed range
+ for (int i=shift;i<kNHistos+shift;i++) {
+ TH2* hist = (TH2*)res->At(i);
+ if (!hist || !hist->InheritsFrom(TH2::Class())) continue;
+ CropHisto(hist, bn0[0],bn1[0], bn0[1],bn1[1]);
+ }
+ //
+ h1mBeta->SetMinimum(0.6);
+ h1mBeta->SetMaximum(0.85);
+ if (hmcComb) {
+ h1mBetaMC->SetMinimum(0.6);
+ h1mBetaMC->SetMaximum(0.85);
+ }
+ //
+ // restore
+ for (int i=3;i--;) { // set default axis range
+ hrawd->GetAxis(i)->SetRange(1,nbTot[i]);
+ hgenb->GetAxis(i)->SetRange(1,nbTot[i]);
+ if (hmcComb) hmcComb->GetAxis(i)->SetRange(1,nbTot[i]);
+ }
+ //
+}
+
+
+void GetRealMinMax(TH1* histo, double &vmn, double &vmx)
+{
+ TAxis *xax = histo->GetXaxis();
+ int nbx = xax->GetNbins();
+ vmn=1e6, vmx=-1e6;
+ if (histo->InheritsFrom(TH2::Class())) {
+ TAxis *yax = histo->GetYaxis();
+ int nby = yax->GetNbins();
+ for (int ix=nbx+2;ix--;) {
+ for (int iy=nby+2;iy--;) {
+ double vl = histo->GetBinContent(ix,iy);
+ if (vl<kEps) continue;
+ if (vl<vmn) vmn = vl;
+ if (vl>vmx) vmx = vl;
+ }
+ }
+ }
+ //
+ else {
+ for (int ix=nbx+2;ix--;) {
+ double vl = histo->GetBinContent(ix);
+ if (vl<vmn) vmn = vl;
+ if (vl>vmx) vmx = vl;
+ }
+ }
+ //
+}
--- /dev/null
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "TList.h"
+#include "TFile.h"
+#include "TStyle.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "THnSparse.h"
+#include "TLegend.h"
+#include "TSystem.h"
+#include "TMath.h"
+#include "TCanvas.h"
+#include "TLegend.h"
+#include "TLatex.h"
+#include "TF1.h"
+#include "TLine.h"
+#include "TPaletteAxis.h"
+#include "TArrayD.h"
+#include "TGraphErrors.h"
+//
+//
+#endif
+#include "/home/shahoian/ALICE/mymacros/SaveCanvas.h"
+
+
+
+const char kHStatName[]="hStat";
+double kEps = 1e-6;
+//
+double kdPhiBgTailMin = 0.1; // lower limit of dphi tail to use for bg normalization
+double kdPhiBgTailMax = 0.3; // upper limit of dphi tail to use for bg normalization
+//
+double kWDistBgTailMin = 5.; // lower limit of wgh.distance tail to use for bg normalization
+double kWDistBgTailMax = 25.; // upper limit of wgh.distance tail to use for bg normalization
+
+double kdPhiSgCut=-1; // cut in dphi-bent used to extract the signal, extracted from stat histo
+double kWDistSgCut=-1; // cut in w.distance used to extract the signal, extracted from stat histo
+//
+enum { kNormShapeDist, // normalize bg tails usig weighted distance shape
+ kNormShapeDPhi, // normalize bg tails usig dPhi-bend shape
+ kNormShapes};
+
+enum { kSclWghMean, // normalize bg tails to data using weighted mean of bin-by-bin ratios
+ kSclIntegral, // normalize bg tails to data using integral
+ kSclTypes};
+
+
+const char* figDir = "figMult";
+TString useBgType = "Inj";
+Int_t useShapeType = kNormShapeDist; // which distribution to use for bg normalization
+Bool_t useMCLB = kFALSE; // use Comb MC Labels as a template for Bg.
+Int_t useScaleType = kSclIntegral;//kSclWghMean; // which type of tails normalization to use
+const double kEtaFitRange = 0.5;
+
+enum {kBitNormPerEvent=BIT(14)};
+ // bins for saved parameters in the hStat histo
+enum {kDummyBin,
+ kEvTot, // events read
+ kOneUnit, // just 1 to track primate merges
+ kNWorkers, // n workers
+ //
+ kDPhi, // dphi window
+ kDTht, // dtheta window
+ kNStd, // N.standard deviations to keep
+ kPhiShift, // bending shift
+ kThtS2, // is dtheta scaled by 1/sin^2
+ kThtCW, // on top of w.dist cut cut also on 1 sigma dThetaX
+ kPhiOvl, // overlap params
+ kZEtaOvl, // overlap params
+ kNoOvl, // flag that overlap are suppressed
+ //
+ kPhiRot, // rotation phi
+ kInjScl, // injection scaling
+ kEtaCut, // eta cut
+ kZVMin, // min ZVertex to process
+ kZVMax, // max ZVertex to process
+ //
+ kDPiSCut, // cut on dphi used to extract signal (when WDist is used in analysis, put it equal to kDPhi
+ kNStdCut, // cut on weighted distance (~1) used to extract signal
+ //
+ kMCV0Scale, // scaling value for V0 in MC
+ //
+ // here we put entries for each mult.bin
+ kBinEntries = 50,
+ kEvProcData, // events with data mult.object (ESD or reco)
+ kEvProcInj, // events Injected, total
+ kEvProcRot, // events Rotated
+ kEvProcMix, // events Mixed
+ kEntriesPerBin
+};
+
+
+enum {kSigCorr,kMCPrim,kRawDtCut,kSignalEst,kSignalEstMC,kBgEst,k1MBeta,k1MBetaMC,kAlpha,kAlphaMC,kBgMC,kBgRescFc,kDataDist,kBgDist,kBgMCDist, kMCShift=20, kNHistos=kMCShift+kMCShift};
+
+void CorrectSpectraMulti(const char* flNameData, const char* flNameMC,const char* unique="");
+Bool_t PrepareHistos(int bin, TList* lst, Bool_t isMC);
+void ProcessHistos(int bin);
+TH1* NormalizeBg(TH1* dataH, TH1* bgH, double &scl, double &scle);
+TObject* FindObject(int bin, const char* nameH, const TList* lst, Bool_t normPerEvent=kTRUE);
+TList* LoadList(const char* flName, const char* addPref, const char* nameL="clist");
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate);
+Int_t CheckStat(const TList* lst,const char* dtType);
+void Integrate(TH1* hist, double xmn,double xmx, double &val, double& err);
+void CropHisto(TH1* histo, int b00, int b01, int b10=-1, int b11=-1);
+void CropHisto(TH1* histo, double b00, double b01, double b10=-1, double b11=-1);
+void GetRealMinMax(TH1* h, double &vmn, double &vmx);
+const char* HName(const char* prefix,const char* htype);
+
+void PlotResults();
+void PlotDNDEta(int bin);
+void PlotAlphaBeta(int bin);
+void PlotSpecies();
+
+Float_t myMergeFactor = -1; // if the files were manually merged, scale everything except statistics by 1/myMergeFactor
+Int_t nCentBins = -1;
+TList *listDt=0, *listMC=0;
+TObjArray resArr;
+char outStr[1000];
+char outTitle[1000];
+TString uniqueName="";
+//
+TArrayD dNdEta,dNdEtaErr;
+TCanvas *canvFin=0;
+//
+Bool_t creatDnDEtaCMacro = kFALSE;
+Bool_t creatAlphaBetaCMacro = kFALSE;
+Bool_t creatSpeciesCMacro = kFALSE;
+
+void CorrectSpectraMulti(const char* flNameData, const char* flNameMC, const char* uniqueNm)
+{
+ //
+ uniqueName = uniqueNm;
+ listDt = LoadList(flNameData,"dt_");
+ listMC = LoadList(flNameMC,"mc_");
+ //
+ resArr.Clear();
+ //
+ TH1* hstat = (TH1*)FindObject(-1,kHStatName,listDt,kFALSE);
+ //
+ int nbstat = hstat->GetNbinsX();
+ nCentBins = (nbstat - kBinEntries)/kEntriesPerBin;
+ printf("%d bins will be processed\n",nCentBins);
+ if (nCentBins<1) return;
+ myMergeFactor = hstat->GetBinContent(kOneUnit);
+ printf("Detected %f mergings\n",myMergeFactor);
+ //
+ dNdEta.Set(nCentBins);
+ dNdEtaErr.Set(nCentBins);
+ //
+ kdPhiSgCut = hstat->GetBinContent(kDPiSCut)/myMergeFactor;
+ kWDistSgCut = hstat->GetBinContent(kNStdCut)/myMergeFactor;
+ printf("Signal cuts used: dPhiS: %f WDist:%f\n",kdPhiSgCut,kWDistSgCut);
+ //
+ for (int ib=0;ib<nCentBins;ib++) {
+ if (!PrepareHistos(ib,listMC,kTRUE)) return;
+ if (!PrepareHistos(ib,listDt,kFALSE)) return;
+ ProcessHistos(ib);
+ //
+ }
+ //
+ sprintf(outStr,"CutEta%.1f_Zv%.1f_%.1f_bg%s_Shape_%s_mcLB%d_cutSig%.1f_cutBg%.1f",
+ hstat->GetBinContent(kEtaCut)/myMergeFactor,
+ hstat->GetBinContent(kZVMin)/myMergeFactor,
+ hstat->GetBinContent(kZVMax)/myMergeFactor,
+ useBgType.Data(),
+ useShapeType==kNormShapeDist ? "wdst":"dphi",
+ useMCLB,
+ useShapeType==kNormShapeDist ? kWDistSgCut:kdPhiSgCut,
+ useShapeType==kNormShapeDist ? kWDistBgTailMin:kdPhiBgTailMin);
+ //
+ PlotResults();
+ //
+ printf("Final Results:\n");
+ printf("dNdEta: ");
+ for (int i=nCentBins;i--;) printf("%.2f,",dNdEta[i]); printf("\n");
+ printf("dNdEtaErr: ");
+ for (int i=nCentBins;i--;) printf("%.2f,",dNdEtaErr[i]); printf("\n");
+
+}
+
+//_____________________________________________________________________
+Bool_t PrepareHistos(int bin, TList* lst, Bool_t isMC)
+{
+ // fill standard histos for given bin
+ //
+ char buffn[500];
+ char bufft[500];
+ //
+ double cutBgMin,cutBgMax;
+ double cutSgMin,cutSgMax;
+ //
+ if (useShapeType==kNormShapeDist) {
+ cutBgMin = kWDistBgTailMin;
+ cutBgMax = kWDistBgTailMax;
+ //
+ cutSgMin = 0;
+ cutSgMax = kWDistSgCut;
+ }
+ else {
+ cutBgMin = kdPhiBgTailMin;
+ cutBgMax = kdPhiBgTailMax;
+ //
+ cutSgMin = 0;
+ cutSgMax = kdPhiSgCut;
+ }
+ //
+ const char* zeCut = "ZvEtaCutT";
+ TObjArray* res = &resArr;
+ int shift = bin*kNHistos + (isMC ? kMCShift : 0);
+ //
+ // histo for "data" Z vs Eta with default signal cut
+ TH2* hRawDtCut = (TH2*) FindObject(bin,HName("Data",zeCut),lst);
+ if (!hRawDtCut) return kFALSE;
+ sprintf(buffn,"bin%d_%s_RawWithCut",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Raw Data with cut on tracklets",bin,isMC ? "mc":"dt");
+ hRawDtCut = (TH2*)hRawDtCut->Clone(buffn);
+ hRawDtCut->SetTitle(bufft);
+ res->AddAtAndExpand(hRawDtCut, kRawDtCut+shift);
+ //
+ int nbEta = hRawDtCut->GetXaxis()->GetNbins();
+ int nbZV = hRawDtCut->GetYaxis()->GetNbins();
+ //
+ // "Data - Est.Bg" histo with cut on tails where we look for signal
+ sprintf(buffn,"bin%d_%s_SignalWithCut",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Signal (raw-bg) with cut on tracklets",bin,isMC ? "mc":"dt");
+ TH2* hSignalEst = (TH2F*)hRawDtCut->Clone(buffn);
+ hSignalEst->SetTitle(bufft);
+ res->AddAtAndExpand(hSignalEst, kSignalEst+shift);
+ //
+ // "Data - MC.Bg" histo with cut on tails where we look for signal
+ TH2* hSignalEstMC = 0;
+ if (isMC) {
+ sprintf(buffn,"bin%d_%s_SignalWithCut_bgMCLabels",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Signal (raw-bg_MCLabels) with cut on tracklets",bin,isMC ? "mc":"dt");
+ hSignalEstMC = (TH2F*)hRawDtCut->Clone(buffn);
+ hSignalEstMC->SetTitle(bufft);
+ res->AddAtAndExpand(hSignalEstMC, kSignalEstMC+shift);
+ }
+ //
+ // Estimated background in the cut range
+ sprintf(buffn,"bin%d_%s_BgEst",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Estimated Bg",bin,isMC ? "mc":"dt");
+ TH2* hBgEst = (TH2*) FindObject(bin,HName(useBgType.Data(),zeCut),lst);
+ if (!hBgEst) return kFALSE;
+ hBgEst = (TH2*)hBgEst->Clone(buffn);
+ hBgEst->SetTitle(bufft);
+ res->AddAtAndExpand(hBgEst,kBgEst +shift);
+ //
+ // special feature: use MC Labels bg as a shape instead of generated bg
+ /*
+ if (useMCLB) {
+ TString nm = hBgEst->GetName(); nm += "_MCLB";
+ TString tit = hBgEst->GetTitle(); tit += "_MCLB";
+ TH2* hBMCLB = (TH2*) FindObject(bin,HName("Comb",zeCut),listMC);
+ if (!hBMCLB) return kFALSE;
+ hBMCLB = (TH2F*)hBMCLB->Clone(nm.Data());
+ hBMCLB->SetTitle(tit.Data());
+ delete hBgEst;
+ hBgEst = hBMCLB;
+ res->AddAtAndExpand(hBgEst,kBgEst +shift);
+ }
+ */
+ //
+ // 1-beta for "data" = (Data_cut - Bg_cut) / Data_cut
+ sprintf(buffn,"bin%d_%s_1mBeta",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s 1-#beta with estimated bg",bin,isMC ? "mc":"dt");
+ TH2* h1mBeta = (TH2*)hBgEst->Clone(buffn);
+ h1mBeta->SetTitle(bufft);
+ h1mBeta->Reset();
+ res->AddAtAndExpand(h1mBeta, k1MBeta+shift);
+ //
+ // If MC labels info is provided, prepare 1-beta with MC bg
+ TH2* h1mBetaMC = 0; // 1-beta for MC with bg from labels
+ TH2* hBgMC = 0; // bg from MC labels
+ if (isMC) {
+ sprintf(buffn,"bin%d_%s_BgMC",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Bg from MC labels",bin,isMC ? "mc":"dt");
+ hBgMC = (TH2*) FindObject(bin,HName("Comb",zeCut),listMC);
+ if (!hBgMC) return kFALSE;
+ hBgMC = (TH2F*)hBgMC->Clone(buffn);
+ hBgMC->SetTitle(bufft);
+ res->AddAtAndExpand(hBgMC, kBgMC+shift);
+ //
+ sprintf(buffn,"bin%d_%s_h1mBetaMC",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s 1-#beta with bg. from MC labels",bin,isMC ? "mc":"dt");
+ h1mBetaMC = (TH2F*) hBgMC->Clone(buffn);
+ h1mBetaMC->SetTitle(bufft);
+ res->AddAtAndExpand(h1mBetaMC, k1MBetaMC+shift);
+ h1mBetaMC->Divide(hRawDtCut);
+ for (int ib0=1;ib0<=nbEta;ib0++)
+ for (int ib1=1;ib1<=nbZV;ib1++)
+ h1mBetaMC->SetBinContent(ib0,ib1, 1.- h1mBetaMC->GetBinContent(ib0,ib1));
+ //
+ hSignalEstMC->Add(hBgMC,-1);
+ }
+ //
+ // uncut w.distance or dphi distribution for data
+ TH1* hDstDt = (TH1*) FindObject(bin,HName("Data",useShapeType==kNormShapeDist ? "WDist":"DPhiS"),lst);
+ if (!hDstDt) return kFALSE;
+ sprintf(buffn,"bin%d_%s_DistRawData",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Raw Distance for Data",bin,isMC ? "mc":"dt");
+ hDstDt = (TH1*) hDstDt->Clone(buffn);
+ hDstDt->SetTitle(bufft);
+ double nrmDst,dumErr = 0;
+ Integrate(hDstDt, cutBgMin,cutBgMax, nrmDst, dumErr);
+ hDstDt->Scale(1./nrmDst);
+ res->AddAtAndExpand(hDstDt, kDataDist+shift);
+ //
+ // uncut w.distance or dphi distribution for generated bg
+ TH1* hDstBg = (TH1*) FindObject(bin,HName(useBgType.Data(),useShapeType==kNormShapeDist ? "WDist":"DPhiS"),lst);
+ if (!hDstBg) return kFALSE;
+ sprintf(buffn,"bin%d_%s_DistRawGenBgNorm",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Raw Distance for Gen.Bg. Normalized to data",bin,isMC ? "mc":"dt");
+ hDstBg = (TH1*) hDstBg->Clone(buffn);
+ hDstBg->SetTitle(bufft);
+ hDstBg->Scale(1./nrmDst);
+ // res->AddAtAndExpand(hDstBg, kBgDist+shift);
+ //
+ if (useMCLB) { // use MC dist. shape as a template
+ TH1* mcshp = (TH1*) FindObject(bin,HName("Comb",useShapeType==kNormShapeDist ? "WDist":"DPhiS"),listMC);
+ double nrm1 = hDstBg->Integral();
+ double nrmMC = mcshp->Integral();
+ sprintf(buffn,"bin%d_%s_DistRawGenBgNormMCLB",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Raw Distance for Gen.Bg. Normalized to data MCLB",bin,isMC ? "mc":"dt");
+ if (hDstBg) delete hDstBg;
+ hDstBg = (TH1*) mcshp->Clone(buffn);
+ hDstBg->SetTitle(bufft);
+ hDstBg->Scale(nrm1/nrmMC);
+ }
+ //
+ // uncut w.distance or dphi distribution for comb. MC labels
+ TH1* hDstBgMC = 0;
+ if (isMC) {
+ hDstBgMC = (TH1*) FindObject(bin,HName("Comb",useShapeType==kNormShapeDist ? "WDist":"DPhiS"),lst);
+ if (!hDstBgMC) return kFALSE;
+ sprintf(buffn,"bin%d_%s_DistBgMC",bin,isMC ? "mc":"dt");
+ sprintf(bufft,"bin%d %s Bg. Distance from MC labels",bin,isMC ? "mc":"dt");
+ hDstBgMC = (TH1*) hDstBgMC->Clone(buffn);
+ hDstBgMC->SetTitle(bufft);
+ hDstBgMC->Scale(1./nrmDst);
+ res->AddAtAndExpand(hDstBgMC, kBgMCDist+shift);
+ }
+ //
+ // fill 1-beta matrix
+ double scl,sclE;
+ hDstBg = NormalizeBg(hDstDt,hDstBg,scl,sclE); // get rescaling factor for bg. from tails comparison
+ res->AddAtAndExpand(hDstBg, kBgDist+shift);
+ double bgVal,bgErr;
+ double dtVal,dtErr;
+ // integral in the range where we look for signal
+ Integrate(hDstBg, cutSgMin, cutSgMax, bgVal, bgErr);
+ Integrate(hDstDt, cutSgMin, cutSgMax, dtVal, dtErr);
+ double sclb,sclbErr;
+ GetRatE(bgVal,bgErr, dtVal, dtErr,sclb,sclbErr);
+ // hDstBg->Scale(1./nrmDst);
+ //
+ // finalize estimated bg and signal matrices
+ hBgEst->Scale(scl);
+ //
+ hSignalEst->Add(hBgEst,-1);
+ //
+ // finalize 1-beta
+ for (int ib0=1;ib0<=nbEta;ib0++) { // eta
+ for (int ib1=1;ib1<=nbZV;ib1++) { // zv
+ // printf("Bin %d %d\n",ib0,ib1);
+ double bg = hBgEst->GetBinContent(ib0,ib1);
+ double bgE = hBgEst->GetBinError(ib0,ib1);
+ double dt = hRawDtCut->GetBinContent(ib0,ib1);
+ double dtE = hRawDtCut->GetBinError(ib0,ib1);
+ double beta,betaE;
+ GetRatE(bg,bgE,dt,dtE, beta,betaE );
+ h1mBeta->SetBinContent(ib0,ib1,1.-beta);
+ h1mBeta->SetBinError(ib0,ib1,betaE);
+ //
+ }
+ }
+ //
+ if (isMC) {
+ // prepare MC primary signal histo
+ sprintf(buffn,"bin%d_zvEtaPrimMC",bin);
+ sprintf(bufft,"bin%d MC True signal Zv vs Eta",bin);
+ TH2F* mcPrim = (TH2F*)FindObject(bin,"zvEtaPrimMC", lst );
+ mcPrim = (TH2F*) mcPrim->Clone(buffn);
+ mcPrim->SetTitle(bufft);
+ res->AddAtAndExpand(mcPrim, kMCPrim + shift);
+ }
+ //
+ return kTRUE;
+}
+
+//_____________________________________________________________________
+void ProcessHistos(int bin)
+{
+ //
+ int shift = bin*kNHistos;
+ //
+ TString prefN = "bin"; prefN += bin; prefN+="_";
+ TString prefT = "bin"; prefT += bin; prefT+=" ";
+ TObjArray* res = &resArr;
+ // build alpha matrix
+ TH2* halp = (TH2*)res->At(shift + kMCShift + kMCPrim);
+ halp = (TH2*) halp->Clone(prefN+"Alpha");
+ halp->SetTitle(prefN+"#alpha");
+ halp->Divide( (TH2*)res->At(shift + kMCShift + k1MBeta) );
+ halp->Divide( (TH2*)res->At(shift + kMCShift + kRawDtCut) );
+ res->AddAtAndExpand(halp, shift + kAlpha);
+ //
+ // build alpha matrix with MC labels bg
+ TH2* halpMC = (TH2*)res->At(shift + kMCShift + kMCPrim);
+ halpMC = (TH2*) halpMC->Clone(prefN + "AlphaMC");
+ halpMC->SetTitle(prefT + "#alpha MC labels");
+ halpMC->Divide( (TH2*)res->At(shift + kMCShift + k1MBetaMC) );
+ halpMC->Divide( (TH2*)res->At(shift + kMCShift + kRawDtCut) );
+ res->AddAtAndExpand(halpMC, shift + kAlphaMC);
+ //
+ // build corrected signal
+ TH2* hsigCorr = (TH2*)res->At(shift + kSignalEst);
+ hsigCorr = (TH2*) hsigCorr->Clone(prefN + "SignalEstCorr");
+ hsigCorr->SetTitle(prefT + "Corrected Signal");
+ hsigCorr->Multiply( halp );
+ res->AddAtAndExpand(hsigCorr, shift + kSigCorr);
+ //
+ TH1* hsigCorrX = hsigCorr->ProjectionX("DataCorrSignalX");
+ hsigCorrX->Scale(1./hsigCorr->GetBinWidth(1));
+ TF1* pl0 = new TF1("pl0","pol0");
+ pl0->SetParameter(0,hsigCorr->GetMinimum());
+ hsigCorrX->Fit(pl0,"q0","",-kEtaFitRange,kEtaFitRange);
+ double fval = pl0->GetParameter(0);
+ double ferr = pl0->GetParError(0);
+ delete hsigCorrX;
+ dNdEta[bin] = fval;
+ dNdEtaErr[bin] = ferr;
+ printf("Bin %d: dN/d#eta_{|#eta|<0.5} = %.2f %.2f\n",bin, fval,ferr);
+ //
+}
+
+void PlotResults()
+{
+ TString psnm1 = figDir; psnm1 += "/"; psnm1 += uniqueName;
+ psnm1 += "_"; psnm1 += nCentBins; psnm1+= "bins_";
+ psnm1 += outStr; psnm1 += ".ps";
+ TString psnm0 = psnm1.Data();
+ psnm0 += "[";
+ TString psnm2 = psnm1.Data();
+ psnm2 += "]";
+ //
+ TH1* hstat = (TH1*)FindObject(-1,kHStatName,listDt,kFALSE);
+ //
+ TH1* hbins = (TH1*)FindObject(-1,"EvCentr",listDt,kFALSE);
+ //
+ if (!canvFin) canvFin = new TCanvas("canvFin", "canvFin",0,50,700,1000);
+ canvFin->Clear();
+ //
+ canvFin->Print(psnm0.Data());
+ //
+ canvFin->Divide(1,2);
+ canvFin->cd(1);
+ gPad->SetLeftMargin(0.15);
+ TGraphErrors* grp = new TGraphErrors(nCentBins);
+ for (int i=0;i<nCentBins;i++) {
+ grp->SetPoint(i,hbins->GetBinCenter(i+1),dNdEta[i]);
+ grp->SetPointError(i,hbins->GetBinWidth(i+1)/2,dNdEtaErr[i]);
+ }
+ grp->SetMarkerStyle(20);
+ grp->SetMarkerColor(kRed);
+ grp->SetLineColor(kRed);
+ grp->SetMinimum(1e-6);
+ grp->Draw("ap");
+ grp->GetXaxis()->SetTitle("Centrality Variable");
+ grp->GetYaxis()->SetTitle("dN/d#eta_{|#eta|<0.5}");
+ grp->GetYaxis()->SetTitleOffset(1.8);
+ gPad->SetGrid(1,1);
+ //
+ canvFin->cd(2);
+ gPad->SetLeftMargin(0.15);
+ hbins->Draw();
+ hbins->SetMinimum(1e-6);
+ hbins->SetMarkerStyle(20);
+ hbins->SetMarkerColor(kRed);
+ hbins->SetLineColor(kRed);
+ hbins->GetYaxis()->SetTitle("accepted events");
+ hbins->GetYaxis()->SetTitleOffset(1.8);
+ gPad->SetGrid(1,1);
+ //
+ canvFin->cd(0);
+ canvFin->Print(psnm1.Data());
+ //
+ const TArrayD &binArr = *hbins->GetXaxis()->GetXbins();
+ //
+ for (int i=0;i<nCentBins;i++) {
+ //
+ sprintf(outTitle,"%s, %d<c<%d, |#eta|<%.1f, %.1f<Z_{V}<%.1f, Bg.:%s, UseMCLB=%d, CutVar:%s, |sig|<%.2f, %.2f<|bg.nrm|<%.2f",
+ uniqueName.Data(),
+ (int)binArr[i],(int)binArr[i+1],
+ hstat->GetBinContent(kEtaCut)/myMergeFactor,
+ hstat->GetBinContent(kZVMin)/myMergeFactor,
+ hstat->GetBinContent(kZVMax)/myMergeFactor,
+ useBgType.Data(),
+ useMCLB,
+ useShapeType==kNormShapeDist ? "#Delta":"#Delta#varphi-#delta_{#varphi}",
+ useShapeType==kNormShapeDist ? kWDistSgCut:kdPhiSgCut,
+ useShapeType==kNormShapeDist ? kWDistBgTailMin : kdPhiBgTailMin,
+ useShapeType==kNormShapeDist ? kWDistBgTailMax : kdPhiBgTailMax
+ );
+ //
+ PlotDNDEta(i);
+ canvFin->Print(psnm1.Data());
+ PlotAlphaBeta(i);
+ canvFin->Print(psnm1.Data());
+ }
+ PlotSpecies();
+ canvFin->Print(psnm1.Data());
+ //
+ canvFin->Print(psnm2.Data());
+}
+
+void PlotDNDEta(int bin)
+{
+ //
+ TObjArray *res = &resArr;
+ TString prefN = "bin"; prefN += bin; prefN+="_";
+ int shift = bin*kNHistos;
+ //
+ char buff[1000];
+ // eta range
+ gStyle->SetOptFit(0);
+ gStyle->SetOptStat(0);
+ gStyle->SetOptTitle(0);
+ double mn = 1e6,mx = -1e6;
+ if (!canvFin) canvFin = new TCanvas("canvFin", "canvFin",0,50,700,1000);
+ canvFin->Clear();
+ canvFin->Divide(1,2);
+ canvFin->cd(1);
+ gPad->SetLeftMargin(0.15);
+ //
+ // corrected data
+ TH1* hsigCorr = ((TH2F*)res->At(shift + kSigCorr))->ProjectionX(prefN+"DataCorrSignal");
+ SetHStyle(hsigCorr,kRed,20,1.0);
+ hsigCorr->Scale(1./hsigCorr->GetBinWidth(1));
+ hsigCorr->Draw();
+ mx = TMath::Max(mx, hsigCorr->GetMaximum());
+ mn = TMath::Min(mn, hsigCorr->GetMinimum());
+ char ftres[1000];
+ sprintf(ftres,"dN/d#eta_{|#eta|<%.1f} = %.1f #pm %.1f",kEtaFitRange,dNdEta[bin],dNdEtaErr[bin]);
+ TLatex *txfit = new TLatex(-0.2,hsigCorr->GetMinimum()*0.9, ftres);
+ txfit->SetTextSize(0.04);
+ txfit->Draw();
+ //
+ // raw data
+ TH1* hraw = ((TH2F*)res->At(shift+kRawDtCut))->ProjectionX(prefN+"DataRaw");
+ SetHStyle(hraw,kRed,21,1.0);
+ hraw->Scale(1./hraw->GetBinWidth(1));
+ hraw->Draw("same");
+ mn = TMath::Min(mn, hraw->GetMinimum());
+ mx = TMath::Max(mx, hraw->GetMaximum());
+ //
+ // raw data bg sub
+ TH1* hraws = ((TH2F*)res->At(shift+kSignalEst))->ProjectionX(prefN+"DataRawSub");
+ SetHStyle(hraws,kRed,23,1.0);
+ hraws->Scale(1./hraw->GetBinWidth(1));
+ hraws->Draw("same");
+ mn = TMath::Min(mn, hraw->GetMinimum());
+ mx = TMath::Max(mx, hraw->GetMaximum());
+ //
+ // bg
+ TH1* hbg = ((TH2F*)res->At(shift+kBgEst))->ProjectionX(prefN+"BgEst");
+ SetHStyle(hbg,kMagenta,22,1.0);
+ hbg->Scale(1./hbg->GetBinWidth(1));
+ hbg->Draw("same");
+ mn = TMath::Min(mn, hbg->GetMinimum());
+ mx = TMath::Max(mx, hbg->GetMaximum());
+ //
+ // mc part ----------------------------
+ // raw data
+ TH1* hrawMC = ((TH2F*)res->At(shift+kRawDtCut+kMCShift))->ProjectionX(prefN+"DataRawMC");
+ SetHStyle(hrawMC,kBlue,24,1.0);
+ hrawMC->Scale(1./hrawMC->GetBinWidth(1));
+ hrawMC->Draw("same");
+ mn = TMath::Min(mn, hrawMC->GetMinimum());
+ mx = TMath::Max(mx, hrawMC->GetMaximum());
+ //
+ // raw data bg sub
+ TH1* hrawsMC = ((TH2F*)res->At(shift+kSignalEst+kMCShift))->ProjectionX(prefN+"DataRawSubMC");
+ SetHStyle(hrawsMC,kBlue,26,1.0);
+ hrawsMC->Scale(1./hrawMC->GetBinWidth(1));
+ hrawsMC->Draw("same");
+ mn = TMath::Min(mn, hrawMC->GetMinimum());
+ mx = TMath::Max(mx, hrawMC->GetMaximum());
+ //
+ // raw data bgMClabels sub
+ TH1* hrawsMCLB = ((TH2F*)res->At(shift+kSignalEstMC+kMCShift))->ProjectionX(prefN+"DataRawSubMCLB");
+ SetHStyle(hrawsMCLB,kGreen+2,30,1.0);
+ hrawsMCLB->Scale(1./hrawsMCLB->GetBinWidth(1));
+ hrawsMCLB->Draw("same");
+ mn = TMath::Min(mn, hrawsMCLB->GetMinimum());
+ mx = TMath::Max(mx, hrawsMCLB->GetMaximum());
+ //
+ // bg est
+ TH1* hbgMCEst = ((TH2F*)res->At(shift+kBgEst+kMCShift))->ProjectionX(prefN+"BgEstMC");
+ SetHStyle(hbgMCEst,kBlue,26,1.0);
+ hbgMCEst->Scale(1./hbgMCEst->GetBinWidth(1));
+ hbgMCEst->Draw("same");
+ mn = TMath::Min(mn, hbgMCEst->GetMinimum());
+ mx = TMath::Max(mx, hbgMCEst->GetMaximum());
+ //
+ // bg MC
+ TH1* hbgMC = ((TH2F*)res->At(shift+kBgMC+kMCShift))->ProjectionX(prefN+"BgMC");
+ SetHStyle(hbgMC,kGreen+2,25,1.0);
+ hbgMC->Scale(1./hbgMC->GetBinWidth(1));
+ hbgMC->Draw("same");
+ mn = TMath::Min(mn, hbgMC->GetMinimum());
+ mx = TMath::Max(mx, hbgMC->GetMaximum());
+ //
+ mn = 0;
+ hsigCorr->SetMinimum(mn);
+ hsigCorr->SetMaximum(mx + 0.4*(mx-mn));
+ gPad->Modified();
+ //
+ TLegend *legDnDeta = new TLegend(0.15,0.75, 0.45,0.95);
+ legDnDeta->SetFillColor(kWhite);
+ legDnDeta->SetHeader("Data");
+ legDnDeta->AddEntry(hsigCorr,"Corrected","pl");
+ legDnDeta->AddEntry(hraw, "Reconstructed","pl");
+ sprintf(buff,"Reconstructed - Bckg.%s.",useBgType.Data());
+ legDnDeta->AddEntry(hraws, buff,"pl");
+ sprintf(buff,"Background %s.",useBgType.Data());
+ legDnDeta->AddEntry(hbg, buff,"pl");
+ legDnDeta->Draw();
+ //
+ TLegend *legDnDetaMC = new TLegend(0.60,0.72, 0.95,0.95);
+ legDnDetaMC->SetFillColor(kWhite);
+ legDnDetaMC->SetHeader("MC");
+ legDnDetaMC->AddEntry(hrawMC, "Reconstructed","pl");
+ sprintf(buff,"Reconstructed - Bckg.%s.",useBgType.Data());
+ legDnDetaMC->AddEntry(hrawsMC, buff,"pl");
+ sprintf(buff,"Reconstructed - Bckg.%s.","MC.Labels");
+ legDnDetaMC->AddEntry(hrawsMCLB, buff,"pl");
+ sprintf(buff,"Background %s.",useBgType.Data());
+ legDnDetaMC->AddEntry(hbgMCEst, buff,"pl");
+ sprintf(buff,"Background %s.","MC Labels");
+ legDnDetaMC->AddEntry(hbgMC, buff,"pl");
+ //
+ legDnDetaMC->Draw();
+ //
+ gPad->SetGrid(1.1);
+ gPad->Modified();
+ AddLabel(outTitle,0.1,0.97, kBlack,0.025);
+ //
+ canvFin->cd();
+ //
+ //---------------- dsitributions
+ canvFin->cd(2);
+ //
+ TH1* mcdst = (TH1*)res->At(shift+kDataDist+kMCShift);
+ TH1* mcdstbg = (TH1*)res->At(shift+kBgDist+kMCShift);
+ TH1* mcdstbgLB = (TH1*)res->At(shift+kBgMCDist+kMCShift);
+ TH1* dtdst = (TH1*)res->At(shift+kDataDist);
+ TH1* dtdstbg = (TH1*)res->At(shift+kBgDist);
+ //
+ TH1* mcDstN = (TH1*)FindObject(bin,HName("Data", useShapeType==kNormShapeDist ? "WDist":"DPhiS"), listMC );
+ TH1* mcDstSec = (TH1*)FindObject(bin,HName("Sec", useShapeType==kNormShapeDist ? "WDist":"DPhiS"), listMC );
+ TH1* mcDstCombU = (TH1*)FindObject(bin,HName("CombU",useShapeType==kNormShapeDist ? "WDist":"DPhiS"), listMC );
+ TH1* mcDstCombC = (TH1*)FindObject(bin,HName("Comb", useShapeType==kNormShapeDist ? "WDist":"DPhiS"), listMC );
+ //
+ double scl,sclE;
+ mcDstN = NormalizeBg(mcdst,mcDstN,scl,sclE);
+ mcDstSec->Scale(scl);
+ mcDstCombU->Scale(scl);
+ mcDstCombC->Scale(scl);
+ mcDstCombC->Add(mcDstCombU,-1);
+
+ dtdst->Draw("");
+ gPad->Modified();
+ dtdst->GetXaxis()->SetLabelSize(0.03);
+ dtdst->GetXaxis()->SetTitleSize(0.03);
+ dtdst->GetXaxis()->SetTitleOffset(2);
+ dtdstbg->Draw("same");
+ //
+ mcdst->Draw("same");
+ mcDstSec->Draw("same");
+ mcdstbgLB->Draw("same");
+ mcdstbg->Draw("same");
+ mcDstCombC->Draw("same");
+ //
+
+ SetHStyle(mcdst,kBlue, 25,0.7);
+ SetHStyle(mcdstbgLB,kGreen, 7/*32*/,0.5);
+ SetHStyle(mcdstbg,kCyan, 7/*26*/,0.5);
+ SetHStyle(mcDstCombC,kGreen+2, 21,0.7);
+ SetHStyle(mcDstSec,kBlue+2, 22,0.7);
+ //
+ SetHStyle(dtdst,kRed, 20,0.7);
+ SetHStyle(dtdstbg,kBlue, 34,0.7);
+ //
+ double vmcTot,vmcTotE;
+ double vmcSec,vmcSecE, ratSec,ratSecE;
+ double vmcCmbEst,vmcCmbEstE, ratCmbEst,ratCmbEstE;
+ double vmcCmb,vmcCmbE, ratCmb,ratCmbE;
+ double vmcCmbC,vmcCmbCE, ratCmbC,ratCmbCE;
+ double cutSgMin,cutSgMax;
+ double cutBgMin,cutBgMax;
+ if (useShapeType==kNormShapeDist) {
+ cutSgMin = 0;
+ cutSgMax = kWDistSgCut;
+ cutBgMin = kWDistBgTailMin;
+ cutBgMax = kWDistBgTailMax;
+ }
+ else {
+ cutSgMin = 0;
+ cutSgMax = kdPhiSgCut;
+ cutBgMin = kdPhiBgTailMin;
+ cutBgMax = kdPhiBgTailMax;
+ }
+ Integrate(mcdst, cutSgMin,cutSgMax, vmcTot,vmcTotE);
+ Integrate(mcDstSec, cutSgMin,cutSgMax, vmcSec,vmcSecE);
+ GetRatE(vmcSec,vmcSecE, vmcTot,vmcTotE, ratSec,ratSecE);
+ //
+ Integrate(mcdstbgLB, cutSgMin,cutSgMax, vmcCmb,vmcCmbE);
+ GetRatE(vmcCmb,vmcCmbE, vmcTot,vmcTotE, ratCmb,ratCmbE);
+ //
+ Integrate(mcdstbg, cutSgMin,cutSgMax, vmcCmbEst,vmcCmbEstE);
+ GetRatE(vmcCmbEst,vmcCmbEstE, vmcTot,vmcTotE, ratCmbEst,ratCmbEstE);
+ //
+ Integrate(mcDstCombC, cutSgMin,cutSgMax, vmcCmbC,vmcCmbCE);
+ GetRatE(vmcCmbC,vmcCmbCE, vmcTot,vmcTotE, ratCmbC,ratCmbCE);
+ //
+ double vdtTot,vdtTotE;
+ double vdtBg,vdtBgE, ratdtBg,ratdtBgE;
+ //
+ Integrate(dtdst, cutSgMin,cutSgMax, vdtTot,vdtTotE);
+ Integrate(dtdstbg, cutSgMin,cutSgMax, vdtBg,vdtBgE);
+ GetRatE( vdtBg,vdtBgE, vdtTot,vdtTotE, ratdtBg,ratdtBgE);
+ //
+ //
+ double dmn = mcdst->GetMinimum();
+ double dmx = mcdst->GetMaximum();
+ TLine *ln = new TLine(cutSgMax, dmn, cutSgMax, dmx);
+ ln->SetLineColor(kBlack);
+ ln->Draw();
+ TLine *lnc = new TLine(cutBgMin, dmn, cutBgMin, dmx);
+ lnc->SetLineColor(kRed);
+ lnc->Draw();
+ if (useShapeType==kNormShapeDPhi) {
+ ln = new TLine(-cutSgMax, dmn, -cutSgMax, dmx);
+ ln->SetLineColor(kBlack);
+ ln->Draw();
+ //
+ lnc = new TLine(-cutBgMin, dmn, -cutBgMin, dmx);
+ lnc->SetLineColor(kRed);
+ lnc->Draw();
+ }
+ //
+ TLegend *legDstMC1 = new TLegend(0.60,0.72, 0.95,0.95);
+ legDstMC1->SetFillColor(kWhite);
+
+ //
+ legDstMC1->AddEntry(dtdst, "Data raw","pl");
+ sprintf(buff,"Data Comb. %s. : %.1f%%",useBgType.Data(),ratdtBg*100);
+ legDstMC1->AddEntry(dtdstbg, buff,"pl");
+ //
+
+
+ legDstMC1->AddEntry(mcdst, "MC raw","pl");
+ sprintf(buff,"MC Comb. %s. : %.1f%%",useBgType.Data(),ratCmbEst*100);
+ legDstMC1->AddEntry(mcdstbg, buff,"pl");
+ //
+ sprintf(buff,"MC Comb. %s. : %.1f%%","MC Lbl.",ratCmb*100);
+ legDstMC1->AddEntry(mcdstbgLB, buff,"pl");
+
+ sprintf(buff,"MC Comb.Uncorr %s. : %.1f%%","MC Lbl.",ratCmbC*100);
+ legDstMC1->AddEntry(mcDstCombC, buff,"pl");
+
+ sprintf(buff,"MC Sec. : %.1f%%",ratSec*100);
+ legDstMC1->AddEntry(mcDstSec, buff,"pl");
+
+ legDstMC1->Draw();
+
+ if (useShapeType==kNormShapeDist) gPad->SetLogx();
+ gPad->SetLogy();
+ gPad->SetGrid(1,1);
+ gPad->Modified();
+ //
+ canvFin->cd();
+ //
+ if (creatDnDEtaCMacro) {
+ sprintf(buff,"%s/%s_b%d_dNdEta_%s",figDir,uniqueName.Data(),bin,outStr);
+ SaveCanvas(canvFin,buff,"cg");
+ }
+ //
+}
+//
+void PlotAlphaBeta(int bin)
+{
+ char buff[1000];
+ int shift = bin*kNHistos;
+ gStyle->SetOptFit(0);
+ gStyle->SetOptStat(0);
+ gStyle->SetOptTitle(0);
+ TObjArray* res = &resArr;
+ //------------------------------------------------------
+ if (!canvFin) canvFin = new TCanvas("canvFin","canvFin",10,10,700,1000);
+ canvFin->Clear();
+ canvFin->Divide(2,3,0.01,0.01);
+ canvFin->cd(1);
+ TH1* dtBet = (TH1*)res->At(shift + k1MBeta);
+ TH1* mcBet = (TH1*)res->At(shift + k1MBeta+kMCShift);
+ TH1* mcBetLB = (TH1*)res->At(shift + k1MBetaMC+kMCShift);
+ double mn,mx,mnt,mxt;
+ GetRealMinMax(dtBet,mn,mx);
+ GetRealMinMax(mcBet,mnt,mxt);
+ if (mnt<mn) mn = mnt;
+ if (mxt>mx) mx = mxt;
+ GetRealMinMax(mcBetLB,mnt,mxt);
+ if (mnt<mn) mn = mnt;
+ if (mxt>mx) mx = mxt;
+ //
+ dtBet->SetMinimum(mn - 0.05*(mx-mn));
+ dtBet->SetMaximum(mx + 0.05*(mx-mn));
+ mcBet->SetMinimum(mn - 0.05*(mx-mn));
+ mcBet->SetMaximum(mx + 0.05*(mx-mn));
+ mcBetLB->SetMinimum(mn - 0.05*(mx-mn));
+ mcBetLB->SetMaximum(mx + 0.05*(mx-mn));
+ //
+ canvFin->cd(1);
+ gPad->SetRightMargin(0.15);
+ dtBet->Draw("colz");
+ AddLabel("#beta Data",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ dtBet->GetYaxis()->SetTitleOffset(1.4);
+ TPaletteAxis *p = (TPaletteAxis*)dtBet->FindObject("palette");
+ if (p) p->SetX1NDC(0.85);
+ canvFin->cd(2);
+ gPad->SetRightMargin(0.15);
+ mcBet->Draw("colz");
+ AddLabel("#beta MC (bckg.estimated)",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ mcBet->GetYaxis()->SetTitleOffset(1.4);
+ p = (TPaletteAxis*)mcBet->FindObject("palette");
+ if (p) p->SetX1NDC(0.85);
+ canvFin->cd(3);
+ gPad->SetRightMargin(0.15);
+ mcBetLB->Draw("colz");
+ AddLabel("#beta MC (bckg.from MC labels)",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ mcBetLB->GetYaxis()->SetTitleOffset(1.4);
+ p = (TPaletteAxis*)mcBetLB->FindObject("palette");
+ if (p) p->SetX1NDC(0.85);
+ //
+ //------------------------------------------------------
+ TH1* dtAlp = (TH1*)res->At(shift + kAlpha);
+ TH1* mcAlp = (TH1*)res->At(shift + kAlphaMC);
+ GetRealMinMax(dtAlp,mn,mx);
+ GetRealMinMax(mcAlp,mnt,mxt);
+ if (mnt<mn) mn = mnt;
+ if (mxt>mx) mx = mxt;
+ dtAlp->SetMinimum(mn - 0.05*(mx-mn));
+ dtAlp->SetMaximum(mx + 0.05*(mx-mn));
+ mcAlp->SetMinimum(mn - 0.05*(mx-mn));
+ mcAlp->SetMaximum(mx + 0.05*(mx-mn));
+ //
+ canvFin->cd(4);
+ gPad->SetRightMargin(0.15);
+ dtAlp->Draw("colz");
+ AddLabel("#alpha (bckg.estimated)",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ dtAlp->GetYaxis()->SetTitleOffset(1.4);
+ TPaletteAxis *pa = (TPaletteAxis*)dtBet->FindObject("palette");
+ if (pa) pa->SetX1NDC(0.85);
+ canvFin->cd(5);
+ gPad->SetRightMargin(0.15);
+ mcAlp->Draw("colz");
+ AddLabel("#alpha (bckg.from MC labels)",0.2,0.95,kBlack,0.05);
+ gPad->Modified();
+ mcAlp->GetYaxis()->SetTitleOffset(1.4);
+ pa = (TPaletteAxis*)mcBet->FindObject("palette");
+ if (pa) pa->SetX1NDC(0.85);
+ gPad->Modified();
+ canvFin->cd(6);
+ AddLabel(outTitle,0.1,0.5, kBlack, 0.025);
+ //
+ if (creatAlphaBetaCMacro) {
+ sprintf(buff,"%s/%sAlphaBeta_%s",figDir,uniqueName.Data(),outStr);
+ SaveCanvas(canvFin,buff,"cg");
+ }
+ //
+}
+
+void PlotSpecies()
+{
+ char buff[1000];
+ gStyle->SetOptFit(0);
+ gStyle->SetOptStat(0);
+ gStyle->SetOptTitle(0);
+ //------------------------------------------------------
+ TH2F* hSpecPrim = (TH2F*)FindObject(-1, "pdgPrim", listMC,kFALSE);
+ TH2F* hSpecSec = (TH2F*)FindObject(-1, "pdgSec", listMC,kFALSE);
+ TH2F* hSpecPrimP = (TH2F*)FindObject(-1, "pdgPrimPar", listMC,kFALSE);
+ TH2F* hSpecSecP = (TH2F*)FindObject(-1, "pdgSecPar", listMC,kFALSE);
+ int nbd = hSpecPrim->GetXaxis()->GetNbins();
+ //
+ TH1* hSpecPrimAll = hSpecPrim->ProjectionX("specPrimAll",1,nbd+1,"e");
+ hSpecPrimAll->Scale(100./hSpecPrimAll->Integral());
+ hSpecPrimAll->GetYaxis()->SetTitle("Fraction,%");
+ hSpecPrimAll->GetXaxis()->SetLabelSize(0.06);
+ hSpecPrimAll->GetXaxis()->LabelsOption("v");
+ //
+ TH1* hSpecSecAll = hSpecSec->ProjectionX("specSecAll",1,nbd+1,"e");
+ hSpecSecAll->Scale(100./hSpecSecAll->Integral());
+ hSpecSecAll->GetYaxis()->SetTitle("Fraction,%");
+ hSpecSecAll->GetXaxis()->SetLabelSize(0.05);
+ //
+ TH1* hSpecPrimPAll = hSpecPrimP->ProjectionX("specPrimPAll",1,nbd+1,"e");
+ hSpecPrimPAll->Scale(100./hSpecPrimPAll->Integral());
+ hSpecPrimPAll->GetYaxis()->SetTitle("Fraction,%");
+ hSpecPrimPAll->GetXaxis()->SetLabelSize(0.06);
+ hSpecPrimPAll->GetXaxis()->LabelsOption("v");
+
+ //
+ TH1* hSpecSecPAll = hSpecSecP->ProjectionX("specSecPAll",1,nbd+1,"e");
+ hSpecSecPAll->Scale(100./hSpecSecPAll->Integral());
+ hSpecSecPAll->GetYaxis()->SetTitle("Fraction,%");
+ hSpecSecPAll->GetXaxis()->SetLabelSize(0.05);
+ //
+ int binCut = hSpecPrim->GetXaxis()->FindBin(kWDistSgCut-kEps);
+ TH1* hSpecPrimSel = hSpecPrim->ProjectionX("specPrimSel",1,binCut,"e");
+ hSpecPrimSel->Scale(100./hSpecPrimSel->Integral());
+ hSpecPrimSel->GetYaxis()->SetTitle("Fraction,%");
+ hSpecPrimSel->GetXaxis()->SetLabelSize(0.05);
+ //
+ TH1* hSpecSecSel = hSpecSec->ProjectionX("specSecSel",1,binCut,"e");
+ hSpecSecSel->Scale(100./hSpecSecSel->Integral());
+ hSpecSecSel->GetYaxis()->SetTitle("Fraction,%");
+ hSpecSecSel->GetXaxis()->SetLabelSize(0.05);
+ //
+ TH1* hSpecPrimPSel = hSpecPrimP->ProjectionX("specPrimPSel",1,binCut,"e");
+ hSpecPrimPSel->Scale(100./hSpecPrimPSel->Integral());
+ hSpecPrimPSel->GetYaxis()->SetTitle("Fraction,%");
+ hSpecPrimPSel->GetXaxis()->SetLabelSize(0.05);
+ //
+ TH1* hSpecSecPSel = hSpecSecP->ProjectionX("specSecPSel",1,binCut,"e");
+ hSpecSecPSel->Scale(100./hSpecSecPSel->Integral());
+ hSpecSecPSel->GetYaxis()->SetTitle("Fraction,%");
+ hSpecSecPSel->GetXaxis()->SetLabelSize(0.05);
+ //
+ if (!canvFin) canvFin = new TCanvas("canvFin","canvFin",10,10,1100,800);
+ canvFin->Clear();
+ canvFin->Divide(1,2,0.01,0.01);
+ canvFin->cd(1);
+ hSpecPrimAll->Draw();
+ SetHStyle(hSpecPrimAll,kBlue,25,1.1);
+ hSpecPrimSel->Draw("same");
+ SetHStyle(hSpecPrimSel,kRed,20,1);
+ //
+ hSpecSecAll->Draw("same");
+ SetHStyle(hSpecSecAll,kGreen,32,1.1);
+ hSpecSecSel->Draw("same");
+ SetHStyle(hSpecSecSel,kBlack,22,1);
+ //
+ TLegend *legPart = new TLegend(0.8,0.72, 0.999,0.999);
+ legPart->SetFillColor(kWhite);
+ legPart->SetHeader("Tracklet PDG");
+ //
+ legPart->AddEntry(hSpecPrimAll, "Prim., before #Delta cut","pl");
+ legPart->AddEntry(hSpecPrimSel, "Prim., after #Delta cut","pl");
+ legPart->AddEntry(hSpecSecAll, "Sec., before #Delta cut","pl");
+ legPart->AddEntry(hSpecSecSel, "Sec., after #Delta cut","pl");
+ //
+ legPart->Draw();
+ gPad->SetLogy();
+ gPad->SetGrid(1,1);
+ gPad->Modified();
+ //
+ canvFin->cd(2);
+ hSpecPrimPAll->Draw();
+ SetHStyle(hSpecPrimPAll,kBlue,25,1.1);
+ hSpecPrimPSel->Draw("same");
+ SetHStyle(hSpecPrimPSel,kRed,20,1);
+ //
+ hSpecSecPAll->Draw("same");
+ SetHStyle(hSpecSecPAll,kGreen,32,1.1);
+ hSpecSecPSel->Draw("same");
+ SetHStyle(hSpecSecPSel,kBlack,22,1);
+ //
+ TLegend *legPartP = new TLegend(0.8,0.72, 0.999,0.999);
+ legPartP->SetFillColor(kWhite);
+ legPartP->SetHeader("Tracklet Parents PDG");
+ //
+ legPartP->AddEntry(hSpecPrimPAll, "Prim., before #Delta cut","pl");
+ legPartP->AddEntry(hSpecPrimPSel, "Prim., after #Delta cut","pl");
+ legPartP->AddEntry(hSpecSecPAll, "Sec., before #Delta cut","pl");
+ legPartP->AddEntry(hSpecSecPSel, "Sec., after #Delta cut","pl");
+ //
+ legPartP->Draw();
+ gPad->SetLogy();
+ gPad->SetGrid(1,1);
+ gPad->Modified();
+ //
+ canvFin->cd(1);
+ // AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+ canvFin->cd();
+ //
+ if (creatSpeciesCMacro) {
+ sprintf(buff,"%s/%sSpecies_%s",figDir,uniqueName.Data(),outStr);
+ SaveCanvas(canvFin,buff,"cg");
+ }
+}
+
+//______________________________________________________________________
+void CropHisto(TH1* histo, int bx0, int bx1, int by0, int by1)
+{
+ // fill 0 to all bins outside defined range
+ TAxis *xax = histo->GetXaxis();
+ int nbx = xax->GetNbins();
+ double vmn=1e16,vmx=-1e16;
+ if (histo->InheritsFrom(TH2::Class())) {
+ TAxis *yax = histo->GetYaxis();
+ int nby = yax->GetNbins();
+ for (int ix=nbx+2;ix--;) {
+ for (int iy=nby+2;iy--;) {
+ if ((ix<bx0||ix>bx1)||(iy<by0||iy>by1)) {
+ histo->SetBinContent(ix,iy,0);
+ histo->SetBinError(ix,iy,0);
+ }
+ else {
+ double vl = histo->GetBinContent(ix,iy);
+ if (vl<vmn) vmn = vl;
+ if (vl>vmx) vmx = vl;
+ }
+ }
+ }
+ }
+ else {
+ for (int ix=nbx+2;ix--;) {
+ if ((ix<bx0||ix>bx1)) {
+ histo->SetBinContent(ix,0);
+ histo->SetBinError(ix,0);
+ }
+ else {
+ double vl = histo->GetBinContent(ix);
+ if (vl<vmn) vmn = vl;
+ if (vl>vmx) vmx = vl;
+ }
+ }
+ }
+ //
+ if (vmn==vmx) {
+ vmn = 0.95*vmn;
+ vmx = 1.05*vmx;
+ }
+ histo->SetMaximum(vmx);
+ histo->SetMinimum(vmn);
+}
+
+//______________________________________________________________________
+void CropHisto(TH1* histo, double vx0, double vx1, double vy0, double vy1)
+{
+ // fill 0 to all bins outside defined range
+ TAxis *xax = histo->GetXaxis();
+ int bx0,bx1,by0=-1,by1=-1;
+ bx0 = xax->FindBin(vx0+kEps);
+ bx1 = xax->FindBin(vx1-kEps);
+ if (histo->InheritsFrom(TH2::Class())) {
+ TAxis *yax = histo->GetYaxis();
+ by0 = yax->FindBin(vy0+kEps);
+ by1 = yax->FindBin(vy1-kEps);
+ }
+ CropHisto(histo,bx0,bx1,by0,by1);
+}
+
+//______________________________________________________________________
+TH1* NormalizeBg(TH1* dataH, TH1* bgH, double &scl, double &sclE)
+{
+ // match generated bg and data tails, calculate normalization, return normalized bg copy
+ //
+ TAxis* xax = dataH->GetXaxis();
+ int nbtot = xax->GetNbins();
+ int bgBins[2][2] = {{0}}; // limiting bins for tails integration
+ Int_t ntails; // 0 for dphi plot, 1 for weighted dist plot
+ if (useShapeType == kNormShapeDist) { // only positive tail
+ bgBins[0][0] = xax->FindBin(kWDistBgTailMin+kEps); // positive tail min bin
+ bgBins[0][1] = xax->FindBin(kWDistBgTailMax-kEps); // positive tail max bin
+ ntails = 1;
+ }
+ else if (useShapeType == kNormShapeDPhi) { // both tails
+ bgBins[0][0] = xax->FindBin( kdPhiBgTailMin+kEps); // positive tail min bin
+ bgBins[0][1] = xax->FindBin( kdPhiBgTailMax-kEps); // positive tail max bin
+ bgBins[1][0] = xax->FindBin(-kdPhiBgTailMax+kEps); // negative tail min bin
+ bgBins[1][1] = xax->FindBin(-kdPhiBgTailMin-kEps); // positive tail max bin
+ ntails = 2;
+ }
+ else {printf("NormalizeBg: unknown shape type %d\n",useShapeType);exit(1);}
+ printf("NormalizeBg: bins for tails: right: %d:%d / left: %d:%d\n",bgBins[0][0],bgBins[0][1],bgBins[1][0],bgBins[1][1]);
+ //
+ double meanR=0,meanRE=0,meanRE2=0;
+ double meanD=0,meanDE2=0;
+ double meanB=0,meanBE2=0;
+ double meanRI=0,meanRIE=0;
+ for (int itp=0;itp<=ntails;itp++) {
+ for (int ib=bgBins[itp][0];ib<=bgBins[itp][1];ib++) {
+ if (ib<1||ib>nbtot) continue;
+ double vD = dataH->GetBinContent(ib);
+ double vB = bgH->GetBinContent(ib);
+ double eD = dataH->GetBinError(ib);
+ double eB = bgH->GetBinError(ib);
+ meanD += vD; meanDE2 += eD*eD;
+ meanB += vB; meanBE2 += eB*eB;
+ if (vD<=0 || vB<=0 || eD<=0 || eB<=0) continue;
+ double rat = vD/vB;
+ double ratE2 = rat*rat*(eD*eD/vD/vD + eB*eB/vB/vB);
+ meanR += rat/ratE2; meanRE2 += 1.0/ratE2;
+ }
+ }
+ //
+ if (meanRE2>0) {
+ meanR /= meanRE2;
+ meanRE2 = 1./meanRE2;
+ meanRE = TMath::Sqrt(meanRE2);
+ }
+ if (meanDE2>0 && meanBE2>0) {
+ meanRI = meanD/meanB;
+ meanRIE = meanRI*TMath::Sqrt(meanDE2/meanD/meanD + meanBE2/meanB/meanB);
+ }
+ printf("NormalizeBg: Tails scaling %s wrt %s: Wgh.Mean:%.4f(%.4f) / Integral:%.4f(%.4f)\n",
+ bgH->GetName(),dataH->GetName(), meanR,meanRE, meanRI,meanRIE);
+ printf("NormalizeBg: Select scaling type %s\n",useScaleType==kSclWghMean ? "Wgh.Mean":"Integral");
+ //
+ scl = useScaleType==kSclWghMean ? meanR : meanRI;
+ sclE = useScaleType==kSclWghMean ? meanRE : meanRIE;
+ //
+ // rescaled bg
+ char buff[1000];
+ sprintf(buff,"%s_bgNorm",bgH->GetName());
+ bgH = (TH1*)bgH->Clone(buff);
+ sprintf(buff,"%s bgNorm%d %.4f+-%.4f",bgH->GetName(),useScaleType,scl,sclE);
+ TH1* dumH = (TH1*)bgH->Clone("dummySCL$"); dumH->Reset();
+ for (int i=1;i<=nbtot;i++) {
+ dumH->SetBinContent(i,scl);
+ dumH->SetBinError(i,sclE);
+ }
+ bgH->Multiply(dumH);
+ delete dumH;
+ return bgH;
+}
+
+//______________________________________________________________________
+TObject* FindObject(int bin, const char* nameH, const TList* lst, Bool_t normPerEvent)
+{
+ // get histo, optionally normalizing it per processed event
+ if (!lst) {printf("FindObject %s: No list provided\n",nameH); exit(1);}
+ int nent = lst->GetEntries();
+ //
+ char buff[200];
+ if (bin>=0) sprintf(buff,"b%d_%s",bin,nameH);
+ else sprintf(buff,"%s",nameH);
+ TString nm;
+ TObject *hst = 0;
+ for (int i=nent;i--;) {
+ nm = lst->At(i)->GetName();
+ if (nm.EndsWith(buff)) {hst = lst->At(i); break;}
+ }
+ if (!hst) {printf("FindObject: No bin %d %s histo in list %s\n",bin,nameH,lst->GetName()); exit(1);}
+ if (!normPerEvent || hst->TestBit(kBitNormPerEvent)) return hst; // already normalized
+ TString nameHS = nameH;
+ if (nameHS==kHStatName) return hst; // never scale stat. histo
+ //
+ TH1* hstat = (TH1*)FindObject(-1,kHStatName,lst,kFALSE);
+ double nrm = hstat->GetBinContent(kBinEntries + kEvProcInj+bin*kEntriesPerBin);
+ // double nrm = hstat->GetBinContent(kBinEntries + kEvProcData+bin*kEntriesPerBin); // HACK
+ if (nrm<1) {printf("FindObject %s: Anomaluous %d number of events processed in bin %d of list %p\n",
+ buff,int(nrm),bin,lst); return 0;}
+ //
+ if (hst->InheritsFrom(TH1::Class())) ((TH1*)hst)->Scale(1./nrm);
+ else if (hst->InheritsFrom(THnSparse::Class())) {
+ THnSparse* spr = (THnSparse*) hst;
+ spr->Sumw2();
+ int coord[3] = {0,0,0};
+ for (Long64_t i = 0; i < spr->GetNbins(); ++i) {
+ // Get the content of the bin from the current histogram
+ Double_t v = spr->GetBinContent(i, coord);
+ spr->SetBinContent(coord, v/nrm);
+ spr->SetBinError(coord,TMath::Sqrt(v)/nrm);
+ }
+ }
+ //
+ hst->SetBit(kBitNormPerEvent);
+ return hst;
+}
+
+//______________________________________________________________________
+TList* LoadList(const char* flName, const char* addPref, const char* nameL)
+{
+ // load list with histos
+ TString nms = flName;
+ gSystem->ExpandPathName(nms);
+ TFile* fl = TFile::Open(nms.Data());
+ if (!fl) {printf("LoadList: No file %s\n",nms.Data()); exit(1);}
+ TList* lst = (TList*)fl->Get(nameL);
+ if (!lst) {printf("LoadList: No list %s in file %s\n",nameL,nms.Data()); exit(1);}
+ lst->SetName(flName);
+ //
+ int nEnt = lst->GetSize();
+ TString nm;
+ for (int i=0;i<nEnt;i++) {
+ TNamed* ob = (TNamed*)lst->At(i);
+ nm = addPref;
+ nm += ob->GetName();
+ ob->SetName(nm.Data());
+ }
+ //
+ return lst;
+}
+
+//____________________________________________________________________________
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate)
+{
+ rat = 0; rate = 0;
+ if (TMath::Abs(y)<1e-16 || TMath::Abs(x)<1e-16) return;
+ rat = x/y;
+ rate = rat*TMath::Sqrt( xe*xe/(x*x) + ye*ye/(y*y));
+}
+
+//____________________________________________________________________________
+void Integrate(TH1* hist, double xmn,double xmx, double &val, double& err)
+{
+ // integrate 1d histo within given limits
+ TAxis* xax = hist->GetXaxis();
+ int bmn = xax->FindBin(xmn+kEps); if (bmn<1) bmn = 0; // include
+ int bmx = xax->FindBin(xmx-kEps);
+ val = hist->IntegralAndError(bmn,bmx,err);
+ // is this histo with symmetric axis ? then integrate also negative half axis
+ if (TMath::Abs( xax->GetXmin() + xax->GetXmax() )<1e-6) {
+ bmn = xax->FindBin(-xmx+kEps);
+ bmx = xax->FindBin(-xmn-kEps);
+ double errn;
+ val += hist->IntegralAndError(bmn,bmx,errn);
+ err = TMath::Sqrt(err*err + errn*errn);
+ }
+}
+
+
+//____________________________________________________________________________
+const char* HName(const char* prefix,const char* htype)
+{
+ // compose the name of histo in the clist
+ static TString strh;
+ strh = "Tr"; strh += prefix; strh += "_"; strh += htype;
+ return strh.Data();
+}
+
+//____________________________________________________________________________
+Int_t CheckStat(const TList* lst, const char* dtType)
+{
+ // check if needed bg was generated
+ TH1* hstat = (TH1*)FindObject(-1,kHStatName,lst);
+ TString dts = dtType;
+ if (dts=="Data") return int( hstat->GetBinContent(kEvProcData) );
+ if (dts=="Mix") return int( hstat->GetBinContent(kEvProcMix) );
+ if (dts=="Inj") return int( hstat->GetBinContent(kEvProcInj) );
+ if (dts=="Rot") return int( hstat->GetBinContent(kEvProcRot) );
+ printf("Unknown process %s statistics is checked. Alowed: Data,Mix,Inj,Rot",dtType);
+ return 0;
+}
+
+
+void GetRealMinMax(TH1* histo, double &vmn, double &vmx)
+{
+ TAxis *xax = histo->GetXaxis();
+ int nbx = xax->GetNbins();
+ vmn=1e6, vmx=-1e6;
+ if (histo->InheritsFrom(TH2::Class())) {
+ TAxis *yax = histo->GetYaxis();
+ int nby = yax->GetNbins();
+ for (int ix=nbx+2;ix--;) {
+ for (int iy=nby+2;iy--;) {
+ double vl = histo->GetBinContent(ix,iy);
+ if (vl<kEps) continue;
+ if (vl<vmn) vmn = vl;
+ if (vl>vmx) vmx = vl;
+ }
+ }
+ }
+ //
+ else {
+ for (int ix=nbx+2;ix--;) {
+ double vl = histo->GetBinContent(ix);
+ if (vl<vmn) vmn = vl;
+ if (vl>vmx) vmx = vl;
+ }
+ }
+ //
+}
--- /dev/null
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "TMath.h"
+#include "TH1F.h"
+#include "TStyle.h"
+#include "TCanvas.h"
+#include "TLegend.h"
+#include "TGraphErrors.h"
+#endif
+
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate);
+TGraphErrors* CreateGraph(const char* nm, int np, const double *x,const double *xe, const double* y,const double *ye,Bool_t rat=kFALSE,int col=kBlack,int mrk=20,double sz=1.2,int lst=1);
+
+double Npart_Geom[11] = {383.851,331.921,262.756,188.639,130.721 ,86.5384,54.0822,31.1483,16.0198,7.75875,3.8324};
+double Npart_rms_Geom[11] = {16.2332,17.7241,26.9529,22.2198,19.1009,15.9985,13.4516,10.7482,7.93099,4.90297,2.52505};
+//
+double Npart_Geom_4b[4] = {396.624,371.028,344.477,319.018};
+double Npart_rms_Geom_4b[4] = {8.84252,11.016,12.1732,12.4974};
+//
+
+//double v0SelNov21[11] = 0,79,247,577,1185,2155,3565,5527,8203,12167,15073,19889
+double Npart_V0CSelNov21[11] ={380.692,328.323,259.018,185.05,128.121,84.9204,52.6411,29.79,15.1951,6.73934,2.95315};
+double Npart2_V0CSelNov21[11]={379.112,323.171,253.417,183.054,129.116,86.9088,54.2474,30.2884,15.1553,6.7094,2.95315};
+double Npart_rms_V0CSelNov21[11] = { 18.4857,19.5242,27.0422,21.1484,16.5675,12.8486,9.64889,6.81264,4.5665,2.72584,1.2575};
+
+//double spdSelNov21[11] = 0,21,69,165,345,637,1069,1683,2511,3721,4585,6213}
+double Npart_spdSelNov21[11] ={378.888,324.787,254.892,183.689,128.448,85.0047,52.3777,28.8656,14.3408,6.70305,3.16337};
+double Npart2_spdSelNov21[11]={379.973,328.414,259.244,185.094,128.309,84.9333,52.7138,29.9245,15.3195,6.98915,3.16337};
+double Npart_rms_spdSelNov21[11] = { 21.8302, 25.7908,30.7147, 24.5131,19.7898,15.9204,12.1924,8.81696,6.18204,3.78075,1.76665 };
+
+//double spdSel[11] = {0,29,85,191,385,687,1133,1743,2567,3765,4611,6213};
+double Npart_spdSel[11] ={379.393,328.651,259.304,185.004,128.265,84.8281,52.7315,29.0842,15.0519,6.876,3.14467};
+double Npart2_spdSel[11]={378.367,322.458,248.503,176.048,121.769,80.3259,49.7426,28.1977,14.5535,6.88646,3.19064};
+double Npart_rms_spdSel[11] = { 21.8302, 25.7908,30.7147, 24.5131,19.7898,15.9204,12.1924,8.81696,6.18204,3.78075,1.76665 };
+//
+//double v0Sel[11] = {0,107,297,659,1305,2301,3747,5715,8361,12307,15153,19889 };
+double Npart_V0CSel[11] ={381.040,328.781,259.314,185.197,128.160,84.8531,52.6495,29.7634,15.0721,6.67109,2.93958};
+double Npart2_V0CSel[11] ={375.596,313.697,240.935,170.22,118.96,79.1409,49.3726,28.2845,14.6765,6.62758,2.91953};
+double Npart_rms_V0CSel[11] = {18.4857,19.5242,27.0422,21.1484,16.5675,12.8486,9.64889,6.81264,4.5665,2.72584,1.2575};
+//
+//double v0rSel[11] = {0,32.5,89.5,198.5,396.5,700.5,1140.5,1744.5,2562.5,3767.5,4647.5,6367.5};
+double Npart_V0CRSel[11] ={379.114,329.655,260.318,185.996,130.454,87.0497,54.7531,31.4739,15.9883,7.28226,3.23659};
+double Npart2_V0CRSel[11] ={376.795,319.268,244.685,172.492,120.471,80.0706,49.9794,28.5653,14.7274,7.13181,3.27423};
+double Npart_rms_V0CRSel[11] = {18.4857,19.5242,27.0422,21.1484,16.5675,12.8486,9.64889,6.81264,4.5665,2.72584,1.2575};
+//
+//double tpcSel[11] = {0,13,37,85,171,307,507,783,1157,1685,2055,2787}; // these are tracks
+double Npart_TPCSel[11] ={378.667,329.234,259.17,185.129,128.221,84.7075,52.6338,29.7764,15.1032,6.98597,3.22604}; // these are tracks
+double Npart2_TPCSel[11] ={378.513,325.472,251.739,178.55,123.373,81.187,50.2066,28.4005,14.466,6.92418,3.30427};
+double Npart_rms_TPCSel[11] = {18.4857,19.5242,27.0422,21.1484,16.5675,12.8486,9.64889,6.81264,4.5665,2.72584,1.2575}; // wrong
+//
+
+//double spdSelNov21[11] = 0,21,69,165,345,637,1069,1683,2511,3721,4585,6213}
+double Npart_spdSelNov21_4b[4] ={396.624,371.02,344.477,319.018};
+double Npart_rms_spdSelNov21_4b[11] = {8.84252,11.016,12.1732,12.4974};
+//
+
+//----------------------------------------------------------------------------------
+double mltV0Ch11Nov27[] = {1590.09,1272.03,951.40,640.01,419.10,256.36,146.50,75.01,34.15,13.10,3.37};
+double mltV0Ch11eNov27[] = {2.29,1.98,1.17,0.94,0.75,0.56,0.41,0.28,0.19,0.11,0.05};
+
+// new baseline with ZDC TDC cleanup
+double mltV0Ch11Nov29[] = {1600.98,1293.63,966.21,649.30,426.09,260.65,149.44,76.23,34.75,13.28,3.38};
+double mltV0Ch11eNov29[] = {2.34,1.96,1.17,0.93,0.74,0.55,0.41,0.28,0.19,0.11,0.05};
+
+// new baseline with ZDC TDC cleanup
+double mltV0Ch11Nov29_4b[4] = {1693.65,1512.59,1365.12,1222.52};
+double mltV0Ch11Nov29_4be[4] = {3.69,3.04,2.91,2.66};
+
+
+//ZDC vs V0C, LHC10h_000137161_ZDCV0_24Nov10RS
+// result from setting ZDC&V0 to 80% in the same V0 as V01D
+////double mltZDCV0Ch8Nov24RS[11]={1599.53,1278.17,941.59,625.66,402.07,240.92,130.04,56.54,29.69,15.04,8.12};
+////double mltZDCV0Ch8eNov24RS[11]={2.31,1.89,1.13,0.89,0.69,0.51,0.35,0.22,0.16,0.12,0.11};
+// result from setting ZDC&V0 to have the same excess at 0 as V01D
+double mltZDCV0Ch8Nov24RS[11]={1606.24,1294.40,964.34,651.15,427.81,264.23,149.39,72.52,34.75,18.79,8.92};
+double mltZDCV0Ch8eNov24RS[11]={2.34,1.93,1.16,0.92,0.74,0.55,0.40,0.27,0.18,0.14,0.12};
+
+//----------------------------------------------------------------------------------
+//V0C, LHC10h8_000137161_V0C
+double mltV0Ch8Nov21[11]={1606.14,1293.78,963.88,650.18,427.15,263.20,151.27,77.95,36.07,13.72,4.19};
+double mltV0Ch8eNov21[11]={2.34,1.93,1.16,0.92,0.74,0.55,0.40,0.28,0.19,0.11,0.06};
+
+
+//-----------------------------------
+//SPD, LHC10h8_000137161_SPD
+double mltSPDh8Nov21[11]={1608.81,1293.03,962.20,647.64,424.17,259.92,149.15,75.83,34.56,12.68,3.40};
+double mltSPDh8eNov21[11]={2.31,1.96,1.15,0.91,0.72,0.54,0.40,0.28,0.19,0.11,0.06};
+
+
+//SPD, LHC10h6_000137161_SPD (off-vertex primaries removed)
+double mltSPDh6[11]={1603.99,1298.08,972.26,661.06,441.62,276.34,163.10,86.02,40.75,16.28,4.13};
+double mltSPDh6e[11]={2.54,2.11,1.26,1.01,0.80,0.61,0.46,0.33,0.23,0.14,0.06};
+
+//-----------------------------------
+//SPD, LHC10h8_000137161_SPD
+double mltSPDh8[11]={1613.30,1304.45,977.46,665.32,442.60,277.46,163.26,86.15,40.97,16.36,4.17};
+double mltSPDh8e[11]={2.35,1.99,1.18,0.94,0.76,0.57,0.43,0.31,0.21,0.13,0.06};
+
+//-----------------------
+//V0C, LHC10h8_000137161_V0C
+double mltV0Ch8[11]={1610.21,1304.62,977.99,667.33,444.72,279.27,164.76,87.79,42.34,17.53,4.89};
+double mltV0Ch8e[11] = {2.38,1.97,1.18,0.95,0.76,0.57,0.43,0.31,0.21,0.13,0.06};
+
+//-----------------------
+//V0CR, LHC10h8_000137161_V0CR
+double mltV0CRh8[11]={1611.13,1304.76,994.16,678.31,449.72,282.53,166.06,87.97,42.40,17.49,4.99};
+double mltV0CRh8e[11]={2.38,1.98,1.19,0.97,0.77,0.58,0.43,0.31,0.21,0.13,0.06};
+
+//-----------------------
+//TPC, LHC10h8_000137161_TPC
+double mltTPCh8[11]={1616.65,1304.32,957.72,656.67,435.59,273.39,160.58,86.09,40.96,16.58,4.16};
+double mltTPCh8e[11]={2.44,2.01,1.15,0.92,0.74,0.56,0.42,0.31,0.21,0.13,0.06};
+
+//--------------------------
+//137366, SPD, LHC10h8_000137366_SPD
+double mlt366SPDh8[11]={1574.05,1278.00,955.98,651.66,432.23,272.50,158.64,84.24,39.71,16.16,4.01};
+double mlt366SPDh8e[11]={1.96,1.69,0.98,0.81,0.62,0.48,0.36,0.25,0.17,0.10,0.05};
+
+//--------------------------
+//SPD, LHC10h2_000137161_SPD DPMJET
+double mltSPDdpmjh2[11]={1624.52,1304.84,976.87,664.33,443.03,277.41,163.68,85.95,40.76,16.58,4.25};
+double mltSPDdpmjh2e[11]={2.12,2.46,1.53,1.29,1.06,0.81,0.62,0.43,0.29,0.19,0.09};
+
+//-------------------------------------------------------------------------
+// top 4x2.5% bins in SPD
+double mltSPDh8_4b[4] = {1702.89,1516.20,1362.55,1221.55}; // w.means: 1587.4, 1259.0
+double mltSPDh8_4be[4] = {3.55,3.06,2.91,2.65};
+//double mltSPDh8_4b[4] = {1681.25,1480.93,1322.75,1188.11}; // w.means: 1587.4, 1259.0
+//double mltSPDh8_4be[4] = {3.51,3.01,2.83,2.59};
+
+//-------------------------------------------------------------------------
+// top 4x2.5% bins in V0
+double mltV0Ch8_4b[4] = {1692.60,1514.45,1363.53,1221.21};
+double mltV0Ch8_4be[4] = {3.69,3.02,2.85,2.61};
+//double mltSPDh8_4b[4] = {1681.25,1480.93,1322.75,1188.11}; // w.means: 1587.4, 1259.0
+//double mltSPDh8_4be[4] = {3.51,3.01,2.83,2.59};
+
+
+
+TGraphErrors *MV0Ch11Nov27A=0,*RV0Ch11Nov27A=0;
+
+TGraphErrors *MV0Ch11Nov29=0,*RV0Ch11Nov29=0;
+
+TGraphErrors *MzdcV0CNov24=0,*RzdcV0CNov24=0;
+//
+TGraphErrors *Mspdh8Nov21=0,*Mspdh8aNov21=0,*Rspdh8Nov21=0,*Rspdh8aNov21=0;
+TGraphErrors *MV0Ch8Nov21=0,*MV0Ch8aNov21=0,*RV0Ch8Nov21=0,*RV0Ch8aNov21=0;
+
+TGraphErrors *Mspdh6=0,*Mspdh6a=0,*Rspdh6=0,*Rspdh6a=0;
+TGraphErrors *Mspdh8=0,*Mspdh8a=0,*Rspdh8=0,*Rspdh8a=0;
+TGraphErrors *MV0Ch8=0,*MV0Ch8a=0,*RV0Ch8=0,*RV0Ch8a=0;
+TGraphErrors *MV0CRh8=0,*MV0CRh8a=0,*RV0CRh8=0,*RV0CRh8a=0;
+TGraphErrors *Mtpch8=0,*Mtpch8a=0,*Rtpch8=0,*Rtpch8a=0;
+TGraphErrors *Mspd366h8=0,*Mspd366h8a=0,*Rspd366h8=0,*Rspd366h8a=0;
+TGraphErrors *MspdDPMJh2=0,*MspdDPMJh2a=0,*RspdDPMJh2=0,*RspdDPMJh2a=0;
+
+TGraphErrors *Mspd4b=0,*Rspd4b=0;
+TGraphErrors *MV0C4b=0,*RV0C4b=0;
+
+TGraphErrors *MV0C29Nov4b=0,*RV0C29Nov4b=0;
+
+TCanvas *cnvMult=0;
+TCanvas *cnvMultR=0;
+TH1F *frMlt,*frMltR=0;
+
+void DrawMult()
+{
+ gStyle->SetOptStat(0);
+
+ /*
+ Mspd4b = CreateGraph("Mspd4b" ,4,Npart_spdSelNov21_4b,Npart_rms_spdSelNov21_4b, mltSPDh8_4b,mltSPDh8_4be ,kFALSE, kGreen, 20,1.2,1);
+ Rspd4b = CreateGraph("Rspd4b" ,4,Npart_spdSelNov21_4b,Npart_rms_spdSelNov21_4b, mltSPDh8_4b,mltSPDh8_4be ,kTRUE, kGreen, 20,1.2,1);
+ //
+ Mspdh8Nov21 = CreateGraph("Mspdh8Nov21" ,11,Npart_spdSelNov21 ,Npart_rms_spdSelNov21,mltSPDh8Nov21,mltSPDh8eNov21, kFALSE, kRed, 20,1.2,1);
+ Mspdh8aNov21 = CreateGraph("Mspdh8aNov21",11,Npart2_spdSelNov21,Npart_rms_spdSelNov21,mltSPDh8Nov21,mltSPDh8eNov21, kFALSE, kRed, 24,1.42,2);
+ Rspdh8Nov21 = CreateGraph("Rspdh8Nov21" ,11,Npart_spdSelNov21 ,Npart_rms_spdSelNov21,mltSPDh8Nov21,mltSPDh8eNov21, kTRUE, kRed, 20,1.2,1);
+ Rspdh8aNov21 = CreateGraph("Rspdh8aNov21",11,Npart2_spdSelNov21,Npart_rms_spdSelNov21,mltSPDh8Nov21,mltSPDh8eNov21, kTRUE, kRed, 24,1.42,2);
+ //
+ MV0Ch8Nov21 = CreateGraph("MV0Ch8Nov21" ,11,Npart_V0CSelNov21 ,Npart_rms_V0CSelNov21,mltV0Ch8Nov21,mltV0Ch8eNov21, kFALSE, kBlue, 20,1.2, 1);
+ MV0Ch8aNov21 = CreateGraph("MV0Ch8aNov21",11,Npart2_V0CSelNov21,Npart_rms_V0CSelNov21,mltV0Ch8Nov21,mltV0Ch8eNov21, kFALSE, kBlue, 24,1.42, 2);
+ RV0Ch8Nov21 = CreateGraph("RV0Ch8Nov21" ,11,Npart_V0CSelNov21 ,Npart_rms_V0CSelNov21,mltV0Ch8Nov21,mltV0Ch8eNov21, kTRUE, kBlue, 20,1.2, 1);
+ RV0Ch8aNov21 = CreateGraph("RV0Ch8aNov21",11,Npart2_V0CSelNov21,Npart_rms_V0CSelNov21,mltV0Ch8Nov21,mltV0Ch8eNov21, kTRUE, kBlue, 24,1.42, 2);
+ //
+ Mtpch8 = CreateGraph("Mtpch8" ,11,Npart_TPCSel ,Npart_rms_TPCSel,mltTPCh8,mltTPCh8e, kFALSE, kBlack, 23, 1.2, 1);
+ Mtpch8a = CreateGraph("Mtpch8a",11,Npart2_TPCSel,Npart_rms_TPCSel,mltTPCh8,mltTPCh8e, kFALSE, kBlack, 32, 1.2, 2);
+ Rtpch8 = CreateGraph("Rtpch8" ,11,Npart_TPCSel ,Npart_rms_TPCSel,mltTPCh8,mltTPCh8e, kTRUE, kBlack, 23, 1.2, 1);
+ Rtpch8a = CreateGraph("Rtpch8a",11,Npart2_TPCSel,Npart_rms_TPCSel,mltTPCh8,mltTPCh8e, kTRUE, kBlack, 32, 1.2, 2);
+ // //
+ */
+ Mspd4b = CreateGraph("Mspd4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltSPDh8_4b,mltSPDh8_4be ,kFALSE, kGreen, 20,1.2,1);
+ Rspd4b = CreateGraph("Rspd4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltSPDh8_4b,mltSPDh8_4be ,kTRUE, kGreen, 20,1.2,1);
+ //
+ MV0C4b = CreateGraph("MV0C4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltV0Ch8_4b,mltV0Ch8_4be ,kFALSE, kMagenta, 21,1.2,1);
+ RV0C4b = CreateGraph("RV0C4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltV0Ch8_4b,mltV0Ch8_4be ,kTRUE, kMagenta, 21,1.2,1);
+ //
+ MV0C29Nov4b = CreateGraph("MV0C29Nov4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltV0Ch11Nov29_4b,mltV0Ch11Nov29_4be ,kFALSE, kGreen+1, 26,1.2,1);
+ RV0C29Nov4b = CreateGraph("RV0C29Nov4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltV0Ch11Nov29_4b,mltV0Ch11Nov29_4be ,kTRUE, kGreen+1, 26,1.2,1);
+ //
+ MzdcV0CNov24 = CreateGraph("MzdcV0CNov24" ,11,Npart_Geom ,Npart_rms_Geom,mltZDCV0Ch8Nov24RS,mltZDCV0Ch8eNov24RS, kFALSE, kBlack, 25,1.4,1);
+ RzdcV0CNov24 = CreateGraph("RzdcV0CNov24" ,11,Npart_Geom ,Npart_rms_Geom,mltZDCV0Ch8Nov24RS,mltZDCV0Ch8eNov24RS, kTRUE, kBlack, 25,1.4,1);
+ //
+ Mspdh8Nov21 = CreateGraph("Mspdh8Nov21" ,11,Npart_Geom ,Npart_rms_Geom,mltSPDh8Nov21,mltSPDh8eNov21, kFALSE, kRed, 20,1.4,1);
+ Rspdh8Nov21 = CreateGraph("Rspdh8Nov21" ,11,Npart_Geom ,Npart_rms_Geom,mltSPDh8Nov21,mltSPDh8eNov21, kTRUE, kRed, 20,1.4,1);
+ //
+ MV0Ch8Nov21 = CreateGraph("MV0Ch8Nov21" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch8Nov21,mltV0Ch8eNov21, kFALSE, kBlue, 20,1.2, 1);
+ RV0Ch8Nov21 = CreateGraph("RV0Ch8Nov21" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch8Nov21,mltV0Ch8eNov21, kTRUE, kBlue, 20,1.2, 1);
+ //
+ //
+ MV0Ch11Nov27A = CreateGraph("MV0Ch8Nov27A" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch11Nov27,mltV0Ch11eNov27, kFALSE, kCyan, 20,1.2, 1);
+ RV0Ch11Nov27A = CreateGraph("RV0Ch8Nov27A" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch11Nov27,mltV0Ch11eNov27, kTRUE, kCyan, 20,1.2, 1);
+ //
+ MV0Ch11Nov29 = CreateGraph("MV0Ch8Nov29" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch11Nov29,mltV0Ch11eNov29, kFALSE, kGreen+1, 22,1., 1);
+ RV0Ch11Nov29 = CreateGraph("RV0Ch8Nov29" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch11Nov29,mltV0Ch11eNov29, kTRUE, kGreen+1, 22,1., 1);
+ //
+ Mtpch8 = CreateGraph("Mtpch8" ,11,Npart_Geom ,Npart_rms_Geom,mltTPCh8,mltTPCh8e, kFALSE, kBlack, 23, 1.2, 1);
+ Rtpch8 = CreateGraph("Rtpch8" ,11,Npart_Geom ,Npart_rms_Geom,mltTPCh8,mltTPCh8e, kTRUE, kBlack, 23, 1.2, 1);
+ //
+ Mspdh6 = CreateGraph("Mspdh6" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDh6,mltSPDh6e, kFALSE, kRed, 29, 1.0,1);
+ Mspdh6a = CreateGraph("Mspdh6a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDh6,mltSPDh6e, kFALSE, kRed, 30, 1.0,2);
+ Rspdh6 = CreateGraph("Rspdh6" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDh6,mltSPDh6e, kTRUE, kRed, 29, 1.0,1);
+ Rspdh6a = CreateGraph("Rspdh6a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDh6,mltSPDh6e, kTRUE, kRed, 30, 1.0,2);
+ //
+ Mspdh8 = CreateGraph("Mspdh8" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDh8,mltSPDh8e, kFALSE, kMagenta, 20,1.02,1);
+ Mspdh8a = CreateGraph("Mspdh8a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDh8,mltSPDh8e, kFALSE, kMagenta, 24,1.02,2);
+ Rspdh8 = CreateGraph("Rspdh8" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDh8,mltSPDh8e, kTRUE, kMagenta, 20,1.02,1);
+ Rspdh8a = CreateGraph("Rspdh8a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDh8,mltSPDh8e, kTRUE, kMagenta, 24,1.02,2);
+ //
+ MV0Ch8 = CreateGraph("MV0Ch8" ,11,Npart_V0CSel ,Npart_rms_V0CSel,mltV0Ch8,mltV0Ch8e, kFALSE, kCyan, 21,1.02, 1);
+ MV0Ch8a = CreateGraph("MV0Ch8a",11,Npart2_V0CSel,Npart_rms_V0CSel,mltV0Ch8,mltV0Ch8e, kFALSE, kCyan, 25,1.02, 2);
+ RV0Ch8 = CreateGraph("RV0Ch8" ,11,Npart_V0CSel ,Npart_rms_V0CSel,mltV0Ch8,mltV0Ch8e, kTRUE, kCyan, 21,1.02, 1);
+ RV0Ch8a = CreateGraph("RV0Ch8a",11,Npart2_V0CSel,Npart_rms_V0CSel,mltV0Ch8,mltV0Ch8e, kTRUE, kCyan, 25,1.02, 2);
+ //
+ MV0CRh8 = CreateGraph("MV0CRh8" ,11,Npart_V0CRSel ,Npart_rms_V0CRSel,mltV0CRh8,mltV0CRh8e, kFALSE, kGreen, 22,1.2, 1);
+ MV0CRh8a = CreateGraph("MV0CRh8a",11,Npart2_V0CRSel,Npart_rms_V0CRSel,mltV0CRh8,mltV0CRh8e, kFALSE, kGreen, 26,1.2, 2);
+ RV0CRh8 = CreateGraph("RV0CRh8" ,11,Npart_V0CRSel ,Npart_rms_V0CRSel,mltV0CRh8,mltV0CRh8e, kTRUE, kGreen, 22,1.2, 1);
+ RV0CRh8a = CreateGraph("RV0CRh8a",11,Npart2_V0CRSel,Npart_rms_V0CRSel,mltV0CRh8,mltV0CRh8e, kTRUE, kGreen, 26,1.2, 2);
+ //
+ Mspd366h8 = CreateGraph("Mspd366h8" ,11,Npart_spdSel ,Npart_rms_spdSel,mlt366SPDh8,mlt366SPDh8e, kFALSE, kRed, 27, 1.0, 1);
+ Mspd366h8a = CreateGraph("Mspd366h8a",11,Npart2_spdSel,Npart_rms_spdSel,mlt366SPDh8,mlt366SPDh8e, kFALSE, kRed, 33, 1.0, 2);
+ Rspd366h8 = CreateGraph("Rspd366h8" ,11,Npart_spdSel ,Npart_rms_spdSel,mlt366SPDh8,mlt366SPDh8e, kTRUE, kRed, 27, 1.0, 1);
+ Rspd366h8a = CreateGraph("Rspd366h8a",11,Npart2_spdSel,Npart_rms_spdSel,mlt366SPDh8,mlt366SPDh8e, kTRUE, kRed, 33, 1.0, 2);
+ //
+ MspdDPMJh2 = CreateGraph("MspdDPMJh2" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDdpmjh2,mltSPDdpmjh2e, kFALSE, kRed, 28, 1.0, 1);
+ MspdDPMJh2a = CreateGraph("MspdDPMJh2a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDdpmjh2,mltSPDdpmjh2e, kFALSE, kRed, 34, 1.0, 2);
+ RspdDPMJh2 = CreateGraph("RspdDPMJh2" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDdpmjh2,mltSPDdpmjh2e, kTRUE, kRed, 28, 1.0, 1);
+ RspdDPMJh2a = CreateGraph("RspdDPMJh2a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDdpmjh2,mltSPDdpmjh2e, kTRUE, kRed, 34, 1.0, 2);
+ //
+ TLegend *lg = new TLegend(0.4,0.2,0.65,0.5);
+ lg->SetFillColor(kWhite);
+ lg->SetHeader("N_{part} Glauber");
+ // lg->AddEntry(Rspdh8,"SPD corr","pl");
+ // lg->AddEntry(RV0Ch8,"V0 corr","pl");
+ // lg->AddEntry(RV0CRh8,"V0 corr resc","pl");
+ // lg->AddEntry(Rtpch8,"TPC","pl");
+ //
+ // lg->AddEntry(Rspdh6,"SPD corr, old hijing","pl");
+ // lg->AddEntry(Rspd366h8,"SPD corr, 137366","pl");
+ // lg->AddEntry(RspdDPMJh2,"SPD corr, dpmjet","pl");
+ //
+ // lg->AddEntry(Rspdh8Nov21,"SPD corr, 21/11/10","pl");
+ lg->AddEntry(RV0Ch8Nov21,"V0 corr, 21/11/10","pl");
+ // lg->AddEntry(RzdcV0CNov24,"ZDC & V0 corr","pl");
+ // lg->AddEntry(Rspd4b,"SPD corr, 4#times2.5%","pl");
+ lg->AddEntry(RV0C4b,"V0 corr, 4#times2.5%","pl");
+ // lg->AddEntry(RV0Ch11Nov27A,"V0 corr, 5+ 27/11/10","pl");
+ lg->AddEntry(RV0Ch11Nov29,"V0 corr, 5+ 29/11/10","pl");
+ lg->AddEntry(RV0C29Nov4b,"V0 corr, 5+ 29/11/10, 4#times2.5%","pl");
+ //
+ TLegend *lga = new TLegend(0.65,0.2,0.8,0.5);
+ lga->SetFillColor(kWhite);
+ lga->SetHeader("N_{part} data");
+ lga->AddEntry(Rspdh8a," ","pl");
+ lga->AddEntry(RV0Ch8a," ","pl");
+ // lga->AddEntry(RV0CRh8a, " ","pl");
+ // lga->AddEntry(Rtpch8a," ","pl");
+ //
+ // lga->AddEntry(Rspdh6a," ","pl");
+ // lga->AddEntry(Rspd366h8a," ","pl");
+ // lga->AddEntry(RspdDPMJh2a," ","pl");
+ //
+ lga->AddEntry(Rspdh8aNov21,"SPD corr, 21/11/10","pl");
+ lga->AddEntry(RV0Ch8aNov21,"V0 corr, 21/11/10","pl");
+ //
+
+
+ frMlt = new TH1F("dndeta","dN/d#eta",86,1,430);
+ frMlt->SetMinimum(1e-3);
+ frMlt->SetMaximum(2000);
+ frMlt->GetXaxis()->SetTitle("N_{part}");
+ frMlt->GetYaxis()->SetTitle("dN/d#eta_{|#eta|<0.5}");
+
+ frMltR = new TH1F("dndetaperpart","dN/d#eta / part.pair",86,1,430);
+ frMltR->SetMinimum(1e-3);
+ frMltR->SetMaximum(10);
+ frMltR->GetXaxis()->SetTitle("N_{part}");
+ frMltR->GetYaxis()->SetTitle("dN/d#eta_{|#eta|<0.5} / part.pair");
+
+ cnvMult = new TCanvas("cnvMult","",10,10,1000,700);
+ cnvMultR = new TCanvas("cnvMultR","",20,20,1000,700);
+ //
+ cnvMult->cd();
+ gPad->Clear();
+ gPad->SetLeftMargin(0.15);
+ gPad->SetBottomMargin(0.15);
+ frMlt->Draw();
+ frMlt->GetYaxis()->SetTitleOffset(1.6);
+ frMlt->GetYaxis()->SetLabelSize(0.03);
+ frMlt->GetXaxis()->SetTitleOffset(1.6);
+ frMlt->GetXaxis()->SetLabelSize(0.03);
+ gPad->SetGrid(1,1);
+ //
+ // Mspdh6->Draw("p");
+ // Mspdh6a->Draw("p");
+ //
+ // Mspd366h8->Draw("p");
+ // Mspd366h8a->Draw("p");
+ //
+ // MspdDPMJh2->Draw("p");
+ // MspdDPMJh2a->Draw("p");
+ //
+ // Mspdh8->Draw("p");
+ // Mspdh8a->Draw("p");
+ //
+ // Mspd4b->Draw("p");
+ MV0C4b->Draw("p");
+ MV0C29Nov4b->Draw("p");
+ //
+ // MV0Ch8->Draw("p");
+ // MV0Ch8a->Draw("p");
+ //
+ // MV0CRh8->Draw("p");
+ // MV0CRh8a->Draw("p");
+ //
+ // Mtpch8->Draw("p");
+ // Mtpch8a->Draw("p");
+ //
+ //
+ // Mspdh8Nov21->Draw("p");
+ // Mspdh8aNov21->Draw("p");
+ //
+ MV0Ch8Nov21->Draw("p");
+ // MV0Ch8aNov21->Draw("p");
+ //
+ // MzdcV0CNov24->Draw("p");
+ //
+
+ // MV0Ch11Nov27A->Draw("p");
+ MV0Ch11Nov29->Draw("p");
+
+ lg->Draw();
+ // lga->Draw();
+ //----------------------------------------
+ //
+ cnvMultR->cd();
+ gPad->Clear();
+ gPad->SetLeftMargin(0.15);
+ gPad->SetBottomMargin(0.15);
+ frMltR->Draw();
+ frMltR->GetYaxis()->SetTitleOffset(1.6);
+ frMltR->GetYaxis()->SetLabelSize(0.03);
+ frMltR->GetXaxis()->SetTitleOffset(1.6);
+ frMltR->GetXaxis()->SetLabelSize(0.03);
+ gPad->SetGrid(1,1);
+ //
+ // /*
+ // Rspdh6->Draw("p");
+ // Rspdh6a->Draw("p");
+ //
+ // Rspd366h8->Draw("p");
+ // Rspd366h8a->Draw("p");
+ //
+ // RspdDPMJh2->Draw("p");
+ // RspdDPMJh2a->Draw("p");
+ //
+ // */
+ // Rspdh8->Draw("p");
+ // Rspdh8a->Draw("p");
+ //
+ // Rspd4b->Draw("p");
+ RV0C4b->Draw("p");
+ //
+ // RV0Ch8->Draw("p");
+ // RV0Ch8a->Draw("p");
+ //
+ // RV0CRh8->Draw("p");
+ // RV0CRh8a->Draw("p");
+ //
+ // Rtpch8->Draw("p");
+ // Rtpch8a->Draw("p");
+ //
+ // Rspdh8Nov21->Draw("p");
+ // Rspdh8aNov21->Draw("p");
+ //
+ RV0Ch8Nov21->Draw("p");
+ // RV0Ch8aNov21->Draw("p");
+ // RzdcV0CNov24->Draw("p");
+
+ // RV0Ch11Nov27A->Draw("p");
+ RV0Ch11Nov29->Draw("p");
+ RV0C29Nov4b->Draw("p");
+ //
+ lg->Draw();
+ // lga->Draw();
+ //
+}
+
+
+
+TGraphErrors* CreateGraph(const char* nm, int np, const double *x,const double *xe, const double* y,const double *ye,Bool_t rat,int col,int mrk,double sz,int lst)
+{
+ TGraphErrors* gr = new TGraphErrors(np);
+ gr->SetName(nm);
+ gr->SetTitle(nm);
+ gr->SetMarkerStyle(mrk);
+ gr->SetMarkerSize(sz);
+ gr->SetMarkerColor(col);
+ gr->SetLineColor(col);
+ gr->SetLineStyle(lst);
+ int ip=0;
+ for (int i=0;i<np;i++) {
+ double px = x[i];
+ double pxe = xe[i];
+ double py = y[i];
+ double pye = ye[i];
+ if (rat) {
+ double rt,rte;
+ GetRatE(py,pye, px/2, 0, rt,rte);
+ py = rt;
+ pye = rte;
+ }
+ gr->SetPoint(ip, px,py);
+ gr->SetPointError(ip, pxe,pye);
+ ip++;
+ }
+ //
+ return gr;
+}
+
+
+
+
+//____________________________________________________________________________
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate)
+{
+ rat = 0; rate = 0;
+ if (TMath::Abs(y)<1e-16 || TMath::Abs(x)<1e-16) return;
+ rat = x/y;
+ rate = rat*TMath::Sqrt( xe*xe/(x*x) + ye*ye/(y*y));
+ // printf("RAT %e %e / %e %e -> %e %e\n",x,xe,y,ye,rat,rate);
+}
--- /dev/null
+void MyAnalysisMacro(TString dataset="/alice/sim/LHC10f8f_130844",
+ TString outFName="trbg.root",
+ Bool_t doRec = kTRUE,
+ Bool_t doInj = kTRUE,
+ Bool_t doRot = kTRUE,
+ Bool_t doMix = kFALSE,
+ Bool_t useMC = kTRUE,
+ Bool_t checkReconstructables = kTRUE,
+ //
+ Float_t etaCut = 2.5,
+ //
+ // specific parameters for reconstruction
+ //----------------------- Zv selection parameters important for mixing, to be tuned
+ Float_t zMin = -20,
+ Float_t zMax = 20,
+ Float_t zMixBinSz = 5, //0.1,
+ //---------------------------------------------------------------------------------
+ //
+ //----------------------- Ntracklets selection parameters important for mixing, to be tuned
+ Float_t ntMin = 1,
+ Float_t ntMax = 15000,
+ Float_t ntMixBinSz = 5000,
+ //---------------------------------------------------------------------------------
+ //
+ float phiRot = 3.14159e+00,
+ float injScale = 0.7,
+ Bool_t scaleDTheta = kTRUE,
+ float nStdDev = 25.,
+ float dphi = 0.08,
+ float dtht = 0.025,
+ float phishift = 0.0045,
+ Bool_t remOvl = kTRUE,
+ float ovlPhiCut = 0.005,
+ float ovlZetaCut = 0.05,
+ Int_t nEvents = 50000,
+ Int_t nEventsSkip = 0)
+{
+ //
+ TString format = GetFormatFromDataSet(dataset);
+ //
+ // ALICE stuff
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) mgr = new AliAnalysisManager("Test train");
+ //
+ InputHandlerSetup(format,useMC);
+ if (doMix) MixHandlerSetup(ntMin,ntMax,ntMixBinSz, zMin,zMax,zMixBinSz);
+ // compile our task
+ gProof->Load("AliITSMultRecBg.cxx++");
+ gProof->Load("AliTrackletTaskUni.cxx++");
+ //
+ // load and run AddTask macro
+ gROOT->LoadMacro("AddMultTaskRS.C");
+ //
+ // create our task
+ AliTrackletTaskUni *mltTask = AddMultTaskRS(outFName.Data());
+ //
+ mltTask->SetDoNormalReco(doRec);
+ mltTask->SetDoInjection(doInj);
+ mltTask->SetDoRotation(doRot);
+ mltTask->SetDoMixing(doMix);
+ //
+ mltTask->SetUseMC(useMC);
+ mltTask->SetCheckReconstructables(checkReconstructables);
+ //
+ mltTask->SetEtaCut(etaCut);
+ mltTask->SetZVertexMin(zMin);
+ mltTask->SetZVertexMax(zMax);
+ mltTask->SetMultCutMin(ntMin);
+ mltTask->SetMultCutMax(ntMax);
+ //
+ mltTask->SetScaleDThetaBySin2T(scaleDTheta);
+ mltTask->SetNStdDev(nStdDev);
+ mltTask->SetPhiWindow(dphi);
+ mltTask->SetThetaWindow(dtht);
+ mltTask->SetPhiShift(phishift);
+ mltTask->SetPhiOverlapCut(ovlPhiCut);
+ mltTask->SetZetaOverlapCut(ovlZetaCut);
+ mltTask->SetPhiRot(phiRot);
+ mltTask->SetInjScale(injScale);
+ mltTask->SetRemoveOverlaps(remOvl);
+ //
+ printf("new Task: %p\n",mltTask);
+ //
+ AddPhysicsSelection(useMC);
+ mltTask->SelectCollisionCandidates(useMC ? (AliVEvent::kMB) : (AliVEvent::kUserDefined) );
+ //
+ // Run analysis
+ mgr->InitAnalysis();
+ // process dataset
+ mgr->StartAnalysis("proof", dataset.Data(), nEvents, nEventsSkip);
+ //
+ TString evstCmd = "if [ -e event_stat.root ]; then \nmv event_stat.root evstat_";
+ evstCmd += outFName; evstCmd += " \nfi";
+ gSystem->Exec( evstCmd.Data() );
+
+}
+
+
+TString GetFormatFromDataSet(TString dataset) {
+
+// Info("runAAF.C","Detecting format from dataset (may take while, depends on network connection)...");
+ TString dsTreeName;
+ if (dataset.Contains("#")) {
+ Info("runAAF.C",Form("Detecting format from dataset name '%s' ...",dataset.Data()));
+ dsTreeName=dataset(dataset.Last('#'),dataset.Length());
+ } else {
+ Info("runAAF.C",Form("Detecting format from dataset '%s' (may take while, depends on network connection) ...",dataset.Data()));
+ TFileCollection *ds = gProof->GetDataSet(dataset.Data());
+ if (!ds) {
+ Error(Form("Dataset %s doesn't exist on proof cluster!!!!",dataset.Data()));
+ return "";
+ }
+ dsTreeName = ds->GetDefaultTreeName();
+ }
+
+ if (dsTreeName.Contains("esdTree")) {
+ Info("runAAF.C","ESD input format detected ...");
+ return "ESD";
+ } else if (dsTreeName.Contains("aodTree")) {
+ Info("runAAF.C","AOD input format detected ...");
+ return "AOD";
+ } else {
+ Error("runAAF.C",Form("Tree %s is not supported !!!",dsTreeName.Data()));
+ Error("runAAF.C",Form("Maybe set your DS to %s#esdTree or %s#aodTree",dataset.Data(),dataset.Data()));
+ }
+
+ return "";
+}
+
+Bool_t InputHandlerSetup(TString format = "esd", Bool_t useKine = kTRUE)
+{
+ format.ToLower();
+
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+
+ AliAnalysisDataContainer *cin = mgr->GetCommonInputContainer();
+
+ if (cin) return;
+
+ if (!format.CompareTo("esd"))
+ {
+ AliESDInputHandler *esdInputHandler = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+ if (!esdInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating esdInputHandler ...");
+ esdInputHandler = new AliESDInputHandlerRP();
+ mgr->SetInputEventHandler(esdInputHandler);
+ }
+
+ if (useKine)
+ {
+ AliMCEventHandler* mcInputHandler = dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+
+ if (!mcInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating mcInputHandler ...");
+ AliMCEventHandler* mcInputHandler = new AliMCEventHandler();
+ mgr->SetMCtruthEventHandler(mcInputHandler);
+ }
+ }
+
+ }
+ else if (!format.CompareTo("aod"))
+ {
+ AliAODInputHandler *aodInputHandler = dynamic_cast<AliAODInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+ if (!aodInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating aodInputHandler ...");
+ aodInputHandler = new AliAODInputHandler();
+ mgr->SetInputEventHandler(aodInputHandler);
+ }
+ }
+ else
+ {
+ Info("Wrong input format!!! Only ESD and AOD are supported. Skipping Task ...");
+ return kFALSE;
+ }
+
+ return kTRUE;
+}
+
+void MixHandlerSetup(float ntMin,float ntMax,float ntMixBinSz,
+ float zMin, float zMax, float zMixBinSz)
+{
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) return;
+ int bufferSize = 1;
+ AliESDInputHandlerRP *esdH = dynamic_cast<AliESDInputHandlerRP*>(mgr->GetInputEventHandler());
+ if (!esdH) return;
+ //
+ AliMixEventInputHandler *esdMixH = new AliMixEventInputHandler(bufferSize);
+ esdMixH->SetInputHandlerForMixing(esdH);
+ AliMixEventPool *evPool = new AliMixEventPool("MyPool");
+ AliMixEventCutObj *tracklets = new AliMixEventCutObj(AliMixEventCutObj::kNumberTracklets, ntMin,ntMax,ntMixBinSz);
+ AliMixEventCutObj *zvertex = new AliMixEventCutObj(AliMixEventCutObj::kZVertex, zMin,zMax, zMixBinSz);
+ // evPool->AddCut(tracklets);
+ evPool->AddCut(zvertex);
+ //evPool->Init();
+ evPool->Print();
+ esdMixH->SetEventPool(evPool);
+ esdH->SetMixingHandler(esdMixH);
+}
+
+void AddPhysicsSelection(Bool_t isMC)
+{
+ // physics selection a la Michele
+ printf("Requesting physics selection in %s mode\n",isMC ? "MC":"Data");
+ gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+ //isMC is true when processing monte carlo, the second 0 disables the cluster vs tracklets
+ AliPhysicsSelectionTask* physicsSelectionTask = AddTaskPhysicsSelection(isMC,0);
+ if(!isMC) {
+ AliPhysicsSelection * physSel = physicsSelectionTask->GetPhysicsSelection();
+ physSel->AddCollisionTriggerClass("+CMBAC-B-NOPF-ALL");
+ /*
+ physSel->AddCollisionTriggerClass("+CMBS1C-B-NOPF-ALL");
+ physSel->AddCollisionTriggerClass("+CMBS1A-B-NOPF-ALL");
+ */
+ //
+ physSel->AddCollisionTriggerClass("+CMBS2C-B-NOPF-ALL");
+ physSel->AddCollisionTriggerClass("+CMBS2A-B-NOPF-ALL");
+ //
+ // This are needed only to fill the statistics tables
+ physSel->AddBGTriggerClass("+CMBAC-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBAC-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBAC-E-NOPF-ALL");
+ //
+ /*
+ physSel->AddBGTriggerClass("+CMBS1C-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1C-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1C-E-NOPF-ALL");
+ //
+ physSel->AddBGTriggerClass("+CMBS1A-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1A-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1A-E-NOPF-ALL");
+ //
+ */
+ /*
+ //
+ physSel->AddBGTriggerClass("+CMBS2C-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2C-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2C-E-NOPF-ALL");
+ //
+ physSel->AddBGTriggerClass("+CMBS2A-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2A-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2A-E-NOPF-ALL");
+ */
+ }
+ // if you use the following line, your task only gets the selected events
+ // task->SelectCollisionCandidates(AliVEvent::kUserDefined);
+ //
+ //Alternatively, in the UserExec of your task:
+ //Bool_t isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kUserDefined);
+ //
+}
--- /dev/null
+void MyAnalysisMacroTrackletMulti
+(TString dataset="/alice/sim/LHC10f8c_130844",
+ TString outFName = "trbg.root",
+ Int_t nEvents = -1,
+ Float_t etaCut = 0.5, // max |eta| range to fill in histos
+ Float_t zMin = -7, // process events with Z vertex min
+ Float_t zMax = 7, // max positions
+ Int_t useCentVar = 0, // centrality variable to use: 0=V0, 1=SPD2corr
+ //
+ Float_t cutSigNStd = 1.5, // cut on weighed distance used to extract signal
+ Float_t cutSigDPhiS = -1, // cut on dPhi-phiBent used to extract signal (if negative -> dphi*sqrt(cutSigNStd)
+ Bool_t useMC = kTRUE, // fill MC info (doRec=kTRUE)
+ Float_t scaleMCV0 = 0.7520, // rescale MC V0 to match the data
+ //
+ Bool_t doRec = kTRUE, // fill data histos from new reco
+ Bool_t doInj = kTRUE, // create Inj. bg
+ Bool_t doRot = kFALSE, // create Rot. bg
+ Bool_t doMix = kFALSE,//kTRUE, // create Mix. bg
+ //
+ // specific parameters for reconstruction
+ float phiRot = 3.14159e+00, // angle for bg. generation with rotation
+ float injScale = 1.,//0.7, // inject injScale*Ncl(Lr1/Lr2) hits
+ Bool_t scaleDTheta = kTRUE, // scale dTheta by 1/sin^2(theta) in trackleting
+ float nStdDev = 25., // number of st.dev. for tracklet cut to keep
+ float dphi = 0.06, // dphi window (sigma of tracklet cut)
+ float dtht = 0.025, // dtheta .... (if negative, abs will be used with additional cut on |dthetaX|, apart from w.distance
+ float phishift = 0.0045, // bending shift
+ Bool_t remOvl = kTRUE,
+ float ovlPhiCut = 0.005,
+ float ovlZetaCut = 0.05,
+ Int_t nEventsSkip = 0,
+ //----------------------- Ntracklets selection parameters important for mixing, to be tuned
+ Float_t ntMin = 1, // process events with ESDmult
+ Float_t ntMax = 20000, // within this range
+ Float_t ntMixBinSz = 20000, // ESDMult bin size for mixing
+ //----------------------- Zv selection parameters important for mixing, to be tuned
+ Float_t zMixBinSz = 14, //0.1, // Zv. bin for mixing
+ //---------------------------------------------------------------------------------
+ //
+ Bool_t checkReconstructables = kFALSE//kTRUE, // fill histos for reconstructable (needs useMC and doRec)
+ //
+ )
+{
+ //
+ if (cutSigDPhiS<0) cutSigDPhiS = TMath::Sqrt(cutSigNStd)*dphi;
+ //
+ printf("Start Analysis for %s, max %d Events skipping %d, Event Cuts: |eta|<%.1f, %.2f<Zv<%.2f\n",
+ dataset.Data(),nEvents,nEventsSkip,etaCut,zMin,zMax);
+ printf("Centrality variable: %d\n",useCentVar);
+ printf("Tracklet cuts: dPhi:%.3f dTheta:%.3f phiShift:%.4f | Keep %.1f NstDev\n"
+ "Scale dTheta: %s | Signal Selection: NstDev:%.1f, dPhiS: %.3f\n",
+ dphi,dtht,phishift,nStdDev,scaleDTheta ? "ON":"OFF",
+ cutSigNStd,cutSigDPhiS);
+ //
+ printf("UseMC: %s. V0 scale: %.4f\n",useMC ? "ON":"OFF",scaleMCV0);
+ printf("Operations: \n"
+ "Reco:%s (RemOvl:%s phi:%.3f zeta:%.3f)\n"
+ "Inj:%s (scale: %.2f)\n"
+ "Rot:%s (phi: %.4f)\n"
+ "Mix:%s (Nt:%.1f:%.1f:%.1f Zv:%.1f:%.1f:%.2f)\n",
+ doRec ? "ON":"OFF",remOvl? "ON":"OFF",ovlPhiCut,ovlZetaCut,
+ doInj ? "ON":"OFF",injScale,
+ doRot ? "ON":"OFF",phiRot,
+ doMix ? "ON":"OFF",ntMin,ntMax,ntMixBinSz, zMin,zMax,zMixBinSz);
+ //
+ if (nEvents<0) nEvents = int(1e9);
+ TString format = GetFormatFromDataSet(dataset);
+ //
+ // ALICE stuff
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) mgr = new AliAnalysisManager("Test train");
+ //
+ InputHandlerSetup(format,useMC);
+ if (doMix) MixHandlerSetup(ntMin,ntMax,ntMixBinSz, zMin,zMax,zMixBinSz);
+ // compile our task
+ gProof->Load("AliITSMultRecBg.cxx++");
+ gProof->Load("AliTrackletTaskMulti.cxx++");
+ //
+ // load and run AddTask macro
+ gROOT->LoadMacro("AddMultTaskTrackletMulti.C");
+ //
+ // create our task
+ AliTrackletTaskMulti *mltTask = AddMultTaskTrackletMulti(outFName.Data());
+ //
+ mltTask->SetUseCentralityVar(useCentVar);
+ mltTask->SetDoNormalReco(doRec);
+ mltTask->SetDoInjection(doInj);
+ mltTask->SetDoRotation(doRot);
+ mltTask->SetDoMixing(doMix);
+ //
+ mltTask->SetUseMC(useMC);
+ mltTask->SetCheckReconstructables(checkReconstructables);
+ //
+ mltTask->SetEtaCut(etaCut);
+ mltTask->SetZVertexMin(zMin);
+ mltTask->SetZVertexMax(zMax);
+ //
+ mltTask->SetDPhiSCut(cutSigDPhiS);
+ mltTask->SetNStdCut(cutSigNStd);
+ mltTask->SetScaleMCV0(scaleMCV0);
+ //
+ mltTask->SetScaleDThetaBySin2T(scaleDTheta);
+ mltTask->SetNStdDev(nStdDev);
+ mltTask->SetPhiWindow(dphi);
+ mltTask->SetThetaWindow(dtht);
+ mltTask->SetPhiShift(phishift);
+ mltTask->SetPhiOverlapCut(ovlPhiCut);
+ mltTask->SetZetaOverlapCut(ovlZetaCut);
+ mltTask->SetPhiRot(phiRot);
+ mltTask->SetInjScale(injScale);
+ mltTask->SetRemoveOverlaps(remOvl);
+ //
+ printf("new Task: %p\n",mltTask);
+ //
+ AddPhysicsSelection(useMC);
+ mltTask->SelectCollisionCandidates(useMC ? (AliVEvent::kMB) : (AliVEvent::kUserDefined) );
+ //mltTask->SelectCollisionCandidates();//AliVEvent::kMB);
+ //
+ // Run analysis
+ mgr->InitAnalysis();
+ // process dataset
+ mgr->StartAnalysis("proof", dataset.Data(), nEvents, nEventsSkip);
+ //
+ TString evstCmd = "if [ -e event_stat.root ]; then \nmv event_stat.root evstat_";
+ evstCmd += outFName; evstCmd += " \nfi";
+ gSystem->Exec( evstCmd.Data() );
+
+}
+
+
+TString GetFormatFromDataSet(TString dataset) {
+
+// Info("runAAF.C","Detecting format from dataset (may take while, depends on network connection)...");
+ TString dsTreeName;
+ if (dataset.Contains("#")) {
+ Info("runAAF.C",Form("Detecting format from dataset name '%s' ...",dataset.Data()));
+ dsTreeName=dataset(dataset.Last('#'),dataset.Length());
+ } else {
+ Info("runAAF.C",Form("Detecting format from dataset '%s' (may take while, depends on network connection) ...",dataset.Data()));
+ TFileCollection *ds = gProof->GetDataSet(dataset.Data());
+ if (!ds) {
+ Error(Form("Dataset %s doesn't exist on proof cluster!!!!",dataset.Data()));
+ return "";
+ }
+ dsTreeName = ds->GetDefaultTreeName();
+ }
+
+ if (dsTreeName.Contains("esdTree")) {
+ Info("runAAF.C","ESD input format detected ...");
+ return "ESD";
+ } else if (dsTreeName.Contains("aodTree")) {
+ Info("runAAF.C","AOD input format detected ...");
+ return "AOD";
+ } else {
+ Error("runAAF.C",Form("Tree %s is not supported !!!",dsTreeName.Data()));
+ Error("runAAF.C",Form("Maybe set your DS to %s#esdTree or %s#aodTree",dataset.Data(),dataset.Data()));
+ }
+
+ return "";
+}
+
+Bool_t InputHandlerSetup(TString format = "esd", Bool_t useKine = kTRUE)
+{
+ format.ToLower();
+
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+
+ AliAnalysisDataContainer *cin = mgr->GetCommonInputContainer();
+
+ if (cin) return;
+
+ if (!format.CompareTo("esd"))
+ {
+ AliESDInputHandler *esdInputHandler = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+ if (!esdInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating esdInputHandler ...");
+ esdInputHandler = new AliESDInputHandlerRP();
+ mgr->SetInputEventHandler(esdInputHandler);
+ }
+
+ if (useKine)
+ {
+ AliMCEventHandler* mcInputHandler = dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+
+ if (!mcInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating mcInputHandler ...");
+ AliMCEventHandler* mcInputHandler = new AliMCEventHandler();
+ mgr->SetMCtruthEventHandler(mcInputHandler);
+ }
+ }
+
+ }
+ else if (!format.CompareTo("aod"))
+ {
+ AliAODInputHandler *aodInputHandler = dynamic_cast<AliAODInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+ if (!aodInputHandler)
+ {
+ Info("CustomAnalysisTaskInputSetup", "Creating aodInputHandler ...");
+ aodInputHandler = new AliAODInputHandler();
+ mgr->SetInputEventHandler(aodInputHandler);
+ }
+ }
+ else
+ {
+ Info("Wrong input format!!! Only ESD and AOD are supported. Skipping Task ...");
+ return kFALSE;
+ }
+
+ return kTRUE;
+}
+
+void MixHandlerSetup(float ntMin,float ntMax,float ntMixBinSz,
+ float zMin, float zMax, float zMixBinSz)
+{
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) return;
+ int bufferSize = 1;
+ AliESDInputHandlerRP *esdH = dynamic_cast<AliESDInputHandlerRP*>(mgr->GetInputEventHandler());
+ if (!esdH) return;
+ //
+ AliMixEventInputHandler *esdMixH = new AliMixEventInputHandler(bufferSize);
+ esdMixH->SetInputHandlerForMixing(esdH);
+ AliMixEventPool *evPool = new AliMixEventPool("MyPool");
+ AliMixEventCutObj *tracklets = new AliMixEventCutObj(AliMixEventCutObj::kNumberTracklets, ntMin,ntMax,ntMixBinSz);
+ AliMixEventCutObj *zvertex = new AliMixEventCutObj(AliMixEventCutObj::kZVertex, zMin,zMax, zMixBinSz);
+ // evPool->AddCut(tracklets);
+ evPool->AddCut(zvertex);
+ //evPool->Init();
+ evPool->Print();
+ esdMixH->SetEventPool(evPool);
+ esdH->SetMixingHandler(esdMixH);
+}
+
+void AddPhysicsSelection(Bool_t isMC)
+{
+ // physics selection a la Michele
+ printf("Requesting physics selection in %s mode\n",isMC ? "MC":"Data");
+ gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+ //isMC is true when processing monte carlo, the second 0 disables the cluster vs tracklets
+ AliPhysicsSelectionTask* physicsSelectionTask = AddTaskPhysicsSelection(isMC,0);
+ if(!isMC) {
+ AliPhysicsSelection * physSel = physicsSelectionTask->GetPhysicsSelection();
+ physSel->AddCollisionTriggerClass("+CMBAC-B-NOPF-ALL");
+ /*
+ physSel->AddCollisionTriggerClass("+CMBS1C-B-NOPF-ALL");
+ physSel->AddCollisionTriggerClass("+CMBS1A-B-NOPF-ALL");
+ */
+ //
+ physSel->AddCollisionTriggerClass("+CMBS2C-B-NOPF-ALL");
+ physSel->AddCollisionTriggerClass("+CMBS2A-B-NOPF-ALL");
+ //
+ // This are needed only to fill the statistics tables
+ physSel->AddBGTriggerClass("+CMBAC-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBAC-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBAC-E-NOPF-ALL");
+ //
+ /*
+ physSel->AddBGTriggerClass("+CMBS1C-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1C-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1C-E-NOPF-ALL");
+ //
+ physSel->AddBGTriggerClass("+CMBS1A-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1A-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS1A-E-NOPF-ALL");
+ //
+ */
+ /*
+ //
+ physSel->AddBGTriggerClass("+CMBS2C-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2C-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2C-E-NOPF-ALL");
+ //
+ physSel->AddBGTriggerClass("+CMBS2A-C-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2A-A-NOPF-ALL");
+ physSel->AddBGTriggerClass("+CMBS2A-E-NOPF-ALL");
+ */
+ }
+ // if you use the following line, your task only gets the selected events
+ // task->SelectCollisionCandidates(AliVEvent::kUserDefined);
+ //
+ //Alternatively, in the UserExec of your task:
+ //Bool_t isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kUserDefined);
+ //
+}
--- /dev/null
+dN/dEta analysis can be done in 2 ways:
+
+1) For single centrality bin:
+Using AliTrackletTaskUni.{h,cxx} steered by the
+runAAF.C and MyAnalysisMacro.C
+
+It will produce a file with 3D (sparse) histos "delta" vs Zv vs eta
+where delta is either "weigted distance" and/or "dphi - bend", which is used
+both the match the tails and to define the signal cut.
+The exact value of cut can be decided at the stage of processing the histos,
+so different signal and tail matching thresholds can be tested
+
+Note that wide Zv eta range can be processed and then restricted at
+the correction stage.
+
+One has to run runAAF.C for over the data and MC datasets and then analyse them
+using the CorrectSpectra.C macro (the cuts/variables use... must be set
+beforehand)
+
+
+2) Mor multiple centrality bins at once:
+AliTrackletTaskMulti.{h,cxx} steered by the
+runAAFMulti.C and MyAnalysisMacroTrackletMulti.C
+
+It produces for each centrality bin a set of histos, particularly 2D histos for
+Zv vs eta with the signal cut on "distance" already applied (by defaults one for
+"w.dist" another for "dphi-bend" + 1D histo of "distance" for selected Zv,eta
+range (to be used for the bg matching the tails of data"
+
+Note: Zv, eta ranges must be defined at data processing stage, as well as the
+signal cut (cutSigNStd in the runAAFMulti) and number of st.dev to keep (nStdDev)
+
+One has to runAAFMulti.C for over the data and MC datasets and then analyse them
+using the CorrectSpectraMulti.C macro
+
+--------------------------------
+Both methods can use 3 types of generated bg: injection, rotation and mixing.
+Simultaneous eployment of all these methods is also possible, but may create
+a memory problem.
+
+The corresponding CorrectSpectra... macros must be tuned for the bg.type used.
+
--- /dev/null
+//
+void runAAF(TString dataset="/alice/sim/LHC10f8c_130844",
+ TString outFName = "trbg.root",
+ Bool_t doRec = kTRUE, // fill data histos from new reco
+ Bool_t doInj = kTRUE, // create Inj. bg
+ Bool_t doRot = kTRUE, // create Rot. bg
+ Bool_t doMix = kFALSE,//kTRUE, // create Mix. bg
+ Bool_t useMC = kTRUE, // fill MC info (doRec=kTRUE)
+ Bool_t checkReconstructables = kFALSE,//kTRUE, // fill histos for reconstructable (needs useMC and doRec)
+ //
+ Float_t etaCut = 3.0, // max |eta| range to fill in histos
+ //
+ // specific parameters for reconstruction
+ //----------------------- Zv selection parameters important for mixing, to be tuned
+ Float_t zMin = -20, // process events with Z vertex min
+ Float_t zMax = 20, // max positions
+ Float_t zMixBinSz = 20, //0.1, // Zv. bin for mixing
+ //---------------------------------------------------------------------------------
+ //
+ //----------------------- Ntracklets selection parameters important for mixing, to be tuned
+ Float_t ntMin = 1, // process events with ESDmult
+ Float_t ntMax = 20000, // within this range
+ Float_t ntMixBinSz = 20000, // ESDMult bin size for mixing
+ //---------------------------------------------------------------------------------
+ float phiRot = 3.14159e+00, // angle for bg. generation with rotation
+ float injScale = 1.,//0.7, // inject injScale*Ncl(Lr1/Lr2) hits
+ Bool_t scaleDTheta = kTRUE, // scale dTheta by 1/sin^2(theta) in trackleting
+ float nStdDev = 25., // number of st.dev. for tracklet cut to keep
+ float dphi = 0.06, // dphi window (sigma of tracklet cut)
+ float dtht = 0.025, // dtheta .... (if negative, abs will be used with additional cut on |dthetaX|, apart from w.distance
+ float phishift = 0.0045, // bending shift
+ Bool_t remOvl = kTRUE,
+ float ovlPhiCut = 0.005,
+ float ovlZetaCut = 0.05,
+ Int_t nEvents = 50000000,
+ Int_t nEventsSkip = 0,
+ TString alirootVer = "VO_ALICE@AliRoot::v4-21-05-AN",
+ TString rootVer = "default",//"VO_ALICE@ROOT::v5-27-06b",
+ //
+ TString proofCluster="shahoian@alice-caf.cern.ch"
+ )
+{
+ //
+ Bool_t runLocal = kFALSE; // true only for local test mode
+ if (runLocal) {
+ dataset = "/default/shahoian/test_pp";
+ //dataset = "/default/shahoian/test";
+ proofCluster = "";
+ alirootVer = "AliRootProofLite";
+ nEvents = 500;
+ }
+ //
+ if (dataset.Contains("alice/data") && useMC) {
+ printf("Running with read data dataset, switching OFF useMC\n");
+ useMC = kFALSE;
+ }
+ //
+ printf("Start Analysis for %s, max %d Events skipping %d\n"
+ "Event Cuts: |eta|<%.1f, %.2f<Zv<%.2f (Mix.Bin:%.2f), %.0f<Mult<%0.f (Mix.Bin:%.0f)\n"
+ "Reco:%d Inj:%d Rot:%d Mix:%d | MCinfo:%d CheckReconstructables:%d\n"
+ "PhiRot:%.4f InjScale:%.2f ScaleDTheta:%d NStdDev:%.1f DPhi:%.4f DTheta:%.4f PhiShift:%.4f\n"
+ "RemoveOverlaps:%d PhiOvl:%.4f ZEtaOvl:%.4f\n",
+ dataset.Data(),nEvents,nEventsSkip,
+ etaCut,zMin,zMax,zMixBinSz,ntMin,ntMax,ntMixBinSz,
+ doRec,doInj,doRot,doMix,useMC,checkReconstructables,
+ phiRot,injScale,scaleDTheta,nStdDev,dphi,dtht,phishift,
+ remOvl,ovlPhiCut,ovlZetaCut);
+ //
+ printf("Requested: %s %s\n",alirootVer.Data(), rootVer.Data());
+ printf("Output expected in %s\n",outFName.Data());
+ //
+ gEnv->SetValue("XSec.GSI.DelegProxy","2");
+ //
+ TString alirootMode="REC";
+ TString extraLibs = "ITSrec:CDB:Geom:"; // not needed in default aliroot mode
+ //extraLibs+= "ANALYSIS:ANALYSISalice";
+ extraLibs+= "ANALYSIS:ANALYSISalice:EventMixing";
+ TList *list = new TList();
+ // sets $ALIROOT_MODE on each worker to let proof to know to run in special mode
+ list->Add(new TNamed("ALIROOT_MODE" , alirootMode.Data()));
+ list->Add(new TNamed("ALIROOT_EXTRA_LIBS", extraLibs.Data()));
+ list->Add(new TNamed("ALIROOT_ENABLE_ALIEN","1"));
+ //
+ //REM: same version of AliRoot on client!!!!! Otherwise error!!
+ TProof::Mgr(proofCluster.Data())->SetROOTVersion(rootVer.Data());
+ TProof::Open(proofCluster.Data());//,"workers=10x");
+ // TProof::Open(proofCluster.Data(),"workers=1x");
+ if (!gProof) {
+ Error("runAAF.C","Connection to AF failed.");
+ return;
+ }
+ gProof->Exec("TObject *o = gEnv->GetTable()->FindObject(\"Proof.UseMergers\");"
+ "gEnv->GetTable()->Remove(o);", kTRUE);
+ // gProof->SetParameter("PROOF_UseMergers", 0);
+ // Lets enable aliroot + extra libs on proof cluster
+ if (runLocal) gProof->UploadPackage(alirootVer.Data());
+ gProof->EnablePackage(alirootVer.Data(), list);
+ //
+ gROOT->LoadMacro("MyAnalysisMacro.C");
+
+ if (runLocal) {
+ Int_t numWorkers = gProof->GetParallel();
+ if (numWorkers<1) {printf("No workers\n"); return;}
+ gProof->SetParameter("PROOF_PacketizerStrategy", (Int_t)0);
+ int frac = (Int_t) 5 / numWorkers;
+ if (frac<1) frac = 1;
+ gProof->SetParameter("PROOF_PacketAsAFraction", frac);
+ }
+ MyAnalysisMacro(dataset,outFName,doRec,doInj,doRot,doMix,useMC,checkReconstructables,
+ etaCut,zMin,zMax,zMixBinSz,ntMin,ntMax,ntMixBinSz,
+ phiRot,injScale,scaleDTheta,nStdDev,dphi,dtht,
+ phishift,remOvl,ovlPhiCut,ovlZetaCut,nEvents,nEventsSkip);
+ //
+}
--- /dev/null
+//
+void runAAFMulti(TString dataset="/alice/sim/LHC10h6_000137161",
+ TString outFName = "trbg.root",
+ Int_t nEvents = -1,//3000,
+ Float_t etaCut = 0.5, // max |eta| range to fill in histos
+ Float_t zMin = -7, // process events with Z vertex min
+ Float_t zMax = 7, // max positions
+ Int_t useCentVar = 0, // centrality variable to use: enum {kCentSPD2, kCentV0, kCentV0CR, kCentTrTPC}
+ Float_t scaleMCV0 = 0.7520, // rescale MC V0 to match data
+ //
+ //
+ Float_t cutSigNStd = 1.5, // cut on weighed distance used to extract signal
+ Float_t cutSigDPhiS = -1, // cut on dPhi-phiBent used to extract signal (if negative -> dphi*sqrt(cutSigNStd)
+ Bool_t useMC = kTRUE, // fill MC info (doRec=kTRUE)
+ //
+ Bool_t doRec = kTRUE,//kTRUE, // fill data histos from new reco
+ Bool_t doInj = kTRUE,//kTRUE, // create Inj. bg
+ Bool_t doRot = kFALSE, // create Rot. bg
+ Bool_t doMix = kFALSE,//kTRUE, // create Mix. bg
+ //
+ // specific parameters for reconstruction
+ float phiRot = 3.14159e+00, // angle for bg. generation with rotation
+ float injScale = 1.,//0.7, // inject injScale*Ncl(Lr1/Lr2) hits
+ Bool_t scaleDTheta = kTRUE, // scale dTheta by 1/sin^2(theta) in trackleting
+ float nStdDev = 25., // number of st.dev. for tracklet cut to keep
+ float dphi = 0.06, // dphi window (sigma of tracklet cut)
+ float dtht = 0.025, // dtheta .... (if negative, abs will be used with additional cut on |dthetaX|, apart from w.distance
+ float phishift = 0.0045, // bending shift
+ Bool_t remOvl = kTRUE,
+ float ovlPhiCut = 0.005,
+ float ovlZetaCut = 0.05,
+ Int_t nEventsSkip = 0,
+ //----------------------- Ntracklets selection parameters important for mixing, to be tuned
+ Float_t ntMin = 1, // process events with ESDmult
+ Float_t ntMax = 20000, // within this range
+ Float_t ntMixBinSz = 20000, // ESDMult bin size for mixing
+ //----------------------- Zv selection parameters important for mixing, to be tuned
+ Float_t zMixBinSz = 14, //0.1, // Zv. bin for mixing
+ //---------------------------------------------------------------------------------
+ //
+ Bool_t checkReconstructables = kFALSE,//kTRUE, // fill histos for reconstructable (needs useMC and doRec)
+ //
+ TString alirootVer = "VO_ALICE@AliRoot::v4-21-05-AN",
+ TString rootVer = "VO_ALICE@ROOT::v5-27-06b",
+ //
+ //TString proofCluster="shahoian@skaf.saske.sk"
+ TString proofCluster="shahoian@alice-caf.cern.ch"
+ )
+{
+ //
+ Bool_t runLocal = kFALSE; // true only for local test mode
+ if (runLocal) {
+ dataset = "/default/shahoian/test_pp";
+ //dataset = "/default/shahoian/test";
+ proofCluster = "";
+ alirootVer = "AliRootProofLite";
+ nEvents = 500;
+ }
+ //
+ if ((!dataset.Contains("alice/sim")) && useMC) {
+ printf("Running with read data dataset, switching OFF useMC\n");
+ useMC = kFALSE;
+ }
+ //
+ printf("Requested: %s %s\n",alirootVer.Data(), rootVer.Data());
+ printf("Output expected in %s\n",outFName.Data());
+ //
+ gEnv->SetValue("XSec.GSI.DelegProxy","2");
+ //
+ TString alirootMode="REC";
+ TString extraLibs = "ITSrec:CDB:Geom:"; // not needed in default aliroot mode
+ //extraLibs+= "ANALYSIS:ANALYSISalice";
+ extraLibs+= "ANALYSIS:ANALYSISalice:EventMixing";
+ TList *list = new TList();
+ // sets $ALIROOT_MODE on each worker to let proof to know to run in special mode
+ list->Add(new TNamed("ALIROOT_MODE" , alirootMode.Data()));
+ list->Add(new TNamed("ALIROOT_EXTRA_LIBS", extraLibs.Data()));
+ list->Add(new TNamed("ALIROOT_ENABLE_ALIEN","1"));
+ //
+ //REM: same version of AliRoot on client!!!!! Otherwise error!!
+ TProof::Mgr(proofCluster.Data())->SetROOTVersion(rootVer.Data());
+ TProof::Open(proofCluster.Data());//,"workers=10x");
+ // TProof::Open(proofCluster.Data(),"workers=1x");
+ if (!gProof) {
+ Error("runAAFMulti.C","Connection to AF failed.");
+ return;
+ }
+ gProof->Exec("TObject *o = gEnv->GetTable()->FindObject(\"Proof.UseMergers\");"
+ "gEnv->GetTable()->Remove(o);", kTRUE);
+ // gProof->SetParameter("PROOF_UseMergers", 0);
+ // Lets enable aliroot + extra libs on proof cluster
+ if (runLocal) gProof->UploadPackage(alirootVer.Data());
+ gProof->EnablePackage(alirootVer.Data(), list);
+ //
+ if (runLocal) {
+ Int_t numWorkers = gProof->GetParallel();
+ if (numWorkers<1) {printf("No workers\n"); return;}
+ gProof->SetParameter("PROOF_PacketizerStrategy", (Int_t)0);
+ int frac = (Int_t) 5 / numWorkers;
+ if (frac<1) frac = 1;
+ gProof->SetParameter("PROOF_PacketAsAFraction", frac);
+ }
+ //
+ gROOT->LoadMacro("MyAnalysisMacroTrackletMulti.C");
+ TStopwatch sw;
+ sw.Start();
+ MyAnalysisMacroTrackletMulti(dataset,outFName,nEvents,etaCut,zMin,zMax,useCentVar,
+ cutSigNStd,cutSigDPhiS,useMC,scaleMCV0,
+ doRec,doInj,doRot,doMix,
+ phiRot,injScale,scaleDTheta,nStdDev,dphi,dtht,
+ phishift,remOvl,ovlPhiCut,ovlZetaCut,nEventsSkip,
+ ntMin,ntMax,ntMixBinSz,zMixBinSz,
+ checkReconstructables);
+ //
+ sw.Stop();
+ sw.Print();
+}
--- /dev/null
+//
+void runAAFglob(TString dataset="/alice/data/LHC10h_000137161_p1_plusplusplus",
+ TString outFName = "globs.root",
+ Int_t nEvents = 50000000,
+ Int_t nEventsSkip = 0,
+ TString alirootVer = "VO_ALICE@AliRoot::v4-21-04-AN",
+ TString rootVer = "VO_ALICE@ROOT::v5-27-06b",
+ TString proofCluster="shahoian@alice-caf.cern.ch"
+ //TString proofCluster="shahoian@skaf.saske.sk"
+ )
+{
+ //
+ Bool_t runLocal = kFALSE; // true only for local test mode
+ if (runLocal) {
+ dataset = "/default/shahoian/test_pp";
+ //dataset = "/default/shahoian/test";
+ proofCluster = "";
+ alirootVer = "AliRootProofLite";
+ nEvents = 500;
+ }
+ //
+ printf("Requested: %s %s\n",alirootVer.Data(), rootVer.Data());
+ printf("Output expected in %s\n",outFName.Data());
+ //
+ gEnv->SetValue("XSec.GSI.DelegProxy","2");
+ //
+ TString alirootMode="REC";
+ TString extraLibs;
+ extraLibs+= "ANALYSIS:ANALYSISalice";
+ TList *list = new TList();
+ // sets $ALIROOT_MODE on each worker to let proof to know to run in special mode
+ list->Add(new TNamed("ALIROOT_MODE" , alirootMode.Data()));
+ list->Add(new TNamed("ALIROOT_EXTRA_LIBS", extraLibs.Data()));
+ // list->Add(new TNamed("ALIROOT_ENABLE_ALIEN","1"));
+ //
+ //REM: same version of AliRoot on client!!!!! Otherwise error!!
+ TProof::Mgr(proofCluster.Data())->SetROOTVersion(rootVer.Data());
+ TProof::Open(proofCluster.Data());//,"workers=10x");
+ // TProof::Open(proofCluster.Data(),"workers=1x");
+ if (!gProof) {
+ Error("runAAFglob.C","Connection to AF failed.");
+ return;
+ }
+ gProof->Exec("TObject *o = gEnv->GetTable()->FindObject(\"Proof.UseMergers\");"
+ "gEnv->GetTable()->Remove(o);", kTRUE);
+ // gProof->SetParameter("PROOF_UseMergers", 0);
+ // Lets enable aliroot + extra libs on proof cluster
+ if (runLocal) gProof->UploadPackage(alirootVer.Data());
+ gProof->EnablePackage(alirootVer.Data(), list);
+ //
+ gROOT->LoadMacro("AnalysisMacroGlob.C");
+ //
+ if (runLocal) {
+ Int_t numWorkers = gProof->GetParallel();
+ if (numWorkers<1) {printf("No workers\n"); return;}
+ gProof->SetParameter("PROOF_PacketizerStrategy", (Int_t)0);
+ int frac = (Int_t) 5 / numWorkers;
+ if (frac<1) frac = 1;
+ gProof->SetParameter("PROOF_PacketAsAFraction", frac);
+ }
+ AnalysisMacroGlob(dataset,outFName,nEvents,nEventsSkip);
+ //
+}