/************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * * Contributors are mentioned in the code where appropriate. * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ // // class to calculate TRD dEdx // xx // xx // xx // xx // // Xianguo Lu // lu@physi.uni-heidelberg.de // Xianguo.Lu@cern.ch // // #include "TF1.h" #include "TFile.h" #include "TH1D.h" #include "TH2D.h" #include "THnSparse.h" #include "TMath.h" #include "TMatrixD.h" #include "TMinuit.h" #include "TObjArray.h" #include "TRandom3.h" #include "TStopwatch.h" #include "TVectorD.h" #include "TTreeStream.h" #include "AliCDBId.h" #include "AliCDBMetaData.h" #include "AliCDBStorage.h" #include "AliESDEvent.h" #include "AliESDfriendTrack.h" #include "AliESDtrack.h" #include "AliTRDtrackV1.h" #include "AliTRDdEdxUtils.h" #define EPSILON 1e-12 THnSparseD * AliTRDdEdxUtils::fgHistGain=0x0; THnSparseD * AliTRDdEdxUtils::fgHistT0=0x0; THnSparseD * AliTRDdEdxUtils::fgHistVd=0x0; TObjArray * AliTRDdEdxUtils::fgHistPHQ=new TObjArray(8); TString AliTRDdEdxUtils::fgCalibFile; TObjArray * AliTRDdEdxUtils::fgObjGain = 0x0; TObjArray * AliTRDdEdxUtils::fgObjT0 = 0x0; TObjArray * AliTRDdEdxUtils::fgObjVd = 0x0; TObjArray * AliTRDdEdxUtils::fgObjPHQ = 0x0; Int_t AliTRDdEdxUtils::fgNchamber = -999; Double_t AliTRDdEdxUtils::fgChamberQ[6]; Double_t AliTRDdEdxUtils::fgChamberTmean[6]; Double_t AliTRDdEdxUtils::fgTrackTmean = -999; //=================================================================================== // Math and Histogram //=================================================================================== void AliTRDdEdxUtils::GetCDFCuts(const TH1D *hh, const Int_t ncut, Double_t cuts[], const Double_t cdfs[], const Double_t thres) { // //counts of hh is sorted // for(Int_t ii=0; iiGetNbinsX(); Double_t datas[nbin]; for(Int_t ii=1; ii<=nbin; ii++){ const Double_t res = hh->GetBinContent(ii); if(res1){ printf("AliTRDdEdxUtils::GetCDFCuts error cdfs[%d] %15f out of range!\n", ii, icdf); exit(1); } cuts[ii] = datas[id[Int_t(icdf*nsel)]]; } } Double_t AliTRDdEdxUtils::GetMeanRMS(const Double_t nn, const Double_t sum, const Double_t w2s, Double_t * grms, Double_t * gerr) { // //calculate mean (with error) and rms from sum, w2s, nn //if nn=0, mean, error, and rms all = 0 // Double_t tmean = 0, trms = 0, terr = 0; if(nn>EPSILON){ tmean = sum/nn; const Double_t arg = w2s/nn-tmean*tmean; if(TMath::Abs(arg)_{low-high according to x} // /* //test-> for(Int_t ii=0; iiGetNbinsX()+1; itmp++){ const Double_t be = hh->GetBinError(itmp); const Double_t bc = hh->GetBinContent(itmp); if(beEPSILON){ printf("AliTRDdEdxUtils::TruncatedMean (hist) error %e %e %d\n", bc, be, itmp); exit(1); } continue; } npreTrunc += bc*bc/be/be; } const Double_t nstart = npreTrunc*lowfrac; const Double_t nstop = npreTrunc*highfrac; //with Double_t this should also handle normalized hist Double_t ntot = 0; Double_t nused = 0; Double_t sum = 0; Double_t w2s = 0; for(Int_t itmp=0; itmp<=hh->GetNbinsX()+1; itmp++){ const Double_t be = hh->GetBinError(itmp); const Double_t bc = hh->GetBinContent(itmp); if(beEPSILON){ printf("AliTRDdEdxUtils::TruncatedMean (hist) error %e %e %d\n", bc, be, itmp); exit(1); } continue; } const Double_t weight = bc*bc/be/be; ntot+=weight; //<= correct, because when high=1, nstop has to be included if(ntot>nstart && ntot<=nstop){ const Double_t val = hh->GetBinCenter(itmp); sum += weight*val; w2s += weight*val*val; nused += weight; //printf("test %d %f %f --- %f %f -- %f %f\n", itmp, weight, val, sum, w2s, nused, nsample); } else if(ntot>nstop){ if(itmp>=hh->GetNbinsX()){ printf("AliTRDdEdxUtils::TruncatedMean warning hist range too small %s %f %f %d %d, %15f %15f %15f; nused w2s sum set to 0\n", hh->GetName(), hh->GetBinLowEdge(1), hh->GetBinLowEdge(itmp), itmp, hh->GetNbinsX(), hh->GetBinContent(hh->GetNbinsX())/hh->Integral(0,hh->GetNbinsX()+1), hh->GetBinContent(hh->GetNbinsX()), hh->Integral(0,hh->GetNbinsX()+1)); //exit(1); nused = 0; w2s = sum = 0; } break; } } return GetMeanRMS(nused, sum, w2s, grms, gerr); } void AliTRDdEdxUtils::FitSlicesY(const TH2D *hh, TH1D *&hnor, TH1D *&hmpv, TH1D *&hwid, TH1D *&hres, const Double_t thres, const Double_t lowfrac, const Double_t highfrac) { // //fit slices of hh using truncation // const Int_t x0 = hh->GetXaxis()->GetFirst(); const Int_t x1 = hh->GetXaxis()->GetLast(); const Int_t y0 = hh->GetYaxis()->GetFirst(); const Int_t y1 = hh->GetYaxis()->GetLast(); const Int_t nx = hh->GetNbinsX(); const Int_t ny = hh->GetNbinsY(); const Double_t xmin = hh->GetXaxis()->GetXmin(); const Double_t xmax = hh->GetXaxis()->GetXmax(); const Double_t ymin = hh->GetYaxis()->GetXmin(); const Double_t ymax = hh->GetYaxis()->GetXmax(); hnor = new TH1D(Form("%s_amp",hh->GetName()), "", nx, xmin, xmax); hmpv = new TH1D(Form("%s_mpv",hh->GetName()), "", nx, xmin, xmax); hwid = new TH1D(Form("%s_wid",hh->GetName()), "", nx, xmin, xmax); hres = new TH1D(Form("%s_res",hh->GetName()), "", nx, xmin, xmax); for(Int_t ix=x0; ix<=x1; ix++){ //to speed up const Double_t rawcount = hh->Integral(ix,ix,0, ny+1); if(rawcountGetName(), ix),"",ny, ymin, ymax); Double_t ntot = 0; for(Int_t iy=y0; iy<=y1; iy++){ const Double_t be = hh->GetBinError(ix,iy); const Double_t bc = hh->GetBinContent(ix, iy); if(beEPSILON){ printf("AliTRDdEdxUtils::FitSlicesY error %d %d %e %e\n", ix, iy, be, bc); exit(1); } continue; } htmp->SetBinContent(iy, bc); htmp->SetBinError(iy, be); ntot += (bc/be)*(bc/be); //if(be) printf("test %d %d : %f %f %f\n", ix, iy, bc, be, pow(bc/be,2)); } hnor->SetBinContent(ix, ntot); hnor->SetBinError( ix, 0); if(ntotGetRMS()Draw(); Double_t trms = -999, terr = -999; const Double_t tmean = TruncatedMean(htmp, lowfrac, highfrac, &trms, &terr); hmpv->SetBinContent(ix, tmean); hmpv->SetBinError( ix, terr); hwid->SetBinContent(ix, trms); hwid->SetBinError( ix, 0); hres->SetBinContent(ix, tmean>EPSILON ? trms/tmean:0); hres->SetBinError( ix, 0); delete htmp; } TH1 *hhs[]={hnor, hmpv, hwid, hres}; const TString yt[]={"N", "MPV", "#sigma", "#sigma/MPV"}; const Int_t nh = sizeof(hhs)/sizeof(TH1*); for(Int_t ii=0; iiSetYTitle(Form("%s of %s", yt[ii].Data(), hh->GetYaxis()->GetTitle())); hhs[ii]->SetXTitle(hh->GetXaxis()->GetTitle()); hhs[ii]->GetYaxis()->SetTitleOffset(hh->GetYaxis()->GetTitleOffset()); hhs[ii]->SetTitle(hh->GetTitle()); } } //=================================================================================== // TRD Analysis Fast Tool //=================================================================================== Int_t AliTRDdEdxUtils::GetNtracklet(const AliESDEvent *esd) { // //number of trd tracklet in one esd event // const Int_t ntrk0 = esd->GetNumberOfTracks(); Int_t ntrdv1=0; for(Int_t ii=0; iiGetTrack(ii)->GetTRDntracklets(); } return ntrdv1; } AliTRDtrackV1 * AliTRDdEdxUtils::GetTRDtrackV1(const AliESDtrack * esdtrack) { // //Get TRD friend track // AliESDfriendTrack * friendtrk = (AliESDfriendTrack *)esdtrack->GetFriendTrack(); if(!friendtrk){ //printf("xlulog AliAnalysisTaskCosmicTRD::GetTRDtrack no friend!!\n"); exit(1); return 0x0; } TObject *calibObject=0x0; AliTRDtrackV1 * trdtrack=0x0; for(Int_t l=0; (calibObject=friendtrk->GetCalibObject(l)); l++) { if( (trdtrack=dynamic_cast(calibObject)) ) break; } return trdtrack; } Bool_t AliTRDdEdxUtils::IsInSameStack(const AliTRDtrackV1 *trdtrack) { // // to check if all tracklets are in the same stack, useful in cosmic // TVectorD secs(18), stks(5); for(Int_t ilayer = 0; ilayer < 6; ilayer++){ AliTRDseedV1 *tracklet=trdtrack->GetTracklet(ilayer); if(!tracklet) continue; const Int_t det = tracklet->GetDetector(); const Int_t isector = AliTRDgeometry::GetSector(det); const Int_t istack = AliTRDgeometry::GetStack(det); secs[isector] = 1; stks[istack] = 1; } if(secs.Sum()!=1 || stks.Sum()!=1){ return kFALSE; } else return kTRUE; } Bool_t AliTRDdEdxUtils::GetFirstSectorStackMomentum(const AliTRDtrackV1 *trdtrack, Int_t & isec, Int_t & istk, Double_t & mom) { // //as function name // isec = istk = -999; mom = -999; for(Int_t ilayer = 0; ilayer < 6; ilayer++){ AliTRDseedV1 *tracklet=trdtrack->GetTracklet(ilayer); if(!tracklet) continue; const Int_t det = tracklet->GetDetector(); isec = AliTRDgeometry::GetSector(det); istk = AliTRDgeometry::GetStack(det); mom = tracklet->GetMomentum(); break; } if(isec<0) return kFALSE; else return kTRUE; } //=================================================================================== // Calibration //=================================================================================== Double_t AliTRDdEdxUtils::GetCalibTPCscale(const Int_t tpcncls, const Double_t tpcsig) { // //the scale used in calibration // if(tpcncls < CalibTPCnclsCut()) return -999; if(tpcsig0)*2 + (charge>0); } TObjArray * AliTRDdEdxUtils::GetObjPHQ(const Bool_t kinvq, const Double_t mag, const Int_t charge) { // //return calib obj // if(!fgObjPHQ){ printf("AliTRDdEdxUtils::GetObjPHQ error fgObjPHQ null!!\n"); exit(1); } return (TObjArray*) fgObjPHQ->At(GetPHQIterator(kinvq, mag, charge)); } THnSparseD * AliTRDdEdxUtils::GetHistPHQ(const Bool_t kinvq, const Double_t mag, const Int_t charge) { // //return calib hist // return (THnSparseD*) fgHistPHQ->At(GetPHQIterator(kinvq, mag, charge)); } TString AliTRDdEdxUtils::GetPHQName(const Bool_t kobj, const Int_t iter) { // //get name of calib obj/hist of PHQ // return Form("TRDCalib%sPHQ%d", kobj?"Obj":"Hist", iter); } void AliTRDdEdxUtils::DeleteCalibObj() { // //delete calib obj // delete fgObjGain; delete fgObjT0; delete fgObjVd; fgObjGain = 0x0; fgObjT0 = 0x0; fgObjVd = 0x0; if(fgObjPHQ){ fgObjPHQ->SetOwner(); delete fgObjPHQ; fgObjPHQ = 0x0; } } Bool_t AliTRDdEdxUtils::GenerateDefaultPHQOCDB(const TString path) { // //generate default OCDB object PHQ, do like //AliTRDdEdxUtils::GenerateDefaultPHQOCDB("local://./") // TObjArray * arr8 = new TObjArray(8); arr8->SetOwner(); for(Int_t ii=0; ii<8; ii++){ TObjArray * arr1 = new TObjArray(1); arr1->SetOwner(); arr1->SetName(GetPHQName(1, ii)); const Int_t nbins = NTRDtimebin(); TVectorD * vec = new TVectorD(nbins); for(Int_t jj=0; jjAdd(vec); arr8->Add(arr1); } AliCDBMetaData *metaData= new AliCDBMetaData(); metaData->SetObjectClassName("TObjArray"); metaData->SetResponsible("Raphaelle Bailhache and Xianguo Lu"); AliCDBId id1("TRD/Calib/PHQ", 0, 999999999); AliCDBStorage * gStorage = AliCDBManager::Instance()->GetStorage(path); gStorage->Put(arr8, id1, metaData); delete metaData; delete arr8; return kTRUE; } void AliTRDdEdxUtils::IniCalibObj() { // //set CalibObj from file, clone to static calib obj // DeleteCalibObj(); TFile *cfile=new TFile(fgCalibFile); if(!cfile->IsOpen()){ printf("AliTRDdEdxUtils::IniCalibObj error fgCalibFile not open! %s\n", fgCalibFile.Data());exit(1); } printf("\nAliTRDdEdxUtils::IniCalibObj file: %s\n", fgCalibFile.Data()); //--- const TString objnames[] ={"TRDCalibObjGain", "TRDCalibObjT0", "TRDCalibObjVd"}; TObjArray ** gobjs[]={ &fgObjGain, &fgObjT0, &fgObjVd}; const Int_t nobj = sizeof(objnames)/sizeof(TString); for(Int_t iobj=0; iobjGetObject(objnames[iobj], tmpo); if(!tmpo){ printf("AliTRDdEdxUtils::IniCalibObj error obj %s not found!\n", objnames[iobj].Data()); exit(1); } (*gobjs[iobj])=(TObjArray*)tmpo->Clone(); (*gobjs[iobj])->SetOwner(); } fgObjPHQ = new TObjArray(8); for(Int_t iter=0; iter<8; iter++){ const TString objn = GetPHQName(1, iter); TObjArray *tmpo=0x0; cfile->GetObject(objn, tmpo); if(!tmpo){ printf("AliTRDdEdxUtils::IniCalibObj error obj %s not found!\n", objn.Data()); exit(1); } TObjArray *obji=(TObjArray*) tmpo->Clone(); obji->SetOwner(); fgObjPHQ->AddAt(obji, iter); } //--- cfile->Close(); delete cfile; } void AliTRDdEdxUtils::DeleteCalibHist() { // //delete calib hist // delete fgHistGain; delete fgHistT0; delete fgHistVd; fgHistGain = 0x0; fgHistT0 = 0x0; fgHistVd = 0x0; //fgHistPHQ owns the hists fgHistPHQ->SetOwner(); fgHistPHQ->Clear(); } void AliTRDdEdxUtils::IniCalibHist(TList *list, const Bool_t kPHQonly) { // //initialize calib hist, list should not own the hist, or list->Clear/delete hist should not be called // DeleteCalibHist(); Int_t nbin[2]; const Double_t xmin[2]={0, 0}; Double_t xmax[2]; nbin[0]=NTRDtimebin(); nbin[1]= 11250; xmax[0]=nbin[0]; xmax[1]=20; for(Int_t iter=0; iter<8; iter++){ const TString hn = GetPHQName(0, iter); THnSparseD *hi = new THnSparseD(hn, "", 2, nbin, xmin, xmax); //fgHistPHQ owns the hists fgHistPHQ->AddAt(hi, iter); list->Add(hi); } if(kPHQonly) return; nbin[0]=NTRDchamber(); nbin[1]= 11250; xmax[0]=nbin[0]; xmax[1]=20; fgHistGain = new THnSparseD("TRDCalibHistGain", "", 2, nbin, xmin, xmax); nbin[0]=NTRDchamber(); nbin[1]= 11250; xmax[0]=nbin[0]; xmax[1]=AliTRDseedV1::kNtb; fgHistT0 = new THnSparseD("TRDCalibHistT0", "", 2, nbin, xmin, xmax); nbin[0]=NTRDchamber(); nbin[1]= 11250; xmax[0]=nbin[0]; xmax[1]=AliTRDseedV1::kNtb; fgHistVd = new THnSparseD("TRDCalibHistVd", "", 2, nbin, xmin, xmax); list->Add(fgHistGain); list->Add(fgHistT0); list->Add(fgHistVd); } Bool_t AliTRDdEdxUtils::ReadCalibHist(const TString filename, const TString listname) { // //used in AliTRDPreprocessorOffline //read in calib hist from file, only for PHQ // DeleteCalibHist(); //maybe already open by others... don't close TFile fcalib(filename); TObjArray * array = (TObjArray*)fcalib.Get(listname); for(Int_t iter=0; iter<8; iter++){ const TString hn = GetPHQName(0, iter); THnSparseD * tmph=0x0; if(array){ tmph = (THnSparseD *) array->FindObject(hn); } else{ tmph = (THnSparseD *) fcalib.Get(hn); } if(!tmph){ printf("AliTRDdEdxUtils::ReadCalibHist warning calib hist not found! %s %s\n", filename.Data(), listname.Data()); fcalib.ls(); array->ls(); return kFALSE; } THnSparseD *hi = (THnSparseD*)tmph->Clone(); fgHistPHQ->AddAt(hi, iter); } return kTRUE; } void AliTRDdEdxUtils::FillCalibHist(const Int_t ncls, const TVectorD *arrayQ, const TVectorD *arrayX, THnSparseD * hcalib, const Double_t scale) { // //fill calibration hist // if(!hcalib){printf("AliTRDdEdxUtils::FillCalibHist errro hcalib null!!\n"); exit(1);} for(Int_t ii=0; iiGetAxis(1)->GetXmax() -0.5 * hcalib->GetAxis(1)->GetBinWidth(1); const Double_t xmin = hcalib->GetAxis(0)->GetXmin(); const Double_t xmax = hcalib->GetAxis(0)->GetXmax(); if(xx>=xmax || xxGetName(), xx, xmin, xmax); exit(1); } const Double_t var[]={xx, TMath::Min(dq, qmax)/scale}; hcalib->Fill(var); } } void AliTRDdEdxUtils::FillCalibHist(const AliTRDtrackV1 *trdv1, const Bool_t kinvq, const Double_t mag, const Int_t charge, const Double_t scale) { // //get cluster Q and fill calib hist, if kinvq = kTRUE, 1/Q is filled // THnSparseD * hcalib = AliTRDdEdxUtils::GetHistPHQ(kinvq, mag, charge); TVectorD arrayQ(200), arrayX(200); const Int_t ncls = AliTRDdEdxUtils::GetArrayClusterQ(kinvq, &arrayQ, &arrayX, trdv1); FillCalibHist(ncls, &arrayQ, &arrayX, hcalib, kinvq ? 1/scale : scale); static Int_t kprint = 100; if(kprint<0){ printf("\nAliTRDdEdxUtils::FillCalibHist summary: \n"); printf("\nkinvq= %d;\n", kinvq); for(Int_t iq=0; iqGetNrows()); TVectorD tmpx(arrayX->GetNrows()); Int_t ncls = 0; const TVectorD * gain = (TVectorD*) cobj->At(0); for(Int_t ii=0; iiSetOwner(); for(Int_t ii=0; iiAdd(new TVectorD(AliTRDseedV1::kNtb)); } //ibin = binlowedge of bin(ibin+1) = the number fills this bin for(Int_t ibin=0; ibinGetNbinsX(); ibin++){ const Double_t stat = hnor->GetBinContent(ibin+1); if(statAt(idet); (*vec)[itb] = stat; } hmean = new TH1D(Form("%sdetmean", hnor->GetName()), "", hnor->GetNbinsX(), hnor->GetXaxis()->GetXmin(), hnor->GetXaxis()->GetXmax()); for(Int_t ibin=0; ibinGetNbinsX(); ibin++){ const Int_t idet = ToDetector(ibin); const TVectorD *vec=(TVectorD *)obj->At(idet); Int_t nonzero = 0; for(Int_t ii=0; iiGetNrows(); ii++){ if((*vec)[ii]>EPSILON){ nonzero++; } } Double_t mean = 0; const Double_t lowfrac = 0.6; //if there are too many 0's, reject this chamber by settig mean=rms=0 if(nonzero> (AliTRDseedV1::kNtb*(1-lowfrac)) ){ //only highest (1-lowfrac)*31 timebins are used to estimate the mean and rms! important! otherwise the 0' will make rms very large! mean = TruncatedMean(AliTRDseedV1::kNtb, vec->GetMatrixArray(), lowfrac, 1); } hmean->SetBinContent(ibin+1, mean); } delete obj; } void AliTRDdEdxUtils::CalibOutput(const TList *lin, Int_t run) { // //produce calibration objects // TString objnames("TRDCalibHistGain TRDCalibHistT0 TRDCalibHistVd "); for(Int_t iter=0; iter<8; iter++){ objnames+= GetPHQName(0, iter)+" "; } TList * lout = new TList; lout->SetOwner(); TTreeSRedirector *calibStream = new TTreeSRedirector(Form("TRDCalibStream_%010d.root", run)); const Int_t nh=lin->GetEntries(); for(Int_t ii=0; iiAt(ii); const TString hname = hh->GetName(); if(!objnames.Contains(hname)) continue; TObjArray * cobj0 = GetCalibObj(hh, run, lout, calibStream); lout->Add(cobj0); } //lout->ls(); //============================================================= //============================================================= TFile *fout=new TFile(Form("TRDCalibObj_%010d.root", run),"recreate"); fout->cd(); const Int_t nout=lout->GetEntries(); for(Int_t ii=0; iiAt(ii)->GetName(); if(oname.Contains("Obj")){ TObjArray * cobj = (TObjArray*) lout->At(ii); cobj->Write(oname, TObjArray::kSingleKey); } } fout->Save(); fout->Close(); delete fout; fout=new TFile(Form("TRDCalibList_%010d.root", run),"recreate"); fout->cd(); lin->Write(); lout->Write(); fout->Save(); fout->Close(); delete fout; delete calibStream; /* http://root.cern.ch/root/html/TH1.html When an histogram is created, a reference to it is automatically added to the list of in-memory objects for the current file or directory. This default behaviour can be changed by: h->SetDirectory(0); for the current histogram h TH1::AddDirectory(kFALSE); sets a global switch disabling the reference When the histogram is deleted, the reference to it is removed from the list of objects in memory. When a file is closed, all histograms in memory associated with this file are automatically deleted. */ delete lout; } TObjArray* AliTRDdEdxUtils::GetCalibObj(const THnSparseD *hh, Int_t run, TList *lout, TTreeSRedirector *calibStream) { // //produce calibration objects // const TString hname = hh->GetName(); const Bool_t kinvq = TString(hname(hname.First('Q')+1,1)).Atoi()&4; //---------------------------------------- // Define nbin, tag, cobj0 //---------------------------------------- Int_t nbin =-999; if(hname.Contains("Gain") || hname.Contains("T0") || hname.Contains("Vd")){ nbin = NTRDchamber(); } else if(hname.Contains("PHQ")){ nbin = NTRDtimebin(); } else{ printf("AliTRDdEdxUtils::GetCalibObj error wrong hname!! %s\n", hname.Data()); exit(1); } TString tag(hname); tag.ReplaceAll("Hist","Obj"); TObjArray * cobj0 = new TObjArray(1); cobj0->SetOwner(); cobj0->SetName(tag); cobj0->Add(new TVectorD(nbin)); //---------------------------------------- // Define lowFrac, highFrac //---------------------------------------- Double_t lowFrac = -999, highFrac = -999; if(hname.Contains("Gain") || (hname.Contains("PHQ") && !kinvq) ){ lowFrac = 0.01; highFrac = Q0Frac(); } else if(hname.Contains("PHQ") && kinvq){ lowFrac = Q1Frac(); highFrac = 0.99; } else{ lowFrac = 0.01; highFrac = 0.99; } //---------------------------------------- // Get analysis result //---------------------------------------- TH1::AddDirectory(kFALSE);//important! TH1D *hnor=0x0, *hmpv=0x0, *hres=0x0, *hwid=0x0, *htrdphmean = 0x0;//if(!lout), these have to be deleted TH2D *hpj = hh->Projection(1,0); FitSlicesY(hpj, hnor, hmpv, hwid, hres, 0, lowFrac, highFrac); if(hname.Contains("PHQ")){ GetPHCountMeanRMS(hnor, htrdphmean); if(lout){ lout->Add(htrdphmean); } } delete hpj; if(lout){ lout->Add(hnor); lout->Add(hmpv); lout->Add(hwid); lout->Add(hres); } //---------------------------------------- // Define Counter //---------------------------------------- TVectorD *countDet=0x0; TObjArray *countSSL=0x0; if(hname.Contains("PHQ") && !kinvq){ countDet=new TVectorD(540); countSSL=new TObjArray(90);//SectorStackLayer countSSL->SetOwner(); for(Int_t ii=0; ii<90; ii++){ countSSL->Add(new TVectorD(6)); } } //---------------------------------------- // Fill cobj0 //---------------------------------------- //ibin = binlowedge of bin(ibin+1) = the number fills this bin for(Int_t ibin=0; ibinGetBinContent(ibin+1); Double_t gmpv = hmpv->GetBinContent(ibin+1); Double_t gwid = hwid->GetBinContent(ibin+1); Double_t gres = hres->GetBinContent(ibin+1); //--- set additional cut by kpass Bool_t kpass = kTRUE; Double_t gtrdphmean = -999; if(htrdphmean){ gtrdphmean = htrdphmean->GetBinContent(ibin+1); //chamber no statistics (e.g. too many 0's), not usual, not seen in run 143237 if(gtrdphmeannstart && ntot<=nstop) is skipped; //2)TruncatedMean(hist) out of range (only for Q0, not Q1). if(gmpv>EPSILON && kpass){ if(tag.Contains("T0")){ p0 = gmpv; } else{ p0 = 1/gmpv; } //printf("outcalibobj%s %d %15.6e\n", tag.Data(), ibin, p0); } (*( (TVectorD*)cobj0->At(0) ))[ibin] = p0; //--- save optional record if(p0>EPSILON && countDet && countSSL){ const Int_t idet = ToDetector(ibin); (*countDet)[idet]=1; const Int_t isector = ToSector(ibin); const Int_t istack = ToStack(ibin); const Int_t ilayer = ToLayer(ibin); TVectorD * vecsectorstack = (TVectorD*)countSSL->At(istack*18+isector); (*vecsectorstack)[ilayer]=1; } if(calibStream){ (*calibStream)<At(ii); const Int_t nlayer = (Int_t)vecsectorstack->Sum(); if(nlayer==6){ count2Dstack[ii]=1; } } printf("\nAliTRDdEdxUtils::GetCalibObj Summary run: %d name: %s entries: %.0f ndetector: %03.0f n2dstack %02.0f\n\n", run, hname.Data(), hh->GetEntries(), countDet->Sum(), count2Dstack.Sum()); } //---------------------------------------- // Clean Up //---------------------------------------- TH1D **hhs[]={&hnor, &hmpv, &hwid, &hres, &htrdphmean}; const Int_t nhh=sizeof(hhs)/sizeof(TH1D**); for(Int_t ihh=0; ihh=1e3? 999 : qq) // if(ncls>1e3){ printf("AliTRDdEdxUtils::GetSignal error ncls>1e3! %d\n", ncls); exit(1); } return nch*1e6 + ncls*1e3 + (qq>=1e3? 999 : qq); } Int_t AliTRDdEdxUtils::GetNch(const Double_t signal) { // //signal = nch*1e6 + ncls*1e3 + (qq>=1e3? 999 : qq) // return Int_t(signal/1e6); } Int_t AliTRDdEdxUtils::GetNcls(const Double_t signal) { // //signal = Nch*1e6 + Ncls*1e3 + (Q>=1e3? 999 : Q) // return Int_t ( (signal-GetNch(signal)*1e6)/1e3 ); } Double_t AliTRDdEdxUtils::GetQ(const Double_t signal) { // //signal = nch*1e6 + ncls*1e3 + (qq>=1e3? 999 : qq) // return signal-GetNch(signal)*1e6 - GetNcls(signal)*1e3; } Double_t AliTRDdEdxUtils::ToyCook(const Bool_t kinvq, Int_t &ncluster, TVectorD *arrayQ, TVectorD *arrayX, const TObjArray *cobj) { // //template for cookdedx // if(cobj){ if(arrayQ && arrayX){ ncluster = ApplyCalib(ncluster, arrayQ, arrayX, cobj); } else{ printf("AliTRDdEdxUtils::ToyCook arrayQ arrayX null, applycalib can not be applied!\n"); exit(1); } } Double_t lowFrac =-999, highFrac = -999; if(kinvq){ lowFrac = Q1Frac(); highFrac = 0.99; } else{ lowFrac = 0.01; highFrac = Q0Frac(); } Double_t meanQ = TruncatedMean(ncluster, arrayQ->GetMatrixArray(), lowFrac, highFrac); if(kinvq){ if(meanQ>EPSILON){ meanQ = 1/meanQ; } } return meanQ; } Double_t AliTRDdEdxUtils::CombineddEdx(const Bool_t kinvq, Int_t &concls, TVectorD *coarrayQ, TVectorD *coarrayX, const Int_t tpcncls, const TVectorD *tpcarrayQ, const TVectorD *tpcarrayX, const Int_t trdncls, const TVectorD *trdarrayQ, const TVectorD *trdarrayX) { // //combine tpc and trd dedx // for(Int_t iq=0; iqGetYref(1)*seed->GetYref(1)+seed->GetZref(1)*seed->GetZref(1)); } Double_t AliTRDdEdxUtils::GetClusterQ(const Bool_t kinvq, const AliTRDseedV1 * seed, const Int_t itb) { // //get cluster charge // Double_t dq = 0; const AliTRDcluster *cl = 0x0; cl = seed->GetClusters(itb); if(cl) dq+=cl->GetRawQ(); cl = seed->GetClusters(itb+AliTRDseedV1::kNtb); if(cl) dq+=cl->GetRawQ(); dq /= GetAngularCorrection(seed); dq /= 45.; if(kinvq){ if(dq>EPSILON){ dq = 1/dq; } } return dq; } Int_t AliTRDdEdxUtils::GetArrayClusterQ(const Bool_t kinvq, TVectorD *arrayQ, TVectorD *arrayX, const AliTRDtrackV1 *trdtrack, Int_t timeBin0, Int_t timeBin1, Int_t tstep) { // //return nclustter //(if kinvq, return 1/q array), size of array must be larger than 31*6 // if(!arrayQ || arrayQ->GetNrows()< (AliTRDseedV1::kNtb*AliTRDtrackV1::kNplane)){ printf("AliTRDdEdxUtils::GetArrayClusterQ error arrayQ null or size too small! %d\n", arrayQ? arrayQ->GetNrows() : -999); exit(1); } if(!arrayX && arrayX->GetNrows()< (AliTRDseedV1::kNtb*AliTRDtrackV1::kNplane)){ printf("AliTRDdEdxUtils::GetArrayClusterQ error arrayX null or size too small! %d\n", arrayX? arrayX->GetNrows() : -999); exit(1); } const Int_t mintb = 0; const Int_t maxtb = AliTRDseedV1::kNtb-1; if(timeBin0maxtb) timeBin1=maxtb; if(tstep<=0) tstep=1; //============ Int_t tbN=0; Double_t tbQ[200]; Int_t tbBin[200]; for(Int_t ichamber=0; ichamber < AliTRDtrackV1::kNplane; ichamber++){ const AliTRDseedV1 * seed = trdtrack->GetTracklet(ichamber); if(!seed) continue; const Int_t det = seed->GetDetector(); for(Int_t itb=timeBin0; itb<=timeBin1; itb+=tstep){ const Double_t dq = GetClusterQ(kinvq, seed, itb); if(dqGetTracklet(ichamber); if(!seed){ printf("error seed null!!\n"); exit(1); } const Double_t rawq = (*arrayQ)[iq] * 45. * GetAngularCorrection(seed); printf("esdid=%d; chamber=%d; timebin=%d; rawq= %.3f; myq[%d]= %e;\n", trdtrack->GetESDid(), ichamber, ToTimeBin((*arrayX)[iq]), rawq, iq, (*arrayQ)[iq]); } printf("\n"); } return ncls; } Int_t AliTRDdEdxUtils::UpdateArrayX(const Int_t ncls, TVectorD* arrayX) { // //arrayX det*Ntb+itb -> itb // TVectorD countChamber(6); for(Int_t ii = 0; iiGetTracklet(ichamber); if (!seed) continue; const Int_t idet = seed->GetDetector(); //------------------------------------------------------------------------- Double_t qsum = 0, qtsum = 0, w2sum = 0; for(Int_t itb=0; itbFill(var); } if(ht0){ const Double_t var[]={idet, tbm}; ht0->Fill(var); } if(hvd){ const Double_t var[]={idet, tbr}; hvd->Fill(var); } Double_t gain = 1, t0 = 0, vd = 1; if(kcalib){ if(!fgObjGain) {printf("AliTRDdEdxUtils::SetChamberQT error Gain array null!!\n"); exit(1);} if(! fgObjT0) {printf("AliTRDdEdxUtils::SetChamberQT error T0 array null!!\n"); exit(1);} if(! fgObjVd) {printf("AliTRDdEdxUtils::SetChamberQT error Vd array null!!\n"); exit(1);} const TVectorD * gainvec = (TVectorD*) fgObjGain->At(0); gain = (*gainvec)[idet]; const TVectorD * t0vec = (TVectorD*) fgObjT0->At(0); t0 = (* t0vec)[idet]; const TVectorD * vdvec = (TVectorD*) fgObjVd->At(0); vd = (* vdvec)[idet]; } if(kprint<0){ printf("\nAliTRDdEdxUtils::CookdEdxV2\n"); printf("idet = %d;\n", idet); printf("gain = %15f; t0 = %15f; vd = %15f;\n", gain, t0, vd); printf("\n"); } qsum *= gain; tbm = (tbm-t0)*vd; if(qsum f(y) with y=log10(x) // const Double_t x2[]={TMath::Power(10, xx[0])}; return func(x2, par); } //=================================================================================== // Detector, Data and Control Constant //=================================================================================== Int_t AliTRDdEdxUtils::ToDetector(const Int_t gtb) { // //gtb = det*Ntb+itb // return gtb/AliTRDseedV1::kNtb; } Int_t AliTRDdEdxUtils::ToTimeBin(const Int_t gtb) { // //gtb = det*Ntb+itb // return gtb%AliTRDseedV1::kNtb; } Int_t AliTRDdEdxUtils::ToSector(const Int_t gtb) { // //return sector // return AliTRDgeometry::GetSector(ToDetector(gtb)); } Int_t AliTRDdEdxUtils::ToStack(const Int_t gtb) { // //return stack // return AliTRDgeometry::GetStack(ToDetector(gtb)); } Int_t AliTRDdEdxUtils::ToLayer(const Int_t gtb) { // //return layer // return AliTRDgeometry::GetLayer(ToDetector(gtb)); } TString AliTRDdEdxUtils::GetRunType(const Int_t run) { // //return run type // TString type; if(run>=121527 && run<= 126460)//LHC10d type="pp2010LHC10d"; else if(run>=126461 && run<= 130930)//LHC10e type="pp2010LHC10e"; else if(run>=136782 && run <= 139846)//LHC10h type="PbPb2010LHC10h"; else if(run>= 143224 && run<= 143237)//2011Feb type="cosmic2011Feb"; else if(run>= 150587 && run<= 154930){ type="cosmic2011MayJun"; TString runstr(Form("%d",run)); const TString listrun1kg("154601 154602 154629 154634 154636 154639 154643"); if(listrun1kg.Contains(runstr)){ type+="1kG"; } else{ type+="5kG"; } } else{ type="unknown"; } type.ToUpper(); return type; } void AliTRDdEdxUtils::PrintControl() { // //print out control variable // printf("\nAliTRDdEdxUtils::PrintControl Q0Frac %.1f, Q1Frac %.1f, TimeBinCountCut %.2f, CalibTPCnclsCut %d, IsExBOn %d\n\n", Q0Frac(), Q1Frac(), TimeBinCountCut(), CalibTPCnclsCut(), IsExBOn()); } //=================================================================================== //===================================================================================