diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 86cce78e96ffa83682ea8984fdd000ad0642b8b5..002bb608794dcb43a4a08fd6e8a9d1263aeff90a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -136,6 +136,7 @@ include: - local: 'benchmarks/ecal_gaps/config.yml' - local: 'benchmarks/tracking_detectors/config.yml' - local: 'benchmarks/tracking_performances/config.yml' + - local: 'benchmarks/tracking_performances_dis/config.yml' - local: 'benchmarks/barrel_ecal/config.yml' - local: 'benchmarks/barrel_hcal/config.yml' - local: 'benchmarks/zdc/config.yml' @@ -158,6 +159,7 @@ deploy_results: - "collect_results:pid" - "collect_results:tracking_performance" - "collect_results:tracking_performance_campaigns" + - "collect_results:tracking_performances_dis" - "collect_results:zdc" - "collect_results:zdc_lyso" script: diff --git a/Snakefile b/Snakefile index d153297c64c2d0bb19bf544a67d875854045b6d5..738bb5e5289c458a0f957fdf02f3a2047800caed 100644 --- a/Snakefile +++ b/Snakefile @@ -6,6 +6,7 @@ include: "benchmarks/barrel_ecal/Snakefile" include: "benchmarks/ecal_gaps/Snakefile" include: "benchmarks/material_scan/Snakefile" include: "benchmarks/tracking_performances/Snakefile" +include: "benchmarks/tracking_performances_dis/Snakefile" include: "benchmarks/zdc_lyso/Snakefile" use_s3 = config["remote_provider"].lower() == "s3" diff --git a/benchmarks/tracking_performances_dis/README.md b/benchmarks/tracking_performances_dis/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7df7078ea23a7059f0f08223fda5df72f033bba8 --- /dev/null +++ b/benchmarks/tracking_performances_dis/README.md @@ -0,0 +1,10 @@ +Detector Benchmark for tracking performance with DIS events +============================================================ + +## Overview +This benchmark generates and reconstructs DIS events. The generated charged-particle spectra is then compared to the spectra of truth-seeded and real-seeded reconstructed tracks. The hit-based track purity is also plotted. + +## Contact +[Barak Schmookler](baraks@ucr.edu) + + diff --git a/benchmarks/tracking_performances_dis/Snakefile b/benchmarks/tracking_performances_dis/Snakefile new file mode 100644 index 0000000000000000000000000000000000000000..7774f2a112c6331d49d5d96e64fd46b79b3562a6 --- /dev/null +++ b/benchmarks/tracking_performances_dis/Snakefile @@ -0,0 +1,148 @@ +import os + +rule compile_analysis: + input: + "{path}/{filename}.cxx", + output: + "{path}/{filename}_cxx.d", + "{path}/{filename}_cxx.so", + "{path}/{filename}_cxx_ACLiC_dict_rdict.pcm", + shell: + """ +root -l -b -q -e '.L {input}+' +""" + +rule trk_dis_compile: + input: + "benchmarks/tracking_performances_dis/analysis/trk_dis_analysis_cxx.so", + "benchmarks/tracking_performances_dis/analysis/trk_dis_plots_cxx.so" + +# Process the generated HepMC files through the simulation +rule trk_dis_sim: + input: + warmup="warmup/{DETECTOR_CONFIG}.edm4hep.root", + output: + "sim_output/tracking_performances_dis/{DETECTOR_CONFIG}/pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_beamEffects_xAngle=-0.025_hiDiv_{INDEX}.edm4hep.root", + params: + N_EVENTS=200, + shell: + """ +ddsim \ + --runType batch \ + --part.minimalKineticEnergy 1000*GeV \ + --filter.tracker edep0 \ + -v WARNING \ + --numberOfEvents {params.N_EVENTS} \ + --compactFile $DETECTOR_PATH/{wildcards.DETECTOR_CONFIG}.xml \ + --inputFiles root://dtn-eic.jlab.org//work/eic2/EPIC/EVGEN/DIS/NC/{wildcards.EBEAM}x{wildcards.PBEAM}/minQ2={wildcards.MINQ2}/pythia8NCDIS_{wildcards.EBEAM}x{wildcards.PBEAM}_minQ2={wildcards.MINQ2}_beamEffects_xAngle=-0.025_hiDiv_vtxfix_{wildcards.INDEX}.hepmc3.tree.root \ + --outputFile {output} +""" + +# Process the files produced in the previous step through EICRecon +rule trk_dis_reco: + input: + "sim_output/tracking_performances_dis/{DETECTOR_CONFIG}/pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_beamEffects_xAngle=-0.025_hiDiv_{INDEX}.edm4hep.root", + output: + "sim_output/tracking_performances_dis/{DETECTOR_CONFIG}/pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_beamEffects_xAngle=-0.025_hiDiv_{INDEX}.edm4eic.root", + shell: + """ +set -m # monitor mode to prevent lingering processes +exec env DETECTOR_CONFIG={wildcards.DETECTOR_CONFIG} \ + eicrecon {input} -Ppodio:output_file={output} \ + -Ppodio:output_collections=MCParticles,ReconstructedChargedParticles,ReconstructedTruthSeededChargedParticles,CentralCKFTrackAssociations,CentralCKFTruthSeededTrackAssociations +""" + +# Process the files -- either from the campaign or local running -- through the analysis script +rule trk_dis_analysis: + input: + script="benchmarks/tracking_performances_dis/analysis/trk_dis_analysis.cxx", + script_compiled="benchmarks/tracking_performances_dis/analysis/trk_dis_analysis_cxx.so", + data="sim_output/tracking_performances_dis/{DETECTOR_CONFIG}/{PREFIX}pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_beamEffects_xAngle=-0.025_hiDiv_{INDEX}.edm4eic.root", + output: + config="results/tracking_performances_dis/{DETECTOR_CONFIG}/{PREFIX}pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_{INDEX}/config.json", + hists="results/tracking_performances_dis/{DETECTOR_CONFIG}/{PREFIX}pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_{INDEX}/hists.root", + wildcard_constraints: + PREFIX= ".*", + EBEAM="\d+", + PBEAM="\d+", + MINQ2="\d+", + INDEX="\d+", + shell: + """ +cat > {output.config} <<EOF +{{ + "rec_file": "{input.data}", + "detector": "{wildcards.DETECTOR_CONFIG}", + "ebeam": {wildcards.EBEAM}, + "pbeam": {wildcards.PBEAM}, + "Min_Q2": {wildcards.MINQ2}, + "output_prefix": "$(dirname "{output.hists}")/hists" +}} +EOF +root -l -b -q '{input.script}+("{output.config}")' +""" + +#Merge all the files produced in the previous step +rule trk_dis_combine: + input: + lambda wildcards: [f"results/tracking_performances_dis/{wildcards.DETECTOR_CONFIG}/{wildcards.PREFIX}pythia8NCDIS_{wildcards.EBEAM}x{wildcards.PBEAM}_minQ2={wildcards.MINQ2}_{ix}/hists.root" for ix in range(1,int(wildcards.NUM_FILES)+1)], + output: + config="results/tracking_performances_dis/{DETECTOR_CONFIG}/{PREFIX}pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_combined_{NUM_FILES}/config.json", + hists="results/tracking_performances_dis/{DETECTOR_CONFIG}/{PREFIX}pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_combined_{NUM_FILES}/hists.root", + wildcard_constraints: + PREFIX= ".*", + EBEAM="\d+", + PBEAM="\d+", + MINQ2="\d+", + NUM_FILES="\d+", + shell: + """ +cat > {output.config} <<EOF +{{ + "hists_file": "{output.hists}", + "detector": "{wildcards.DETECTOR_CONFIG}", + "ebeam": {wildcards.EBEAM}, + "pbeam": {wildcards.PBEAM}, + "Min_Q2": {wildcards.MINQ2}, + "nfiles": {wildcards.NUM_FILES}, + "output_prefix": "$(dirname "{output.hists}")/plots" +}} +EOF +hadd {output.hists} {input} +""" + +#Process the merged file through the plotting script +rule trk_dis_plots: + input: + script="benchmarks/tracking_performances_dis/analysis/trk_dis_plots.cxx", + script_compiled="benchmarks/tracking_performances_dis/analysis/trk_dis_plots_cxx.so", + config="results/tracking_performances_dis/{DETECTOR_CONFIG}/{PREFIX}pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_combined_{NUM_FILES}/config.json", + output: + "results/tracking_performances_dis/{DETECTOR_CONFIG}/{PREFIX}pythia8NCDIS_{EBEAM}x{PBEAM}_minQ2={MINQ2}_combined_{NUM_FILES}/plots.pdf" + wildcard_constraints: + PREFIX= ".*", + EBEAM="\d+", + PBEAM="\d+", + MINQ2="\d+", + NUM_FILES="\d+", + shell: + """ +root -l -b -q '{input.script}+("{input.config}")' +""" + + +#Examples of invocation +rule trk_dis_run_locally: + input: + "results/tracking_performances_dis/" + os.environ["DETECTOR_CONFIG"] + "/pythia8NCDIS_18x275_minQ2=1_combined_5/plots.pdf", + message: + "See output in {input[0]}" + + +rule trk_dis_run_locally_trk_only: + input: + "results/tracking_performances_dis/epic_craterlake_tracking_only/pythia8NCDIS_18x275_minQ2=1_combined_5/plots.pdf", + message: + "See output in {input[0]}" + + diff --git a/benchmarks/tracking_performances_dis/analysis/trk_dis_analysis.cxx b/benchmarks/tracking_performances_dis/analysis/trk_dis_analysis.cxx new file mode 100644 index 0000000000000000000000000000000000000000..52dfdaf70339d40329e3eb08c2e8ec2c3c0fb308 --- /dev/null +++ b/benchmarks/tracking_performances_dis/analysis/trk_dis_analysis.cxx @@ -0,0 +1,236 @@ +#include <fstream> +#include <iostream> +#include <string> + +#include <TChain.h> +#include <TFile.h> +#include <TTreeReader.h> +#include <TTreeReaderArray.h> +#include <TH1D.h> +#include <TH2D.h> +#include <Math/Vector3D.h> +#include <Math/Vector4D.h> +#include <Math/RotationY.h> +#include <TMath.h> +#include <TVector3.h> +#include <TLorentzVector.h> + +#include "fmt/color.h" +#include "fmt/core.h" + +#include "nlohmann/json.hpp" + +void trk_dis_analysis(const std::string& config_name) +{ + // Read our configuration + std::ifstream config_file{config_name}; + nlohmann::json config; + config_file >> config; + + const std::string rec_file = config["rec_file"]; + const std::string detector = config["detector"]; + const std::string output_prefix = config["output_prefix"]; + const int ebeam = config["ebeam"]; + const int pbeam = config["pbeam"]; + const int Q2_min = config["Min_Q2"]; + + fmt::print(fmt::emphasis::bold | fg(fmt::color::forest_green), + "Running DIS tracking analysis...\n"); + fmt::print(" - Detector package: {}\n", detector); + fmt::print(" - input file: {}\n", rec_file); + fmt::print(" - output prefix for histograms: {}\n", output_prefix); + fmt::print(" - ebeam: {}\n", ebeam); + fmt::print(" - pbeam: {}\n", pbeam); + fmt::print(" - Minimum Q2: {}\n", Q2_min); + + //-------------------------------------------------------------------------------------------------------------------------------------------- + + // Set output file for the histograms + std::string output_name_hists = fmt::format("{}.root", output_prefix); + cout << "Output file for histograms = " << output_name_hists << endl; + TFile* ofile = new TFile(output_name_hists.c_str(), "RECREATE"); + + //-------------------------------------------------------------------------------------------------------------------------------------------- + + // Set up input file chain + TChain *mychain = new TChain("events"); + mychain->Add(rec_file.c_str()); + + //-------------------------------------------------------------------------------------------------------------------------------------------- + + // Initialize reader + TTreeReader tr(mychain); + + // Generated Particle Information + TTreeReaderArray<int> gen_status(tr, "MCParticles.generatorStatus"); + TTreeReaderArray<int> gen_pid(tr, "MCParticles.PDG"); + TTreeReaderArray<float> gen_px(tr, "MCParticles.momentum.x"); + TTreeReaderArray<float> gen_py(tr, "MCParticles.momentum.y"); + TTreeReaderArray<float> gen_pz(tr, "MCParticles.momentum.z"); + TTreeReaderArray<double> gen_mass(tr, "MCParticles.mass"); //Not important here + TTreeReaderArray<float> gen_charge(tr, "MCParticles.charge"); + TTreeReaderArray<double> gen_vx(tr, "MCParticles.vertex.x"); + TTreeReaderArray<double> gen_vy(tr, "MCParticles.vertex.y"); + TTreeReaderArray<double> gen_vz(tr, "MCParticles.vertex.z"); + + // Reconstructed real-seeded tracks (charged particles) + TTreeReaderArray<float> rec_px(tr, "ReconstructedChargedParticles.momentum.x"); + TTreeReaderArray<float> rec_py(tr, "ReconstructedChargedParticles.momentum.y"); + TTreeReaderArray<float> rec_pz(tr, "ReconstructedChargedParticles.momentum.z"); + TTreeReaderArray<float> rec_mass(tr, "ReconstructedChargedParticles.mass"); + TTreeReaderArray<int> rec_type(tr, "ReconstructedChargedParticles.type"); //Type 0: successful eta/phi match to generated particle + TTreeReaderArray<int> rec_pdg(tr, "ReconstructedChargedParticles.PDG"); //Uses PID lookup table information + + // Reconstructed truth-seeded tracks (charged particles) + TTreeReaderArray<float> rec_ts_px(tr, "ReconstructedTruthSeededChargedParticles.momentum.x"); + TTreeReaderArray<float> rec_ts_py(tr, "ReconstructedTruthSeededChargedParticles.momentum.y"); + TTreeReaderArray<float> rec_ts_pz(tr, "ReconstructedTruthSeededChargedParticles.momentum.z"); + TTreeReaderArray<float> rec_ts_mass(tr, "ReconstructedTruthSeededChargedParticles.mass"); + TTreeReaderArray<int> rec_ts_type(tr, "ReconstructedTruthSeededChargedParticles.type"); //Type 0: successful eta/phi match to generated particle + TTreeReaderArray<int> rec_ts_pdg(tr, "ReconstructedTruthSeededChargedParticles.PDG"); //Uses PID lookup table information + + // Hit-based track to MC Particle association weight + TTreeReaderArray<float> hit_assoc_weight(tr,"CentralCKFTrackAssociations.weight"); //Real-seeded tracking + TTreeReaderArray<float> hit_assoc_weight_ts(tr,"CentralCKFTruthSeededTrackAssociations.weight"); //Truth-seeded tracking + + //-------------------------------------------------------------------------------------------------------------------------------------------- + // Define Histograms + + //Eta distribution of generated charged particles + TH1 *h1a = new TH1D("h1a","Generated Charged Particles",100,-4,4); + h1a->GetXaxis()->SetTitle("#eta_{gen.}");h1a->GetXaxis()->CenterTitle(); + h1a->SetLineColor(kTeal);h1a->SetLineWidth(2); + + TH1 *h1a1 = new TH1D("h1a1","Generated Charged Particles",100,-4,4); //Minimum momentum cut of Pt > 200 MeV/c + h1a1->GetXaxis()->SetTitle("#eta_{gen.}");h1a1->GetXaxis()->CenterTitle(); + h1a1->SetLineColor(kRed);h1a1->SetLineWidth(2); + + TH1 *h1a2 = new TH1D("h1a2","Generated Charged Particles",100,-4,4); //Minimum momentum cut of Pt > 500 MeV/c + h1a2->GetXaxis()->SetTitle("#eta_{gen.}");h1a2->GetXaxis()->CenterTitle(); + h1a2->SetLineColor(kBlack);h1a2->SetLineWidth(2); + h1a2->SetFillColor(kBlack);h1a2->SetFillStyle(3244); + + //Eta distribution of reconstructed real-seeded tracks (charged particles) + TH1 *h1b = new TH1D("h1b","Reconstructed Real-seeded tracks",100,-4,4); + h1b->GetXaxis()->SetTitle("#eta_{rec.}");h1b->GetXaxis()->CenterTitle(); + h1b->SetLineColor(kGreen);h1b->SetLineWidth(2); + + TH1 *h1b1 = new TH1D("h1b1","Reconstructed Real-seeded tracks",100,-4,4); //Minimum momentum cut of Pt > 200 MeV/c + h1b1->GetXaxis()->SetTitle("#eta_{rec.}");h1b1->GetXaxis()->CenterTitle(); + h1b1->SetLineColor(kBlue);h1b1->SetLineWidth(2); + + TH1 *h1b2 = new TH1D("h1b2","Reconstructed Real-seeded tracks",100,-4,4); //Minimum momentum cut of Pt > 500 MeV/c + h1b2->GetXaxis()->SetTitle("#eta_{rec.}");h1b2->GetXaxis()->CenterTitle(); + h1b2->SetLineColor(kRed);h1b2->SetLineWidth(2); + h1b2->SetMarkerColor(kRed);h1b2->SetMarkerStyle(kFullCrossX); + + //Eta distribution of reconstructed truth-seeded tracks (charged particles) + TH1 *h1c = new TH1D("h1c","Reconstructed Truth-seeded tracks",100,-4,4); + h1c->GetXaxis()->SetTitle("#eta_{rec.}");h1c->GetXaxis()->CenterTitle(); + h1c->SetLineColor(kRed);h1c->SetLineWidth(2); + + TH1 *h1c1 = new TH1D("h1c1","Reconstructed Truth-seeded tracks",100,-4,4); //Minimum momentum cut of Pt > 200 MeV/c + h1c1->GetXaxis()->SetTitle("#eta_{rec.}");h1c1->GetXaxis()->CenterTitle(); + h1c1->SetLineColor(kOrange);h1c1->SetLineWidth(2); + + TH1 *h1c2 = new TH1D("h1c2","Reconstructed Truth-seeded tracks",100,-4,4); //Minimum momentum cut of Pt > 500 MeV/c + h1c2->GetXaxis()->SetTitle("#eta_{rec.}");h1c2->GetXaxis()->CenterTitle(); + h1c2->SetLineColor(kMagenta);h1c2->SetLineWidth(2); + h1c2->SetMarkerColor(kMagenta);h1c2->SetMarkerStyle(kFullCrossX); + + //Track purity + TH1 *h2a = new TH1D("h2a","Real-seeded tracks purity",100,0,1.1); + h2a->GetXaxis()->SetTitle("Fraction of track measurements from a given MC Particle");h2a->GetXaxis()->CenterTitle(); + h2a->GetYaxis()->SetTitle("Number of Tracks");h2a->GetYaxis()->CenterTitle(); + h2a->SetLineColor(kBlack);h2a->SetLineWidth(2); + + TH1 *h2b = new TH1D("h2b","Truth-seeded tracks purity",100,0,1.1); + h2b->GetXaxis()->SetTitle("Fraction of track measurements from a given MC Particle");h2b->GetXaxis()->CenterTitle(); + h2b->GetYaxis()->SetTitle("Number of Tracks");h2b->GetYaxis()->CenterTitle(); + h2b->SetLineColor(kBlack);h2b->SetLineWidth(2); + + //Define additional variables + TLorentzVector gen_vec; + TVector3 gen_vertex; + + TLorentzVector rec_vec; + TVector3 track_vec; //Reconstructed track momentum vector + int counter(0); + + //Loop over events + std::cout<<"Analyzing "<<mychain->GetEntries()<<" events!"<<std::endl; + while (tr.Next()) { + + if(counter%100==0) std::cout<<"Analyzing event "<<counter<<std::endl; + counter++; + + //Loop over generated particles + for(size_t igen=0;igen<gen_status.GetSize();igen++){ + + auto charge = gen_charge[igen]; + auto status = gen_status[igen]; + + //Require final-state, charged particle (no secondaries) + if(status==1 && fabs(charge) > 0.01 ){ + gen_vec.SetXYZM(gen_px[igen],gen_py[igen],gen_pz[igen],gen_mass[igen]); + gen_vertex.SetXYZ(gen_vx[igen],gen_vy[igen],gen_vz[igen]); + + //Fill eta histogram + h1a->Fill(gen_vec.Eta()); + if( gen_vec.Pt()>0.2 ) h1a1->Fill(gen_vec.Eta()); + if( gen_vec.Pt()>0.5 ) h1a2->Fill(gen_vec.Eta()); + } + } //End loop over generated particles + + //Loop over reconstructed real-seeded charged particles (copy of tracks with PID info) + size_t rec_mult = rec_type.GetSize(); + + for(size_t irec=0;irec<rec_mult;irec++){ + + rec_vec.SetXYZM(rec_px[irec],rec_py[irec],rec_pz[irec],rec_mass[irec]); + + //Fill histograms + h1b->Fill(rec_vec.Eta()); + if( rec_vec.Pt() > 0.2 ) h1b1->Fill(rec_vec.Eta()); + if( rec_vec.Pt() > 0.5 ) h1b2->Fill(rec_vec.Eta()); + + } //End loop over reconstructed particles + + //Loop over reconstructed truth-seeded charged particles (copy of tracks with PID info) + size_t rec_ts_mult = rec_ts_type.GetSize(); + + for(size_t irec=0;irec<rec_ts_mult;irec++){ + + rec_vec.SetXYZM(rec_ts_px[irec],rec_ts_py[irec],rec_ts_pz[irec],rec_ts_mass[irec]); + + //Fill histograms + h1c->Fill(rec_vec.Eta()); + if( rec_vec.Pt() > 0.2 ) h1c1->Fill(rec_vec.Eta()); + if( rec_vec.Pt() > 0.5 ) h1c2->Fill(rec_vec.Eta()); + + } //End loop over reconstructed particles + + // Loop over truth-seeded hit-based associations + for(size_t iassoc=0;iassoc<hit_assoc_weight.GetSize();iassoc++){ + + auto assoc_weight = hit_assoc_weight[iassoc]; + h2a->Fill(assoc_weight); + + } //End loop over hit associations + + // Loop over truth-seeded hit-based associations + for(size_t iassoc=0;iassoc<hit_assoc_weight_ts.GetSize();iassoc++){ + + auto assoc_weight = hit_assoc_weight_ts[iassoc]; + h2b->Fill(assoc_weight); + + } //End loop over hit associations + + } //End loop over events + + //-------------------------------------------------------------------------------------------------------------------------------------------- + + ofile->Write(); // Write histograms to file + ofile->Close(); // Close output file + +} \ No newline at end of file diff --git a/benchmarks/tracking_performances_dis/analysis/trk_dis_plots.cxx b/benchmarks/tracking_performances_dis/analysis/trk_dis_plots.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7a69816136db8970a563384ba1b1fc0448fc1c57 --- /dev/null +++ b/benchmarks/tracking_performances_dis/analysis/trk_dis_plots.cxx @@ -0,0 +1,254 @@ +#include <fstream> +#include <iostream> +#include <string> + +#include <TCanvas.h> +#include <TChain.h> +#include <TFile.h> +#include <TH1D.h> +#include <TH2D.h> +#include <TMath.h> +#include <TStyle.h> +#include <TLegend.h> + +#include "fmt/color.h" +#include "fmt/core.h" + +#include "nlohmann/json.hpp" + +void trk_dis_plots(const std::string& config_name) +{ + // Read our configuration + std::ifstream config_file{config_name}; + nlohmann::json config; + config_file >> config; + + const std::string hists_file = config["hists_file"]; + const std::string detector = config["detector"]; + const std::string output_prefix = config["output_prefix"]; + const int ebeam = config["ebeam"]; + const int pbeam = config["pbeam"]; + const int Q2_min = config["Min_Q2"]; + const int nfiles = config["nfiles"]; + + fmt::print(fmt::emphasis::bold | fg(fmt::color::forest_green), + "Plotting DIS tracking analysis...\n"); + fmt::print(" - Detector package: {}\n", detector); + fmt::print(" - input file for histograms: {}\n", hists_file); + fmt::print(" - output prefix for plots: {}\n", output_prefix); + fmt::print(" - ebeam: {}\n", ebeam); + fmt::print(" - pbeam: {}\n", pbeam); + fmt::print(" - Minimum Q2: {}\n", Q2_min); + fmt::print(" - nfiles: {}\n", nfiles); + + //-------------------------------------------------------------------------------------------------------------------------------------------- + + // Read file with histograms + TFile* file = new TFile(hists_file.c_str()); + + std::cout<<"Reading histograms..."<<std::endl; + + TH1D* h1a = (TH1D*) file->Get("h1a"); + TH1D* h1a1 = (TH1D*) file->Get("h1a1"); + TH1D* h1a2 = (TH1D*) file->Get("h1a2"); + + TH1D* h1b = (TH1D*) file->Get("h1b"); + TH1D* h1b1 = (TH1D*) file->Get("h1b1"); + TH1D* h1b2 = (TH1D*) file->Get("h1b2"); + + TH1D* h1c = (TH1D*) file->Get("h1c"); + TH1D* h1c1 = (TH1D*) file->Get("h1c1"); + TH1D* h1c2 = (TH1D*) file->Get("h1c2"); + + TH1D* h2a = (TH1D*) file->Get("h2a"); + TH1D* h2b = (TH1D*) file->Get("h2b"); + + //-------------------------------------------------------------------------------------------------------------------------------------------- + + // Make ratio histograms + TH1 *h1rb1 = new TH1D("h1rb1","",100,-4,4); //Real-seeded tracks (Pt > 200 MeV/c cut) + TH1 *h1rc1 = new TH1D("h1rc1","",100,-4,4); //Truth-seeded tracks (Pt > 200 MeV/c cut) + TH1 *h1rb2 = new TH1D("h1rb2","",100,-4,4); //Real-seeded tracks (Pt > 500 MeV/c cut) + TH1 *h1rc2 = new TH1D("h1rc2","",100,-4,4); //Truth-seeded tracks (Pt > 500 MeV/c cut) + + h1rb1 = (TH1*) h1b1->Clone("h1rb1"); + h1rb1->Divide(h1a1); + h1rb1->SetTitle("Ratio of recontructed to generated particle counts: P_{T} > 200 MeV/c"); + h1rb1->GetXaxis()->SetTitle("#eta");h1rb1->GetXaxis()->CenterTitle(); + h1rb1->GetYaxis()->SetTitle("Ratio");h1rb1->GetYaxis()->CenterTitle(); + + h1rc1 = (TH1*) h1c1->Clone("h1rc1"); + h1rc1->Divide(h1a1); + h1rc1->SetTitle("Ratio of recontructed to generated particle counts: P_{T} > 200 MeV/c"); + h1rc1->GetXaxis()->SetTitle("#eta");h1rc1->GetXaxis()->CenterTitle(); + h1rc1->GetYaxis()->SetTitle("Ratio");h1rc1->GetYaxis()->CenterTitle(); + + h1rb2 = (TH1*) h1b2->Clone("h1rb2"); + h1rb2->Divide(h1a2); + h1rb2->SetTitle("Ratio of recontructed to generated particle counts: P_{T} > 500 MeV/c"); + h1rb2->GetXaxis()->SetTitle("#eta");h1rb2->GetXaxis()->CenterTitle(); + h1rb2->GetYaxis()->SetTitle("Ratio");h1rb2->GetYaxis()->CenterTitle(); + + h1rc2 = (TH1*) h1c2->Clone("h1rc2"); + h1rc2->Divide(h1a2); + h1rc2->SetTitle("Ratio of recontructed to generated particle counts: P_{T} > 500 MeV/c"); + h1rc2->GetXaxis()->SetTitle("#eta");h1rc2->GetXaxis()->CenterTitle(); + h1rc2->GetYaxis()->SetTitle("Ratio");h1rc2->GetYaxis()->CenterTitle(); + + //-------------------------------------------------------------------------------------------------------------------------------------------- + + // Make plots and save to PDF file + + // Update Style + gStyle->SetPadGridX(0); + gStyle->SetPadGridY(0); + gStyle->SetOptStat(0); + + std::cout<<"Making plots..."<<std::endl; + + //Generated charged particles + TCanvas *c1a = new TCanvas("c1a"); + h1a->Draw(); + h1a1->Draw("same"); + h1a2->Draw("same"); + + TLegend *leg1a = new TLegend(0.25,0.6,0.6,0.875); + leg1a->SetBorderSize(0);leg1a->SetFillStyle(0); + leg1a->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg1a->AddEntry("h1a","All generated charged particles","l"); + leg1a->AddEntry("h1a1","+ P_{T} > 200 MeV/c","l"); + leg1a->AddEntry("h1a2","+ P_{T} > 500 MeV/c","l"); + leg1a->Draw(); + + //Real-seeded tracks + TCanvas *c1b = new TCanvas("c1b"); + h1b->Draw(); + h1b1->Draw("same"); + h1b2->Draw("same"); + + TLegend *leg1b = new TLegend(0.25,0.6,0.6,0.875); + leg1b->SetBorderSize(0);leg1b->SetFillStyle(0); + leg1b->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg1b->AddEntry("h1b","All real-seeded tracks","l"); + leg1b->AddEntry("h1b1","+ P_{T} > 200 MeV/c","l"); + leg1b->AddEntry("h1b2","+ P_{T} > 500 MeV/c","l"); + leg1b->Draw(); + + //Truth-seeded tracks + TCanvas *c1c = new TCanvas("c1c"); + h1c->Draw(); + h1c1->Draw("same"); + h1c2->Draw("same"); + + TLegend *leg1c = new TLegend(0.25,0.6,0.6,0.875); + leg1c->SetBorderSize(0);leg1c->SetFillStyle(0); + leg1c->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg1c->AddEntry("h1c","All truth-seeded tracks","l"); + leg1c->AddEntry("h1c1","+ P_{T} > 200 MeV/c","l"); + leg1c->AddEntry("h1c2","+ P_{T} > 500 MeV/c","l"); + leg1c->Draw(); + + //Comparison 1 + TCanvas *c1d = new TCanvas("c1d"); + auto frame_d1 = c1d->DrawFrame(-4,0,4,1.2*h1a1->GetMaximum()); + frame_d1->GetXaxis()->SetTitle("#eta_{gen} or #eta_{rec}");frame_d1->GetXaxis()->CenterTitle(); + h1a1->Draw("same"); + h1b1->Draw("same"); + h1c1->Draw("same"); + + TLegend *leg1d = new TLegend(0.15,0.675,0.6,0.875); + leg1d->SetBorderSize(0);leg1d->SetFillStyle(0); + leg1d->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg1d->AddEntry("h1a1","Generated charged particles w/ P_{T} > 200 MeV/c","l"); + leg1d->AddEntry("h1b1","Real-seeded tracks w/ P_{T} > 200 MeV/c","l"); + leg1d->AddEntry("h1c1","Truth-seeded tracks w/ P_{T} > 200 MeV/c","l"); + leg1d->Draw(); + + //Comparison 2a + TCanvas *c1e = new TCanvas("c1e"); + auto frame_e1 = c1e->DrawFrame(-4,0,4,1.2*h1a1->GetMaximum()); + frame_e1->GetXaxis()->SetTitle("#eta_{gen} or #eta_{rec}");frame_e1->GetXaxis()->CenterTitle(); + h1a2->Draw("same"); + h1b2->Draw("P same"); + + TLegend *leg1e = new TLegend(0.15,0.675,0.6,0.875); + leg1e->SetBorderSize(0);leg1e->SetFillStyle(0); + leg1e->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg1e->AddEntry("h1a2","Generated charged particles w/ P_{T} > 500 MeV/c","fl"); + leg1e->AddEntry("h1b2","Real-seeded tracks w/ P_{T} > 500 MeV/c","p"); + leg1e->Draw(); + + //Comparison 2b + TCanvas *c1e1 = new TCanvas("c1e1"); + frame_e1->Draw(); + h1a2->Draw("same"); + h1c2->Draw("P same"); + + TLegend *leg1e1 = new TLegend(0.15,0.675,0.6,0.875); + leg1e1->SetBorderSize(0);leg1e1->SetFillStyle(0); + leg1e1->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg1e1->AddEntry("h1a2","Generated charged particles w/ P_{T} > 500 MeV/c","fl"); + leg1e1->AddEntry("h1c2","Truth-seeded tracks w/ P_{T} > 500 MeV/c","p"); + leg1e1->Draw(); + + //Comparison 1 ratio + TCanvas *c1f = new TCanvas("c1f"); + h1rb1->Draw(); + h1rc1->Draw("same"); + + TLegend *leg1f = new TLegend(0.575,0.25,0.875,0.45); + leg1f->SetBorderSize(0);leg1f->SetFillStyle(0); + leg1f->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg1f->AddEntry("h1rb1","Real-seeded tracking","l"); + leg1f->AddEntry("h1rc1","Truth-seeded tracking","l"); + leg1f->Draw(); + + //Comparison 2 ratio + TCanvas *c1g = new TCanvas("c1g"); + h1rb2->Draw(); + h1rc2->Draw("same"); + + TLegend *leg1g = new TLegend(0.575,0.25,0.875,0.45); + leg1g->SetBorderSize(0);leg1g->SetFillStyle(0); + leg1g->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg1g->AddEntry("h1rb2","Real-seeded tracking","l"); + leg1g->AddEntry("h1rc2","Truth-seeded tracking","l"); + leg1g->Draw(); + + //Hit-based associations -- real-seeded tracks + TCanvas *c2a = new TCanvas("c2a"); + c2a->SetLogy(); + h2a->Draw(); + + TLegend *leg2a = new TLegend(0.25,0.6,0.6,0.875); + leg2a->SetBorderSize(0);leg2a->SetFillStyle(0); + leg2a->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg2a->Draw(); + + //Hit-based associations -- truth-seeded tracks + TCanvas *c2b = new TCanvas("c2b"); + c2b->SetLogy(); + h2b->Draw(); + + TLegend *leg2b = new TLegend(0.25,0.6,0.6,0.875); + leg2b->SetBorderSize(0);leg2a->SetFillStyle(0); + leg2b->SetHeader(Form("Pythia8: %dx%d GeV, Q^{2} > %d GeV^{2}",ebeam,pbeam,Q2_min)); + leg2b->Draw(); + + //-------------------------------------------------------------------------------------------------------------------------------------------- + + // Print plots to pdf file + c1a->Print(fmt::format("{}.pdf[", output_prefix).c_str()); + c1a->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c1b->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c1c->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c1d->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c1e->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c1e1->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c1f->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c1g->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c2a->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c2b->Print(fmt::format("{}.pdf", output_prefix).c_str()); + c2b->Print(fmt::format("{}.pdf]", output_prefix).c_str()); + +} \ No newline at end of file diff --git a/benchmarks/tracking_performances_dis/config.yml b/benchmarks/tracking_performances_dis/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..961df5492dfe5871cea6bd441f6d5b9d23c101f8 --- /dev/null +++ b/benchmarks/tracking_performances_dis/config.yml @@ -0,0 +1,35 @@ +sim:tracking_performances_dis: + extends: .det_benchmark + stage: simulate + script: + - snakemake --cache --cores 5 results/tracking_performances_dis/epic_craterlake_tracking_only/pythia8NCDIS_18x275_minQ2=1_combined_5/hists.root + retry: + max: 2 + when: + - runner_system_failure + +bench:tracking_performances_dis: + extends: .det_benchmark + stage: benchmarks + needs: + - ["sim:tracking_performances_dis"] + script: + - snakemake --cores 1 trk_dis_run_locally_trk_only + # avoid uploading intermediate results + - find results/tracking_performances_dis/ -mindepth 2 -maxdepth 2 -type d ! -name "*combined*" | xargs rm -rfv + +collect_results:tracking_performances_dis: + extends: .det_benchmark + stage: collect + needs: + - "bench:tracking_performances_dis" + script: + - ls -lrht + - mv results{,_save}/ # move results directory out of the way to preserve it + - snakemake --cores 1 --delete-all-output trk_dis_run_locally_trk_only + - mv results{_save,}/ + # convert to png + - | + gs -sDEVICE=pngalpha -dUseCropBox -r144 \ + -o 'results/tracking_performances_dis/epic_craterlake_tracking_only/pythia8NCDIS_18x275_minQ2=1_combined_5/plot_%03d.png' \ + results/tracking_performances_dis/epic_craterlake_tracking_only/pythia8NCDIS_18x275_minQ2=1_combined_5/plots.pdf