//======================================================================= // idBlobdEdx 4 planes //======================================================================= StatusCode HTBlob::idBlobdEdx( Minerva::IDBlob *idblob, double &dEdx ) const { debug() << "CCPi0HoughTool::idBlobdEdx" << endmsg; SmartRefVector< Minerva::IDCluster > idClusters = idblob->clusters(); SmartRefVector< Minerva::IDCluster >::iterator it_clus = idClusters.begin(); TH1D *h = new TH1D ("h","h", 100,0,4500); // bin size 45mm <> 1 module dEdx = 0; Gaudi::XYZPoint vert = idblob->startPoint(); double x, z, distance, vt_x, vt_u, vt_v, vt_z; // event vertex per view vt_x = vert.x(); vt_u = -vert.y()*sqrt(3)/2 + vert.x()*.5; // -ycos30 + xsin30 vt_v = vert.y()*sqrt(3)/2 + vert.x()*.5; // ycos30 + xsin30 vt_z = vert.z(); for ( ; it_clus != idClusters.end(); it_clus++ ){ x = vt_x - (*it_clus)->position(); z = vt_z - (*it_clus)->z(); if ( (*it_clus)->view() == Minerva::IDCluster::U ){ x = vt_u - (*it_clus)->position(); z = vt_z - (*it_clus)->z(); } if ( (*it_clus)->view() == Minerva::IDCluster::V ){ x = vt_v - (*it_clus)->position(); z = vt_z - (*it_clus)->z(); } distance = sqrt( pow(x,2) + pow(z,2) ); h->Fill(distance, (*it_clus)->energy()); } // dEdx calculation, maybe not clear int binmin = h->FindFirstBinAbove(); int binmax = (h->FindLastBinAbove()-m_planesdEdx/2); for ( int i = binmin; i <= binmax; i++ ){ if ( FinddEdxPlanes(h, i, dEdx) ) break; dEdx = 0; } if ( dEdx == 0 ) dEdx = -999; else dEdx = dEdx/m_planesdEdx; info () << " dEdx = " << dEdx << " number planes " << m_planesdEdx << endmsg; delete h; return StatusCode::SUCCESS; }
//___________________________________________________________________ Int_t studyBinZero(TString pathData, TString fileNameData, TString listName = "", Double_t etaLow = -0.9, Double_t etaUp = 0.9, Double_t lowerCentrality = -2, Double_t upperCentrality = -2) { PrintSettingsAxisRangeForMultiplicityAxisForMB(); TString pathNameData = Form("%s/%s", pathData.Data(), fileNameData.Data()); if (listName == "") { listName = pathNameData; listName.Replace(0, listName.Last('/') + 1, ""); listName.ReplaceAll(".root", ""); } TObjArray* histList = 0x0; TFile* f = TFile::Open(pathNameData.Data()); if (!f) { std::cout << std::endl; std::cout << "Failed to open file \"" << pathNameData.Data() << "\"!" << std::endl; return -1; } histList = (TObjArray*)(f->Get(listName.Data())); if (!histList) { std::cout << std::endl; std::cout << "Failed to load list \"" << listName.Data() << "\"!" << std::endl; return -1; } // Extract the data histograms TH1* hNumEventsTriggerSel = dynamic_cast<TH1*>(histList->FindObject("fhEventsTriggerSel")); TH1* hNumEventsTriggerSelVtxCut = dynamic_cast<TH1*>(histList->FindObject("fhEventsTriggerSelVtxCut")); TH1* hNumEventsTriggerSelVtxCutZ= dynamic_cast<TH1*>(histList->FindObject("fhEventsProcessedNoPileUpRejection")); TH1* hNumEventsTriggerSelVtxCutZPileUpRej= dynamic_cast<TH1*>(histList->FindObject("fhEventsProcessed")); THnSparse* hDataTriggerSel = dynamic_cast<THnSparse*>(histList->FindObject("fChargedGenPrimariesTriggerSel")); THnSparse* hDataTriggerSelVtxCut = dynamic_cast<THnSparse*>(histList->FindObject("fChargedGenPrimariesTriggerSelVtxCut")); THnSparse* hDataTriggerSelVtxCutZ = dynamic_cast<THnSparse*>(histList->FindObject("fChargedGenPrimariesTriggerSelVtxCutZ")); THnSparse* hDataTriggerSelVtxCutZPileUpRej = dynamic_cast<THnSparse*>(histList->FindObject("fChargedGenPrimariesTriggerSelVtxCutZPileUpRej")); setSparseErrors(hDataTriggerSel); setSparseErrors(hDataTriggerSelVtxCut); setSparseErrors(hDataTriggerSelVtxCutZ); setSparseErrors(hDataTriggerSelVtxCutZPileUpRej); // Set multiplicity range, if desired. Note that mult and pT axes are the same for all histos Int_t lowerCentralityBinLimit = -1; Int_t upperCentralityBinLimit = -2; Bool_t restrictCentralityAxis = kFALSE; Double_t actualLowerCentrality = -1.; Double_t actualUpperCentrality = -1.; if (lowerCentrality >= -1 && upperCentrality >= -1) { // Add subtract a very small number to avoid problems with values right on the border between to bins lowerCentralityBinLimit = hNumEventsTriggerSel->GetXaxis()->FindFixBin(lowerCentrality + 0.001); upperCentralityBinLimit = hNumEventsTriggerSel->GetXaxis()->FindFixBin(upperCentrality - 0.001); // Check if the values look reasonable if (lowerCentralityBinLimit <= upperCentralityBinLimit && lowerCentralityBinLimit >= 1 && upperCentralityBinLimit <= hNumEventsTriggerSel->GetXaxis()->GetNbins()) { actualLowerCentrality = hNumEventsTriggerSel->GetXaxis()->GetBinLowEdge(lowerCentralityBinLimit); actualUpperCentrality = hNumEventsTriggerSel->GetXaxis()->GetBinUpEdge(upperCentralityBinLimit); restrictCentralityAxis = kTRUE; } else { std::cout << std::endl; std::cout << "Requested centrality range out of limits or upper and lower limit are switched!" << std::endl; return -1; } } if (!restrictCentralityAxis) GetAxisRangeForMultiplicityAxisForMB(hNumEventsTriggerSel->GetXaxis(), lowerCentralityBinLimit, upperCentralityBinLimit); hNumEventsTriggerSel->GetXaxis()->SetRange(lowerCentralityBinLimit, upperCentralityBinLimit); actualLowerCentrality = hNumEventsTriggerSel->GetXaxis()->GetBinLowEdge(hNumEventsTriggerSel->GetXaxis()->GetFirst()); actualUpperCentrality = hNumEventsTriggerSel->GetXaxis()->GetBinUpEdge(hNumEventsTriggerSel->GetXaxis()->GetLast()); std::cout << "centrality: "; if (restrictCentralityAxis) { std::cout << actualLowerCentrality << " - " << actualUpperCentrality << std::endl; std::cout << "WARNING: Does it really make sense to restrict the centrality? Usually, centrality estimators imply centrality >= 0!" << std::endl; } else std::cout << "MB (" << actualLowerCentrality << " - " << actualUpperCentrality << ")" << std::endl; if (restrictCentralityAxis) { hDataTriggerSel->GetAxis(iMult)->SetRange(lowerCentralityBinLimit, upperCentralityBinLimit); hDataTriggerSelVtxCut->GetAxis(iMult)->SetRange(lowerCentralityBinLimit, upperCentralityBinLimit); hDataTriggerSelVtxCutZ->GetAxis(iMult)->SetRange(lowerCentralityBinLimit, upperCentralityBinLimit); hDataTriggerSelVtxCutZPileUpRej->GetAxis(iMult)->SetRange(lowerCentralityBinLimit, upperCentralityBinLimit); } // Restrict eta range const Int_t lowerEtaBinLimit = hDataTriggerSel->GetAxis(iEta)->FindFixBin(etaLow + 0.0001); const Int_t upperEtaBinLimit = hDataTriggerSel->GetAxis(iEta)->FindFixBin(etaUp - 0.0001); const Double_t actualLowerEta = hDataTriggerSel->GetAxis(iEta)->GetBinLowEdge(lowerEtaBinLimit); const Double_t actualUpperEta = hDataTriggerSel->GetAxis(iEta)->GetBinUpEdge(upperEtaBinLimit); std::cout << "Eta: "; std::cout << actualLowerEta << " - " << actualUpperEta << std::endl; Bool_t symmetricInEta = TMath::Abs(TMath::Abs(actualLowerEta) - TMath::Abs(actualUpperEta)) < 1e-6; TString etaRange = symmetricInEta ? Form("|#it{#eta}| < %.1f", TMath::Abs(actualLowerEta)) : Form("%.1f < #it{#eta} < %.1f", actualLowerEta, actualUpperEta); hDataTriggerSel->GetAxis(iEta)->SetRange(lowerEtaBinLimit, upperEtaBinLimit); hDataTriggerSelVtxCut->GetAxis(iEta)->SetRange(lowerEtaBinLimit, upperEtaBinLimit); hDataTriggerSelVtxCutZ->GetAxis(iEta)->SetRange(lowerEtaBinLimit, upperEtaBinLimit); hDataTriggerSelVtxCutZPileUpRej->GetAxis(iEta)->SetRange(lowerEtaBinLimit, upperEtaBinLimit); // Obtain number of events for each class // Note: Under- and overflow automatically taken into account for unrestricted axis by using -1 and -2 for limits const Double_t numEvtsTriggerSel = hNumEventsTriggerSel->Integral(lowerCentralityBinLimit, upperCentralityBinLimit); const Double_t numEvtsTriggerSelVtxCut = hNumEventsTriggerSelVtxCut->Integral(lowerCentralityBinLimit, upperCentralityBinLimit); const Double_t numEvtsTriggerSelVtxCutZ = hNumEventsTriggerSelVtxCutZ->Integral(lowerCentralityBinLimit, upperCentralityBinLimit); const Double_t numEvtsTriggerSelVtxCutZPileUpRej = hNumEventsTriggerSelVtxCutZPileUpRej->Integral(lowerCentralityBinLimit, upperCentralityBinLimit); // Project pT spectra TH1D* hSpectraTriggerSel = (TH1D*)hDataTriggerSel->Projection(iPt, "e"); TH1D* hSpectraTriggerSelVtxCut = (TH1D*)hDataTriggerSelVtxCut->Projection(iPt, "e"); TH1D* hSpectraTriggerSelVtxCutZ = (TH1D*)hDataTriggerSelVtxCutZ->Projection(iPt, "e"); TH1D* hSpectraTriggerSelVtxCutZPileUpRej = (TH1D*)hDataTriggerSelVtxCutZPileUpRej->Projection(iPt, "e"); // Normalise histos to 1/Nevt dN/dPt normaliseHist(hSpectraTriggerSel, numEvtsTriggerSel); normaliseHist(hSpectraTriggerSelVtxCut, numEvtsTriggerSelVtxCut); normaliseHist(hSpectraTriggerSelVtxCutZ, numEvtsTriggerSelVtxCutZ); normaliseHist(hSpectraTriggerSelVtxCutZPileUpRej, numEvtsTriggerSelVtxCutZPileUpRej); setupHist(hSpectraTriggerSel, kBlack, "Trigger selection"); setupHist(hSpectraTriggerSelVtxCut, kRed, "& vertex cut"); setupHist(hSpectraTriggerSelVtxCutZ, kBlue, "& vertex #it{z} cut"); setupHist(hSpectraTriggerSelVtxCutZPileUpRej, kGreen, "& pile-up rejection"); TCanvas* canvSpectra = new TCanvas("canvSpectra", "Spectra", 760, 420); canvSpectra->SetLogx(); canvSpectra->SetLogy(); canvSpectra->SetGrid(0, 0); SetCanvasMargins(canvSpectra); TLegend* leg = new TLegend(0.14, 0.26, 0.62, 0.55); leg->SetHeader(Form("MC pp #sqrt{s}=7 TeV, inclusive, %s", etaRange.Data())); leg->AddEntry(hSpectraTriggerSel, "", "l"); leg->AddEntry(hSpectraTriggerSelVtxCut, "", "l"); leg->AddEntry(hSpectraTriggerSelVtxCutZ, "", "l"); if (drawPileUp) leg->AddEntry(hSpectraTriggerSelVtxCutZPileUpRej, "", "l"); SetupLegend(leg); leg->SetMargin(0.15); hSpectraTriggerSel->Draw(); hSpectraTriggerSelVtxCut->Draw("same"); hSpectraTriggerSelVtxCutZ->Draw("same"); if (drawPileUp) hSpectraTriggerSelVtxCutZPileUpRej->Draw("same"); leg->Draw("same"); // Ratios (take binomial errors, since real sub-samples) TH1D* hRatioVtxCut = new TH1D(*hSpectraTriggerSelVtxCut); hRatioVtxCut->SetName("hRatioVtxCut"); setupHist(hRatioVtxCut, kBlack, "MB & vtx / MB"); hRatioVtxCut->GetYaxis()->SetTitle("1/#it{N}_{evt} d#it{N}/d#it{p}_{T}^{gen} ratio"); hRatioVtxCut->Divide(hRatioVtxCut, hSpectraTriggerSel, 1., 1., "B"); hRatioVtxCut->GetYaxis()->SetRangeUser(1.08, 1.14); // Mean ratio of spectra and of Nevt TF1* funcRatioVtxCut = new TF1("funcRatioVtxCut", "pol0", 0.15, hRatioVtxCut->GetXaxis()->GetBinUpEdge(hSpectraTriggerSelVtxCut->FindLastBinAbove(0))); funcRatioVtxCut->SetLineWidth(2); funcRatioVtxCut->SetLineColor(kRed); hRatioVtxCut->Fit(funcRatioVtxCut, "N"); const Double_t meanRatioVtxCut = funcRatioVtxCut->GetParameter(0); const Double_t ratioNevtVtxCut = numEvtsTriggerSelVtxCut > 0 ? numEvtsTriggerSel / numEvtsTriggerSelVtxCut : -1.; const Double_t doubleRatioMinusOne = meanRatioVtxCut > 0 ? (ratioNevtVtxCut / meanRatioVtxCut - 1.) : -999.; TH1D* hRatioVtxCutZ = new TH1D(*hSpectraTriggerSelVtxCutZ); hRatioVtxCutZ->SetName("hRatioVtxCutZ"); setupHist(hRatioVtxCutZ, kBlack, "MB & vtx & #it{z} vtx / MB & vtx"); hRatioVtxCutZ->GetYaxis()->SetTitle("1/#it{N}_{evt} d#it{N}/d#it{p}_{T}^{gen} ratio"); hRatioVtxCutZ->Divide(hRatioVtxCutZ, hSpectraTriggerSelVtxCut, 1., 1., "B"); hRatioVtxCutZ->GetYaxis()->SetRangeUser(0.95, 1.05); // Mean ratio of spectra and of Nevt TF1* funcRatioVtxCutZ = new TF1("funcRatioVtxCutZ", "pol0", 0.15, hRatioVtxCutZ->GetXaxis()->GetBinUpEdge(hSpectraTriggerSelVtxCutZ->FindLastBinAbove(0))); hRatioVtxCutZ->Fit(funcRatioVtxCutZ, "N"); funcRatioVtxCutZ->SetLineWidth(2); funcRatioVtxCutZ->SetLineColor(kRed); const Double_t meanRatioVtxCutZ = funcRatioVtxCutZ->GetParameter(0); const Double_t ratioNevtVtxCutZ = numEvtsTriggerSelVtxCutZ > 0 ? numEvtsTriggerSelVtxCut / numEvtsTriggerSelVtxCutZ : -1.; TH1D* hRatioPileUp = new TH1D(*hSpectraTriggerSelVtxCutZPileUpRej); hRatioPileUp->SetName("hRatioPileUp"); setupHist(hRatioPileUp, kBlack, "MB & vtx & #it{z} vtx & pile-up / MB & vtx & #it{z} vtx"); hRatioPileUp->GetYaxis()->SetTitle("1/#it{N}_{evt} d#it{N}/d#it{p}_{T}^{gen} ratio"); hRatioPileUp->Divide(hRatioPileUp, hSpectraTriggerSelVtxCutZ, 1., 1., "B"); /* TF1* funcRatioPileUp = new TF1("funcRatioPileUp", "pol0", 0.15, hRatioPileUp->GetXaxis()->GetBinUpEdge(hSpectraTriggerSelVtxCutZPileUpRej->FindLastBinAbove(0))); hRatioPileUp->Fit(funcRatioPileUp, "N");*/ ClearTitleFromHistoInCanvas(canvSpectra); TCanvas* canvRatioVtx = new TCanvas("canvRatioVtx", "Ratio vertex", 760, 420); canvRatioVtx->SetLogx(); canvRatioVtx->SetGrid(0, 1); SetCanvasMargins(canvRatioVtx); hRatioVtxCut->Draw(); funcRatioVtxCut->Draw("same"); TLegend* leg2 = new TLegend(0.22, 0.7, drawPileUp ? 0.87 : 0.72, 0.9); leg2->SetHeader(Form("MC pp #sqrt{s}=7 TeV, inclusive, %s", etaRange.Data())); leg2->AddEntry(hRatioVtxCut, "", "l"); SetupLegend(leg2); leg2->SetMargin(0.1); leg2->Draw("same"); ClearTitleFromHistoInCanvas(canvRatioVtx); TCanvas* canvRatioOther = new TCanvas("canvRatioOther", "Ratio others", 760, 420); canvRatioOther->SetLogx(); canvRatioOther->SetGrid(0, 1); SetCanvasMargins(canvRatioOther); hRatioVtxCutZ->Draw(); if (drawPileUp) hRatioPileUp->Draw("same"); TLegend* leg3 = new TLegend(0.22, drawPileUp ? 0.63 : 0.7, drawPileUp ? 0.87 : 0.72, 0.9); leg3->SetHeader(Form("MC pp #sqrt{s}=7 TeV, inclusive, %s", etaRange.Data())); leg3->AddEntry(hRatioVtxCutZ, "", "l"); if (drawPileUp) leg3->AddEntry(hRatioPileUp, "", "l"); SetupLegend(leg3); leg3->SetMargin(0.1); leg3->Draw("same"); ClearTitleFromHistoInCanvas(canvRatioOther); printf("meanRatioVtxCut %f <-> ratioNevtVtxCut %f => meanRatioVtxCutZ/ratioNevtVtxCutZ - 1 = %f\nmeanRatioVtxCutZ %f <-> ratioNevtVtxCutZ %f\n", meanRatioVtxCut, ratioNevtVtxCut, doubleRatioMinusOne, meanRatioVtxCutZ, ratioNevtVtxCutZ); TNamed* settings = new TNamed( Form("Settings: Data file \"%s\", lowerEta %.2f, uppEta %.2f, lowerCentrality %.3f, upperCentrality %.3f, doubleRatioMinusOne %.4f\n", pathNameData.Data(), etaLow, etaUp, lowerCentrality, upperCentrality, doubleRatioMinusOne), ""); // Save results to file TString saveFileName = pathNameData; saveFileName = Form("%s_binZeroStudy.root", saveFileName.ReplaceAll(".root", "").Data()); TFile *saveFile = TFile::Open(saveFileName.Data(), "RECREATE"); saveFile->cd(); hSpectraTriggerSel->Write(); hSpectraTriggerSelVtxCut->Write(); hSpectraTriggerSelVtxCutZ->Write(); hSpectraTriggerSelVtxCutZPileUpRej->Write(); hRatioVtxCut->Write(); hRatioVtxCutZ->Write(); hRatioPileUp->Write(); funcRatioVtxCut->Write(); funcRatioVtxCutZ->Write(); canvSpectra->Write(); canvRatioVtx->Write(); canvRatioOther->Write(); settings->Write(); saveFile->Close(); TString temp = saveFileName; canvRatioVtx->SaveAs(Form("%s", temp.ReplaceAll(".root", "_ratioVtx.pdf").Data())); temp = saveFileName; canvRatioOther->SaveAs(Form("%s", temp.ReplaceAll(".root", "_ratioOther.pdf").Data())); PrintSettingsAxisRangeForMultiplicityAxisForMB(); return 0; }
void DetermineAnchorsPP(const Char_t* inputDir, TString lPeriodName = "LHC18f", Int_t runNo, const Char_t* chunkName = "", Bool_t automaticMode=kFALSE) { // // In automatic mode the function does not request any standard input and creates anchor points if the fit was ok // using the anchor value determined automatically. // One must check the QA plots for individual run to make sure the automatic values are fine and eventually run this // function again in manual mode. // Bool_t lUseDefaultAnchorPercentile = kFALSE; Double_t lDefaultAnchorPercentile = 0.10; Double_t lMinimumAnchorPercentile = 0.05; // open minimum bias OADB file TString lOADBfile = Form("OADB-%s-MB.root", lPeriodName.Data()); cout << "Opening minimum bias info ... " << endl; TFile *foadb = new TFile( lOADBfile.Data(), "READ" ); AliOADBContainer *lOADBcontainer = (AliOADBContainer*)foadb->Get("MultSel"); // set percentile boundaries for the estimator histos // (based on what is implemented in the calibration) Double_t lDesiredBoundaries[1000]; Long_t lNDesiredBoundaries=0; lDesiredBoundaries[0] = 0.0; //From High To Low Multiplicity for( Int_t ib = 1; ib < 101; ib++) { // 100 bins ] 0.0 , 0.1 ] lNDesiredBoundaries++; lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries-1] + 0.01; } for( Int_t ib = 1; ib < 91; ib++) { // 90 bins ] 1.0 , 10. ] lNDesiredBoundaries++; lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries-1] + 0.1; } for( Int_t ib = 1; ib < 91; ib++) { // 90 bins ] 10.0 , 100.0 ] lNDesiredBoundaries++; lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries-1] + 1.0; } FILE *fap = 0x0; // auxiliary objects TLegend *legEstimator = 0x0; // TLine *anchorLine = new TLine(); anchorLine->SetLineStyle(2); // TLatex *latex = new TLatex(); latex->SetTextFont(42); latex->SetTextSize(0.025); // constant function for the scaling factor determination TF1 *fpol0 = new TF1("fpol0", "[0]", 0.005, lMinimumAnchorPercentile); fpol0->SetLineStyle(3); fpol0->SetLineWidth(1); fpol0->SetLineColor(kBlack); TF1 *fpol0_hi = (TF1*)fpol0->Clone("fpol0_hi"); TF1 *fpol0_lo = (TF1*)fpol0->Clone("fpol0_lo"); // Int_t npar = 3; TF1 *fturnon = new TF1("fturnon", func_turnon, 0., 1., npar); fturnon->SetParameters(1., 0.1, -1.); fturnon->SetParLimits(1, lMinimumAnchorPercentile, 1.0); fturnon->SetParLimits(2, -1.e15, 0.); fturnon->SetLineColor(1); // open input AnalysisResults.root file for the VHM sample TString fileIdentifier = Form("%d", runNo); if(chunkName[0]!='\0') fileIdentifier = chunkName; TFile *fin = TFile::Open(Form("%s/AnalysisResults_%s.root", inputDir, fileIdentifier.Data()), "READ"); TTree *treeEvent = (TTree*)fin->Get("MultSelection/fTreeEvent"); cout << " - run number....................: " << runNo << endl; // define estimator histo for this run TH1D* hEstimator = new TH1D(Form("hEstimator_%d", runNo), "", lNDesiredBoundaries, lDesiredBoundaries); hEstimator->Sumw2(); hEstimator->GetXaxis()->SetTitle("V0M Percentile"); hEstimator->GetYaxis()->SetTitle("Counts"); hEstimator->SetStats(0); hEstimator->SetLineColor(kRed); // get corresponding calibration histogram from OADB AliOADBMultSelection* lOADB = (AliOADBMultSelection*)lOADBcontainer->GetObject( runNo, "Default" ); if( (Int_t)lOADBcontainer->GetIndexForRun( runNo )<0 ) { cout << " ---> Warning: no calibration histo found for this run - skipping..." << endl; return; } // set the pointer to the calib histo for this run hCalib = (TH1D*)lOADB->GetCalibHisto( "hCalib_V0M" );; // Double_t nall = treeEvent->Draw(Form("get_percentile(fAmplitude_V0A+fAmplitude_V0C)>>hEstimator_%d", runNo), Form("fRunNumber==%d && fEvSel_Triggered && fEvSel_IsNotPileupInMultBins && fEvSel_PassesTrackletVsCluster && fEvSel_INELgtZERO && fEvSel_HasNoInconsistentVertices && TMath::Abs(fEvSel_VtxZ)<=10.0 && isSelectedHM(fEvSel_TriggerMask)", runNo), "goff"); hEstimator->Scale(1., "width"); Double_t nevents = (Double_t)hEstimator->GetEntries(); cout << " - number of events (selected)...: " << nevents << endl; // draw histogram TCanvas *cEstimator = new TCanvas(Form("cEstimator_%d", runNo), "Estimator Distribution", 10, 10, 1000, 750); cEstimator->SetRightMargin(0.05); cEstimator->SetTopMargin(0.11); hEstimator->GetXaxis()->SetRangeUser(0., 0.2); hEstimator->Draw("hist e0"); latex->SetNDC(); latex->SetTextSize(0.06); latex->DrawLatex(0.1, 0.93, Form("Run: %d", runNo)); // first, fit a pol0 in the flat region (usually up to 0.05) hEstimator->Fit(fpol0, "RQ0"); Double_t flat_top = fpol0->GetParameter(0); // get standard deviantion of bin contents in the flat region Double_t flat_top_stdev = 0.; for(Int_t ibin=1; ibin<=hEstimator->FindBin(lMinimumAnchorPercentile); ++ibin) { Double_t content = hEstimator->GetBinContent(ibin); Double_t width = hEstimator->GetBinWidth(ibin); flat_top_stdev += TMath::Power((content-flat_top), 2.)*width; } flat_top_stdev = TMath::Sqrt(flat_top_stdev/lMinimumAnchorPercentile) / 2.; fpol0_hi->SetParameter(0, flat_top+flat_top_stdev); fpol0_lo->SetParameter(0, flat_top-flat_top_stdev); // now, fix the constant parameter in the turnon function fturnon->SetParameters(1., 0.1, -1.); fturnon->FixParameter(0, flat_top); // get the maximum range to perform the fit Double_t range_max = (hEstimator->GetBinLowEdge(hEstimator->FindLastBinAbove())) / 1.8; fturnon->SetRange(0.005, (range_max>0.1) ? range_max : 0.1); // get anchor percentile Double_t anchor_percentile = -1.; TString fitstatus = ""; if(nevents>0) { TFitResultPtr fitr = hEstimator->Fit(fturnon, "RQM"); fturnon->Draw("lsame"); fitstatus = gMinuit->fCstatu; } cEstimator->Flush(); cEstimator->Update(); cout << " - fit status....................: " << fitstatus << endl; if( !fitstatus.Contains("OK") ) { if(gROOT->IsBatch()) { cout << " ---> Warning: fit failed! -- skipping this run..." << endl; if(!automaticMode) { fap = fopen(Form("temp/anchors/Anchor_%s_%d_VHM.txt", lPeriodName.Data(), runNo), "w"); fprintf(fap, "%d %d %.2lf %lf\n", runNo, runNo, -1., -1.); } return; } if(!automaticMode) { cout << " - Please, provide an anchor percentile to continue: " << endl; cout << " (entering a negative value will skip this run)" << endl; cout << " >>>> anchor percentile: "; cin >> anchor_percentile; if(anchor_percentile<0.) { cout << " ---> Warning: percentile provided is negative -- skipping this run..." << endl; fap = fopen(Form("temp/anchors/Anchor_%s_%d_VHM.txt", lPeriodName.Data(), runNo), "w"); fprintf(fap, "%d %d %.2lf %lf\n", runNo, runNo, -1., -1.); return; } } else return; // in automatic mode we do not create an anchor file