void plotDYUnfoldingMatrix(const TString input, int systematicsMode = DYTools::NORMAL, int randomSeed = 1, double reweightFsr = 1.0, double massLimit = -1.0) //systematicsMode 0 (NORMAL) - no systematic calc //1 (RESOLUTION_STUDY) - systematic due to smearing, 2 (FSR_STUDY) - systematics due to FSR, reweighting //check mass spectra with reweightFsr = 0.95; 1.00; 1.05 //mass value until which do reweighting { // check whether it is a calculation if (input.Contains("_DebugRun_")) { std::cout << "plotDYUnfoldingMatrix: _DebugRun_ detected. Terminating the script\n"; return; } // normal calculation gBenchmark->Start("plotDYUnfoldingMatrix"); if (systematicsMode==DYTools::NORMAL) std::cout<<"Running script in the NORMAL mode"<<std::endl; else if (systematicsMode==DYTools::RESOLUTION_STUDY) std::cout<<"Running script in the RESOLUTION_STUDY mode"<<std::endl; else if (systematicsMode==DYTools::FSR_STUDY) std::cout<<"Running script in the FSR_STUDY mode"<<std::endl; else if (systematicsMode==DYTools::ESCALE_RESIDUAL) std::cout << "Running script in the ESCALE_RESIDUAL mode\n"; else { std::cout<<"requested mode not recognized"<<std::endl; assert(0); } //-------------------------------------------------------------------------------------------------------------- // Settings //============================================================================================================== Bool_t doSave = false; // save plots? TString format = "png"; // output file format int saveMadePlots = 1; // whether save produced canvases vector<TString> fnamev; // file names vector<TString> labelv; // legend label vector<Int_t> colorv; // color in plots vector<Int_t> linev; // line style vector<Double_t> xsecv; vector<Double_t> lumiv; TString dirTag; ifstream ifs; ifs.open(input.Data()); if (!ifs.is_open()) std::cout << "failed to open a file <" << input.Data() << ">\n"; assert(ifs.is_open()); string line; Int_t state=0; const int inputFileMayContainEScaleDefinition = 1; int expectEscaleLine=1; ElectronEnergyScale escale((inputFileMayContainEScaleDefinition) ? ElectronEnergyScale::UNDEFINED : // read electron energy scale from the file ElectronEnergyScale::Date20120101_default); while(getline(ifs,line)) { if(line[0]=='#') continue; if(state == 0){ dirTag = TString(line); state++; continue; }else{ if (inputFileMayContainEScaleDefinition && expectEscaleLine) { expectEscaleLine=0; // try to determine whether the input file was updated if (ElectronEnergyScale::DetermineCalibrationSet(line.c_str()) != ElectronEnergyScale::UNDEFINED) { //std::cout << "got it ok: <" << line << ">" << std::endl; escale.init(TString(line.c_str())); if (!escale.isInitialized()) { std::cout << "code error\n"; return; } // continue reading the file getline(ifs,line); } else { std::cout << "\n"; std::cout << "\n\tInput file does not contain electron energy scale. The expected file format:\n"; std::cout << "\tLine1: directory\n"; std::cout << "\tLine2: electron energy scale correction name (NEW from 2012 Jan 21)\n"; std::cout << "\tLine3: file_name.root xsect color linesty label\n"; std::cout << "using the default set\n\n"; escale.init("Date20120101_default"); if (!escale.isInitialized()) { std::cout << "failed to correct the behavior\n"; return; } } std::cout << "energy scale corrections: " << escale.calibrationSetName() << "\n"; } string fname; Int_t color, linesty; stringstream ss(line); Double_t xsec; ss >> fname >> xsec >> color >> linesty; string label = line.substr(line.find('@')+1); fnamev.push_back(fname); labelv.push_back(label); colorv.push_back(color); linev.push_back(linesty); xsecv.push_back(xsec); lumiv.push_back(0); } } ifs.close(); const Double_t kGAP_LOW = 1.4442; const Double_t kGAP_HIGH = 1.566; //-------------------------------------------------------------------------------------------------------------- // Main analysis code //============================================================================================================== TRandom random; // The random seeds are needed only if we are running this script in systematics mode int seed = randomSeed; random.SetSeed(seed); gRandom->SetSeed(seed); // In the case of systematic studies, generate an array of random offsets TVectorD shift(escale._nEtaBins); // this vector is outdated by the new features in the escale obj.class shift = 0; if(systematicsMode==DYTools::RESOLUTION_STUDY) { escale.randomizeSmearingWidth(seed); for(int i=0; i<escale._nEtaBins; i++) shift[i] = gRandom->Gaus(0,1); } // prepare tools for ESCALE_RESIDUAL TH1F *shapeWeights=NULL; if (systematicsMode==DYTools::ESCALE_RESIDUAL) { TString shapeFName=TString("../root_files/yields/") + dirTag + TString("/shape_weights.root"); std::cout << "Obtaining shape_weights.root from <" << shapeFName << ">\n"; TFile fshape(shapeFName); if (!fshape.IsOpen()) { std::cout << "failed to open a file <" << shapeFName << ">\n"; throw 2; } shapeWeights = (TH1F*)fshape.Get("weights"); shapeWeights->SetDirectory(0); dirTag += TString("_escale_residual"); std::cout << "changing dirTag to <" << dirTag << ">\n"; } // // Set up histograms // vector<TH1F*> hZMassv;//, hZMass2v, hZPtv, hZPt2v, hZyv, hZPhiv; char hname[100]; for(UInt_t ifile = 0; ifile<fnamev.size(); ifile++) { sprintf(hname,"hZMass_%i",ifile); hZMassv.push_back(new TH1F(hname,"",500,0,1500)); hZMassv[ifile]->Sumw2(); } TH1F *hMassDiff = new TH1F("hMassDiff","", 100, -30, 30); TH1F *hMassDiffBB = new TH1F("hMassDiffBB","", 100, -30, 30); TH1F *hMassDiffEB = new TH1F("hMassDiffEB","", 100, -30, 30); TH1F *hMassDiffEE = new TH1F("hMassDiffEE","", 100, -30, 30); TH1F *hMassDiffV[DYTools::nMassBins]; for(int i=0; i<DYTools::nMassBins; i++){ sprintf(hname,"hMassDiffV_%d",i); hMassDiffV[i] = new TH1F(hname,"",100,-50,50); } // MC spectra for storage in ROOT file // The FSR of RECO means that this is the spectrum of generator-level // post-FSR mass for events that were actually reconstructed (i.e. includes // efficiency and acceptances losses) TVectorD yieldsMcFsrOfRec (DYTools::nMassBins); TVectorD yieldsMcFsrOfRecErr (DYTools::nMassBins); TVectorD yieldsMcRec (DYTools::nMassBins); TVectorD yieldsMcRecErr (DYTools::nMassBins); yieldsMcFsrOfRec = 0; yieldsMcFsrOfRecErr = 0; yieldsMcRec = 0; yieldsMcRecErr = 0; // The yields at generator level with mass bins defined by post-FSR di-leptons TVectorD yieldsMcFsr (DYTools::nMassBins); yieldsMcFsr = 0; // Vectors for bin to bin corrections TVectorD DetCorrFactorNumerator (DYTools::nMassBins); TVectorD DetCorrFactorDenominator(DYTools::nMassBins); TVectorD DetCorrFactor (DYTools::nMassBins); TVectorD DetCorrFactorErrPos (DYTools::nMassBins); TVectorD DetCorrFactorErrNeg (DYTools::nMassBins); DetCorrFactorNumerator = 0; DetCorrFactorDenominator = 0; DetCorrFactor = 0; DetCorrFactorErrPos = 0; DetCorrFactorErrNeg = 0; // Matrices for unfolding TMatrixD DetMigration(DYTools::nMassBins, DYTools::nMassBins); TMatrixD DetResponse(DYTools::nMassBins, DYTools::nMassBins); TMatrixD DetResponseErrPos(DYTools::nMassBins, DYTools::nMassBins); TMatrixD DetResponseErrNeg(DYTools::nMassBins, DYTools::nMassBins); for(int i=0; i<DYTools::nMassBins; i++){ for(int j=0; j<DYTools::nMassBins; j++){ DetMigration(i,j) = 0; DetResponse(i,j) = 0; DetResponseErrPos(i,j) = 0; DetResponseErrNeg(i,j) = 0; } } // // Access samples and fill histograms // TFile *infile=0; TTree *eventTree=0; // Data structures to store info from TTrees mithep::TEventInfo *info = new mithep::TEventInfo(); mithep::TGenInfo *gen = new mithep::TGenInfo(); TClonesArray *dielectronArr = new TClonesArray("mithep::TDielectron"); // loop over samples for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) { // Read input file cout << "Processing " << fnamev[ifile] << "..." << endl; infile = new TFile(fnamev[ifile]); assert(infile); // Get the TTrees eventTree = (TTree*)infile->Get("Events"); assert(eventTree); // Find weight for events for this file // The first file in the list comes with weight 1, // all subsequent ones are normalized to xsection and luminosity double xsec=xsecv[ifile]; AdjustXSectionForSkim(infile,xsec,eventTree->GetEntries(),1); lumiv[ifile] = eventTree->GetEntries()/xsec; double scale = lumiv[0]/lumiv[ifile]; cout << " -> sample weight is " << scale << endl; // Set branch address to structures that will store the info eventTree->SetBranchAddress("Info",&info); TBranch *infoBr = eventTree->GetBranch("Info"); eventTree->SetBranchAddress("Gen",&gen); TBranch *genBr = eventTree->GetBranch("Gen"); eventTree->SetBranchAddress("Dielectron",&dielectronArr); TBranch *dielectronBr = eventTree->GetBranch("Dielectron"); // loop over events for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { //if (ientry>100000) break; genBr->GetEntry(ientry); infoBr->GetEntry(ientry); double reweight; if (systematicsMode!=DYTools::FSR_STUDY) reweight=1.0; else if (((gen->mass)-(gen->vmass))>massLimit) reweight=1.0; else reweight=reweightFsr; if (ientry<20) std::cout<<"reweight="<<reweight<<std::endl; // Use post-FSR generator level mass in unfolding int ibinFsr = DYTools::findMassBin(gen->mass); if(ibinFsr != -1 && ibinFsr < yieldsMcFsr.GetNoElements()){ yieldsMcFsr[ibinFsr] += reweight * scale * gen->weight; } /* // For EPS2011 for both data and MC (starting from Summer11 production) // we use an OR of the twi triggers below. Both are unpresecaled. ULong_t eventTriggerBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL | kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL; ULong_t leadingTriggerObjectBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL_Ele1Obj | kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele1Obj; ULong_t trailingTriggerObjectBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL_Ele2Obj | kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele2Obj; */ const bool isData=kFALSE; TriggerConstantSet constantsSet = Full2011DatasetTriggers; // Enum from TriggerSelection.hh TriggerSelection requiredTriggers(constantsSet, isData, info->runNum); ULong_t eventTriggerBit = requiredTriggers.getEventTriggerBit(info->runNum); ULong_t leadingTriggerObjectBit = requiredTriggers.getLeadingTriggerObjectBit(info->runNum); ULong_t trailingTriggerObjectBit = requiredTriggers.getTrailingTriggerObjectBit(info->runNum); if(!(info->triggerBits & eventTriggerBit)) continue; // no trigger accept? Skip to next event... // loop through dielectrons dielectronArr->Clear(); dielectronBr->GetEntry(ientry); for(Int_t i=0; i<dielectronArr->GetEntriesFast(); i++) { const mithep::TDielectron *dielectron = (mithep::TDielectron*)((*dielectronArr)[i]); // Apply selection // Eta cuts if((fabs(dielectron->scEta_1)>kGAP_LOW) && (fabs(dielectron->scEta_1)<kGAP_HIGH)) continue; if((fabs(dielectron->scEta_2)>kGAP_LOW) && (fabs(dielectron->scEta_2)<kGAP_HIGH)) continue; if((fabs(dielectron->scEta_1) > 2.5) || (fabs(dielectron->scEta_2) > 2.5)) continue; // outside eta range? Skip to next event... // Asymmetric SC Et cuts if( ! ( ( dielectron->scEt_1 > DYTools::etMinLead && dielectron->scEt_2 > DYTools::etMinTrail) || ( dielectron->scEt_1 > DYTools::etMinTrail && dielectron->scEt_2 > DYTools::etMinLead) )) continue; // Both electrons must match trigger objects. At least one ordering // must match if( ! ( (dielectron->hltMatchBits_1 & leadingTriggerObjectBit && dielectron->hltMatchBits_2 & trailingTriggerObjectBit ) || (dielectron->hltMatchBits_1 & trailingTriggerObjectBit && dielectron->hltMatchBits_2 & leadingTriggerObjectBit ) ) ) continue; // The Smurf electron ID package is the same as used in HWW analysis // and contains cuts like VBTF WP80 for pt>20, VBTF WP70 for pt<10 // with some customization, plus impact parameter cuts dz and dxy if(!passSmurf(dielectron)) continue; // We have a Z candidate! HURRAY! // Apply extra smearing to MC reconstructed dielectron mass // to better resemble the data /* outdated lines. kept for reference double smear1 = escale.extraSmearingSigma(dielectron->scEta_1); double smear2 = escale::extraSmearingSigma(dielectron->scEta_2); // In systematics mode, overwrite the smear values with // shifted ones. if(systematicsMode==DYTools::RESOLUTION_STUDY){ smear1 = escale::extraSmearingSigmaShifted(dielectron->scEta_1,shift); smear2 = escale::extraSmearingSigmaShifted(dielectron->scEta_2,shift); } double smearTotal = sqrt(smear1*smear1 + smear2*smear2); double massResmeared = dielectron->mass + random.Gaus(0.0,smearTotal); */ /* lines based on new features -- begin */ double massSmear = (systematicsMode == DYTools::RESOLUTION_STUDY) ? escale.generateMCSmearRandomized(dielectron->scEta_1,dielectron->scEta_2) : escale.generateMCSmear(dielectron->scEta_1,dielectron->scEta_2); double massResmeared = dielectron->mass + massSmear; /* lines based on new features -- end */ hZMassv[ifile]->Fill(massResmeared,scale * gen->weight); // Fill structures for response matrix and bin by bin corrections if(ibinFsr != -1 && ibinFsr < yieldsMcFsrOfRec.GetNoElements()){ yieldsMcFsrOfRec[ibinFsr] += reweight * scale * gen->weight; DetCorrFactorDenominator(ibinFsr) += reweight * scale * gen->weight; } else if(ibinFsr >= yieldsMcFsrOfRec.GetNoElements()) cout << "ERROR: binning problem" << endl; int ibinRec = DYTools::findMassBin(massResmeared); double shape_weight = (shapeWeights && (ibinRec!=-1)) ? shapeWeights->GetBinContent(ibinRec+1) : 1.0; if(ibinRec != -1 && ibinRec < yieldsMcRec.GetNoElements()){ yieldsMcRec[ibinRec] += reweight * scale * gen->weight; DetCorrFactorNumerator(ibinRec) += reweight * scale * gen->weight * shape_weight; } else if(ibinRec >= yieldsMcRec.GetNoElements()) cout << "ERROR: binning problem" << endl; if( ibinRec != -1 && ibinRec < yieldsMcRec.GetNoElements() && ibinFsr != -1 && ibinFsr < yieldsMcRec.GetNoElements() ){ DetMigration(ibinFsr,ibinRec) += reweight * scale * gen->weight * shape_weight; } Bool_t isB1 = (fabs(dielectron->scEta_1)<kGAP_LOW); Bool_t isB2 = (fabs(dielectron->scEta_2)<kGAP_LOW); hMassDiff->Fill(massResmeared - gen->mass); if( isB1 && isB2 ) hMassDiffBB->Fill(massResmeared - gen->mass); if( (isB1 && !isB2) || (!isB1 && isB2) ) hMassDiffEB->Fill(massResmeared - gen->mass); if( !isB1 && !isB2 ) hMassDiffEE->Fill(massResmeared - gen->mass); if(ibinFsr != -1){ hMassDiffV[ibinFsr]->Fill(massResmeared - gen->mass); } // if(ibinRec == -1) // printf("Missed bin: M_fsr=%f M_reco=%f\n", gen->mass, massResmeared); } // end loop over dielectrons } // end loop over events delete infile; infile=0, eventTree=0; } // end loop over files delete gen; //finish reweighting of mass spectra // Find bin by bin corrections and the errors double tCentral, tErrNeg, tErrPos; for(int i=0; i<DYTools::nMassBins; i++){ if ( DetCorrFactorDenominator(i) != 0 ){ // This method does not take into account correlation between numerator // and denominator in calculation of errors. This is a flaw to be corrected // in the future. SimpleDivide( DetCorrFactorNumerator(i), DetCorrFactorDenominator(i), tCentral, tErrNeg, tErrPos); DetCorrFactor(i) = tCentral; DetCorrFactorErrPos(i) = tErrPos; DetCorrFactorErrNeg(i) = tErrNeg; } else { DetCorrFactor(i) = 0; DetCorrFactorErrPos(i) = 0; DetCorrFactorErrNeg(i) = 0; } } // Find response matrix, which is simply the normalized migration matrix for(int ifsr = 0; ifsr < DetMigration.GetNrows(); ifsr++){ double nEventsInFsrMassBin = 0; for(int ireco = 0; ireco < DetMigration.GetNcols(); ireco++) nEventsInFsrMassBin += DetMigration(ifsr,ireco); // Now normalize each element and find errors for(int ireco = 0; ireco < DetMigration.GetNcols(); ireco++){ tCentral = 0; tErrPos = 0; tErrNeg = 0; // Note: the event counts supposedly are dominated with events with weight "1" // coming from the primary MC sample, so the error is assumed Poissonian in // the call for efficiency-calculating function below. if( nEventsInFsrMassBin != 0 ){ EfficiencyDivide(DetMigration(ifsr,ireco), nEventsInFsrMassBin, tCentral, tErrNeg, tErrPos); // BayesEfficiency does not seem to be working in newer ROOT versions, // so it is replaced by simler method // BayesEfficiency( DetMigration(ifsr,ireco), nEventsInFsrMassBin, tCentral, tErrNeg, tErrPos); } DetResponse (ifsr,ireco) = tCentral; DetResponseErrPos(ifsr,ireco) = tErrPos; DetResponseErrNeg(ifsr,ireco) = tErrNeg; } } // Find inverted response matrix TMatrixD DetInvertedResponse = DetResponse; Double_t det; DetInvertedResponse.Invert(&det); TMatrixD DetInvertedResponseErr(DetInvertedResponse.GetNrows(), DetInvertedResponse.GetNcols()); calculateInvertedMatrixErrors(DetResponse, DetResponseErrPos, DetResponseErrNeg, DetInvertedResponseErr); // Package bin limits into TVectorD for storing in a file TVectorD BinLimitsArray(DYTools::nMassBins+1); for(int i=0; i<DYTools::nMassBins+1; i++) BinLimitsArray(i) = DYTools::massBinLimits[i]; // Store constants in the file TString outputDir(TString("../root_files/constants/")+dirTag); if((systematicsMode==DYTools::RESOLUTION_STUDY) || (systematicsMode==DYTools::FSR_STUDY)) outputDir = TString("../root_files/systematics/")+dirTag; gSystem->mkdir(outputDir,kTRUE); TString unfoldingConstFileName(outputDir+TString("/unfolding_constants.root")); if(systematicsMode==DYTools::RESOLUTION_STUDY){ unfoldingConstFileName = outputDir+TString("/unfolding_constants_seed_"); unfoldingConstFileName += seed; unfoldingConstFileName += ".root"; } if(systematicsMode==DYTools::FSR_STUDY){ unfoldingConstFileName = outputDir+TString("/unfolding_constants_reweight_"); unfoldingConstFileName += int(100*reweightFsr); unfoldingConstFileName += ".root"; } TFile fConst(unfoldingConstFileName, "recreate" ); DetResponse .Write("DetResponse"); DetInvertedResponse .Write("DetInvertedResponse"); DetInvertedResponseErr .Write("DetInvertedResponseErr"); BinLimitsArray .Write("BinLimitsArray"); DetCorrFactor .Write("DetCorrFactor"); DetCorrFactorErrPos .Write("DetCorrFactorErrPos"); DetCorrFactorErrNeg .Write("DetCorrFactorErrNeg"); fConst.Close(); // Store reference MC arrays in a file TString refFileName(outputDir+TString("/yields_MC_unfolding_reference.root")); TFile fRef(refFileName, "recreate" ); BinLimitsArray .Write("BinLimitsArray"); yieldsMcFsr .Write("yieldsMcFsr"); yieldsMcFsrOfRec .Write("yieldsMcFsrOfRec"); yieldsMcRec .Write("yieldsMcRec"); fRef.Close(); //-------------------------------------------------------------------------------------------------------------- // Make plots //============================================================================================================== std::vector<TCanvas*> canvasV; // holder for a quick saver canvasV.reserve(10); TCanvas *c = MakeCanvas("zMass1","zMass1",800,600); canvasV.push_back(c); // string buffers char ylabel[50]; // y-axis label // Z mass sprintf(ylabel,"a.u. / %.1f GeV/c^{2}",hZMassv[0]->GetBinWidth(1)); CPlot plotZMass1("zmass1","","m(ee) [GeV/c^{2}]",ylabel); if (fnamev.size()) hZMassv[0]->GetXaxis()->SetLimits(10.,2000.); for(UInt_t i=0; i<fnamev.size(); i++) { plotZMass1.AddHist1D(hZMassv[i],labelv[i],"hist",colorv[i],linev[i]); } plotZMass1.SetLogy(); plotZMass1.SetLogx(); plotZMass1.TransLegend(0.02, 0.0); plotZMass1.Draw(c,doSave,format); // Create plots of how reco mass looks and how unfolded mass should look like TVectorD massBinCentral (DYTools::nMassBins); TVectorD massBinHalfWidth (DYTools::nMassBins); TVectorD yieldMcFsrOfRecErr (DYTools::nMassBins); TVectorD yieldMcRecErr (DYTools::nMassBins); for(int i=0; i < DYTools::nMassBins; i++){ massBinCentral (i) = (DYTools::massBinLimits[i+1] + DYTools::massBinLimits[i])/2.0; massBinHalfWidth(i) = (DYTools::massBinLimits[i+1] - DYTools::massBinLimits[i])/2.0; yieldsMcFsrOfRecErr(i) = sqrt(yieldsMcFsrOfRec[i]); yieldsMcRecErr (i) = sqrt(yieldsMcRec[i]); } TGraphErrors *grFsrOfRec = new TGraphErrors(massBinCentral, yieldsMcFsrOfRec, massBinHalfWidth, yieldsMcFsrOfRecErr); TGraphErrors *grRec = new TGraphErrors(massBinCentral, yieldsMcRec, massBinHalfWidth, yieldsMcRecErr); TCanvas *d = MakeCanvas("zMass2","zMass2",800,600); canvasV.push_back(d); CPlot plotZMass2("zmass2","","m(ee) [GeV/c^{2}]","events"); plotZMass2.SetLogx(1); plotZMass2.AddGraph(grFsrOfRec,"no detector effects","PE",kBlack); plotZMass2.AddGraph(grRec,"reconstructed","PE",kBlue); plotZMass2.Draw(d); // double xsize = 600; // double ysize = 600; int xsize = 600; int ysize = 400; // Create the plot of the response matrix TH2F *hResponse = new TH2F("hResponse","",DYTools::nMassBins, DYTools::massBinLimits, DYTools::nMassBins, DYTools::massBinLimits); for(int i=1; i<=DYTools::nMassBins; i++) for(int j=1; j<=DYTools::nMassBins; j++) hResponse->SetBinContent(i,j,DetResponse(i-1,j-1)); TCanvas *e = MakeCanvas("response","response",xsize,ysize); canvasV.push_back(e); CPlot plotResponse("response","", "generator post-FSR m(ee) [GeV/c^{2}]", "reconstructed m(ee) [GeV/c^{2}]"); plotResponse.AddHist2D(hResponse,"COLZ"); e->cd(); plotResponse.SetLogx(); plotResponse.SetLogy(); gPad->SetRightMargin(0.15); gStyle->SetPalette(1); hResponse->GetXaxis()->SetMoreLogLabels(); hResponse->GetXaxis()->SetNoExponent(); hResponse->GetYaxis()->SetNoExponent(); plotResponse.Draw(e); // Create the plot of the inverted response matrix TH2F *hInvResponse = new TH2F("hInvResponse","",DYTools::nMassBins, DYTools::massBinLimits, DYTools::nMassBins, DYTools::massBinLimits); for(int i=1; i<=DYTools::nMassBins; i++) for(int j=1; j<=DYTools::nMassBins; j++) hInvResponse->SetBinContent(i,j,DetInvertedResponse(i-1,j-1)); TCanvas *f = MakeCanvas("invResponse","invResponse",xsize,ysize); canvasV.push_back(f); CPlot plotInvResponse("inverted response","", "reconstructed m(ee) [GeV/c^{2}]", "generator post-FSR m(ee) [GeV/c^{2}]"); plotInvResponse.AddHist2D(hInvResponse,"COLZ"); f->cd(); plotInvResponse.SetLogx(); plotInvResponse.SetLogy(); gPad->SetRightMargin(0.15); gStyle->SetPalette(1); hInvResponse->GetXaxis()->SetMoreLogLabels(); hInvResponse->GetXaxis()->SetNoExponent(); hInvResponse->GetYaxis()->SetNoExponent(); plotInvResponse.Draw(f); // Create a plot of detector resolution without mass binning TCanvas *g = MakeCanvas("massDiff","massDiff",600,600); canvasV.push_back(g); CPlot plotMassDiff("massDiff","","reco mass - gen post-FSR mass [GeV/c^{2}]","a.u."); hMassDiffBB->Scale(1.0/hMassDiffBB->GetSumOfWeights()); hMassDiffEB->Scale(1.0/hMassDiffEB->GetSumOfWeights()); hMassDiffEE->Scale(1.0/hMassDiffEE->GetSumOfWeights()); plotMassDiff.AddHist1D(hMassDiffBB,"EB-EB","hist",kBlack); plotMassDiff.AddHist1D(hMassDiffEB,"EE-EB","hist",kBlue); plotMassDiff.AddHist1D(hMassDiffEE,"EE-EE","hist",kRed); plotMassDiff.TransLegend(0.1, 0.0); plotMassDiff.Draw(g); // Create a plot of reco - gen post-FSR mass difference for several mass bins TCanvas *h = MakeCanvas("massDiffV","massDiffV",600,600); canvasV.push_back(h); CPlot plotMassDiffV("massDiffV","","reco mass - gen post-FSR mass [GeV/c^{2}]","a.u."); hMassDiffV[7]->Scale(1.0/hMassDiffV[7]->GetSumOfWeights()); hMassDiffV[6]->Scale(1.0/hMassDiffV[6]->GetSumOfWeights()); hMassDiffV[5]->Scale(1.0/hMassDiffV[5]->GetSumOfWeights()); hMassDiffV[4]->Scale(1.0/hMassDiffV[4]->GetSumOfWeights()); plotMassDiffV.AddHist1D(hMassDiffV[4],"50-60 GeV/c^{2}","hist",kBlack); plotMassDiffV.AddHist1D(hMassDiffV[5],"60-76 GeV/c^{2}","hist",kBlue); plotMassDiffV.AddHist1D(hMassDiffV[6],"76-86 GeV/c^{2}","hist",kRed); plotMassDiffV.AddHist1D(hMassDiffV[7],"86-96 GeV/c^{2}","hist",kMagenta); plotMassDiffV.SetXRange(-20,50); plotMassDiffV.Draw(h); // Create graph of bin-to-bin corrections TGraphAsymmErrors *grCorrFactor = new TGraphAsymmErrors(massBinCentral, DetCorrFactor, massBinHalfWidth, massBinHalfWidth, DetCorrFactorErrNeg, DetCorrFactorErrPos); TCanvas *c11 = MakeCanvas("corrFactor","corrFactor",800,600); canvasV.push_back(c11); CPlot plotCorrFactor("corrFactor","","m(ee) [GeV/c^{2}]","correction factor"); plotCorrFactor.AddGraph(grCorrFactor,"PE",kBlue); plotCorrFactor.SetLogx(); plotCorrFactor.SetYRange(0,2.0); plotCorrFactor.Draw(c11); if (saveMadePlots) { TString plotPath=TString("../root_files/plots/") + dirTag; TString name=plotPath + TString("/unfolding_plots.root"); gSystem->mkdir(plotPath,true); TFile* fplots = TFile::Open(name,"RECREATE"); for (unsigned int i=0; i<canvasV.size(); ++i) { canvasV[i]->Write(); } fplots->Close(); } //-------------------------------------------------------------------------------------------------------------- // Summary print out //============================================================================================================== cout << endl; cout << "*" << endl; cout << "* SUMMARY" << endl; cout << "*--------------------------------------------------" << endl; cout << endl; // Printout of all constants, uncomment if needed //printf("DetMigration:\n"); DetMigration.Print(); //printf("DetResponse:\n"); DetResponse.Print(); //printf("DetInvertedResponse:\n"); DetInvertedResponse.Print(); // DetCorrFactor.Print(); // DetResponse.Print(); // printf("Detector corr factor numerator:\n"); // DetCorrFactorNumerator.Print(); // printf("yieldsMcRec:\n"); // yieldsMcRec.Print(); // printf("Detector corr factor denominator:\n"); // DetCorrFactorDenominator.Print(); // printf("yieldsMcFsrOfRec:\n"); // yieldsMcFsrOfRec.Print(); gBenchmark->Show("plotDYUnfoldingMatrix"); }
int main( int argc, char** argv ) { CCP4program prog( "cecalc", "0.1", "$Date: 2004/07/01" ); // defaults clipper::String ipfile = "NONE"; clipper::String ipcolfo = "NONE"; clipper::String opfile = "ecalc.mtz"; clipper::String opcol = "ecalc"; const int nprm = 12; // command input CommandInput args( argc, argv, true ); int arg = 0; while ( ++arg < args.size() ) { if ( args[arg] == "-mtzin" ) { if ( ++arg < args.size() ) ipfile = args[arg]; } else if ( args[arg] == "-mtzout" ) { if ( ++arg < args.size() ) opfile = args[arg]; } else if ( args[arg] == "-colin-fo" ) { if ( ++arg < args.size() ) ipcolfo = args[arg]; } else if ( args[arg] == "-colout" ) { if ( ++arg < args.size() ) opcol = args[arg]; } else { std::cout << "Unrecognized:\t" << args[arg] << "\n"; args.clear(); } } if ( args.size() <= 1 ) { std::cout << "Usage: cecalc\n\t-mtzin <filename>\n\t-mtzout <filename>\n\t-colin-fo <colpath>\n\t-colout <colpath>\nCalculate E's from F's\n"; exit(1); } // make data objects clipper::CCP4MTZfile mtzin, mtzout; clipper::HKL_info hkls; typedef clipper::HKL_data_base::HKL_reference_index HRI; // open file mtzin.open_read( ipfile ); mtzin.import_hkl_info( hkls ); clipper::HKL_data<clipper::data32::F_sigF> fsig( hkls ); mtzin.import_hkl_data( fsig, ipcolfo ); if ( opcol[0] != '/' ) opcol = mtzin.assigned_paths()[0].notail()+"/"+opcol; mtzin.close_read(); // create initial E clipper::HKL_data<clipper::data32::E_sigE> esig( hkls ); esig.compute( fsig, clipper::data32::Compute_EsigE_from_FsigF() ); // calc E-scaling std::vector<double> params_init( nprm, 1.0 ); clipper::BasisFn_spline basis_fo( esig, nprm, 2.0 ); clipper::TargetFn_scaleEsq<clipper::data32::E_sigE> target_fo( esig ); clipper::ResolutionFn escale( hkls, basis_fo, target_fo, params_init ); // apply E-scaling for ( HRI ih = esig.first(); !ih.last(); ih.next() ) if ( !esig[ih].missing() ) esig[ih].scale( sqrt( escale.f(ih) ) ); // output data mtzout.open_append( ipfile, opfile ); mtzout.export_hkl_data( esig, opcol ); mtzout.close_append(); }
void calcEscaleSystematics(TString lumiTag="DY_j22_19712pb", int saveTexTable=0){ int nUnfoldingBins = DYTools::getTotalNumberOfBins(); TVectorD observedYields(nUnfoldingBins); TVectorD observedYieldsErr(nUnfoldingBins); TVectorD dummyArr(nUnfoldingBins); TVectorD unfoldedYields(nUnfoldingBins); // // Indicators (and also counters) whether the data was present // int countEScaleSyst=0; int countResidualShape=0; int countEtaSyst=0; int countFittingShape=0; std::vector<TString> usedFiles; ElectronEnergyScale escale("Date20120802_default"); // // Calculate error associated with statistical // uncertainty on the energy scale factors // TVectorD unfoldedYieldsMean(nUnfoldingBins); TVectorD unfoldedYieldsRMS(nUnfoldingBins); TVectorD unfoldedYieldsSquaredMean(nUnfoldingBins); unfoldedYieldsMean = 0; unfoldedYieldsRMS = 0; unfoldedYieldsSquaredMean = 0; TString matrixFileName = TString("../root_files/constants/") + lumiTag + TString("/detResponse_unfolding_constants") + DYTools::analysisTag + TString("_PU.root"); const int nFiles1 = 20; // expected number of files if (1) for(int ifile=0; ifile<nFiles1; ifile++){ int seed = 1001+ifile; escale.randomizeEnergyScaleCorrections(seed); TString fname = TString("../root_files/yields/") + lumiTag + TString("_escale_randomized/yields_bg-subtracted") + DYTools::analysisTag + TString("__") + escale.calibrationSetShortName(); fname += ".root"; TFile file(fname); if (!file.IsOpen()) { std::cout << "failed to open a file <" << fname << ">\n"; } else { file.Close(); // register usedFiles.push_back(fname); // work with data int res= (readData(fname, observedYields,observedYieldsErr,dummyArr) == 1) && (applyUnfoldingLocal(observedYields,unfoldedYields,matrixFileName) == 1); if (res==1) { countEScaleSyst++; //std::cout << "unfoldedYields for seed=" << seed << ": "; unfoldedYields.Print(); // Accumulate mean and RMS for(int idx = 0; idx < nUnfoldingBins; idx++){ unfoldedYieldsMean[idx] += unfoldedYields[idx]; unfoldedYieldsSquaredMean[idx] += unfoldedYields[idx]*unfoldedYields[idx]; } } } } // Final calculation of the mean and RMS for Smearing TVectorD escaleRandomizedSystRelative(nUnfoldingBins); if (countEScaleSyst) { for(int idx = 0; idx < nUnfoldingBins; idx++){ unfoldedYieldsMean[idx] = unfoldedYieldsMean[idx]/double(countEScaleSyst); unfoldedYieldsSquaredMean[idx] = unfoldedYieldsSquaredMean[idx]/double(countEScaleSyst); unfoldedYieldsRMS[idx] = sqrt(unfoldedYieldsSquaredMean[idx] - unfoldedYieldsMean[idx]*unfoldedYieldsMean[idx]); escaleRandomizedSystRelative[idx] = unfoldedYieldsRMS[idx]/unfoldedYieldsMean[idx]; } //std::cout << "unfoldedYieldsMean=" << ": "; unfoldedYieldsMean.Print(); //std::cout << "escaleRandomizedSystRelative: "; escaleRandomizedSystRelative.Print(); } else { std::cout << "escaleRandomizomized files were not found\n"; } // // Calculate error related to the difference between // data and MC mass distribution shape after all corrections // had been applied to data and MC. "Residual differences" // TVectorD unfoldedYieldsVariation(nUnfoldingBins); TVectorD escaleResidualDiffSystRelative(nUnfoldingBins); TString fname = TString("../root_files/yields/") + lumiTag + TString("/yields_bg-subtracted") + DYTools::analysisTag + TString(".root"); int res=1; { TFile file(fname); if (file.IsOpen()) { file.Close(); if (readData(fname,observedYields,observedYieldsErr,dummyArr) != 1) { std::cout << "failed to get data from file <" << fname << ">\n"; throw 2; } // matrixFileName = TString("../root_files/constants/") + lumiTag + TString("/detResponse_unfolding_constants") + DYTools::analysisTag + TString("_PU.root"); res=applyUnfoldingLocal(observedYields, unfoldedYields, matrixFileName); if (res==1) usedFiles.push_back(matrixFileName); // if (res==1) { matrixFileName = TString("../root_files/constants/") + lumiTag + TString("_escale_residual/unfolding_constants") + DYTools::analysisTag + TString("_escaleResidual.root"); res=applyUnfoldingLocal(observedYields, unfoldedYieldsVariation, matrixFileName); if (res==1) { countResidualShape++; usedFiles.push_back(matrixFileName); } } } if (res==1) { for(int idx=0; idx<nUnfoldingBins; idx++){ escaleResidualDiffSystRelative[idx] = fabs(unfoldedYields[idx] - unfoldedYieldsVariation[idx]) /(unfoldedYields[idx] + unfoldedYieldsVariation[idx]); } } } // // Calculate error related to extra smearing function shape // std::vector<TString> shapeNames; shapeNames.push_back("_6binNegs_BreitWigner_20120802"); shapeNames.push_back("_6binNegs_Voigtian_20120802"); std::vector<TVectorD*> unfoldedYieldsShape; if (1) for (unsigned int i=0; i<shapeNames.size(); ++i) { TVectorD observedYieldsShape(nUnfoldingBins); TVectorD observedYieldsShapeErr(nUnfoldingBins); TString shapeFName=TString("../root_files/yields/") + lumiTag + TString("_escale_shape/yields_bg-subtracted") + DYTools::analysisTag + TString("_") + shapeNames[i] + TString(".root"); TFile fShape(shapeFName); if (fShape.IsOpen()) { fShape.Close(); usedFiles.push_back(shapeFName); if ( readData(shapeFName,observedYieldsShape,observedYieldsShapeErr,dummyArr) !=1) { std::cout << "failed to load data from <" << shapeFName << ">\n"; throw 2; } TString matrixFileNameShape = TString("../root_files/constants/") + lumiTag + TString("_escale_shape/unfolding_constants") + DYTools::analysisTag + TString("_") + shapeNames[i] + TString(".root"); TVectorD *shapeYields=new TVectorD(nUnfoldingBins); { TFile ftmp(TString("tmp_") + shapeNames[i] + TString(".root"),"recreate"); observedYieldsShape.Write("YieldsSignal"); TVectorD tmp(nUnfoldingBins); tmp=0; tmp.Write("YieldsSignalErr"); tmp.Write("YieldsSignalSystErr"); ftmp.Close(); } res=applyUnfoldingLocal(observedYieldsShape, *shapeYields, matrixFileNameShape); if (res) { countFittingShape++; usedFiles.push_back(matrixFileNameShape); unfoldedYieldsShape.push_back(shapeYields); } else delete shapeYields; } } // TVectorD escaleFitShapeSystRelative(nUnfoldingBins); for(int idx=0; idx<nUnfoldingBins; idx++){ double min = unfoldedYields[idx]; double max = unfoldedYields[idx]; for (unsigned int iShape=0; iShape<unfoldedYieldsShape.size(); ++iShape) { min = TMath::Min( min, (*unfoldedYieldsShape[iShape])[idx] ); max = TMath::Max( max, (*unfoldedYieldsShape[iShape])[idx] ); } escaleFitShapeSystRelative[idx] = fabs(max-min)/(max+min); } // // Calculate error related to eta binning // std::vector<TString> etaBinNames; etaBinNames.push_back("_2binNegs_Gauss_20120802"); etaBinNames.push_back("_3EB3EENegs_Gauss_20120802"); etaBinNames.push_back("_4binNegs_Gauss_20120802"); etaBinNames.push_back("_4EB3EENegs_Gauss_20120802"); etaBinNames.push_back("_5binNegs_Gauss_20120802"); etaBinNames.push_back("_6binNegs_Gauss_20120802"); // default etaBinNames.push_back("_6bins_Gauss_20120802"); std::vector<TVectorD*> unfoldedYieldsEta; unfoldedYieldsEta.reserve(etaBinNames.size()); if (1) for (unsigned int i=0; i<etaBinNames.size(); ++i) { TString fEtaFileName=TString("../root_files/yields/") + lumiTag + TString("_escale_eta/yields_bg-subtracted") + DYTools::analysisTag + TString("_") + etaBinNames[i] + TString(".root"); TFile fEta(fEtaFileName); if (fEta.IsOpen()) { fEta.Close(); usedFiles.push_back(fEtaFileName); TVectorD observedYieldsEta(nUnfoldingBins); TVectorD observedYieldsEtaErr(nUnfoldingBins); if (readData(fEtaFileName,observedYieldsEta,observedYieldsEtaErr,dummyArr)!=1) { std::cout << "failed to get info from <" << fEtaFileName << ">\n"; throw 2; } matrixFileName = TString("../root_files/constants/") + lumiTag + TString("_escale_eta/unfolding_constants") + DYTools::analysisTag + TString("_") + etaBinNames[i] + TString(".root"); TVectorD *unfYields = new TVectorD(nUnfoldingBins); res=applyUnfoldingLocal(observedYieldsEta, *unfYields, matrixFileName); if (res==1) { countEtaSyst++; usedFiles.push_back(matrixFileName); unfoldedYieldsEta.push_back(unfYields); } else { delete unfYields; } } } // TVectorD escaleEtaBinSystRelative(nUnfoldingBins); for(int idx=0; idx<nUnfoldingBins; idx++){ double min = unfoldedYields[idx]; double max = unfoldedYields[idx]; for (unsigned int iShape=0; iShape<unfoldedYieldsEta.size(); ++iShape) { min = TMath::Min( min, (*unfoldedYieldsEta[iShape])[idx] ); max = TMath::Max( max, (*unfoldedYieldsEta[iShape])[idx] ); } escaleEtaBinSystRelative[idx] = fabs(max-min)/(max+min); } // // Put all errors together // TVectorD escaleSystPercent(nUnfoldingBins); for(int idx = 0; idx < nUnfoldingBins; idx++){ escaleSystPercent[idx] = 100.0 * sqrt( escaleRandomizedSystRelative[idx]*escaleRandomizedSystRelative[idx] + escaleResidualDiffSystRelative[idx]*escaleResidualDiffSystRelative[idx] + escaleFitShapeSystRelative[idx]*escaleFitShapeSystRelative[idx] + escaleEtaBinSystRelative[idx]*escaleEtaBinSystRelative[idx] ); } // Don't write TObject part of the objects TDescriptiveInfo_t::Class()->IgnoreTObjectStreamer(); TDescriptiveInfo_t *info= new TDescriptiveInfo_t(); std::vector<std::string> *lines = (info) ? (& info->_info) : NULL; const int bufsize=300; char buf[bufsize]; std::string sbuf; snprintf(buf,bufsize," Summary of successful loads:\n"); printf(buf); if (lines) lines->push_back(buf); snprintf(buf,bufsize," escale systematics file count= %2d\n", countEScaleSyst); printf(buf); if (lines) lines->push_back(buf); snprintf(buf,bufsize," residual shape syst. file count= %2d\n", countResidualShape); printf(buf); if (lines) lines->push_back(buf); snprintf(buf,bufsize," eta systematics file count= %2d\n", countEtaSyst); printf(buf); if (lines) lines->push_back(buf); snprintf(buf,bufsize," fitting shape file count= %2d\n", countFittingShape); printf(buf); if (lines) { lines->push_back(buf); lines->push_back("\n"); } std::cout << "\n"; int listFilesOnScreen=1; snprintf(buf,bufsize," Loaded files:\n"); if (listFilesOnScreen) printf(buf); if (lines) lines->push_back(buf); for (unsigned int i=0; i<usedFiles.size(); ++i) { snprintf(buf,bufsize," %s\n",usedFiles[i].Data()); if (listFilesOnScreen) printf(buf); if (lines) lines->push_back(buf); } std::cout << std::endl; if (saveTexTable) { std::vector<TString> headers; std::vector<int> padding; std::vector<TVectorD*> data; std::vector<double> factors; headers.push_back("mass range"); headers.push_back("rapidity range"); headers.push_back("\\multicolumn{1}{c|}{statistical, \\%}"); data.push_back(&escaleRandomizedSystRelative); factors.push_back(100.); padding.push_back(6); headers.push_back("\\multicolumn{1}{c|}{shape, \\%}"); data.push_back(&escaleFitShapeSystRelative); factors.push_back(100.); padding.push_back(4); headers.push_back("\\multicolumn{1}{c|}{residual, \\%}"); data.push_back(&escaleResidualDiffSystRelative); factors.push_back(100.); padding.push_back(5); headers.push_back("\\multicolumn{1}{c|}{$\\eta$ binning, \\%}"); data.push_back(&escaleEtaBinSystRelative); factors.push_back(100.); padding.push_back(6); headers.push_back("\\multicolumn{1}{c|}{total, \\%}"); data.push_back(&escaleSystPercent); factors.push_back(1.); padding.push_back(3); TString texFName=TString("../root_files/systematics/") + lumiTag + TString("/escale_systematics") + DYTools::analysisTag + TString("_tmp.tex"); printTexTable(texFName,headers,padding,data,factors); } TString finalFName=TString("../root_files/systematics/") + lumiTag + TString("/escale_systematics") + DYTools::analysisTag + TString("_tmp.root"); TFile fout(finalFName,"recreate"); unfolding::writeBinningArrays(fout); escaleRandomizedSystRelative.Write("escaleRandomizedSystRelativeFI"); escaleFitShapeSystRelative.Write("escaleFitShapeSystRelativeFI"); escaleResidualDiffSystRelative.Write("escaleResidualDiffSystRelativeFI"); escaleEtaBinSystRelative.Write("escaleEtaBinSystRelativeFI"); escaleSystPercent.Write("escaleSystPercentFI"); if (info) { TTree *infoTree = new TTree("Description","description"); infoTree->Branch("description","TDescriptiveInfo_t",&info); infoTree->Fill(); infoTree->Write(); } fout.Close(); return; }