19 #include <TStopwatch.h> 20 #include <TParameter.h> 42 fUsePhiAcceptance(kPhiCorrectNch),
56 fRecalculatePhi(false),
68 DGUARD(
fDebug, 3,
"Default CTOR of FMD density calculator");
109 DGUARD(
fDebug, 3,
"Named CTOR of FMD density calculator: %s", title);
116 fWeightedSum =
new TH1D(
"weightedSum",
"Weighted sum of Landau propability",
119 fWeightedSum->SetXTitle(
"#sum_{i} i a_{i} f_{i}(#Delta)");
133 fLowCuts =
new TH2D(
"lowCuts",
"Low cuts used", 1, 0, 1, 1, 0, 1);
178 DGUARD(
fDebug, 3,
"Copy CTOR of FMD density calculator");
207 DGUARD(
fDebug, 3,
"Assignment of FMD density calculator");
208 if (&o ==
this)
return *
this;
209 TNamed::operator=(o);
259 while ((o = static_cast<RingHistos*>(next()))) {
282 case 1: idx = 0;
break;
283 case 2: idx = 1 + (r ==
'I' || r ==
'i' ? 0 : 1);
break;
284 case 3: idx = 3 + (r ==
'I' || r ==
'i' ? 0 : 1);
break;
287 AliWarning(Form(
"Index %d of FMD%d%c out of range", idx, d, r));
298 if (xbin < 1 && xbin > h->GetXaxis()->GetNbins())
return ret;
301 case 1: ybin = 1;
break;
302 case 2: ybin = (r==
'i' || r==
'I') ? 2 : 3;
break;
303 case 3: ybin = (r==
'i' || r==
'I') ? 4 : 5;
break;
306 ret = h->GetBinContent(xbin,ybin);
324 return Rng2Cut(d, r, ieta,
fLowCuts);
342 return Rng2Cut(d, r, ieta,
fLowCuts);
347 # define START_TIMER(T) if (fDoTiming) T.Start(true) 348 # define GET_TIMER(T,V) if (fDoTiming) V = T.CpuTime() 349 # define ADD_TIMER(T,V) if (fDoTiming) V += T.CpuTime() 351 # define START_TIMER(T) do {} while (false) 352 # define GET_TIMER(T,V) do {} while (false) 353 # define ADD_TIMER(T,V) do {} while (false) 375 DGUARD(
fDebug, 1,
"Calculate density in FMD density calculator");
409 Char_t r = (q == 0 ?
'I' :
'O');
415 AliError(Form(
"No ring histogram found for FMD%d%c", d, r));
428 memset(etaCache, 0,
sizeof(
Double_t)*20*512);
429 memset(phiCache, 0,
sizeof(
Double_t)*20*512);
437 Float_t mult = fmd.Multiplicity(d,r,s,t);
438 Double_t phi = fmd.Phi(d,r,s,t) * TMath::DegToRad();
447 TMath::Abs(eta) < 1) {
448 AliWarningF(
"FMD%d%c[%2d,%3d] (%f,%f,%f) eta=%f phi=%f (%f)",
449 d, r, s, t, ip.X(), ip.Y(), ip.Z(), eta,
454 DMSG(
fDebug, 10,
"IP(x,y,z)=%f,%f,%f Eta=%f -> %f Phi=%f -> %f",
455 ip.X(), ip.Y(), ip.Z(), oldEta, eta, oldPhi, phi);
459 etaCache[s*nt+t] = eta;
460 phiCache[s*nt+t] = phi;
464 if (mult == AliESDFMD::kInvalidMult) {
472 AliWarningF(
"Raw multiplicity of FMD%d%c[%02d,%03d] = %f > 20",
475 rh->
fGood->Fill(eta);
492 if (eta != AliESDFMD::kInvalidEta) cut =
GetMultCut(d, r, eta,
false);
493 else AliWarningF(
"Eta for FMD%d%c[%02d,%03d] is invalid: %f",
499 if (cut > 0 && mult > cut) n =
NParticles(mult,d,r,eta,lowFlux);
517 rh->
fCorr ->Fill(eta, c);
550 for (
Int_t i = 0; i <= h->GetNbinsX()+1; i++) {
551 for (
Int_t j = 0; j <= h->GetNbinsY()+1; j++) {
552 hclone->SetBinContent(i,j,h->GetBinContent(i,j));
553 hclone->SetBinError(i,j,h->GetBinError(i,j));
564 for (
Int_t t=0; t < poisson->GetNbinsX(); t++) {
565 for (
Int_t s=0; s < poisson->GetNbinsY(); s++) {
567 Double_t poissonV = poisson->GetBinContent(t+1,s+1);
575 h->Fill(eta,phi,poissonV);
576 rh->
fDensity->Fill(eta, phi, poissonV);
579 hclone->Fill(eta,phi,poissonV);
586 Int_t nY = h->GetNbinsY();
589 for (
Int_t ieta=1; ieta <= h->GetNbinsX(); ieta++) {
593 h->SetBinContent(ieta, nY+1, phiAcc);
594 h->SetBinError(ieta, nY+1, phiAccE);
595 Double_t eta = h->GetXaxis()->GetBinCenter(ieta);
596 rh->
fPhiAcc->Fill(eta, ip.Z(), phiAcc);
597 for (
Int_t iphi=1; iphi<= nY; iphi++) {
602 poissonV = h->GetBinContent(ieta,iphi);
603 eLossV = hclone->GetBinContent(ieta,iphi);
606 poissonV = hclone->GetBinContent(ieta,iphi);
607 eLossV = h->GetBinContent(ieta,iphi);
610 if (poissonV < 1e-12 && eLossV < 1e-12)
615 Double_t rel = eLossV < 1e-12 ? 0 : (poissonV - eLossV) / eLossV;
628 Int_t nTotal = (nIn+nOut);
659 if (eloss < 1e-6)
return true;
660 Double_t diff = TMath::Abs(poisson - eloss) / eloss;
677 DGUARD(
fDebug, 10,
"Find maximum weight in FMD density calculator");
703 DGUARD(
fDebug, 10,
"Find maximum weight in FMD density calculator");
723 DGUARD(
fDebug, 2,
"Cache maximum weights in FMD density calculator");
729 TAxis eta(axis.GetNbins(),
737 Int_t nEta = eta.GetNbins();
744 fMaxWeights->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
751 AliInfo(Form(
"Get eta axis with %d bins from %f to %f",
752 nEta, eta.GetXmin(), eta.GetXmax()));
753 fLowCuts->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
754 fLowCuts->GetYaxis()->SetBinLabel(1,
"FMD1i");
755 fLowCuts->GetYaxis()->SetBinLabel(2,
"FMD2i");
756 fLowCuts->GetYaxis()->SetBinLabel(3,
"FMD2o");
757 fLowCuts->GetYaxis()->SetBinLabel(4,
"FMD3i");
758 fLowCuts->GetYaxis()->SetBinLabel(5,
"FMD3o");
760 for (
Int_t i = 0; i < nEta; i++) {
768 for (
Int_t j = 0; j < 5; j++)
769 if (w[j] > 0)
fMaxWeights->SetBinContent(i+1, j+1, w[j]);
792 if (iEta < 0)
return -1;
801 AliWarning(Form(
"No array for FMD%d%c", d, r));
805 if (iEta >= max->fN) {
806 AliWarning(Form(
"Eta bin %3d out of bounds [0,%d]",
811 AliDebug(30,Form(
"Max weight for FMD%d%c eta bin %3d: %d", d, r, iEta,
813 return max->At(iEta);
863 DGUARD(
fDebug, 3,
"Calculate Nch in FMD density calculator");
864 if (lowFlux)
return 1;
869 AliWarning(Form(
"No energy loss fit for FMD%d%c at eta=%f qual=%d",
876 AliWarning(Form(
"No good fits for FMD%d%c at eta=%f", d, r, eta));
884 AliInfo(Form(
"FMD%d%c, eta=%7.4f, %8.5f -> %8.5f", d, r, eta, mult, ret));
920 DGUARD(
fDebug, 10,
"Apply correction in FMD density calculator");
932 Double_t dblC = dblHitCor->GetBinContent(dblHitCor->FindBin(eta));
933 if (dblC > 0) correction *= dblC;
955 DGUARD(
fDebug, 3,
"Make acceptance correction in FMD density calculator");
956 const Double_t ic1[] = { 4.9895, 15.3560 };
957 const Double_t ic2[] = { 1.8007, 17.2000 };
958 const Double_t oc1[] = { 4.2231, 26.6638 };
959 const Double_t oc2[] = { 1.8357, 27.9500 };
960 const Double_t* c1 = (r ==
'I' || r ==
'i' ? ic1 : oc1);
961 const Double_t* c2 = (r ==
'I' || r ==
'i' ? ic2 : oc2);
962 Double_t minR = (r ==
'I' || r ==
'i' ? 4.5213 : 15.4);
963 Double_t maxR = (r ==
'I' || r ==
'i' ? 17.2 : 28.0);
964 Int_t nStrips = (r ==
'I' || r ==
'i' ? 512 : 256);
965 Int_t nSec = (r ==
'I' || r ==
'i' ? 20 : 40);
966 Float_t basearc = 2 * TMath::Pi() / nSec;
968 Float_t segment = rad / nStrips;
969 Float_t cr = TMath::Sqrt(c1[0]*c1[0]+c1[1]*c1[1]);
973 Float_t D = c1[0] * c2[1] - c1[1] * c2[0];
976 Float_t dr = TMath::Sqrt(dx*dx+dy*dy);
978 TH1D* ret =
new TH1D(Form(
"acc%c", r),
979 Form(
"Acceptance correction for FMDx%c", r),
980 nStrips, -.5, nStrips-.5);
981 ret->SetXTitle(
"Strip");
982 ret->SetYTitle(
"#varphi acceptance");
983 ret->SetDirectory(0);
984 ret->SetFillColor(r ==
'I' || r ==
'i' ? kRed+1 : kBlue+1);
985 ret->SetFillStyle(3001);
987 for (
Int_t t = 0; t < nStrips; t++) {
988 Float_t radius = minR + t * segment;
993 ret->SetBinContent(t+1, 1);
1002 Float_t det = radius * radius * dr * dr - D*D;
1007 ret->SetBinContent(t+1, 1);
1012 Float_t x = (+D * dy + dx * TMath::Sqrt(det)) / dr / dr;
1013 Float_t y = (-D * dx + dy * TMath::Sqrt(det)) / dr / dr;
1014 Float_t th = TMath::ATan2(x, y);
1016 ret->SetBinContent(t+1, th / basearc);
1036 return acc->GetBinContent(t+1);
1051 DGUARD(
fDebug, 1,
"Scale histograms in FMD density calculator");
1052 if (nEvents <= 0)
return;
1053 TList* d =
static_cast<TList*
>(dir->FindObject(GetName()));
1057 out->SetName(d->GetName());
1067 THStack* sums =
new THStack(
"sums",
"sums of ring signals");
1068 while ((o = static_cast<RingHistos*>(next()))) {
1071 Warning(
"Terminate",
"No density in %s", o->
GetName());
1076 sum->Scale(1.,
"width");
1078 sum->SetDirectory(0);
1079 sum->SetYTitle(
"#sum N_{ch,incl}");
1096 DGUARD(
fDebug, 1,
"Define output FMD density calculator");
1099 d->SetName(GetName());
1110 nFiles->SetMergeMode(
'+');
1134 while ((o = static_cast<RingHistos*>(next()))) {
1141 fHTiming =
new TProfile(
"timing",
"#LTt_{part}#GT", 8, .5, 8.5);
1143 fHTiming->SetYTitle(
"#LTt_{part}#GT");
1152 xaxis->SetBinLabel(1,
"Re-calculation of #eta");
1153 xaxis->SetBinLabel(2,
"N_{particle}");
1154 xaxis->SetBinLabel(3,
"Correction");
1155 xaxis->SetBinLabel(4,
"Re-calculation of #phi");
1156 xaxis->SetBinLabel(5,
"Copy to cache");
1157 xaxis->SetBinLabel(6,
"Poisson calculation");
1158 xaxis->SetBinLabel(7,
"Diagnostics");
1159 xaxis->SetBinLabel(8,
"Total");
1162 #define PF(N,V,...) \ 1163 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__) 1164 #define PFB(N,FLAG) \ 1166 AliForwardUtil::PrintName(N); \ 1167 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \ 1169 #define PFV(N,VALUE) \ 1171 AliForwardUtil::PrintName(N); \ 1172 std::cout << (VALUE) << std::endl; } while(false) 1185 gROOT->IncreaseDirLevel();
1199 PFB(
"Use phi acceptance", phiM);
1204 PFV(
"Lower cut",
"");
1209 if (!opt.Contains(
"nomax")) {
1210 PFV(
"Max weights",
"");
1213 for (
Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] =
' ';
1214 ind[gROOT->GetDirLevel()] =
'\0';
1218 ind[gROOT->GetDirLevel()] =
' ';
1219 ind[gROOT->GetDirLevel()+1] =
'\0';
1220 Char_t r = (q == 0 ?
'I' :
'O');
1221 std::cout << ind <<
" FMD" << d << r <<
":";
1222 ind[gROOT->GetDirLevel()+1] =
' ';
1223 ind[gROOT->GetDirLevel()+2] =
'\0';
1229 for (
Int_t i = 0; i < a.fN; i++) {
1230 if (a.fArray[i] < 1)
continue;
1231 if (j % 6 == 0) std::cout <<
"\n " << ind;
1233 std::cout <<
" " << std::setw(3) << i <<
": " << a.fArray[i];
1235 std::cout << std::endl;
1239 gROOT->DecreaseDirLevel();
1254 fDiffELossPoisson(0),
1255 fELossVsPoissonOut(0),
1256 fDiffELossPoissonOut(0),
1311 fEvsN =
new TH2D(
"elossVsNnocorr",
1312 "#Delta E/#Delta E_{mip} vs uncorrected inclusive N_{ch}",
1313 250, -.5, 24.5, 251, -1.5, 24.5);
1314 fEvsN->SetXTitle(
"#Delta E/#Delta E_{mip}");
1315 fEvsN->SetYTitle(
"Inclusive N_{ch} (uncorrected)");
1317 fEvsN->SetDirectory(0);
1319 fEvsM =
static_cast<TH2D*
>(fEvsN->Clone(
"elossVsNcorr"));
1320 fEvsM->SetTitle(
"#Delta E/#Delta E_{mip} vs corrected inclusive N_{ch}");
1321 fEvsM->SetDirectory(0);
1323 fEtaVsN =
new TProfile(
"etaVsNnocorr",
1324 "Average inclusive N_{ch} vs #eta (uncorrected)",
1326 fEtaVsN->SetXTitle(
"#eta");
1327 fEtaVsN->SetYTitle(
"#LT N_{ch,incl}#GT (uncorrected)");
1328 fEtaVsN->SetDirectory(0);
1329 fEtaVsN->SetLineColor(
Color());
1330 fEtaVsN->SetFillColor(
Color());
1332 fEtaVsM =
static_cast<TProfile*
>(fEtaVsN->Clone(
"etaVsNcorr"));
1333 fEtaVsM->SetTitle(
"Average inclusive N_{ch} vs #eta (corrected)");
1334 fEtaVsM->SetYTitle(
"#LT N_{ch,incl}#GT (corrected)");
1335 fEtaVsM->SetDirectory(0);
1338 fCorr =
new TProfile(
"corr",
"Average correction", 200, -4, 6);
1339 fCorr->SetXTitle(
"#eta");
1340 fCorr->SetYTitle(
"#LT correction#GT");
1341 fCorr->SetDirectory(0);
1345 fSignal =
new TH2D(
"signal",
"Signal distribution", 200, -4, 6, 1000, 0, 10);
1350 fDensity =
new TH2D(
"inclDensity",
"Inclusive N_{ch} density",
1351 200, -4, 6, (r ==
'I' || r ==
'i' ? 20 : 40),
1356 fDensity->SetYTitle(
"#phi [radians]");
1357 fDensity->SetZTitle(
"Inclusive N_{ch} density");
1362 const char* nchP =
"N_{ch}^{Poisson}";
1363 const char* nchE =
"N_{ch}^{#Delta}";
1366 "N_{ch} from energy loss vs from Poisson",
1367 bins.GetSize()-1, bins.GetArray(),
1368 bins.GetSize()-1, bins.GetArray());
1375 ->Clone(Form(
"%sOutlier",
1385 Form(
"(%s-%s)/%s", nchP, nchE, nchE),
1405 fOutliers =
new TH1D(
"outliers",
"Fraction of outliers", 100, 0, 1);
1407 fOutliers->SetXTitle(
"N_{outlier}/(N_{outlier}+N_{inside})");
1408 fOutliers->SetYTitle(
"#sum_{events}#sum_{bins}");
1413 fELoss =
new TH1D(
"eloss",
"#Delta/#Delta_{mip} in all strips",
1415 fELoss->SetXTitle(
"#Delta/#Delta_{mip} (selected)");
1416 fELoss->SetYTitle(
"P(#Delta/#Delta_{mip})");
1418 fELoss->SetFillStyle(3003);
1419 fELoss->SetLineColor(kBlack);
1425 fELossUsed->SetTitle(
"#Delta/#Delta_{mip} in used strips");
1430 fPhiBefore =
new TH1D(
"phiBefore",
"#phi distribution (before recalc)",
1431 (r ==
'I' || r ==
'i' ? 20 : 40), 0, 2*TMath::Pi());
1442 fPhiAfter->SetTitle(
"#phi distribution (after re-calc)");
1445 fEtaBefore =
new TH1D(
"etaBefore",
"#eta distribution (before recalc)",
1457 fEtaAfter->SetTitle(
"#eta distribution (after re-calc)");
1510 if (&o ==
this)
return *
this;
1534 fCorr =
static_cast<TProfile*
>(o.
fCorr->Clone());
1570 fTotal =
new TH1D(
"total",
"Total # of strips per #eta",
1571 eAxis.GetNbins(), eAxis.GetXmin(), eAxis.GetXmax());
1573 fTotal->SetXTitle(
"#eta");
1574 fTotal->SetYTitle(
"# of strips");
1576 fGood->SetTitle(
"# of good strips per #eta");
1577 fGood->SetDirectory(0);
1579 fPhiAcc =
new TH2D(
"phiAcc",
"#phi acceptance vs Ip_{z}",
1580 eAxis.GetNbins(), eAxis.GetXmin(), eAxis.GetXmax(),
1583 fPhiAcc->SetYTitle(
"v_{z} [cm]");
1584 fPhiAcc->SetZTitle(
"#phi acceptance");
1626 x.SetTitle(
"strip");
1627 y.SetTitle(
"sector");
1649 if (density) density->Scale(1./nEvents);
Double_t GetMultCut(UShort_t d, Char_t r, Double_t eta, Bool_t errors=true) const
virtual void SetupForData(const TAxis &etaAxis)
RingHistos & operator=(const RingHistos &o)
void Print(Option_t *option="") const
void CacheMaxWeights(const TAxis &axis)
Int_t GetMaxWeight(UShort_t d, Char_t r, Int_t iEta) const
virtual void Terminate(const TList *dir, TList *output, Int_t nEvents)
const AliFMDCorrDoubleHit * GetDoubleHit() const
void Reset(const TH2D *base)
void Define(const TAxis &xaxis, const TAxis &yaxis)
UShort_t fUsePhiAcceptance
static Bool_t GetEtaPhi(UShort_t det, Char_t ring, UShort_t sec, UShort_t str, const TVector3 &ip, Double_t &eta, Double_t &phi)
const UShort_t & NStrip() const
const TAxis & GetEtaAxis() const
RingHistos & operator=(const RingHistos &o)
ELossFit * FindFit(UShort_t d, Char_t r, Double_t eta, UShort_t minQ) const
#define DMSG(L, N, F,...)
void SetLumping(UShort_t nx, UShort_t ny)
void Print(Option_t *option="R") const
const char * GetName() const
TH2D * Result(Bool_t correct=true)
void CacheBins(UShort_t minQuality=kDefaultQuality) const
TH1D * GetOccupancy() const
virtual ~AliFMDDensityCalculator()
RingHistos * GetRingHistos(UShort_t d, Char_t r) const
AliForwardUtil::Histos fCache
void Init(Int_t xLumping=-1, Int_t yLumping=-1)
void SetupForData(const TAxis &eAxis)
TH2D * fELossVsPoissonOut
AliFMDDensityCalculator & operator=(const AliFMDDensityCalculator &o)
void Output(TList *l, const char *name=0) const
Int_t FindEtaBin(Double_t eta) const
static Double_t fgMaxRelError
Cached maximum weight.
Various utilities used in PWGLF/FORWARD.
void Fill(UShort_t strip, UShort_t sec, Bool_t hit, Double_t weight=1)
Double_t nEvents
plot quality messages
virtual void CreateOutputObjects(TList *dir)
virtual Float_t NParticles(Float_t mult, UShort_t d, Char_t r, Float_t eta, Bool_t lowFlux) const
const AliFMDCorrELossFit * GetELossFit() const
static const char * fgkFolderName
#define DGUARD(L, N, F,...)
static void PrintTask(const TObject &o)
virtual Bool_t Calculate(const AliESDFMD &fmd, AliForwardUtil::Histos &hists, Bool_t lowFlux, Double_t cent=-1, const TVector3 &ip=TVector3(1024, 1024, 0))
TH2D * Get(UShort_t d, Char_t r) const
static TObject * MakeParameter(const char *name, UShort_t value)
void CreateOutputObjects(TList *dir)
virtual Float_t AcceptanceCorrection(Char_t r, UShort_t t) const
const UShort_t & NSector() const
TH1 * GetOutputHist(const TList *d, const char *name) const
void Terminate(TList *dir, Int_t nEvents)
void Init(const TAxis &etaAxis)
void FillHistogram(TH2 *h) const
TH1D * fDiffELossPoissonOut
Int_t FindMaxWeight(const AliFMDCorrELossFit *cor, UShort_t d, Char_t r, Int_t iEta) const
static void MakeLogScale(Int_t nBins, Int_t minOrder, Int_t maxOrder, TArrayD &bins)
virtual TH1D * GenerateAcceptanceCorrection(Char_t r) const
TList * DefineOutputList(TList *d) const
TH1D * GetCorrection(UShort_t d, Char_t r) const
AliFMDDensityCalculator()
Double_t EvaluateWeighted(Double_t x, UShort_t maxN=9999) const
virtual Bool_t CheckOutlier(Double_t eloss, Double_t poisson, Double_t cut=0.5) const
virtual Float_t Correction(UShort_t d, Char_t r, UShort_t t, Float_t eta, Bool_t lowFlux) const
void Print(Option_t *option="") const
static Double_t fgLeastWeight
AliPoissonCalculator fPoisson
Int_t FindMaxWeight(Double_t maxRelError=2 *fgMaxRelError, Double_t leastWeight=fgLeastWeight, UShort_t maxN=999) const
static AliForwardCorrectionManager & Instance()
TList * GetOutputList(const TList *d) const