8#include "BmnGlobalTrack.h"
9#include "BmnMCInfoDst.h"
10#include "BmnTrackMatch.h"
11#include "CbmMCTrack.h"
13#include "FairLogger.h"
14#include "FairMCEventHeader.h"
15#include "FairRootManager.h"
16#include "FairTrackParam.h"
33#include "TVirtualMC.h"
125 LOG(error) <<
"Errors occurred while initializing the BmnParticleEqualizer2D generator, "
126 "the simulation run will be stopped";
131 vector<Int_t> pdg_codes,
146 for (
auto pdg_key : pdg_codes) {
148 LOG(warning) <<
"The PDG code " << pdg_key
149 <<
" is listed more than once for the equalizing generator, "
150 "the extra entries are ignored";
172 LOG(error) <<
"Errors occurred while initializing the BmnParticleEqualizer2D generator, "
173 "the simulation run will be stopped";
190 TF1* p_distribution =
191 new TF1(func_name,
"(x<[9])*(gaus(0)+gaus(3)+landau(6))+(x>=[9])*[10]*TMath::Exp(-[11]*(x-[9]))", p_min, p_max);
192 Double_t p_avg = (p_min + p_max) / 2;
204 Double_t margin = 0.01 * (max_value - min_value);
205 p_distribution->
SetParLimits(index, min_value, max_value);
212 set_parameter(0, 0., 10. * y_peak, 0.3 * y_peak);
213 set_parameter(1, p_min, p_avg, x_peak - 0.5 * rms);
214 set_parameter(2, 0.1, p_avg, 0.5 * rms);
215 set_parameter(3, 0., 10. * y_peak, 0.5 * y_peak);
216 set_parameter(4, x_max_value - 0.1, p_max, x_peak + 0.5 * rms);
217 set_parameter(5, 0.1, p_avg, rms);
218 set_parameter(6, 0., 100. * y_peak, 2. * y_peak);
219 set_parameter(7, p_min,
TMath::Min(x_max_value, p_avg), x_peak - 0.1);
220 set_parameter(8, 0.1, p_avg, 0.3 * rms);
225 const Double_t tail_fraction = 0.05, min_tail_entries = 30;
249 for (
Int_t index = 0; index <= 8; index++)
252 Double_t bulk_value = p_distribution->
Eval(p_tail * (1. - 1.e-12));
254 set_parameter(10, 0., 100. *
TMath::Max(bulk_value, 1.), bulk_value);
256 set_parameter(11, 0., 50., 2.);
257 p_distribution->
SetRange(p_tail, p_max);
258 is_valid = hP->
Fit(p_distribution,
"SQ0LR")->
IsValid() && is_valid;
261 p_distribution->
SetRange(p_min, p_max);
263 if (fitted_function !=
nullptr)
264 fitted_function->
SetRange(p_min, p_max);
272 if (hP->GetEntries() == 0) {
273 LOG(warning) <<
TString::Format(
"P (momentum) histogram is empty for PDG = %d", pdg_key);
279 LOG(error) <<
TString::Format(
"Fit of the P (momentum) histogram failed for PDG = %d", pdg_key);
294 if (hPt->GetEntries() == 0) {
295 LOG(warning) <<
TString::Format(
"Pt (transverse momentum) histogram is empty for PDG = %d", pdg_key);
303 TF1* pt_distribution =
new TF1(
304 dist_func_name,
TString::Format(
"[0]*x*exp(-sqrt(x*x+%.10g)/[1])", pdg_mass * pdg_mass), pt_min, pt_max);
312 "Fit of the Pt (transverse momentum) histogram failed for PDG = %d, the previous temperature value "
328 if (hY->GetEntries() == 0) {
329 LOG(warning) <<
TString::Format(
"Rapidity histogram is empty for %d PDG code", pdg_key);
334 if (pdg_key != 2212) {
340 Double_t max_bin_value = hY->GetMaximum();
354 unique_ptr<TF1> fProtonYDistribution =
355 make_unique<TF1>(
"distProtonY",
"gaus(0)+gaus(3)+gaus(6)", 0.2, 5);
356 fProtonYDistribution->SetParLimits(0, 0, max_bin_value);
357 fProtonYDistribution->SetParLimits(1, 0, 0.05);
358 fProtonYDistribution->SetParLimits(2, 0.01, 0.4);
359 fProtonYDistribution->SetParameter(2, 0.2);
360 fProtonYDistribution->SetParLimits(3, 0, max_bin_value);
361 fProtonYDistribution->SetParName(4,
"proton_y0");
362 fProtonYDistribution->SetParLimits(4, 0.3, 2);
363 fProtonYDistribution->SetParameter(4, 1);
364 fProtonYDistribution->SetParName(5,
"proton_sigma");
365 fProtonYDistribution->SetParLimits(5, 0.05, 1);
366 fProtonYDistribution->SetParameter(5, 0.5);
367 fProtonYDistribution->SetParLimits(6, 0, max_bin_value);
368 fProtonYDistribution->SetParLimits(7, 1.5, 3);
369 fProtonYDistribution->SetParameter(7, 2.25);
370 fProtonYDistribution->SetParLimits(8, 0.05, 1);
371 fProtonYDistribution->SetParameter(8, 0.5);
373 TFitResultPtr r = hY->Fit(fProtonYDistribution.get(),
"SQ0",
"", 0, 5);
386 if (hEta->GetEntries() == 0) {
387 LOG(warning) <<
TString::Format(
"Eta (pseudorapidity) histogram is empty for PDG = %d", pdg_key);
393 TF1* eta_distribution =
new TF1(dist_func_name,
"crystalball", eta_min, eta_max);
405 LOG(error) <<
TString::Format(
"Fit of the Eta (pseudorapidity) histogram failed for PDG = %d", pdg_key);
414 gSystem->ExpandPathName(input_list_file);
417 list<string> file_list;
418 ifstream list_file(input_list_file.
Data());
420 while (getline(list_file, s))
421 file_list.push_back(s);
422 if (file_list.empty()) {
423 cout <<
"ERROR: There are no files in the list of the input text file: " << input_list_file << endl;
428 TChain dataChain(
"bmndata");
429 for (
auto const& cur_file_path : file_list) {
430 TString strFilePath(cur_file_path);
431 gSystem->ExpandPathName(strFilePath);
433 dataChain.
AddFile(strFilePath);
437 cout <<
"ERROR: There are no correct input files in the text list stored at: \"" << input_list_file <<
"\""
446 if (dataChain.
GetBranch(
"MCTrack") ==
nullptr) {
447 LOG(info) <<
"'MCTrack' branch was not found, searching for 'BmnMCInfo->MCTrack'...";
448 if (dataChain.
GetBranch(
"BmnMCInfo.") ==
nullptr) {
449 LOG(error) <<
"'BmnMCInfo.' branch was not found too, please, check the structure of the files, exiting...";
453 if (mcInfo ==
nullptr) {
455 <<
"'BmnMCInfo.' branch was not read correctly, please, check the structure of the files, exiting...";
459 LOG(info) <<
"'BmnMCInfo->MCTrack' has been found";
464 if (mcTracks ==
nullptr) {
466 <<
"MCTrack' branch was not read correctly, please, check the structure of the files, exiting...";
474 if (iEventNumber < 1) {
475 cout <<
"ERROR: There are no correct entries in the file list stored at: \"" << input_list_file <<
"\"" << endl;
480 unique_ptr<TFile> hist_file(
TFile::Open(output_histo_file,
"RECREATE"));
481 if ((!hist_file) || (!hist_file->IsOpen())) {
482 cout <<
"ERROR: unable to create ROOT file for the sample histograms: " << output_histo_file << endl;
487 map<Int_t, unique_ptr<stParticleInfo>> particle_infos;
495 particle_infos[pdg_key]->fPHist = make_unique<TH1D>(histogram_name, histogram_name, 80,
fPMin,
fPMax);
497 particle_infos[pdg_key]->fPtHist = make_unique<TH1D>(histogram_name, histogram_name, 60,
fPtMin,
fPtMax);
499 particle_infos[pdg_key]->fYHist = make_unique<TH1D>(histogram_name, histogram_name, 60,
fYMin,
fYMax);
501 particle_infos[pdg_key]->fEtaHist = make_unique<TH1D>(histogram_name, histogram_name, 60,
fEtaMin,
fEtaMax);
503 particle_infos[pdg_key]->fThetaHist =
506 particle_infos[pdg_key]->fPhiHist = make_unique<TH1D>(histogram_name, histogram_name, 64,
fPhiMin,
fPhiMax);
510 particle_infos[pdg_key]->fPEtaHist =
513 particle_infos[pdg_key]->fEtaPhiHist = make_unique<TH2D>(histogram_name, histogram_name,
kEtaBinCount,
fEtaMin,
518 particle_infos[pdg_key]->fPHist->SetDirectory(
nullptr);
519 particle_infos[pdg_key]->fPtHist->SetDirectory(
nullptr);
520 particle_infos[pdg_key]->fYHist->SetDirectory(
nullptr);
521 particle_infos[pdg_key]->fEtaHist->SetDirectory(
nullptr);
522 particle_infos[pdg_key]->fThetaHist->SetDirectory(
nullptr);
523 particle_infos[pdg_key]->fPhiHist->SetDirectory(
nullptr);
524 particle_infos[pdg_key]->fPEtaHist->SetDirectory(
nullptr);
525 particle_infos[pdg_key]->fEtaPhiHist->SetDirectory(
nullptr);
526 int hist_counter = 0;
529 for (
auto& p_hist : particle_infos[pdg_key]->fPHistVector) {
530 histogram_name =
TString::Format(
"hP%d_pdg%d", ++hist_counter, pdg_key);
531 p_hist = make_unique<TH1D>(histogram_name, histogram_name, 40,
fPMin + (hist_counter - 1) * interval_width,
532 fPMin + hist_counter * interval_width);
533 p_hist->SetDirectory(
nullptr);
536 for (
auto& eta_hist : particle_infos[pdg_key]->fEtaHistVector) {
537 histogram_name =
TString::Format(
"hEta%d_pdg%d", ++hist_counter, pdg_key);
538 eta_hist = make_unique<TH1D>(histogram_name, histogram_name, 60,
fEtaMin,
fEtaMax);
539 eta_hist->SetDirectory(
nullptr);
542 for (
auto& phi_hist : particle_infos[pdg_key]->fPhiHistVector) {
543 histogram_name =
TString::Format(
"hPhi%d_pdg%d", ++hist_counter, pdg_key);
545 phi_hist->SetDirectory(
nullptr);
549 for (
auto& p_eta_hist : particle_infos[pdg_key]->fPEtaHistVector) {
550 histogram_name =
TString::Format(
"hPEta%d_pdg%d", ++hist_counter, pdg_key);
551 p_eta_hist = make_unique<TH2D>(histogram_name, histogram_name,
kPEtaPBinCount,
552 fPMin + (hist_counter - 1) * interval_width,
554 p_eta_hist->SetDirectory(
nullptr);
557 for (
auto& eta_phi_hist : particle_infos[pdg_key]->fEtaPhiHistVector) {
558 histogram_name =
TString::Format(
"hEtaPhi%d_pdg%d", ++hist_counter, pdg_key);
561 eta_phi_hist->SetDirectory(
nullptr);
566 int iCurrentEvent = 0;
567 LOG(info) <<
"Processing events...";
568 for (
Int_t iEvent = 0; iEvent < iEventNumber; iEvent++) {
571 if (iCurrentEvent % 1000 == 0)
572 LOG(info) <<
"Processing event #" << iCurrentEvent <<
" of " << iEventNumber;
579 mc_tracks = mcTracks;
601 if (
auto part_iter = particle_infos.find(part_code); part_iter != particle_infos.end()) {
602 int interval_number = (pTrack->
GetP() -
fPMin) / interval_width;
607 part_iter->second->fPHist->Fill(track_p);
608 part_iter->second->fPtHist->Fill(pTrack->
GetPt());
609 part_iter->second->fYHist->Fill(pTrack->
GetRapidity());
610 part_iter->second->fEtaHist->Fill(track_eta);
611 part_iter->second->fThetaHist->Fill(
TMath::ACos(pTrack->
GetPz() / track_p));
612 part_iter->second->fPhiHist->Fill(track_phi);
613 part_iter->second->fPEtaHist->Fill(track_p, track_eta);
614 part_iter->second->fEtaPhiHist->Fill(track_eta, track_phi);
616 if ((track_p >=
fPMin) && (isless(track_p,
fPMax))) {
617 part_iter->second->fPHistVector[interval_number]->Fill(track_p);
618 part_iter->second->fEtaHistVector[interval_number]->Fill(track_eta);
619 part_iter->second->fPhiHistVector[interval_number]->Fill(track_phi);
620 part_iter->second->fPEtaHistVector[interval_number]->Fill(track_p, track_eta);
621 part_iter->second->fEtaPhiHistVector[interval_number]->Fill(track_eta, track_phi);
629 if (particle_infos[pdg_key]->fPHist->GetEntries() == 0) {
630 LOG(error) <<
"Momentum histogram is empty for pdg=" << pdg_key;
633 if (particle_infos[pdg_key]->fPtHist->GetEntries() == 0) {
634 LOG(error) <<
"Transverse momentum histogram is empty for pdg=" << pdg_key;
637 if (particle_infos[pdg_key]->fYHist->GetEntries() == 0) {
638 LOG(error) <<
"Rapidity histogram is empty for pdg=" << pdg_key;
641 if (particle_infos[pdg_key]->fEtaHist->GetEntries() == 0) {
642 LOG(error) <<
"Pseudorapidity histogram is empty for pdg=" << pdg_key;
645 if (particle_infos[pdg_key]->fThetaHist->GetEntries() == 0) {
646 LOG(error) <<
"Theta angle histogram is empty for pdg=" << pdg_key;
649 if (particle_infos[pdg_key]->fPhiHist->GetEntries() == 0) {
650 LOG(error) <<
"Phi angle histogram is empty for pdg=" << pdg_key;
653 if (particle_infos[pdg_key]->fPEtaHist->GetEntries() == 0) {
654 LOG(error) <<
"(P, Eta) histogram is empty for pdg=" << pdg_key;
657 if (particle_infos[pdg_key]->fEtaPhiHist->GetEntries() == 0) {
658 LOG(error) <<
"(Eta, Phi) histogram is empty for pdg=" << pdg_key;
667 Double_t fY0 = 0, fSigma = 0.72, fT = 0.223;
671 LOG(fatal) <<
"PDG code " << pdg_key <<
"is not defined. exiting...";
685 if (
FitYHistogram(particle_infos[pdg_key]->fYHist, pdg_key, fY0, fSigma) != 0)
689 hist_file->WriteObject(&Y0SigmaT, vector_name);
695 LOG(info) <<
TString::Format(
"pdg=%i y0=%4.2f sigma_y=%4.2f T_pt=%6.4f", pdg_key, fY0, fSigma, fT);
702 momentum_grid[0] =
fPMin;
703 momentum_grid[1] =
fPMax;
709 hist_file->WriteTObject(particle_infos[pdg_key]->fPHist.get());
710 hist_file->WriteTObject(particle_infos[pdg_key]->fPtHist.get());
711 hist_file->WriteTObject(particle_infos[pdg_key]->fYHist.get());
712 hist_file->WriteTObject(particle_infos[pdg_key]->fEtaHist.get());
713 hist_file->WriteTObject(particle_infos[pdg_key]->fThetaHist.get());
714 hist_file->WriteTObject(particle_infos[pdg_key]->fPhiHist.get());
715 hist_file->WriteTObject(particle_infos[pdg_key]->fPEtaHist.get());
716 hist_file->WriteTObject(particle_infos[pdg_key]->fEtaPhiHist.get());
717 for (
auto& p_hist : particle_infos[pdg_key]->fPHistVector)
718 hist_file->WriteTObject(p_hist.get());
719 for (
auto& eta_hist : particle_infos[pdg_key]->fEtaHistVector)
720 hist_file->WriteTObject(eta_hist.get());
721 for (
auto& phi_hist : particle_infos[pdg_key]->fPhiHistVector)
722 hist_file->WriteTObject(phi_hist.get());
723 for (
auto& p_eta_hist : particle_infos[pdg_key]->fPEtaHistVector)
724 hist_file->WriteTObject(p_eta_hist.get());
725 for (
auto& eta_phi_hist : particle_infos[pdg_key]->fEtaPhiHistVector)
726 hist_file->WriteTObject(eta_phi_hist.get());
739 LOG(error) <<
"The efficiency map is absent in the file with the sample histograms for at least one of the "
740 "particle types, so the correction by the efficiency cannot be switched on. Build the map with "
741 "BmnParticleEqualizer2D::ProduceEfficiencyMap() from the reconstructed (DST) files first";
744 if (min_efficiency <= 0.) {
745 LOG(error) <<
"The lower limit of the efficiency has to be positive, otherwise the correction factor is "
746 "unlimited; the correction is not switched on";
759 LOG(error) <<
"The rebin factor of the sample statistics filtering has to be 1 or greater, " << factor
782 for (
int cur_interval = 0; cur_interval <
fIntervalCount; cur_interval++) {
783 const TH2D* hist_pair[2] = {
fParticleInfos[pdg_key]->fPEtaHistVector[cur_interval].get(),
785 for (
const TH2D* hist : hist_pair) {
792 << hist->GetNbinsX() <<
"x" << hist->GetNbinsY() <<
" bins of the histogram '"
793 << hist->GetName() <<
"'";
801 for (
int cur_interval = 0; cur_interval <
fIntervalCount; cur_interval++) {
802 unique_ptr<TH2D>* full_hist[2] = {&
fParticleInfos[pdg_key]->fPEtaHistVector[cur_interval],
804 unique_ptr<TH2D>* cut_hist[2] = {&
fParticleInfos[pdg_key]->fPEtaCutHistVector[cur_interval],
806 for (
int iHist = 0; iHist < 2; iHist++) {
809 cut_hist[iHist]->reset(
810 (
TH2D*)(*full_hist[iHist])
812 if (*cut_hist[iHist] ==
nullptr) {
813 LOG(error) <<
"Unable to rebin the histogram '" << (*full_hist[iHist])->GetName() <<
"'";
817 (*cut_hist[iHist])->SetDirectory(
nullptr);
828 if ((hist_file ==
nullptr) || (!hist_file->
IsOpen())) {
829 LOG(error) <<
"The file with the sample histograms is not open";
834 if ((momentum_grid ==
nullptr) || (momentum_grid->GetNoElements() !=
kMomentumGridSize)) {
836 <<
"') is absent in the file with the sample histograms: " << hist_file->
GetName()
837 <<
". The file was produced by an older version of the equalizing generator, please, recreate it "
838 "with ProduceSampleHistograms()";
847 "The sample histograms were produced for %d momentum intervals in [%g, %g] GeV, but the generator is "
848 "configured for %d intervals in [%g, %g] GeV. Please, recreate the file '%s' with "
849 "ProduceSampleHistograms() or configure the generator accordingly",
861 gSystem->ExpandPathName(input_list_file);
864 list<string> file_list;
865 ifstream list_file(input_list_file.
Data());
867 while (getline(list_file, s))
868 file_list.push_back(s);
869 if (file_list.empty()) {
870 LOG(error) <<
"There are no files in the list of the input text file: " << input_list_file;
875 TChain dataChain(
"bmndata");
876 for (
auto const& cur_file_path : file_list) {
877 TString strFilePath(cur_file_path);
878 gSystem->ExpandPathName(strFilePath);
879 dataChain.
AddFile(strFilePath);
882 LOG(error) <<
"There are no correct input files in the text list stored at: " << input_list_file;
888 unique_ptr<TFile> hist_file(
TFile::Open(histo_file,
"UPDATE"));
889 if ((!hist_file) || (!hist_file->IsOpen())) {
890 LOG(error) <<
"Unable to open the file with the sample histograms for updating: " << histo_file;
901 if (dataChain.
GetBranch(
"BmnMCInfo.") ==
nullptr) {
902 LOG(error) <<
"Neither 'MCTrack' nor 'BmnMCInfo.' branch was found: the acceptance map is built from the "
903 "simulated files, please, check the structure of the given files";
918 map<Int_t, vector<unique_ptr<TH2D>>> all_hists, pass_hists;
920 for (
int cur_interval = 0; cur_interval <
fIntervalCount; cur_interval++) {
922 all_hists[pdg_key].push_back(make_unique<TH2D>(histogram_name, histogram_name,
kEtaBinCount,
fEtaMin,
924 all_hists[pdg_key].back()->SetDirectory(
nullptr);
925 histogram_name =
TString::Format(
"hAccPass%d_pdg%d", cur_interval + 1, pdg_key);
926 pass_hists[pdg_key].push_back(make_unique<TH2D>(histogram_name, histogram_name,
kEtaBinCount,
fEtaMin,
928 pass_hists[pdg_key].back()->SetDirectory(
nullptr);
934 for (
Long64_t iEvent = 0; iEvent < iEventNumber; iEvent++) {
935 if ((iEvent + 1) % 1000 == 0)
936 LOG(info) <<
"Processing event #" << iEvent + 1 <<
" of " << iEventNumber;
939 if (mc_tracks ==
nullptr)
942 for (
int iTrack = 0; iTrack < mc_tracks->
GetEntriesFast(); iTrack++) {
945 if ((mc_track ==
nullptr) || (mc_track->
GetMotherId() >= 0))
948 auto all_iter = all_hists.find(pdg_key);
949 if (all_iter == all_hists.end())
952 if ((track_p <
fPMin) || (!isless(track_p,
fPMax)))
954 int interval_number = (track_p -
fPMin) / interval_width;
961 all_iter->second[interval_number]->Fill(track_eta, track_phi);
971 pass_hists[pdg_key][interval_number]->Fill(track_eta, track_phi);
978 for (
int cur_interval = 0; cur_interval <
fIntervalCount; cur_interval++) {
979 hist_file->WriteTObject(all_hists[pdg_key][cur_interval].get(),
nullptr,
"overwrite");
980 hist_file->WriteTObject(pass_hists[pdg_key][cur_interval].get(),
nullptr,
"overwrite");
981 Double_t all_count = all_hists[pdg_key][cur_interval]->GetEntries();
982 Double_t pass_count = pass_hists[pdg_key][cur_interval]->GetEntries();
983 probability_values +=
TString::Format(
" %4.2f", (all_count > 0) ? pass_count / all_count : 0.);
985 LOG(info) <<
"Acceptance probability for pdg=" << pdg_key <<
":" << probability_values;
998 gSystem->ExpandPathName(input_list_file);
1001 list<string> file_list;
1002 ifstream list_file(input_list_file.
Data());
1004 while (getline(list_file, s))
1005 file_list.push_back(s);
1006 if (file_list.empty()) {
1007 LOG(error) <<
"There are no files in the list of the input text file: " << input_list_file;
1012 TChain dataChain(
"bmndata");
1013 for (
auto const& cur_file_path : file_list) {
1014 TString strFilePath(cur_file_path);
1015 gSystem->ExpandPathName(strFilePath);
1016 dataChain.
AddFile(strFilePath);
1019 LOG(error) <<
"There are no correct input files in the text list stored at: " << input_list_file;
1025 unique_ptr<TFile> hist_file(
TFile::Open(histo_file,
"UPDATE"));
1026 if ((!hist_file) || (!hist_file->IsOpen())) {
1027 LOG(error) <<
"Unable to open the file with the sample histograms for updating: " << histo_file;
1036 if (dataChain.
GetBranch(
"BmnGlobalTrack") ==
nullptr) {
1037 LOG(error) <<
"'BmnGlobalTrack' branch was not found: the efficiency map is built from the reconstructed "
1038 "(DST) files, please, check the structure of the given files";
1050 Bool_t isMatched = isMC && (dataChain.
GetBranch(
"BmnGlobalTrackMatch") !=
nullptr);
1053 LOG(info) <<
"Building the efficiency map from the " << (isMC ?
"simulated" :
"experimental") <<
" DST files";
1054 if (isMC && (!isMatched))
1055 LOG(warning) <<
"'BmnGlobalTrackMatch' branch was not found, the particle types of the reconstructed tracks "
1056 "without an MC index are defined by the mass measured by the ToF detectors";
1059 map<Int_t, vector<Double_t>> reconstructed_count;
1065 for (
int iEvent = 0; iEvent < iEventNumber; iEvent++) {
1066 if ((iEvent + 1) % 1000 == 0)
1067 LOG(info) <<
"Processing event #" << iEvent + 1 <<
" of " << iEventNumber;
1069 if (globalTracks ==
nullptr)
1073 for (
int iTrack = 0; iTrack < globalTracks->
GetEntries(); iTrack++) {
1075 if (global_track ==
nullptr)
1090 if (reconstructed_count.find(track_pdg) == reconstructed_count.end())
1094 if (parFirst ==
nullptr)
1096 Double_t track_qp = parFirst->GetQp();
1102 int interval_number = (track_p -
fPMin) / interval_width;
1103 if ((interval_number < 0) || (interval_number >=
fIntervalCount))
1106 reconstructed_count[track_pdg][interval_number] += 1.;
1113 for (
int cur_interval = 0; cur_interval <
fIntervalCount; cur_interval++) {
1117 unique_ptr<TH2D> p_eta_hist((
TH2D*)hist_file->Get(histogram_name));
1118 if (p_eta_hist ==
nullptr) {
1119 LOG(error) <<
"The (P, Eta) histogram '" << histogram_name
1120 <<
"' does not exist in the file with the sample histograms: " << histo_file;
1123 p_eta_hist->SetDirectory(
nullptr);
1124 Double_t sample_count = p_eta_hist->GetEntries();
1125 efficiency[cur_interval] =
1126 (sample_count > 0) ? (reconstructed_count[pdg_key][cur_interval] / sample_count) : 0.;
1127 max_efficiency =
TMath::Max(max_efficiency, efficiency[cur_interval]);
1130 if (max_efficiency <= 0.) {
1131 LOG(error) <<
"No track of pdg=" << pdg_key <<
" was reconstructed in the given files, "
1132 <<
"the efficiency map cannot be built";
1137 efficiency *= 1. / max_efficiency;
1142 for (
int cur_interval = 0; cur_interval <
fIntervalCount; cur_interval++)
1143 efficiency_values +=
TString::Format(
" %4.2f", efficiency[cur_interval]);
1144 LOG(info) <<
"Relative efficiency for pdg=" << pdg_key <<
":" << efficiency_values;
1157 if ((hist_file ==
nullptr) || (hist_file->
IsZombie())) {
1158 LOG(error) <<
"The file with the sample histograms was not opened: " << input_histo_file;
1174 LOG(error) <<
"Momentum histogram does not exist for pdg=" << pdg_key;
1181 LOG(error) <<
"Momentum histogram is empty for pdg=" << pdg_key;
1187 LOG(info) <<
"The fitted momentum function is absent for pdg=" << pdg_key <<
", fitting it now";
1193 LOG(error) <<
"Transverse momentum histogram does not exist for pdg=" << pdg_key;
1198 LOG(error) <<
"Transverse momentum histogram is empty for pdg=" << pdg_key;
1204 LOG(error) <<
"Rapidity histogram does not exist for pdg=" << pdg_key;
1209 LOG(error) <<
"Rapidity histogram is empty for pdg=" << pdg_key;
1215 LOG(error) <<
"Pseudorapidity histogram does not exist for pdg=" << pdg_key;
1220 LOG(error) <<
"Pseudorapidity histogram is empty for pdg=" << pdg_key;
1226 LOG(error) <<
"Theta angle histogram does not exist for pdg=" << pdg_key;
1231 LOG(error) <<
"Theta angle histogram is empty for pdg=" << pdg_key;
1237 LOG(error) <<
"Phi angle histogram does not exist for pdg=" << pdg_key;
1242 LOG(error) <<
"Phi angle histogram is empty for pdg=" << pdg_key;
1250 LOG(error) <<
"(P, Eta) histogram does not exist for pdg=" << pdg_key
1251 <<
". The file with the sample histograms was produced by an older version of "
1252 "BmnParticleEqualizer2D or by BmnParticleEqualizer1D, please, recreate it with "
1253 "BmnParticleEqualizer2D::ProduceSampleHistograms()";
1258 LOG(error) <<
"(P, Eta) histogram is empty for pdg=" << pdg_key;
1264 LOG(error) <<
"(Eta, Phi) histogram does not exist for pdg=" << pdg_key;
1269 LOG(error) <<
"(Eta, Phi) histogram is empty for pdg=" << pdg_key;
1276 int hist_counter = 0;
1277 for (
auto& p_eta_hist :
fParticleInfos[pdg_key]->fPEtaHistVector) {
1278 histogram_name =
TString::Format(
"hPEta%d_pdg%d", ++hist_counter, pdg_key);
1279 p_eta_hist = unique_ptr<TH2D>((
TH2D*)hist_file->
Get(histogram_name));
1280 if (p_eta_hist.get() ==
nullptr) {
1281 LOG(error) <<
"(P, Eta) histogram does not exist for pdg=" << pdg_key
1282 <<
" in interval=" << hist_counter;
1285 p_eta_hist->SetDirectory(
nullptr);
1288 for (
auto& eta_phi_hist :
fParticleInfos[pdg_key]->fEtaPhiHistVector) {
1289 histogram_name =
TString::Format(
"hEtaPhi%d_pdg%d", ++hist_counter, pdg_key);
1290 eta_phi_hist = unique_ptr<TH2D>((
TH2D*)hist_file->
Get(histogram_name));
1291 if (eta_phi_hist.get() ==
nullptr) {
1292 LOG(error) <<
"(Eta, Phi) histogram does not exist for pdg=" << pdg_key
1293 <<
" in interval=" << hist_counter;
1296 eta_phi_hist->SetDirectory(
nullptr);
1304 if (p_dist_func !=
nullptr) {
1318 if (
fParticleInfos[pdg_key]->fPEtaHistVector[cur_interval]->GetEntries() > 2)
1322 else if ((p_dist_func !=
nullptr)
1328 "There is neither sample statistics nor a significant fitted momentum function for pdg=%d in the "
1329 "momentum interval [%4.2f, %4.2f] GeV: no particles will be added there",
1335 LOG(error) <<
"PDG code " << pdg_key <<
" is not defined in the PDG database";
1343 unique_ptr<TVector3> y0_sigma_t((
TVector3*)hist_file->
Get(vector_name));
1344 if (y0_sigma_t ==
nullptr) {
1345 LOG(error) <<
"The fitted distribution parameters ('" << vector_name
1346 <<
"') do not exist in the file with the sample histograms. It was produced by an older "
1347 "version of the equalizing generator, please, recreate it with ProduceSampleHistograms()";
1359 unique_ptr<TVectorD> efficiency(
1361 if ((efficiency !=
nullptr) && (efficiency->GetNoElements() ==
fIntervalCount)) {
1362 for (
int cur_interval = 0; cur_interval <
fIntervalCount; cur_interval++)
1363 fParticleInfos[pdg_key]->fEfficiency[cur_interval] = (*efficiency)[cur_interval];
1365 if (efficiency !=
nullptr)
1366 LOG(error) <<
"The efficiency map of pdg=" << pdg_key <<
" has " << efficiency->GetNoElements()
1367 <<
" elements instead of " <<
fIntervalCount <<
" momentum intervals, it is ignored";
1368 is_efficiency_map_read =
kFALSE;
1376 <<
"Unable to build the histograms for the filtering of the event particles by the sample statistics";
1396 TObjArray* generator_list = primGen->GetListOfGenerators();
1397 if ((generator_list ==
nullptr) || (generator_list->
Last() !=
this)) {
1398 LOG(error) <<
"The BmnParticleEqualizer2D generator is not the last one registered in FairPrimaryGenerator: "
1399 "it has to be added by AddGenerator() after all the other generators of the event";
1404 CbmStack* stack = (gMC ==
nullptr) ?
nullptr :
dynamic_cast<CbmStack*
>(gMC->GetStack());
1405 if (stack ==
nullptr) {
1406 LOG(error) <<
"The BmnParticleEqualizer2D generator requires the particle stack of the simulation (CbmStack) "
1407 "to count the particles of the event, but it is not available";
1414 fill(part_iter->second->fParticleNumber.begin(), part_iter->second->fParticleNumber.end(), 0);
1426 if ((part ==
nullptr) || (!part->
IsPrimary()))
1441 if ((interval_number < 0) || (interval_number >=
fIntervalCount))
1445 LOG(debug) <<
TString::Format(
"Found particle: PDG=%i P=%4.2f Eta=%4.2f", part_code, part_p, part_eta);
1453 TH2D* p_eta_hist =
fParticleInfos[part_code]->fPEtaCutHistVector[interval_number].get();
1456 TH2D* eta_phi_hist =
fParticleInfos[part_code]->fEtaPhiCutHistVector[interval_number].get();
1461 part_iter->second->fParticleNumber[interval_number] += 1;
1463 if (part_iter->second->fParticleNumber[interval_number] >
fMaxParticles[interval_number])
1464 fMaxParticles[interval_number] = part_iter->second->fParticleNumber[interval_number];
1483 TVector3 beam_x(1., 0., 0.), beam_y(0., 1., 0.), beam_z(0., 0., 1.);
1484 if ((event_header !=
nullptr) && ((event_header->GetRotX() != 0.) || (event_header->GetRotY() != 0.))) {
1486 beam_direction = beam_direction.
Unit();
1488 beam_y.RotateUz(beam_direction);
1494 LOG(debug) <<
TString::Format(
"Current particle type to be equalized: pdg=%i y0=%4.2f sigma_y=%4.2f T_pt=%6.4f",
1504 LOG(debug) <<
"Adding paticle to equalize the numbers...";
1528 particle_debt += particle_number;
1532 if (add_particle < 0)
1534 particle_debt -= add_particle;
1541 <<
" " << add_particle <<
" particle with PDG = " << pdg_key <<
" (" << cur_p <<
" GeV)";
1542 for (
Int_t k = 0; k < add_particle; k++) {
1546 fParticleInfos[pdg_key]->fPEtaHistVector[cur_interval]->GetRandom2(p, eta);
1554 LOG(warning) <<
"The pseudorapidity cannot be sampled for pdg=" << pdg_key <<
" and p=" << p
1555 <<
" GeV, the particle is skipped";
1566 LOG(warning) <<
"The azimuth angle cannot be sampled for pdg=" << pdg_key <<
" and eta=" << eta
1567 <<
", the particle is skipped";
1574 LOG(warning) <<
"An incorrect momentum (" << p <<
") or pseudorapidity (" << eta
1575 <<
") was sampled for pdg=" << pdg_key <<
", the particle is skipped";
1582 mom.
SetXYZ(mom * beam_x, mom * beam_y, mom * beam_z);
1584 LOG(debug) <<
"Particle generated: pdg=" << pdg_key <<
" p=" << p <<
" eta=" << eta;
1589 primGen->AddTrack(pdg_key, mom.
X(), mom.
Y(), mom.
Z(), 0., 0., 0.);
1596 if (added_particle !=
nullptr)
1609 if (hist ==
nullptr)
1617 for (
Int_t half_width = 0;; half_width = 2 * half_width + 1) {
1622 for (
Int_t iy = 1; iy <= bin_count_y; iy++)
1623 for (
Int_t ix = first_x; ix <= last_x; ix++)
1630 for (
Int_t iy = 1; iy <= bin_count_y; iy++) {
1631 for (
Int_t ix = first_x; ix <= last_x; ix++)
1634 if (sum > random_value) {
1645 if ((first_x == 1) && (last_x == bin_count_x))
1654 if ((!f) || (!f->IsOpen())) {
1655 cout <<
"ERROR: unable to open ROOT file: " << input_histo_file << endl;
1660 TString::Format(
"Distributions for particle PDG = %d", particle_number), 1000,
1663 if (h1 ==
nullptr) {
1664 cout <<
"ERROR: the momentum histogram is absent for PDG = " << particle_number << endl;
1671 cout <<
"avg_value = " << p_avg << endl;
1672 cout <<
"x_max_value = " << x_max_value << endl;
1673 cout <<
"y_max_value = " << y_max_value << endl;
1678 if (p_distribution !=
nullptr)
1689 if ((!f) || (!f->IsOpen())) {
1690 cout <<
"ERROR: unable to open ROOT file: " << input_histo_file << endl;
1696 TString::Format(
"Distributions for particle PDG = %d", particle_number), 1000,
1699 if (h1 ==
nullptr) {
1700 cout <<
"ERROR: the momentum histogram is absent for PDG = " << particle_number << endl;
1704 if (f1 ==
nullptr) {
1705 cout <<
"ERROR: the fitted momentum function is absent for PDG = " << particle_number << endl;
1723 cout <<
"ERROR: Could not get TDatabasePDG instance" << endl;
1730 if (vecParticlePDG.empty()) {
1733 if (
TMath::Abs(particle->Mass() - mass) < (tolerance > 0 ? tolerance * mass : -1 * tolerance))
1734 return particle->PdgCode();
1737 for (
int particle_number : vecParticlePDG) {
1739 if (particle ==
nullptr)
1741 if (
TMath::Abs(particle->
Mass() - mass) < (tolerance > 0 ? tolerance * mass : -1 * tolerance))
1756 if (global_track ==
nullptr)
1762 if (mc_tracks !=
nullptr) {
1764 if ((mc_index < 0) && (global_match !=
nullptr) && (global_match->
GetNofLinks() > 0))
1766 if (mc_index > -1) {
1770 return (mc_track ==
nullptr) ? 0 : mc_track->
GetPdgCode();
1773 if (global_match !=
nullptr)
1780 if (mass_tof2 == -1000.0)
1781 mass_tof2 = global_track->
GetMass2(2);
1783 if ((mass_tof2 == -1000.0) || (mass_tof2 < 0))
1786 if ((par_first ==
nullptr) || (par_first->GetQp() == 0))
1792 vector<Int_t> candidates;
1795 if ((particle !=
nullptr) && (particle->
Charge() * par_first->GetQp() > 0))
1796 candidates.push_back(pdg_code);
1798 if (candidates.empty())
1810 gSystem->ExpandPathName(input_list_file);
1813 list<string> file_list;
1814 ifstream list_file(input_list_file.
Data());
1816 while (getline(list_file, s))
1817 file_list.push_back(s);
1818 if (file_list.empty()) {
1819 cout <<
"ERROR: There are no files in the list of the input text file: " << input_list_file << endl;
1824 TChain dataChain(
"bmndata");
1825 for (
auto const& cur_file_path : file_list) {
1826 TString strFilePath(cur_file_path);
1827 gSystem->ExpandPathName(strFilePath);
1829 dataChain.
Add(strFilePath);
1834 TClonesArray *mcTracks =
nullptr, *globalTracks =
nullptr, *globalMatches =
nullptr;
1836 if (dataChain.
GetBranch(
"MCTrack") ==
nullptr) {
1837 if (dataChain.
GetBranch(
"BmnMCInfo.") ==
nullptr) {
1838 LOG(error) <<
"'MCTrack' and 'BmnMCInfo.' branches were not found, please, check the structure of the "
1839 "files, exiting...";
1843 if (mcInfo ==
nullptr) {
1845 <<
"'BmnMCInfo.' branch was not read correctly, please, check the structure of the files, exiting...";
1849 if (globalTracks ==
nullptr) {
1850 LOG(error) <<
"'BmnGlobalTrack' branch was not read correctly, please, check the structure of the files, "
1856 if (dataChain.
GetBranch(
"BmnGlobalTrackMatch") !=
nullptr)
1859 LOG(warning) <<
"'BmnGlobalTrackMatch' branch was not found, the particle types of the reconstructed "
1860 "tracks without an MC index are defined by the mass measured by the ToF detectors";
1867 if (mcTracks ==
nullptr) {
1869 <<
"MCTrack' branch was not read correctly, please, check the structure of the files, exiting...";
1878 new TCanvas(
"c_number",
"Multiplicity of different particle types for all the momentum intervals", 1000, 500);
1883 map<int, TH1I*> mapParticleNumberHists;
1885 TH1I* hParticleNumber =
1927 mapParticleNumberHists[particle_number] = hParticleNumber;
1932 map<int, TH1D*> mapPHists, mapPtHists, mapYHists, mapEtaHists, mapThetaHists, mapPhiHists;
1936 mapPHists[particle_number] = hP;
1939 mapPtHists[particle_number] = hPt;
1942 mapYHists[particle_number] = hY;
1945 mapEtaHists[particle_number] = hEta;
1948 mapThetaHists[particle_number] = hTheta;
1951 mapPhiHists[particle_number] = hPhi;
1954 int iEventNumber = dataChain.
GetEntries(), iCurrentEvent = 0;
1955 if (iEventNumber < 1) {
1956 cout <<
"ERROR: There are no correct entries in the file list stored at: \"" << input_list_file <<
"\"" << endl;
1961 for (iCurrentEvent = 0; iCurrentEvent < iEventNumber; iCurrentEvent++) {
1963 if ((iCurrentEvent + 1) % 1000 == 0)
1964 LOG(info) <<
"Processing event #" << iCurrentEvent + 1 <<
" of " << iEventNumber;
1967 Int_t track_count = 0;
1971 track_count = globalTracks->GetEntries();
1973 mc_tracks = mcTracks;
1978 for (
Int_t iTrack = 0; iTrack < track_count; iTrack++) {
1979 Int_t track_pdg = -1;
1981 Double_t track_p = 0, track_pt = 0, track_y = 0, track_eta = 0, track_theta = 0, track_phi = 0;
1987 global_track = (
BmnGlobalTrack*)globalTracks->UncheckedAt(iTrack);
1996 BmnTrackMatch* global_match = ((globalMatches !=
nullptr) && (iTrack < globalMatches->GetEntriesFast()))
2005 track_mass = tof_mass;
2008 if (particle ==
nullptr)
2010 track_mass = particle->
Mass();
2016 if (parFirst ==
nullptr)
2018 Double_t track_qp = parFirst->GetQp();
2021 parFirst->Momentum(vecMom);
2022 track_pt =
TMath::Sqrt(vecMom.
x() * vecMom.
x() + vecMom.
y() * vecMom.
y());
2024 track_y = 0.5 *
TMath::Log((e + vecMom.
z()) / (e - vecMom.
z()));
2025 track_eta = 0.5 *
TMath::Log((track_p + vecMom.
z()) / (track_p - vecMom.
z()));
2026 Double_t track_tx = parFirst->GetTx(), track_ty = parFirst->GetTy();
2035 if (mc_track ==
nullptr)
2055 track_p = mc_track->
GetP();
2056 track_pt = mc_track->
GetPt();
2067 if ((track_p >=
fPMin) && (track_p <
fPMax)) {
2068 mapParticleNumberHists[*iter_pdg]->Fill(track_p);
2069 mapPHists[*iter_pdg]->Fill(track_p);
2070 mapPtHists[*iter_pdg]->Fill(track_pt);
2071 mapYHists[*iter_pdg]->Fill(track_y);
2072 mapEtaHists[*iter_pdg]->Fill(track_eta);
2073 mapThetaHists[*iter_pdg]->Fill(track_theta);
2074 mapPhiHists[*iter_pdg]->Fill(track_phi);
2080 if (iCurrentEvent == 0) {
2081 cout <<
"ERROR: There are no necessary tree branches or DST events in the files from the list: "
2082 << input_list_file << endl;
2083 for (
const auto& pair : mapPHists)
2085 for (
const auto& pair : mapPtHists)
2087 for (
const auto& pair : mapYHists)
2089 for (
const auto& pair : mapEtaHists)
2091 for (
const auto& pair : mapThetaHists)
2093 for (
const auto& pair : mapPhiHists)
2101 for (
const auto& pair_hist : mapParticleNumberHists) {
2102 if (max_y_value < pair_hist.second->GetMaximum())
2103 max_y_value = pair_hist.second->GetMaximum();
2108 TString hist_options =
"bar2,hist,text";
2110 for (
const auto& pair_hist : mapParticleNumberHists) {
2111 if (cur_hist == 0) {
2112 if (pair_hist.second->GetMaximum() < max_y_value)
2113 pair_hist.second->SetMaximum(max_y_value + 10);
2114 pair_hist.second->DrawCopy(hist_options);
2116 pair_hist.second->DrawCopy(hist_options +
",same");
2125 TCanvas* c_p =
new TCanvas(
"c_p",
"Particle Momentum", 1000, 500);
2130 mapPHists[particle_number]->
Draw();
2133 TCanvas* c_pt =
new TCanvas(
"c_pt",
"Transverse Momentum", 1000, 500);
2138 mapPtHists[particle_number]->
Draw();
2146 mapYHists[particle_number]->
Draw();
2149 TCanvas* c_eta =
new TCanvas(
"c_eta",
"Pseudorapidity", 1000, 500);
2153 c_eta->
cd(cur_hist);
2154 mapEtaHists[particle_number]->
Draw();
2157 TCanvas* c_theta =
new TCanvas(
"c_theta",
"Theta angle", 1000, 500);
2161 c_theta->
cd(cur_hist);
2162 mapThetaHists[particle_number]->
Draw();
2169 c_phi->
cd(cur_hist);
2170 mapPhiHists[particle_number]->
Draw();
static Bool_t FitMomentumFunction(TH1D *hP, const TString &func_name, Double_t p_min, Double_t p_max)
static const char * kEfficiencyNamePrefix
static Double_t fThetaMax
static const char * kMomentumGridName
static const int kMomentumGridSize
static Double_t fThetaMin
static const int kEtaPhiPhiBinCount
static Bool_t FitMomentumFunction(TH1D *hP, const TString &func_name, Double_t p_min, Double_t p_max)
static const char * kAcceptanceCutName
Cut applied to the tracks of the sample (see SetSampleTrackCut).
static const int kSampleStatisticsCutRebin
static const int kEtaBinCount
static const int kPEtaPBinCount
R__EXTERN TRandom * gRandom
R__EXTERN TSystem * gSystem
TVectorT< Double_t > TVectorD
Int_t GetTof2HitIndex() const
Int_t GetTof1HitIndex() const
Float_t GetMass2(Int_t tofID) const
TClonesArray * GetMCTracks() const
rot. around z-axis [rad]
const BmnLink & GetMatchedLink() const
Int_t GetNofLinks() const
static int FitYHistogram(unique_ptr< TH1D > &hY, int pdg_key, Double_t &y0_output, Double_t &sigma_putput)
static Int_t GetPDGCodeByMass(Double_t mass, Double_t tolerance=1.e-6, const vector< int > &vecParticlePDG={})
Double_t fTargetPerInterval
static int FitEtaHistogram(unique_ptr< TH1D > &hEta, int pdg_key, Double_t eta_min, Double_t eta_max)
static int ShowSampleHistograms(TString input_histo_file="$VMCWORKDIR/macro/recotools/particle_hists.root")
static Bool_t GetConditionalRandomY(const TH2D *hist, Double_t x, Double_t &y)
static Bool_t CheckMomentumGrid(TFile *hist_file)
Bool_t BuildStatisticsCutHistograms()
Bool_t SetSampleStatisticsCutRebin(Int_t factor)
Set how much the two dimensional sample histograms are rebinned for the filtering of the event partic...
Bool_t isActive
Interval step.
Int_t fSampleStatisticsCutRebin
Lower limit of the efficiency used for the correction.
static int ProduceAcceptanceMap(TString input_list_file, TString histo_file="$VMCWORKDIR/macro/recotools/particle_hists.root")
static int ProduceSampleHistograms(TString input_list_file, TString output_histo_file="$VMCWORKDIR/macro/recotools/particle_hists.root")
static Double_t fPMin
Min value of momentum.
Double_t fMinEfficiency
Whether the added particle number is corrected by the efficiency.
static Double_t fPMax
Max value of momentum.
Bool_t SetEfficiencyCorrection(Bool_t is_used, Double_t min_efficiency=0.05)
Switch on the correction of the number of the added particles by the reconstruction efficiency (off b...
static void FitSampleHistograms(TString input_histo_file="$VMCWORKDIR/macro/recotools/particle_hists.root")
additional functions to check results of fitting and particle equalizing
static Int_t fIntervalCount
Interval count for momentum to equalize particles at all the intervals.
Bool_t fUseEfficiencyCorrection
Target particle number per interval, 0 = maximum of the event (see the setter).
map< Int_t, unique_ptr< stParticleInfo > > fParticleInfos
Bool_t fIsEfficiencyMapRead
Rebin factor of the histograms used to filter the particles of an event.
static int FitPtHistogram(unique_ptr< TH1D > &hPt, int pdg_key, Double_t pdg_mass, Double_t pt_min, Double_t pt_max, Double_t &t_output)
vector< int > fMaxParticles
virtual Bool_t ReadEvent(FairPrimaryGenerator *primGen)
Creates an event with equal number of particles at all momentum intervals.
BmnParticleEqualizer2D(TString hist_file_name)
Constructor with input histograms.
static Int_t fSampleTrackCut
Cut applied to the tracks of the sample (see SetSampleTrackCut).
Bool_t Init()
Initializer.
static int FitPHistogram(unique_ptr< TH1D > &hP, int pdg_key, Double_t p_min, Double_t p_max)
static vector< Int_t > fParticles
static int ShowResultDistributions(TString input_list_file)
static int ProduceEfficiencyMap(TString input_list_file, TString histo_file="$VMCWORKDIR/macro/recotools/particle_hists.root")
Bool_t fUseSampleStatisticsCut
Whether the efficiency map has been found in the sample histogram file.
static Int_t GetGlobalTrackPDG(BmnGlobalTrack *global_track, BmnTrackMatch *global_match, TClonesArray *mc_tracks, Double_t &tof_mass)
Bool_t ReadSampleHistograms(TString input_histo_file="$VMCWORKDIR/macro/recotools/particle_hists.root")
FairTrackParam * GetParamFirst()
Long64_t GetNPoints(DetectorId detId) const
Accessors to the number of MCPoints in the detectors.
Double_t GetRapidity() const
Int_t GetMotherId() const
Int_t GetPdgCode() const
Accessors.
TClonesArray * GetListOfParticles()
int Index(const std::string &name) const
double Parameter(unsigned int i) const
static void SetDefaultMinimizer(const char *type, const char *algo=nullptr)
static const std::string & DefaultMinimizerType()
virtual void SetLabelSize(Float_t size=0.04)
virtual void SetTitleSize(Float_t size=0.04)
virtual void SetNdivisions(Int_t n1, Int_t n2, Int_t n3, Bool_t optim=kTRUE)
virtual void SetFillColor(Color_t fcolor)
virtual void SetMarkerSize(Size_t msize=1)
virtual Int_t FindBin(const char *label)
virtual Double_t GetBinCenter(Int_t bin) const
virtual Double_t GetBinLowEdge(Int_t bin) const
void CenterTitle(Bool_t center=kTRUE)
virtual Double_t GetBinWidth(Int_t bin) const
virtual Double_t GetBinUpEdge(Int_t bin) const
TVirtualPad * cd(Int_t subpadnumber=0) override
Int_t SetBranchAddress(const char *bname, T **add, TBranch **ptr=nullptr)
virtual Int_t AddFile(const char *name, Long64_t nentries=TTree::kMaxEntries, const char *tname="")
TBranch * GetBranch(const char *name) override
virtual Int_t Add(const char *name, Long64_t nentries=TTree::kMaxEntries)
void SetBranchStatus(const char *bname, bool status=true, UInt_t *found=nullptr) override
Long64_t GetEntries() const override
Int_t GetEntry(Long64_t entry=0, Int_t getall=0) override
static TDatabasePDG * Instance()
const THashList * ParticleList() const
TParticlePDG * GetParticle(const char *name) const
T * Get(const char *namecycle)
virtual void ReleaseParameter(Int_t ipar)
virtual Double_t GetParameter(const TString &name) const
virtual void SetRange(Double_t xmin, Double_t xmax)
virtual void SetNpx(Int_t npx=100)
void Draw(Option_t *option="") override
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
virtual Double_t GetRandom(Double_t xmin, Double_t xmax, TRandom *rng=nullptr, Option_t *opt=nullptr)
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
virtual Double_t GetMaximum(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual void SetParameter(const TString &name, Double_t value)
virtual void FixParameter(Int_t ipar, Double_t value)
virtual Int_t GetNpx() const
virtual Bool_t IsOpen() const
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
void Close(Option_t *option="") override
virtual void SetLabelFont(Style_t font=62, Option_t *axis="X")
virtual void SetBarOffset(Float_t offset=0.25)
void SetTitle(const char *title) override
virtual Int_t GetNbinsY() const
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
virtual Int_t GetNbinsX() const
void Draw(Option_t *option="") override
Double_t GetRMS(Int_t axis=1) const
virtual TF1 * GetFunction(const char *name) const
virtual Double_t Integral(Int_t binx1, Int_t binx2, Option_t *option="") const
virtual Int_t GetMaximumBin() const
virtual Double_t GetBinContent(Int_t bin) const
virtual Double_t GetBinWidth(Int_t bin) const
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
virtual void LabelsDeflate(Option_t *axis="X")
virtual void SetBarWidth(Float_t width=0.5)
virtual void SetStats(Bool_t stats=kTRUE)
virtual Double_t GetBinContent(Int_t bin) const
void Draw(Option_t *option="") override
TLegendEntry * AddEntry(const char *name, const char *label="", Option_t *option="lpf")
virtual void SetTitle(const char *title="")
const char * GetName() const override
Int_t GetEntriesFast() const
TObject * Last() const override
Int_t GetEntries() const override
TObject * At(Int_t idx) const override
TObject * UncheckedAt(Int_t i) const
R__ALWAYS_INLINE Bool_t IsZombie() const
void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0) override
const char * Data() const
static TString Format(const char *fmt,...)
void SetXYZ(Double_t x, Double_t y, Double_t z)
void RotateUz(const TVector3 &)
void Draw(Option_t *option="") override=0
Double_t Min(Double_t a, Double_t b)
Double_t Floor(Double_t x)
Double_t ATan2(Double_t y, Double_t x)
Double_t Sqrt(Double_t x)
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Double_t Max(Double_t a, Double_t b)
Double_t Range(Double_t lb, Double_t ub, Double_t x)
vector< unique_ptr< TH2D > > fEtaPhiCutHistVector
The same rebinned copies of 'fEtaPhiHistVector' (divided by momentum intervals -> vector).
Double_t fT
Temperature in the P distribution.
vector< unique_ptr< TH1D > > fPHistVector
P histograms for the particle type (divided by momentum intervals -> vector).
vector< Double_t > fParticleDebt
Part of the target number of the particles that has not been added yet, kept between the events so th...
stParticleInfo(int pdg_key, Double_t min_p, Double_t max_p, Int_t interval_count)
Double_t fY0
Mean rapidity.
vector< unique_ptr< TH2D > > fPEtaHistVector
(P, Eta) histograms for the particle type (divided by momentum intervals -> vector).
vector< unique_ptr< TH1D > > fPhiHistVector
Phi histograms for the particle type (divided by momentum intervals -> vector).
vector< Int_t > fParticleNumber
PDG -> Particle Count (divided by momentum intervals -> vector).
@ kNone
the interval cannot be sampled at all, new particles are not added there
@ kIntervalHist
P and Eta together from the (P, Eta) histogram of the interval itself.
@ kFitFunction
P from the fitted function of the full P histogram (too little sample statistics).
vector< EPSampling > fPSampling
Momentum sampling way for the particle type (divided by momentum intervals -> vector).
vector< unique_ptr< TH2D > > fPEtaCutHistVector
Rebinned copies of 'fPEtaHistVector' used to check whether the sample has statistics for a particle o...
vector< unique_ptr< TH2D > > fEtaPhiHistVector
(Eta, Phi) histograms for the particle type (divided by momentum intervals -> vector)
Double_t fSigma
Sigma in the rapidity distribution.
vector< unique_ptr< TH1D > > fEtaHistVector
Eta histograms for the particle type (divided by momentum intervals -> vector).
vector< Double_t > fEfficiency
Relative reconstruction efficiency of the particle type, 1 for all the intervals if the efficiency ma...