From d020ad1bfe7bdbcf2fa67afc986c3796f6a895ce Mon Sep 17 00:00:00 2001 From: mmusich Date: Mon, 4 Apr 2022 17:11:17 +0200 Subject: [PATCH 1/4] add plugin for DiMuonValidation --- .../plugins/DiMuonValidation.cc | 332 ++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 Alignment/OfflineValidation/plugins/DiMuonValidation.cc diff --git a/Alignment/OfflineValidation/plugins/DiMuonValidation.cc b/Alignment/OfflineValidation/plugins/DiMuonValidation.cc new file mode 100644 index 0000000000000..35d5f0f0e1c94 --- /dev/null +++ b/Alignment/OfflineValidation/plugins/DiMuonValidation.cc @@ -0,0 +1,332 @@ +// system includes +#include +#include +#include + +// user include files +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Candidate/interface/Particle.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "Geometry/CommonDetUnit/interface/GeomDet.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" + +// ROOT includes +#include "TH1D.h" +#include "TH2D.h" +#include "TH3D.h" + +namespace DiMuonValid { + using LV = reco::Particle::LorentzVector; +} +// +// class declaration +// +class DiMuonValidation : public edm::one::EDAnalyzer { +public: + explicit DiMuonValidation(const edm::ParameterSet& pset) + : eBeam_(pset.getParameter("eBeam")), + compressionSettings_(pset.getUntrackedParameter("compressionSettings", -1)), + TkTag_(pset.getParameter("TkTag")), + pair_mass_min_(pset.getParameter("Pair_mass_min")), + pair_mass_max_(pset.getParameter("Pair_mass_max")), + pair_mass_nbins_(pset.getParameter("Pair_mass_nbins")), + pair_etaminpos_(pset.getParameter("Pair_etaminpos")), + pair_etamaxpos_(pset.getParameter("Pair_etamaxpos")), + pair_etaminneg_(pset.getParameter("Pair_etaminneg")), + pair_etamaxneg_(pset.getParameter("Pair_etamaxneg")), + variable_CosThetaCS_xmin_(pset.getParameter("Variable_CosThetaCS_xmin")), + variable_CosThetaCS_xmax_(pset.getParameter("Variable_CosThetaCS_xmax")), + variable_CosThetaCS_nbins_(pset.getParameter("Variable_CosThetaCS_nbins")), + variable_DeltaEta_xmin_(pset.getParameter("Variable_DeltaEta_xmin")), + variable_DeltaEta_xmax_(pset.getParameter("Variable_DeltaEta_xmax")), + variable_DeltaEta_nbins_(pset.getParameter("Variable_DeltaEta_nbins")), + variable_EtaMinus_xmin_(pset.getParameter("Variable_EtaMinus_xmin")), + variable_EtaMinus_xmax_(pset.getParameter("Variable_EtaMinus_xmax")), + variable_EtaMinus_nbins_(pset.getParameter("Variable_EtaMinus_nbins")), + variable_EtaPlus_xmin_(pset.getParameter("Variable_EtaPlus_xmin")), + variable_EtaPlus_xmax_(pset.getParameter("Variable_EtaPlus_xmax")), + variable_EtaPlus_nbins_(pset.getParameter("Variable_EtaPlus_nbins")), + variable_PhiCS_xmin_(pset.getParameter("Variable_PhiCS_xmin")), + variable_PhiCS_xmax_(pset.getParameter("Variable_PhiCS_xmax")), + variable_PhiCS_nbins_(pset.getParameter("Variable_PhiCS_nbins")), + variable_PhiMinus_xmin_(pset.getParameter("Variable_PhiMinus_xmin")), + variable_PhiMinus_xmax_(pset.getParameter("Variable_PhiMinus_xmax")), + variable_PhiMinus_nbins_(pset.getParameter("Variable_PhiMinus_nbins")), + variable_PhiPlus_xmin_(pset.getParameter("Variable_PhiPlus_xmin")), + variable_PhiPlus_xmax_(pset.getParameter("Variable_PhiPlus_xmax")), + variable_PhiPlus_nbins_(pset.getParameter("Variable_PhiPlus_nbins")), + variable_PairPt_xmin_(pset.getParameter("Variable_PairPt_xmin")), + variable_PairPt_xmax_(pset.getParameter("Variable_PairPt_xmax")), + variable_PairPt_nbins_(pset.getParameter("Variable_PairPt_nbins")) { + usesResource(TFileService::kSharedResource); + theTrackCollectionToken_ = consumes(TkTag_); + + variables_min_[0] = variable_CosThetaCS_xmin_; + variables_min_[1] = variable_DeltaEta_xmin_; + variables_min_[2] = variable_EtaMinus_xmin_; + variables_min_[3] = variable_EtaPlus_xmin_; + variables_min_[4] = variable_PhiCS_xmin_; + variables_min_[5] = variable_PhiMinus_xmin_; + variables_min_[6] = variable_PhiPlus_xmin_; + variables_min_[7] = variable_PairPt_xmin_; + + variables_max_[0] = variable_CosThetaCS_xmax_; + variables_max_[1] = variable_DeltaEta_xmax_; + variables_max_[2] = variable_EtaMinus_xmax_; + variables_max_[3] = variable_EtaPlus_xmax_; + variables_max_[4] = variable_PhiCS_xmax_; + variables_max_[5] = variable_PhiMinus_xmax_; + variables_max_[6] = variable_PhiPlus_xmax_; + variables_max_[7] = variable_PairPt_xmax_; + + variables_bins_number_[0] = variable_CosThetaCS_nbins_; + variables_bins_number_[1] = variable_DeltaEta_nbins_; + variables_bins_number_[2] = variable_EtaMinus_nbins_; + variables_bins_number_[3] = variable_EtaPlus_nbins_; + variables_bins_number_[4] = variable_PhiCS_nbins_; + variables_bins_number_[5] = variable_PhiMinus_nbins_; + variables_bins_number_[6] = variable_PhiPlus_nbins_; + variables_bins_number_[7] = variable_PairPt_nbins_; + } + + ~DiMuonValidation() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + static constexpr int varNumber_ = 8; + static constexpr double mu_mass2_ = 0.105658 * 0.105658; //The invariant mass of muon 105.658MeV + +private: + void beginJob() override; + void analyze(const edm::Event&, const edm::EventSetup&) override; + + // ----------member data --------------------------- + float eBeam_; + int compressionSettings_; + std::string TkTag_; + + double pair_mass_min_; + double pair_mass_max_; + int pair_mass_nbins_; + double pair_etaminpos_; + double pair_etamaxpos_; + double pair_etaminneg_; + double pair_etamaxneg_; + + double variable_CosThetaCS_xmin_; + double variable_CosThetaCS_xmax_; + int variable_CosThetaCS_nbins_; + + double variable_DeltaEta_xmin_; + double variable_DeltaEta_xmax_; + int variable_DeltaEta_nbins_; + + double variable_EtaMinus_xmin_; + double variable_EtaMinus_xmax_; + int variable_EtaMinus_nbins_; + + double variable_EtaPlus_xmin_; + double variable_EtaPlus_xmax_; + int variable_EtaPlus_nbins_; + + double variable_PhiCS_xmin_; + double variable_PhiCS_xmax_; + int variable_PhiCS_nbins_; + + double variable_PhiMinus_xmin_; + double variable_PhiMinus_xmax_; + int variable_PhiMinus_nbins_; + + double variable_PhiPlus_xmin_; + double variable_PhiPlus_xmax_; + int variable_PhiPlus_nbins_; + + double variable_PairPt_xmin_; + double variable_PairPt_xmax_; + int variable_PairPt_nbins_; + + edm::EDGetTokenT theTrackCollectionToken_; + TH2D* th2d_mass_variables_[varNumber_]; // actual histograms + std::string variables_name_[varNumber_] = { + "CosThetaCS", "DeltaEta", "EtaMinus", "EtaPlus", "PhiCS", "PhiMinus", "PhiPlus", "Pt"}; + + int variables_bins_number_[varNumber_]; // = {20, 20, 12, 12, 20, 16, 16, 100}; + double variables_min_[varNumber_]; // = {-1, -4.8, -2.4, -2.4, -M_PI / 2, -M_PI, -M_PI, 0}; + double variables_max_[varNumber_]; // = {+1, +4.8, +2.4, +2.4, +M_PI / 2, +M_PI, +M_PI, 100}; +}; + +// +// member functions +// + +// ------------ method called for each event ------------ +void DiMuonValidation::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + + const reco::TrackCollection& tC = iEvent.get(theTrackCollectionToken_); + + DiMuonValid::LV LV_mother(0., 0., 0., 0.); + //for (reco::TrackCollection::const_iterator track1 = tC.begin(); track1 != tC.end(); track1++) { + for (const auto& track1 : tC) { + DiMuonValid::LV LV_track1(track1.px(), + track1.py(), + track1.pz(), + sqrt((track1.p() * track1.p()) + mu_mass2_)); //old 106 + + for (const auto& track2 : tC) { + if (&track1 == &track2) { + continue; + } // discard the same track + + if (track1.charge() == track2.charge()) { + continue; + } // only reconstruct opposite charge pair + + DiMuonValid::LV LV_track2(track2.px(), track2.py(), track2.pz(), sqrt((track2.p() * track2.p()) + mu_mass2_)); + + LV_mother = LV_track1 + LV_track2; + double mother_mass = LV_mother.M(); + double mother_pt = LV_mother.Pt(); + + int charge1 = track1.charge(); + double etaMu1 = track1.eta(); + double phiMu1 = track1.phi(); + double ptMu1 = track1.pt(); + + int charge2 = track2.charge(); + double etaMu2 = track2.eta(); + double phiMu2 = track2.phi(); + double ptMu2 = track2.pt(); + + if (charge1 < 0) { // use Mu+ for charge1, Mu- for charge2 + std::swap(charge1, charge2); + std::swap(etaMu1, etaMu2); + std::swap(phiMu1, phiMu2); + std::swap(ptMu1, ptMu2); + } + //eta cut + if (etaMu1 < pair_etaminpos_ || etaMu1 > pair_etamaxpos_ || etaMu2 < pair_etaminneg_ || + etaMu2 > pair_etamaxneg_) { + continue; + } + + double delta_eta = etaMu1 - etaMu2; + + double muplus = 1.0 / sqrt(2.0) * (LV_track1.E() + LV_track1.Z()); + double muminus = 1.0 / sqrt(2.0) * (LV_track1.E() - LV_track1.Z()); + double mubarplus = 1.0 / sqrt(2.0) * (LV_track2.E() + LV_track2.Z()); + double mubarminus = 1.0 / sqrt(2.0) * (LV_track2.E() - LV_track2.Z()); + //double costheta = 2.0 / Q.mag() / sqrt(pow(Q.mag(), 2) + pow(Q.Pt(), 2)) * (muplus * mubarminus - muminus * mubarplus); + double costhetaCS = 2.0 / LV_mother.mag() / sqrt(pow(LV_mother.mag(), 2) + pow(LV_mother.Pt(), 2)) * + (muplus * mubarminus - muminus * mubarplus); + + DiMuonValid::LV Pbeam(0., 0., eBeam_, eBeam_); + auto R = Pbeam.Vect().Cross(LV_mother.Vect()); + auto Runit = R.Unit(); + auto Qt = LV_mother.Vect(); + Qt.SetZ(0); + auto Qtunit = Qt.Unit(); + DiMuonValid::LV D(LV_track1 - LV_track2); + auto Dt = D.Vect(); + Dt.SetZ(0); + double tanphi = + sqrt(pow(LV_mother.mag(), 2) + pow(LV_mother.Pt(), 2)) / LV_mother.mag() * Dt.Dot(Runit) / Dt.Dot(Qtunit); + double phiCS = atan(tanphi); + + if (mother_mass > pair_mass_min_ && mother_mass < pair_mass_max_) { + th2d_mass_variables_[0]->Fill(mother_mass, costhetaCS, 1); + th2d_mass_variables_[1]->Fill(mother_mass, delta_eta, 1); + th2d_mass_variables_[2]->Fill(mother_mass, etaMu2, 1); + th2d_mass_variables_[3]->Fill(mother_mass, etaMu1, 1); + th2d_mass_variables_[4]->Fill(mother_mass, phiCS, 1); + th2d_mass_variables_[5]->Fill(mother_mass, phiMu2, 1); + th2d_mass_variables_[6]->Fill(mother_mass, phiMu1, 1); + th2d_mass_variables_[7]->Fill(mother_mass, mother_pt, 1); + } + } + } +} + +// ------------ method called once each job just before starting event loop ------------ +void DiMuonValidation::beginJob() { + edm::Service fs; + if (compressionSettings_ > 0) { + fs->file().SetCompressionSettings(compressionSettings_); + } + + for (int i = 0; i < varNumber_; i++) { + std::string th2d_name = fmt::sprintf("th2d_mass_%s", variables_name_[i].c_str()); + th2d_mass_variables_[i] = fs->make(th2d_name.c_str(), + th2d_name.c_str(), + pair_mass_nbins_, + pair_mass_min_, + pair_mass_max_, + variables_bins_number_[i], + variables_min_[i], + variables_max_[i]); + } +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void DiMuonValidation::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.setComment("Validates alignment payloads by evaluating bias in Z->mm mass distributions"); + desc.addUntracked("compressionSettings", -1); + + desc.add("eBeam", 3500.)->setComment("beam energy in GeV"); + desc.add("TkTag", "ALCARECOTkAlZMuMu"); + + desc.add("Pair_mass_min", 60); + desc.add("Pair_mass_max", 120); + desc.add("Pair_mass_nbins", 120); + desc.add("Pair_etaminpos", 60); + desc.add("Pair_etamaxpos", 60); + desc.add("Pair_etaminneg", 60); + desc.add("Pair_etamaxneg", 60); + + desc.add("Variable_CosThetaCS_xmin", -1.); + desc.add("Variable_CosThetaCS_xmax", 1.); + desc.add("Variable_CosThetaCS_nbins", 20); + + desc.add("Variable_DeltaEta_xmin", -4.8); + desc.add("Variable_DeltaEta_xmax", 4.8); + desc.add("Variable_DeltaEta_nbins", 20); + + desc.add("Variable_EtaMinus_xmin", -2.4); + desc.add("Variable_EtaMinus_xmax", 2.4); + desc.add("Variable_EtaMinus_nbins", 12); + + desc.add("Variable_EtaPlus_xmin", -2.4); + desc.add("Variable_EtaPlus_xmax", 2.4); + desc.add("Variable_EtaPlus_nbins", 12); + + desc.add("Variable_PhiCS_xmin", -M_PI / 2); + desc.add("Variable_PhiCS_xmax", M_PI / 2); + desc.add("Variable_PhiCS_nbins", 20); + + desc.add("Variable_PhiMinus_xmin", -M_PI); + desc.add("Variable_PhiMinus_xmax", M_PI); + desc.add("Variable_PhiMinus_nbins", 16); + + desc.add("Variable_PhiPlus_xmin", -M_PI); + desc.add("Variable_PhiPlus_xmax", M_PI); + desc.add("Variable_PhiPlus_nbins", 16); + + desc.add("Variable_PairPt_xmin", 0.); + desc.add("Variable_PairPt_xmax", 100.); + desc.add("Variable_PairPt_nbins", 100); + + descriptions.add("DiMuonValidation", desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(DiMuonValidation); From dc541b4795d1b25541fa8f6ea2efff6147374d19 Mon Sep 17 00:00:00 2001 From: mmusich Date: Tue, 5 Apr 2022 09:21:41 +0200 Subject: [PATCH 2/4] add macro for DiMuonValidation fitting --- .../OfflineValidation/bin/FitWithRooFit.cc | 777 ++++++++++++++++++ 1 file changed, 777 insertions(+) create mode 100644 Alignment/OfflineValidation/bin/FitWithRooFit.cc diff --git a/Alignment/OfflineValidation/bin/FitWithRooFit.cc b/Alignment/OfflineValidation/bin/FitWithRooFit.cc new file mode 100644 index 0000000000000..3cee03177a6b3 --- /dev/null +++ b/Alignment/OfflineValidation/bin/FitWithRooFit.cc @@ -0,0 +1,777 @@ +#ifndef FitWithRooFit_cc +#define FitWithRooFit_cc + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "TCanvas.h" +#include "TTree.h" +#include "TH1D.h" +#include "TRandom.h" +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooVoigtian.h" +#include "RooExponential.h" +#include "RooPlot.h" +#include "RooDataHist.h" +#include "RooAddPdf.h" +#include "RooChebychev.h" +#include "RooGenericPdf.h" +#include "RooGaussModel.h" +#include "RooAddModel.h" +#include "RooPolynomial.h" +#include "RooCBShape.h" +#include "RooChi2Var.h" +#include "RooMinuit.h" +#include "RooBreitWigner.h" +#include "RooFFTConvPdf.h" + +/** + * This macro allows to use RooFit to perform a fit on a TH1 histogram.
+ * The currently implemented functions are:
+ * - signal:
+ * -- gaussian
+ * -- double gaussian
+ * -- voigtian
+ * - background:
+ * -- exponential
+ * It is possible to select any combination of signal and background.
+ * The fit() method receives the TH1, two strings specifying the signal and background type + * and the min and max x of the histogram over which to perform the fit.
+ * The variables of the fit must be initialized separately. For example when doing a gaussian+exponential + * fit the initMean, initSigma, initFSig and initExpCoeff methods must be used to create and initialize + * the corresponding variables.
+ * The methods names after the variables return the fit result. + */ + +namespace { + typedef std::pair rooPair; +} + +class FitWithRooFit { +public: + FitWithRooFit() + : useChi2_(false), + mean_(nullptr), + mean2_(nullptr), + mean3_(nullptr), + sigma_(nullptr), + sigma2_(nullptr), + sigma3_(nullptr), + gamma_(nullptr), + gaussFrac_(nullptr), + gaussFrac2_(nullptr), + expCoeffa0_(nullptr), + expCoeffa1_(nullptr), + expCoeffa2_(nullptr), + fsig_(nullptr), + a0_(nullptr), + a1_(nullptr), + a2_(nullptr), + a3_(nullptr), + a4_(nullptr), + a5_(nullptr), + a6_(nullptr), + alpha_(nullptr), + n_(nullptr), + fGCB_(nullptr) {} + + // Import TH1 histogram into a RooDataHist + rooPair importTH1(TH1* histo, const double& inputXmin, const double& inputXmax) { + double xMin = inputXmin; + double xMax = inputXmax; + if ((xMin == xMax) && xMin == 0) { + xMin = histo->GetXaxis()->GetXmin(); + xMax = histo->GetXaxis()->GetXmax(); + } + // Declare observable x + RooRealVar x("x", "x", xMin, xMax); + // Create a binned dataset that imports contents of TH1 and associates its contents to observable 'x' + return (std::make_pair(x, new RooDataHist("dh", "dh", x, RooFit::Import(*histo)))); + } + + // Plot and fit a RooDataHist fitting signal and background + void fit(TH1* histo, + const TString signalType, + const TString backgroundType, + const double& xMin = 0., + const double& xMax = 0., + bool sumW2Error = false) { + reinitializeParameters(); + + rooPair imported = importTH1(histo, xMin, xMax); + RooRealVar x(imported.first); + RooDataHist* dh = imported.second; + + // Make plot of binned dataset showing Poisson error bars (RooFit default) + RooPlot* frame = x.frame(RooFit::Title("Imported TH1 with Poisson error bars")); + frame->SetName(TString(histo->GetName()) + "_frame"); + dh->plotOn(frame); + + // Build the composite model + RooAbsPdf* model = buildModel(&x, signalType, backgroundType); + + RooChi2Var chi2("chi2", "chi2", *model, *dh, RooFit::DataError(RooAbsData::SumW2)); + + // Fit the composite model + // ----------------------- + // Fit with likelihood + if (!useChi2_) { + if (sumW2Error) + model->fitTo(*dh, RooFit::Save(), RooFit::SumW2Error(kTRUE)); + else + model->fitTo(*dh); + } + // Fit with chi^2 + else { + std::cout << "FITTING WITH CHI^2" << std::endl; + RooMinuit m(chi2); + m.migrad(); + m.hesse(); + // RooFitResult* r_chi2_wgt = m.save(); + } + model->plotOn(frame); + model->plotOn(frame, RooFit::Components(backgroundType), RooFit::LineStyle(kDotted), RooFit::LineColor(kRed)); + model->paramOn(frame, RooFit::Label("fit result"), RooFit::Format("NEU", RooFit::AutoPrecision(2))); + + // TODO: fix next lines to get the prob(chi2) (ndof should be dynamically set according to the choosen pdf) + // double chi2 = xframe.chiSquare("model","data",ndof); + // double ndoff = xframeGetNbinsX(); + // double chi2prob = TMath::Prob(chi2,ndoff); + + // P l o t a n d f i t a R o o D a t a H i s t w i t h i n t e r n a l e r r o r s + // --------------------------------------------------------------------------------------------- + + // If histogram has custom error (i.e. its contents is does not originate from a Poisson process + // but e.g. is a sum of weighted events) you can data with symmetric 'sum-of-weights' error instead + // (same error bars as shown by ROOT) + RooPlot* frame2 = x.frame(RooFit::Title("Imported TH1 with internal errors")); + dh->plotOn(frame2, RooFit::DataError(RooAbsData::SumW2)); + model->plotOn(frame2); + model->plotOn(frame2, RooFit::Components(backgroundType), RooFit::LineColor(kRed)); + model->paramOn(frame2, RooFit::Label("fit result"), RooFit::Format("NEU", RooFit::AutoPrecision(2))); + + // Please note that error bars shown (Poisson or SumW2) are for visualization only, the are NOT used + // in a maximum likelihood fit + // + // A (binned) ML fit will ALWAYS assume the Poisson error interpretation of data (the mathematical definition + // of likelihood does not take any external definition of errors). Data with non-unit weights can only be correctly + // fitted with a chi^2 fit (see rf602_chi2fit.C) + + // Draw all frames on a canvas + // if( canvas == 0 ) { + // canvas = new TCanvas("rf102_dataimport","rf102_dataimport",800,800); + // canvas->cd(1); + // } + // canvas->Divide(2,1); + // canvas->cd(1) ; frame->Draw(); + // canvas->cd(2) ; frame2->Draw(); + + frame2->Draw(); + } + + // Initialization methods for all the parameters + void initMean(const double& value, + const double& min, + const double& max, + const TString& name = "mean", + const TString& title = "mean") { + if (mean_ != nullptr) + delete mean_; + mean_ = new RooRealVar(name, title, value, min, max); + initVal_mean = value; + } + void initMean2(const double& value, + const double& min, + const double& max, + const TString& name = "mean2", + const TString& title = "mean2") { + if (mean2_ != nullptr) + delete mean2_; + mean2_ = new RooRealVar(name, title, value, min, max); + initVal_mean2 = value; + } + void initMean3(const double& value, + const double& min, + const double& max, + const TString& name = "mean3", + const TString& title = "mean3") { + if (mean3_ != nullptr) + delete mean3_; + mean3_ = new RooRealVar(name, title, value, min, max); + initVal_mean3 = value; + } + void initSigma(const double& value, + const double& min, + const double& max, + const TString& name = "sigma", + const TString& title = "sigma") { + if (sigma_ != nullptr) + delete sigma_; + sigma_ = new RooRealVar(name, title, value, min, max); + initVal_sigma = value; + } + void initSigma2(const double& value, + const double& min, + const double& max, + const TString& name = "sigma2", + const TString& title = "sigma2") { + if (sigma2_ != nullptr) + delete sigma2_; + sigma2_ = new RooRealVar(name, title, value, min, max); + initVal_sigma2 = value; + } + void initSigma3(const double& value, + const double& min, + const double& max, + const TString& name = "sigma3", + const TString& title = "sigma3") { + if (sigma3_ != nullptr) + delete sigma3_; + sigma3_ = new RooRealVar(name, title, value, min, max); + initVal_sigma3 = value; + } + void initGamma(const double& value, + const double& min, + const double& max, + const TString& name = "gamma", + const TString& title = "gamma") { + if (gamma_ != nullptr) + delete gamma_; + gamma_ = new RooRealVar(name, title, value, min, max); + initVal_gamma = value; + } + void initGaussFrac(const double& value, + const double& min, + const double& max, + const TString& name = "GaussFrac", + const TString& title = "GaussFrac") { + if (gaussFrac_ != nullptr) + delete gaussFrac_; + gaussFrac_ = new RooRealVar(name, title, value, min, max); + initVal_gaussFrac = value; + } + void initGaussFrac2(const double& value, + const double& min, + const double& max, + const TString& name = "GaussFrac2", + const TString& title = "GaussFrac2") { + if (gaussFrac2_ != nullptr) + delete gaussFrac2_; + gaussFrac2_ = new RooRealVar(name, title, value, min, max); + initVal_gaussFrac2 = value; + } + void initExpCoeffA0(const double& value, + const double& min, + const double& max, + const TString& name = "expCoeffa0", + const TString& title = "expCoeffa0") { + if (expCoeffa0_ != nullptr) + delete expCoeffa0_; + expCoeffa0_ = new RooRealVar(name, title, value, min, max); + initVal_expCoeffa0 = value; + } + void initExpCoeffA1(const double& value, + const double& min, + const double& max, + const TString& name = "expCoeffa1", + const TString& title = "expCoeffa1") { + if (expCoeffa1_ != nullptr) + delete expCoeffa1_; + expCoeffa1_ = new RooRealVar(name, title, value, min, max); + initVal_expCoeffa1 = value; + } + void initExpCoeffA2(const double& value, + const double& min, + const double& max, + const TString& name = "expCoeffa2", + const TString& title = "expCoeffa2") { + if (expCoeffa2_ != nullptr) + delete expCoeffa2_; + expCoeffa2_ = new RooRealVar(name, title, value, min, max); + initVal_expCoeffa2 = value; + } + void initFsig(const double& value, + const double& min, + const double& max, + const TString& name = "fsig", + const TString& title = "signal fraction") { + if (fsig_ != nullptr) + delete fsig_; + fsig_ = new RooRealVar(name, title, value, min, max); + initVal_fsig = value; + } + void initA0(const double& value, + const double& min, + const double& max, + const TString& name = "a0", + const TString& title = "a0") { + if (a0_ != nullptr) + delete a0_; + a0_ = new RooRealVar(name, title, value, min, max); + initVal_a0 = value; + } + void initA1(const double& value, + const double& min, + const double& max, + const TString& name = "a1", + const TString& title = "a1") { + if (a1_ != nullptr) + delete a1_; + a1_ = new RooRealVar(name, title, value, min, max); + initVal_a1 = value; + } + void initA2(const double& value, + const double& min, + const double& max, + const TString& name = "a2", + const TString& title = "a2") { + if (a2_ != nullptr) + delete a2_; + a2_ = new RooRealVar(name, title, value, min, max); + initVal_a2 = value; + } + void initA3(const double& value, + const double& min, + const double& max, + const TString& name = "a3", + const TString& title = "a3") { + if (a3_ != nullptr) + delete a3_; + a3_ = new RooRealVar(name, title, value, min, max); + initVal_a3 = value; + } + void initA4(const double& value, + const double& min, + const double& max, + const TString& name = "a4", + const TString& title = "a4") { + if (a4_ != nullptr) + delete a4_; + a4_ = new RooRealVar(name, title, value, min, max); + initVal_a4 = value; + } + void initA5(const double& value, + const double& min, + const double& max, + const TString& name = "a5", + const TString& title = "a5") { + if (a5_ != nullptr) + delete a5_; + a5_ = new RooRealVar(name, title, value, min, max); + initVal_a5 = value; + } + void initA6(const double& value, + const double& min, + const double& max, + const TString& name = "a6", + const TString& title = "a6") { + if (a6_ != nullptr) + delete a6_; + a6_ = new RooRealVar(name, title, value, min, max); + initVal_a6 = value; + } + void initAlpha(const double& value, + const double& min, + const double& max, + const TString& name = "alpha", + const TString& title = "alpha") { + if (alpha_ != nullptr) + delete alpha_; + alpha_ = new RooRealVar(name, title, value, min, max); + initVal_alpha = value; + } + void initN(const double& value, + const double& min, + const double& max, + const TString& name = "n", + const TString& title = "n") { + if (n_ != nullptr) + delete n_; + n_ = new RooRealVar(name, title, value, min, max); + initVal_n = value; + } + void initFGCB(const double& value, + const double& min, + const double& max, + const TString& name = "fGCB", + const TString& title = "fGCB") { + if (fGCB_ != nullptr) + delete fGCB_; + fGCB_ = new RooRealVar(name, title, value, min, max); + initVal_fGCB = value; + } + + void reinitializeParameters() { + if (mean_ != nullptr) + mean_->setVal(initVal_mean); + if (mean2_ != nullptr) + mean2_->setVal(initVal_mean2); + if (mean3_ != nullptr) + mean3_->setVal(initVal_mean3); + if (sigma_ != nullptr) + sigma_->setVal(initVal_sigma); + if (sigma2_ != nullptr) + sigma2_->setVal(initVal_sigma2); + if (sigma3_ != nullptr) + sigma3_->setVal(initVal_sigma3); + if (gamma_ != nullptr) + gamma_->setVal(initVal_gamma); + if (gaussFrac_ != nullptr) + gaussFrac_->setVal(initVal_gaussFrac); + if (gaussFrac2_ != nullptr) + gaussFrac2_->setVal(initVal_gaussFrac2); + if (expCoeffa0_ != nullptr) + expCoeffa0_->setVal(initVal_expCoeffa0); + if (expCoeffa1_ != nullptr) + expCoeffa1_->setVal(initVal_expCoeffa1); + if (expCoeffa2_ != nullptr) + expCoeffa2_->setVal(initVal_expCoeffa2); + if (fsig_ != nullptr) + fsig_->setVal(initVal_fsig); + if (a0_ != nullptr) + a0_->setVal(initVal_a0); + if (a1_ != nullptr) + a1_->setVal(initVal_a1); + if (a2_ != nullptr) + a2_->setVal(initVal_a2); + if (a3_ != nullptr) + a3_->setVal(initVal_a3); + if (a4_ != nullptr) + a4_->setVal(initVal_a4); + if (a5_ != nullptr) + a5_->setVal(initVal_a5); + if (a6_ != nullptr) + a6_->setVal(initVal_a6); + if (alpha_ != nullptr) + alpha_->setVal(initVal_alpha); + if (n_ != nullptr) + n_->setVal(initVal_n); + if (fGCB_ != nullptr) + fGCB_->setVal(initVal_fGCB); + } + + inline RooRealVar* mean() { return mean_; } + inline RooRealVar* mean2() { return mean2_; } + inline RooRealVar* mean3() { return mean3_; } + inline RooRealVar* sigma() { return sigma_; } + inline RooRealVar* sigma2() { return sigma2_; } + inline RooRealVar* sigma3() { return sigma3_; } + inline RooRealVar* gamma() { return gamma_; } + inline RooRealVar* gaussFrac() { return gaussFrac_; } + inline RooRealVar* gaussFrac2() { return gaussFrac2_; } + inline RooRealVar* expCoeffa0() { return expCoeffa0_; } + inline RooRealVar* expCoeffa1() { return expCoeffa1_; } + inline RooRealVar* expCoeffa2() { return expCoeffa2_; } + inline RooRealVar* fsig() { return fsig_; } + inline RooRealVar* a0() { return a0_; } + inline RooRealVar* a1() { return a1_; } + inline RooRealVar* a2() { return a2_; } + inline RooRealVar* a3() { return a3_; } + inline RooRealVar* a4() { return a4_; } + inline RooRealVar* a5() { return a5_; } + inline RooRealVar* a6() { return a6_; } + inline RooRealVar* alpha() { return alpha_; } + inline RooRealVar* n() { return n_; } + inline RooRealVar* fGCB() { return fGCB_; } + + /// Build the model for the specified signal type + RooAbsPdf* buildSignalModel(RooRealVar* x, const TString& signalType) { + RooAbsPdf* signal = nullptr; + if (signalType == "gaussian") { + // Fit a Gaussian p.d.f to the data + if ((mean_ == nullptr) || (sigma_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean and sigma" + << std::endl; + exit(1); + } + signal = new RooGaussian("gauss", "gauss", *x, *mean_, *sigma_); + } else if (signalType == "doubleGaussian") { + // Fit with double gaussian + if ((mean_ == nullptr) || (sigma_ == nullptr) || (sigma2_ == nullptr)) { + std::cout + << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma and sigma2" + << std::endl; + exit(1); + } + RooGaussModel* gaussModel = new RooGaussModel("gaussModel", "gaussModel", *x, *mean_, *sigma_); + RooGaussModel* gaussModel2 = new RooGaussModel("gaussModel2", "gaussModel2", *x, *mean_, *sigma2_); + signal = new RooAddModel("doubleGaussian", "double gaussian", RooArgList(*gaussModel, *gaussModel2), *gaussFrac_); + } else if (signalType == "tripleGaussian") { + // Fit with triple gaussian + if ((mean_ == nullptr) || (mean2_ == nullptr) || (mean3_ == nullptr) || (sigma_ == nullptr) || + (sigma2_ == nullptr) || (sigma3_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, " + "mean3, sigma, sigma2, sigma3" + << std::endl; + exit(1); + } + RooGaussModel* gaussModel = new RooGaussModel("gaussModel", "gaussModel", *x, *mean_, *sigma_); + RooGaussModel* gaussModel2 = new RooGaussModel("gaussModel2", "gaussModel2", *x, *mean2_, *sigma2_); + RooGaussModel* gaussModel3 = new RooGaussModel("gaussModel3", "gaussModel3", *x, *mean3_, *sigma3_); + signal = new RooAddModel("tripleGaussian", + "triple gaussian", + RooArgList(*gaussModel, *gaussModel2, *gaussModel3), + RooArgList(*gaussFrac_, *gaussFrac2_)); + } else if (signalType == "breitWigner") { + // Fit a Breit-Wigner + if ((mean_ == nullptr) || (gamma_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean and gamma" + << std::endl; + exit(1); + } + signal = new RooBreitWigner("breiWign", "breitWign", *x, *mean_, *gamma_); + } else if (signalType == "relBreitWigner") { + // Fit a relativistic Breit-Wigner + if ((mean_ == nullptr) || (gamma_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean and gamma" + << std::endl; + exit(1); + } + signal = new RooGenericPdf("Relativistic Breit-Wigner", + "RBW", + "@0/(pow(@0*@0 - @1*@1,2) + @2*@2*@0*@0*@0*@0/(@1*@1))", + RooArgList(*x, *mean_, *gamma_)); + } else if (signalType == "voigtian") { + // Fit a Voigtian + if ((mean_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr)) { + std::cout + << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma and gamma" + << std::endl; + exit(1); + } + signal = new RooVoigtian("voigt", "voigt", *x, *mean_, *gamma_, *sigma_); + } else if (signalType == "crystalBall") { + // Fit a CrystalBall + if ((mean_ == nullptr) || (sigma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma, " + "alpha and n" + << std::endl; + exit(1); + } + signal = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma_, *alpha_, *n_); + } else if (signalType == "breitWignerTimesCB") { + // Fit a Breit Wigner convoluted with a CrystalBall + if ((mean_ == nullptr) || (mean2_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) || + (alpha_ == nullptr) || (n_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, " + "sigma, gamma, alpha and n" + << std::endl; + exit(1); + } + RooAbsPdf* bw = new RooBreitWigner("breiWigner", "breitWigner", *x, *mean_, *gamma_); + RooAbsPdf* cb = new RooCBShape("crystalBall", "crystalBall", *x, *mean2_, *sigma_, *alpha_, *n_); + signal = new RooFFTConvPdf("breitWignerTimesCB", "breitWignerTimesCB", *x, *bw, *cb); + } else if (signalType == "relBreitWignerTimesCB") { + // Fit a relativistic Breit Wigner convoluted with a CrystalBall + if ((mean_ == nullptr) || (mean2_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) || + (alpha_ == nullptr) || (n_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, " + "sigma, gamma, alpha and n" + << std::endl; + exit(1); + } + RooGenericPdf* bw = new RooGenericPdf("Relativistic Breit-Wigner", + "RBW", + "@0/(pow(@0*@0 - @1*@1,2) + @2*@2*@0*@0*@0*@0/(@1*@1))", + RooArgList(*x, *mean_, *gamma_)); + RooAbsPdf* cb = new RooCBShape("crystalBall", "crystalBall", *x, *mean2_, *sigma_, *alpha_, *n_); + signal = new RooFFTConvPdf("relBreitWignerTimesCB", "relBreitWignerTimesCB", *x, *bw, *cb); + } else if (signalType == "gaussianPlusCrystalBall") { + // Fit a Gaussian + CrystalBall with the same mean + if ((mean_ == nullptr) || (sigma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) || (sigma2_ == nullptr) || + (fGCB_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma, " + "sigma2, alpha, n and fGCB" + << std::endl; + exit(1); + } + RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma_, *alpha_, *n_); + RooAbsPdf* tempGaussian = new RooGaussian("gauss", "gauss", *x, *mean_, *sigma2_); + + signal = new RooAddPdf( + "gaussianPlusCrystalBall", "gaussianPlusCrystalBall", RooArgList(*tempCB, *tempGaussian), *fGCB_); + } else if (signalType == "voigtianPlusCrystalBall") { + // Fit a Voigtian + CrystalBall with the same mean + if ((mean_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) || + (sigma2_ == nullptr) || (fGCB_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, gamma, " + "sigma, sigma2, alpha, n and fGCB" + << std::endl; + exit(1); + } + RooAbsPdf* tempVoigt = new RooVoigtian("voigt", "voigt", *x, *mean_, *gamma_, *sigma_); + RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma2_, *alpha_, *n_); + + signal = + new RooAddPdf("voigtianPlusCrystalBall", "voigtianPlusCrystalBall", RooArgList(*tempCB, *tempVoigt), *fGCB_); + } else if (signalType == "breitWignerPlusCrystalBall") { + // Fit a Breit-Wigner + CrystalBall with the same mean + if ((mean_ == nullptr) || (gamma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) || (sigma2_ == nullptr) || + (fGCB_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, gamma, " + "sigma, alpha, n and fGCB" + << std::endl; + exit(1); + } + RooAbsPdf* tempBW = new RooBreitWigner("breitWign", "breitWign", *x, *mean_, *gamma_); + RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma2_, *alpha_, *n_); + + signal = new RooAddPdf( + "breitWignerPlusCrystalBall", "breitWignerPlusCrystalBall", RooArgList(*tempCB, *tempBW), *fGCB_); + } + + else if (signalType != "") { + std::cout << "Unknown signal function: " << signalType << ". Signal will not be in the model" << std::endl; + } + return signal; + } + + /// Build the model for the specified background type + RooAbsPdf* buildBackgroundModel(RooRealVar* x, const TString& backgroundType) { + RooAbsPdf* background = nullptr; + if (backgroundType == "exponential") { + // Add an exponential for the background + if ((expCoeffa1_ == nullptr) || (fsig_ == nullptr)) { + std::cout + << "Error: one or more parameters are not initialized. Please be sure to initialize expCoeffa1 and fsig" + << std::endl; + exit(1); + } + background = new RooExponential("exponential", "exponential", *x, *expCoeffa1_); + } + + if (backgroundType == "exponentialpol") { + // Add an exponential for the background + if ((expCoeffa0_ == nullptr) || (expCoeffa1_ == nullptr) || (expCoeffa2_ == nullptr) || (fsig_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize expCoeff and fsig" + << std::endl; + exit(1); + } + background = new RooGenericPdf("exponential", + "exponential", + "TMath::Exp(@1+@2*@0+@3*@0*@0)", + RooArgList(*x, *expCoeffa0_, *expCoeffa1_, *expCoeffa2_)); + } + + else if (backgroundType == "chebychev0") { + // Add a linear background + if (a0_ == nullptr) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize a0" << std::endl; + exit(1); + } + background = new RooChebychev("chebychev0", "chebychev0", *x, *a0_); + } else if (backgroundType == "chebychev1") { + // Add a 2nd order chebychev polynomial background + if ((a0_ == nullptr) || (a1_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize a0 and a1" + << std::endl; + exit(1); + } + background = new RooChebychev("chebychev1", "chebychev1", *x, RooArgList(*a0_, *a1_)); + } else if (backgroundType == "chebychev3") { + // Add a 3rd order chebychev polynomial background + if ((a0_ == nullptr) || (a1_ == nullptr) || (a2_ == nullptr) || (a3_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize a0, a1, a2 and a3" + << std::endl; + exit(1); + } + background = new RooChebychev("3rdOrderPol", "3rdOrderPol", *x, RooArgList(*a0_, *a1_, *a2_, *a3_)); + } + + else if (backgroundType == "chebychev6") { + // Add a 6th order chebychev polynomial background + if ((a0_ == nullptr) || (a1_ == nullptr) || (a2_ == nullptr) || (a3_ == nullptr) || (a4_ == nullptr) || + (a5_ == nullptr) || (a6_ == nullptr)) { + std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize a0, a1, a2, a3, " + "a4, a5 and a6" + << std::endl; + exit(1); + } + background = + new RooChebychev("6thOrderPol", "6thOrderPol", *x, RooArgList(*a0_, *a1_, *a2_, *a3_, *a4_, *a5_, *a6_)); + } + + return background; + } + + /// Build the model to fit + RooAbsPdf* buildModel(RooRealVar* x, const TString& signalType, const TString& backgroundType) { + RooAbsPdf* model = nullptr; + + RooAbsPdf* signal = buildSignalModel(x, signalType); + RooAbsPdf* background = buildBackgroundModel(x, backgroundType); + + if ((signal != nullptr) && (background != nullptr)) { + // Combine signal and background pdfs + std::cout << "Building model with signal and backgound" << std::endl; + model = new RooAddPdf("model", "model", RooArgList(*signal, *background), *fsig_); + } else if (signal != nullptr) { + std::cout << "Building model with signal" << std::endl; + model = signal; + } else if (background != nullptr) { + std::cout << "Building model with backgound" << std::endl; + model = background; + } else { + std::cout << "Nothing to fit" << std::endl; + exit(0); + } + return model; + } + + bool useChi2_; + +protected: + // Declare all variables + RooRealVar* mean_; + RooRealVar* mean2_; + RooRealVar* mean3_; + RooRealVar* sigma_; + RooRealVar* sigma2_; + RooRealVar* sigma3_; + RooRealVar* gamma_; + RooRealVar* gaussFrac_; + RooRealVar* gaussFrac2_; + RooRealVar* expCoeffa0_; + RooRealVar* expCoeffa1_; + RooRealVar* expCoeffa2_; + RooRealVar* fsig_; + RooRealVar* a0_; + RooRealVar* a1_; + RooRealVar* a2_; + RooRealVar* a3_; + RooRealVar* a4_; + RooRealVar* a5_; + RooRealVar* a6_; + RooRealVar* alpha_; + RooRealVar* n_; + RooRealVar* fGCB_; + + // Initial values + double initVal_mean; + double initVal_mean2; + double initVal_mean3; + double initVal_sigma; + double initVal_sigma2; + double initVal_sigma3; + double initVal_gamma; + double initVal_gaussFrac; + double initVal_gaussFrac2; + double initVal_expCoeffa0; + double initVal_expCoeffa1; + double initVal_expCoeffa2; + double initVal_fsig; + double initVal_a0; + double initVal_a1; + double initVal_a2; + double initVal_a3; + double initVal_a4; + double initVal_a5; + double initVal_a6; + double initVal_alpha; + double initVal_n; + double initVal_fGCB; +}; + +#endif From 09b34e09b810e32168b3ca7231f9f3d115361619 Mon Sep 17 00:00:00 2001 From: mmusich Date: Fri, 16 Dec 2022 14:37:40 +0100 Subject: [PATCH 3/4] add merge step for DiMuon validation --- Alignment/OfflineValidation/bin/BuildFile.xml | 20 +- Alignment/OfflineValidation/bin/Zmumumerge.cc | 292 ++++++++++++++++++ 2 files changed, 303 insertions(+), 9 deletions(-) create mode 100644 Alignment/OfflineValidation/bin/Zmumumerge.cc diff --git a/Alignment/OfflineValidation/bin/BuildFile.xml b/Alignment/OfflineValidation/bin/BuildFile.xml index c96f10c2e7e7b..b8d68c8419dcf 100644 --- a/Alignment/OfflineValidation/bin/BuildFile.xml +++ b/Alignment/OfflineValidation/bin/BuildFile.xml @@ -1,18 +1,20 @@ - - - - + + + - - + + + + - + + - - + + diff --git a/Alignment/OfflineValidation/bin/Zmumumerge.cc b/Alignment/OfflineValidation/bin/Zmumumerge.cc new file mode 100644 index 0000000000000..3ee9aab7e7a98 --- /dev/null +++ b/Alignment/OfflineValidation/bin/Zmumumerge.cc @@ -0,0 +1,292 @@ +#include +#include +#include +#include +#include + +#include "toolbox.h" +#include "FitWithRooFit.cc" +#include "Options.h" + +#include "TAxis.h" +#include "TBranch.h" +#include "TCanvas.h" +#include "TChain.h" +#include "TCut.h" +#include "TF1.h" +#include "TFile.h" +#include "TFrame.h" +#include "TH1.h" +#include "TH1D.h" +#include "TH1F.h" +#include "TH2.h" +#include "TH2F.h" +#include "THStack.h" +#include "TLatex.h" +#include "TLegend.h" +#include "TMath.h" +#include "TPad.h" +#include "TPaveText.h" +#include "TRandom.h" +#include "TString.h" +#include "TStyle.h" +#include "TSystem.h" +#include "TTree.h" +//#include "RooGlobalFunc.h" + +#include +#include +#include +#include + +using namespace RooFit; +using namespace std; +using namespace AllInOneConfig; +namespace pt = boost::property_tree; +/*--------------------------------------------------------------------*/ +void makeNicePlotStyle(RooPlot* plot) { + plot->GetXaxis()->CenterTitle(true); + plot->GetYaxis()->CenterTitle(true); + plot->GetXaxis()->SetTitleFont(42); + plot->GetYaxis()->SetTitleFont(42); + plot->GetXaxis()->SetTitleSize(0.05); + plot->GetYaxis()->SetTitleSize(0.05); + plot->GetXaxis()->SetTitleOffset(0.9); + plot->GetYaxis()->SetTitleOffset(1.3); + plot->GetXaxis()->SetLabelFont(42); + plot->GetYaxis()->SetLabelFont(42); + plot->GetYaxis()->SetLabelSize(.05); + plot->GetXaxis()->SetLabelSize(.05); +} +/*--------------------------------------------------------------------*/ + +RooRealVar MuMu_mass("MuMu_mass", "MuMu_mass", 70, 110); +static TString GT = ""; +TLatex* tlxg = new TLatex(); +class FitOut { +public: + double mean; + double mean_err; + double sigma; + double sigma_err; + double chi2; + FitOut(double a, double b, double c, double d) : mean(a), mean_err(b), sigma(c), sigma_err(d) {} +}; + +FitOut ZMassBinFit_OldTool(TH1D* th1d_input, TString s_name = "zmumu_fitting", TString output_path = "./") { + double xMin(75), xMax(105), xMean(91); + double sigma = 2; + double sigmaMin = 0.1; + double sigmaMax = 10; + + FitWithRooFit* fitter = new FitWithRooFit(); + double sigma2(0.1), sigma2Min(0.), sigma2Max(10.), useChi2(false); + fitter->useChi2_ = useChi2; + fitter->initMean(xMean, xMin, xMax); + fitter->initSigma(sigma, sigmaMin, sigmaMax); + fitter->initSigma2(sigma2, sigma2Min, sigma2Max); + fitter->initAlpha(1.5, 0.05, 10.); + fitter->initN(1, 0.01, 100.); + fitter->initFGCB(0.4, 0., 1.); + + fitter->initMean(91.1876, xMin, xMax); + fitter->initGamma(2.4952, 0., 10.); + fitter->gamma()->setConstant(kTRUE); + fitter->initMean2(0., -20., 20.); + fitter->mean2()->setConstant(kTRUE); + fitter->initSigma(1.2, 0., 5.); + fitter->initAlpha(1.5, 0.05, 10.); + fitter->initN(1, 0.01, 100.); + fitter->initExpCoeffA0(-1., -10., 10.); + fitter->initExpCoeffA1(0., -10., 10.); + fitter->initExpCoeffA2(0., -2., 2.); + fitter->initFsig(0.9, 0., 1.); + fitter->initA0(0., -10., 10.); + fitter->initA1(0., -10., 10.); + fitter->initA2(0., -10., 10.); + fitter->initA3(0., -10., 10.); + fitter->initA4(0., -10., 10.); + fitter->initA5(0., -10., 10.); + fitter->initA6(0., -10., 10.); + TCanvas* c1 = new TCanvas(); + c1->Clear(); + c1->SetLeftMargin(0.15); + c1->SetRightMargin(0.10); + + fitter->fit(th1d_input, "breitWignerTimesCB", "exponential", xMin, xMax, false); + + c1->Print(Form("%s/fitResultPlot/%s_oldtool.pdf", output_path.Data(), s_name.Data())); + c1->Print(Form("%s/fitResultPlot/%s_oldtool.root", output_path.Data(), s_name.Data())); + + FitOut fitRes( + fitter->mean()->getValV(), fitter->mean()->getError(), fitter->sigma()->getValV(), fitter->sigma()->getError()); + return fitRes; +} +void Draw_th1d(TH1D* th1d_input, TString variable_name) { + TCanvas* c = new TCanvas(); + c->cd(); + gStyle->SetOptStat(0); + th1d_input->SetMarkerStyle(kFullCircle); + th1d_input->SetMarkerColor(kRed); + th1d_input->SetLineColor(kRed); + th1d_input->SetMaximum(91.4); + th1d_input->SetMinimum(90.85); + th1d_input->GetXaxis()->SetTitle(variable_name.Data()); + th1d_input->GetXaxis()->SetTitleOffset(1.2); + th1d_input->GetYaxis()->SetTitle("Mass mean (GeV)"); + th1d_input->Draw(); + tlxg->DrawLatexNDC(0.2, 0.8, Form("%s", GT.Data())); + c->Print(Form("%s/fitResultPlot/mass_VS_%s.pdf", GT.Data(), variable_name.Data())); +} + +const static int variables_number = 8; +const TString tstring_variables_name[variables_number] = { + "CosThetaCS", "DeltaEta", "EtaMinus", "EtaPlus", "PhiCS", "PhiMinus", "PhiPlus", "Pt"}; +void Fitting_GetMassmeanVSvariables(TString inputfile_name, TString output_path) { + TH2D* th2d_mass_variables[variables_number]; + TFile* inputfile = TFile::Open(inputfile_name.Data()); + TDirectoryFile* tdirectory = (TDirectoryFile*)inputfile->Get("myanalysis"); + for (int i = 0; i < variables_number; i++) { + TString th2d_name = Form("th2d_mass_%s", tstring_variables_name[i].Data()); + th2d_mass_variables[i] = (TH2D*)tdirectory->Get(th2d_name); + } + + gSystem->Exec(Form("mkdir -p %s", output_path.Data())); + gSystem->Exec(Form("mkdir -p %s/fitResultPlot", output_path.Data())); + TFile* outpufile = TFile::Open(Form("%s/fitting_output.root", output_path.Data()), "recreate"); + TH1D* th1d_variables_meanmass[variables_number]; + TH1D* th1d_variables_entries[variables_number]; + const int variables_rebin[variables_number] = {1, 1, 1, 1, 1, 1, 1, 1}; + const double xaxis_range[variables_number][2] = { + {-1, 1}, {-4.8, 4.8}, {-2.4, 2.4}, {-2.4, 2.4}, {-1, 1}, {-M_PI, M_PI}, {-M_PI, M_PI}, {0, 100}}; + for (int i = 0; i < variables_number; i++) { + TString th1d_name = Form("th1d_meanmass_%s", tstring_variables_name[i].Data()); + + th2d_mass_variables[i]->RebinY(variables_rebin[i]); + th1d_variables_meanmass[i] = th2d_mass_variables[i]->ProjectionY(th1d_name, 1, 1, "d"); + for (int j = 0; j < th1d_variables_meanmass[i]->GetNbinsX(); j++) { + if (i == 7 and j > 25) { + continue; + } + cout << "th1d_variables_meanmass[i]->GetNbinsX()=" << th1d_variables_meanmass[i]->GetNbinsX() << endl; + cout << "th2d_mass_variables[i]->GetNbinsY()=" << th2d_mass_variables[i]->GetNbinsY() << endl; + th1d_variables_meanmass[i]->SetBinContent(j, 0); + th1d_variables_meanmass[i]->SetBinError(j, 0); + + TString th1d_mass_temp_name = Form("th1d_mass_%s_%d", tstring_variables_name[i].Data(), j); + TH1D* th1d_i = th2d_mass_variables[i]->ProjectionX(th1d_mass_temp_name, j, j, "d"); + th1d_i->Write(th1d_mass_temp_name); + TString s_cut = Form("nocut"); + TString s_name = Form("%s_%d", tstring_variables_name[i].Data(), j); + + FitOut fitR = ZMassBinFit_OldTool(th1d_i, s_name, output_path); + th1d_variables_meanmass[i]->SetBinContent(j, fitR.mean); + th1d_variables_meanmass[i]->SetBinError(j, fitR.mean_err); + } + th1d_variables_meanmass[i]->GetXaxis()->SetRangeUser(xaxis_range[i][0], xaxis_range[i][1]); + Draw_th1d(th1d_variables_meanmass[i], tstring_variables_name[i]); + outpufile->cd(); + th1d_variables_meanmass[i]->Write(th1d_name); + + TString th1d_name_entries = Form("th1d_entries_%s", tstring_variables_name[i].Data()); + th1d_variables_entries[i] = th2d_mass_variables[i]->ProjectionY(th1d_name_entries, 0, -1, "d"); + th1d_variables_entries[i]->GetXaxis()->SetTitle(tstring_variables_name[i].Data()); + th1d_variables_entries[i]->GetYaxis()->SetTitle("Entry"); + outpufile->cd(); + th1d_variables_entries[i]->Write(th1d_name_entries); + } + + outpufile->Write(); + outpufile->Close(); + delete outpufile; +} + +const static int max_file_number = 10; +void Draw_TH1D_forMultiRootFiles(vector file_names, + vector label_names, + vector colors, + vector styles, + TString th1d_name, + TString output_name) { + TH1D* th1d_input[max_file_number]; + TFile* file_input[max_file_number]; + for (auto const& filename : file_names | boost::adaptors::indexed(0)) { + file_input[filename.index()] = TFile::Open(filename.value()); + th1d_input[filename.index()] = (TH1D*)file_input[filename.index()]->Get(th1d_name); + } + + TCanvas* c = new TCanvas(); + TLegend* lg = new TLegend(0.2, 0.7, 0.5, 0.95); + c->cd(); + gStyle->SetOptStat(0); + th1d_input[0]->SetTitle(""); + + for (auto const& labelname : label_names | boost::adaptors::indexed(0)) { + th1d_input[labelname.index()]->SetMarkerColor(colors[labelname.index()]); + th1d_input[labelname.index()]->SetLineColor(colors[labelname.index()]); + th1d_input[labelname.index()]->SetMarkerStyle(styles[labelname.index()]); + th1d_input[labelname.index()]->Draw("same"); + lg->AddEntry(th1d_input[labelname.index()], labelname.value()); + } + lg->Draw("same"); + c->SaveAs(output_name); +} + +int Zmumumerge(int argc, char* argv[]) { + vector vec_single_file_path; + vector vec_single_file_name; + vector vec_global_tag; + vector vec_color; + vector vec_style; + + Options options; + options.helper(argc, argv); + options.parser(argc, argv); + pt::ptree main_tree; + pt::read_json(options.config, main_tree); + pt::ptree alignments = main_tree.get_child("alignments"); + pt::ptree validation = main_tree.get_child("validation"); + for (const auto& childTree : alignments) { + vec_single_file_path.push_back(childTree.second.get("file")); + vec_single_file_name.push_back(childTree.second.get("file") + "/Zmumu.root"); + vec_color.push_back(childTree.second.get("color")); + vec_style.push_back(childTree.second.get("style")); + vec_global_tag.push_back(childTree.second.get("globaltag")); + + //Fitting_GetMassmeanVSvariables(childTree.second.get("file") + "/Zmumu.root", childTree.second.get("file")); + } + TString merge_output = main_tree.get("output"); + //============================================= + vector vec_single_fittingoutput; + vec_single_fittingoutput.clear(); + for (unsigned i = 0; i < vec_single_file_path.size(); i++) { + Fitting_GetMassmeanVSvariables(vec_single_file_name[i], vec_single_file_path[i]); + vec_single_fittingoutput.push_back(vec_single_file_path[i] + "/fitting_output.root"); + } + + int files_number = vec_single_file_path.size(); + cout << "files_number=" << files_number << endl; + for (int idx_variable = 0; idx_variable < variables_number; idx_variable++) { + TString th1d_name = Form("th1d_meanmass_%s", tstring_variables_name[idx_variable].Data()); + Draw_TH1D_forMultiRootFiles( + vec_single_fittingoutput, + vec_global_tag, + vec_color, + vec_style, + th1d_name, + merge_output + Form("/meanmass_%s_GTs.pdf", tstring_variables_name[idx_variable].Data())); + TString th1d_name_entries = Form("th1d_entries_%s", tstring_variables_name[idx_variable].Data()); + Draw_TH1D_forMultiRootFiles( + vec_single_fittingoutput, + vec_global_tag, + vec_color, + vec_style, + th1d_name_entries, + merge_output + Form("/entries_%s_GTs.pdf", tstring_variables_name[idx_variable].Data())); + } + //============================================= + return EXIT_SUCCESS; +} +#ifndef DOXYGEN_SHOULD_SKIP_THIS +int main(int argc, char* argv[]) { return Zmumumerge(argc, argv); } +#endif From e600cb0657aee3e54e13555420c53d1c99f73ec8 Mon Sep 17 00:00:00 2001 From: mmusich Date: Fri, 16 Dec 2022 14:38:11 +0100 Subject: [PATCH 4/4] add configuration files for Z->mm validation in new all-in-one --- .../python/TkAlAllInOneTool/Zmumu.py | 93 +++++++++ .../python/TkAlAllInOneTool/Zmumu_cfg.py | 187 ++++++++++++++++++ .../scripts/validateAlignments.py | 4 + 3 files changed, 284 insertions(+) create mode 100644 Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu.py create mode 100644 Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu_cfg.py diff --git a/Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu.py b/Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu.py new file mode 100644 index 0000000000000..7889121b5263f --- /dev/null +++ b/Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu.py @@ -0,0 +1,93 @@ +import copy +import os + +def Zmumu(config, validationDir): + ##List with all jobs + jobs = [] + zmumuType = "single" + + ##List with all wished IOVs + IOVs = [] + + ##Start with single Zmumu jobs + if not zmumuType in config["validations"]["Zmumu"]: + raise Exception("No 'single' key word in config for Zmumu") + + for datasetName in config["validations"]["Zmumu"][zmumuType]: + for IOV in config["validations"]["Zmumu"][zmumuType][datasetName]["IOV"]: + ##Save IOV to loop later for merge jobs + if not IOV in IOVs: + IOVs.append(IOV) + + for alignment in config["validations"]["Zmumu"][zmumuType][datasetName]["alignments"]: + ##Work directory for each IOV + workDir = "{}/Zmumu/{}/{}/{}/{}".format(validationDir, zmumuType, datasetName, alignment, IOV) + + ##Write local config + local = {} + local["output"] = "{}/{}/{}/{}/{}/{}".format(config["LFS"], config["name"], zmumuType, alignment, datasetName, IOV) + local["alignment"] = copy.deepcopy(config["alignments"][alignment]) + local["validation"] = copy.deepcopy(config["validations"]["Zmumu"][zmumuType][datasetName]) + local["validation"].pop("alignments") + local["validation"]["IOV"] = IOV + if "goodlumi" in local["validation"]: + local["validation"]["goodlumi"] = local["validation"]["goodlumi"].format(IOV) + + ##Write job info + job = { + "name": "Zmumu_{}_{}_{}_{}".format(zmumuType, alignment, datasetName, IOV), + "dir": workDir, + "exe": "cmsRun", + "cms-config": "{}/src/Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu_cfg.py".format(os.environ["CMSSW_BASE"]), + "run-mode": "Condor", + "dependencies": [], + "config": local, + } + + jobs.append(job) + + ##Do merge Zmumu if wished + if "merge" in config["validations"]["Zmumu"]: + ##List with merge jobs, will be expanded to jobs after looping + mergeJobs = [] + zmumuType = "merge" + + ##Loop over all merge jobs/IOVs which are wished + for mergeName in config["validations"]["Zmumu"][zmumuType]: + for IOV in IOVs: + ##Work directory for each IOV + workDir = "{}/Zmumu/{}/{}/{}".format(validationDir, zmumuType, mergeName, IOV) + + ##Write job info + local = {} + + job = { + "name": "Zmumu_{}_{}_{}".format(zmumuType, mergeName, IOV), + "dir": workDir, + "exe": "Zmumumerge", + "run-mode": "Condor", + "dependencies": [], + "config": local, + } + + for alignment in config["alignments"]: + ##Deep copy necessary things from global config + local.setdefault("alignments", {}) + local["alignments"][alignment] = copy.deepcopy(config["alignments"][alignment]) + local["validation"] = copy.deepcopy(config["validations"]["Zmumu"][zmumuType][mergeName]) + local["output"] = "{}/{}/{}/{}/{}".format(config["LFS"], config["name"], zmumuType, mergeName, IOV) + + ##Loop over all single jobs + for singleJob in jobs: + ##Get single job info and append to merge job if requirements fullfilled + alignment, datasetName, singleIOV = singleJob["name"].split("_")[2:] + + if int(singleIOV) == IOV and datasetName in config["validations"]["Zmumu"][zmumuType][mergeName]["singles"]: + local["alignments"][alignment]["file"] = singleJob["config"]["output"] + job["dependencies"].append(singleJob["name"]) + + mergeJobs.append(job) + + jobs.extend(mergeJobs) + + return jobs diff --git a/Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu_cfg.py b/Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu_cfg.py new file mode 100644 index 0000000000000..b9895ced8afa8 --- /dev/null +++ b/Alignment/OfflineValidation/python/TkAlAllInOneTool/Zmumu_cfg.py @@ -0,0 +1,187 @@ +import math +import json +import os + +import FWCore.ParameterSet.Config as cms +import FWCore.PythonUtilities.LumiList as LumiList +from FWCore.ParameterSet.VarParsing import VarParsing +from Alignment.OfflineValidation.TkAlAllInOneTool.utils import _byteify + +################################################################### +# Define process +################################################################### +process = cms.Process("TkAlignmentDiMuonValidation") + +################################################################### +# Argument parsing +################################################################### +options = VarParsing() +options.register("config", "", VarParsing.multiplicity.singleton, VarParsing.varType.string , "AllInOne config") +options.parseArguments() + +##Set validation mode +valiMode = "StandAlone" + +################################################################### +# Read in AllInOne config in JSON format +################################################################### +with open(options.config, "r") as configFile: + config = _byteify(json.load(configFile, object_hook=_byteify),ignore_dicts=True) + +################################################################### +# Read filenames from given TXT file +################################################################### +readFiles = [] + +with open(config["validation"]["dataset"], "r") as datafiles: + for fileName in datafiles.readlines(): + readFiles.append(fileName.replace("\n", "")) + +################################################################### +# Get good lumi section +################################################################### +if "goodlumi" in config["validation"]: + if os.path.isfile(config["validation"]["goodlumi"]): + goodLumiSecs = cms.untracked.VLuminosityBlockRange(LumiList.LumiList(filename = config["validation"]["goodlumi"]).getCMSSWString().split(',')) + + else: + print("Does not exist: {}. Continue without good lumi section file.") + goodLumiSecs = cms.untracked.VLuminosityBlockRange() + +else: + goodLumiSecs = cms.untracked.VLuminosityBlockRange() + +################################################################### +# Define input source +################################################################### +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(readFiles), + lumisToProcess = goodLumiSecs, + skipEvents = cms.untracked.uint32(0) + ) +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(config["validation"].get("maxevents", 2000000)) +) + +################################################################### +# Bookeeping +################################################################### +process.options = cms.untracked.PSet( + wantSummary = cms.untracked.bool(False), + Rethrow = cms.untracked.vstring("ProductNotFound"), + fileMode = cms.untracked.string('NOMERGE'), +) + +################################################################### +# Standard includes +################################################################### +process.load("FWCore.MessageService.MessageLogger_cfi") +process.load("RecoVertex.BeamSpotProducer.BeamSpot_cff") +process.load("Configuration.StandardSequences.Services_cff") +process.load("Configuration.StandardSequences.GeometryRecoDB_cff") +process.load("Configuration.StandardSequences.MagneticField_cff") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") + +################################################################### +# Messages +################################################################### +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.MessageLogger.cerr.FwkReport.reportEvery = 1000 + +################################################################### +# Load and configure Track Refitter +################################################################### +process.load("RecoTracker.TrackProducer.TrackRefitters_cff") +import RecoTracker.TrackProducer.TrackRefitters_cff +process.TrackRefitter = process.TrackRefitterP5.clone( + src = 'ALCARECOTkAlZMuMu', + TrajectoryInEvent = True, + TTRHBuilder = "WithAngleAndTemplate", + NavigationSchool = "", +) + +################################################################### +# Global Tag +################################################################### +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, config["alignment"].get("globaltag", "auto:run2_data")) + +################################################################### +# Load conditions if wished +################################################################### +import CalibTracker.Configuration.Common.PoolDBESSource_cfi +if "conditions" in config["alignment"]: + from CalibTracker.Configuration.Common.PoolDBESSource_cfi import poolDBESSource + for condition in config["alignment"]["conditions"]: + setattr(process, "conditionsIn{}".format(condition), poolDBESSource.clone( + connect = cms.string(str(config["alignment"]["conditions"][condition]["connect"])), + toGet = cms.VPSet(cms.PSet(record = cms.string(str(condition)), + tag = cms.string(str(config["alignment"]["conditions"][condition]["tag"])) + ) + ) + ) + ) + + setattr(process, "prefer_conditionsIn{}".format(condition), cms.ESPrefer("PoolDBESSource", "conditionsIn{}".format(condition))) + +################################################################### +# The Di Muon Mass Validation module +################################################################### +process.DiMuonMassValidation = cms.EDAnalyzer('DiMuonValidation', + TkTag = cms.string ('TrackRefitter'), + # mu mu mass + Pair_mass_min = cms.double(80.), + Pair_mass_max = cms.double(120.), + Pair_mass_nbins = cms.int32(80), + Pair_etaminpos = cms.double(-1), + Pair_etamaxpos = cms.double(1), + Pair_etaminneg = cms.double(-1), + Pair_etamaxneg = cms.double(1), + + # cosTheta CS + Variable_CosThetaCS_xmin = cms.double(-1.), + Variable_CosThetaCS_xmax = cms.double(1.), + Variable_CosThetaCS_nbins = cms.int32(20), + # DeltaEta + Variable_DeltaEta_xmin = cms.double(-4.8), + Variable_DeltaEta_xmax = cms.double(4.8), + Variable_DeltaEta_nbins = cms.int32(20), + # EtaMinus + Variable_EtaMinus_xmin = cms.double(-2.4), + Variable_EtaMinus_xmax = cms.double(2.4), + Variable_EtaMinus_nbins = cms.int32(12), + # EtaPlus + Variable_EtaPlus_xmin = cms.double(-2.4), + Variable_EtaPlus_xmax = cms.double(2.4), + Variable_EtaPlus_nbins = cms.int32(12), + # Phi CS + Variable_PhiCS_xmin = cms.double(-math.pi/2.), + Variable_PhiCS_xmax = cms.double(math.pi/2.), + Variable_PhiCS_nbins = cms.int32(20), + # Phi Minus + Variable_PhiMinus_xmin = cms.double(-math.pi), + Variable_PhiMinus_xmax = cms.double(math.pi), + Variable_PhiMinus_nbins = cms.int32(16), + # Phi Plus + Variable_PhiPlus_xmin = cms.double(-math.pi), + Variable_PhiPlus_xmax = cms.double(math.pi), + Variable_PhiPlus_nbins = cms.int32(16), + # mu mu pT + Variable_PairPt_xmin = cms.double(0.), + Variable_PairPt_xmax = cms.double(100.), + Variable_PairPt_nbins= cms.int32(100)), + # + + +################################################################### +# Define sequences depending on validation mode +################################################################### +if valiMode == "StandAlone": + # Output file + process.TFileService = cms.Service("TFileService", + fileName = cms.string("{}/Zmumu.root".format(config["output"])), + closeFileFast = cms.untracked.bool(True), + ) + +process.p = cms.Path(process.offlineBeamSpot*process.TrackRefitter*process.DiMuonMassValidation) diff --git a/Alignment/OfflineValidation/scripts/validateAlignments.py b/Alignment/OfflineValidation/scripts/validateAlignments.py index 4b0f9a2d581b5..e07d7f41de736 100755 --- a/Alignment/OfflineValidation/scripts/validateAlignments.py +++ b/Alignment/OfflineValidation/scripts/validateAlignments.py @@ -14,6 +14,7 @@ import Alignment.OfflineValidation.TkAlAllInOneTool.GCP as GCP import Alignment.OfflineValidation.TkAlAllInOneTool.DMR as DMR +import Alignment.OfflineValidation.TkAlAllInOneTool.Zmumu as Zmumu import Alignment.OfflineValidation.TkAlAllInOneTool.PV as PV import Alignment.OfflineValidation.TkAlAllInOneTool.SplitV as SplitV import Alignment.OfflineValidation.TkAlAllInOneTool.JetHT as JetHT @@ -249,6 +250,9 @@ def main(): elif validation == "DMR": jobs.extend(DMR.DMR(config, validationDir)) + elif validation == "Zmumu": + jobs.extend(Zmumu.Zmumu(config, validationDir)) + elif validation == "PV": jobs.extend(PV.PV(config, validationDir))