diff --git a/Generators/include/Generators/Generator.h b/Generators/include/Generators/Generator.h index 67277e20736ce..5a4921e036ca3 100644 --- a/Generators/include/Generators/Generator.h +++ b/Generators/include/Generators/Generator.h @@ -161,7 +161,7 @@ class Generator : public FairGenerator void updateSubGeneratorInformation(o2::dataformats::MCEventHeader* header) const; // loopers flag - Bool_t mAddTPCLoopers = kFALSE; // Flag is automatically set to true if TPC is in readout detectors, loopers are not vetoed and transport is enabled + Bool_t mAddTPCLoopers = kFALSE; // Flag is automatically set to true if TPC is in readout detectors, loopers are not vetoed and transport is enabled // collect an ID and a short description of sub-generator entities std::unordered_map mSubGeneratorsIdToDesc; // the current ID of the sub-generator used in the current event (if applicable) diff --git a/Generators/include/Generators/TPCLoopersParam.h b/Generators/include/Generators/TPCLoopersParam.h index 24d905c59c967..49c8e5f5927b6 100644 --- a/Generators/include/Generators/TPCLoopersParam.h +++ b/Generators/include/Generators/TPCLoopersParam.h @@ -28,22 +28,22 @@ namespace eventgen ** allow the user to modify them **/ struct GenTPCLoopersParam : public o2::conf::ConfigurableParamHelper { - bool loopersVeto = false; // if true, no loopers are generated - std::string model_pairs = "ccdb://Users/m/mgiacalo/WGAN_ExtGenPair"; // ONNX model for e+e- pair production - std::string model_compton = "ccdb://Users/m/mgiacalo/WGAN_ExtGenCompton"; // ONNX model for Compton scattering - std::string poisson = "${O2_ROOT}/share/Generators/egconfig/poisson_params.csv"; // file with Poissonian parameters - std::string gauss = "${O2_ROOT}/share/Generators/egconfig/gaussian_params.csv"; // file with Gaussian parameters - std::string scaler_pair = "${O2_ROOT}/share/Generators/egconfig/ScalerPairParams.json"; // file with scaler parameters for e+e- pair production + bool loopersVeto = false; // if true, no loopers are generated + std::string model_pairs = "ccdb://Users/m/mgiacalo/WGAN_ExtGenPair"; // ONNX model for e+e- pair production + std::string model_compton = "ccdb://Users/m/mgiacalo/WGAN_ExtGenCompton"; // ONNX model for Compton scattering + std::string poisson = "${O2_ROOT}/share/Generators/egconfig/poisson_params.csv"; // file with Poissonian parameters + std::string gauss = "${O2_ROOT}/share/Generators/egconfig/gaussian_params.csv"; // file with Gaussian parameters + std::string scaler_pair = "${O2_ROOT}/share/Generators/egconfig/ScalerPairParams.json"; // file with scaler parameters for e+e- pair production std::string scaler_compton = "${O2_ROOT}/share/Generators/egconfig/ScalerComptonParams.json"; // file with scaler parameters for Compton scattering std::string nclxrate = "ccdb://Users/m/mgiacalo/ClustersTrackRatio"; // file with clusters/rate information per orbit std::string colsys = "PbPb"; // collision system (PbPb or pp) int intrate = -1; // Automatic IR from collision context if -1, else user-defined interaction rate in Hz - bool flat_gas = true; // if true, the gas density is considered flat in the TPC volume - unsigned int nFlatGasLoopers = 500; // number of loopers to be generated per event in case of flat gas [currently unused, kept for possible future debug developments] - float fraction_pairs = 0.08; // fraction of loopers [currently unused, kept for possible future debug developments] - float multiplier[2] = {1., 1.}; // multiplier for pairs and compton loopers for Poissonian and Gaussian sampling - unsigned int fixedNLoopers[2] = {1, 1}; // fixed number of loopers coming from pairs and compton electrons - valid if flat gas is false and both Poisson and Gaussian params files are empty - float adjust_flatgas = 0.f; // adjustment for the number of flat gas loopers per orbit (in percentage, e.g. -0.1 = -10%) [-1, inf)] + bool flat_gas = true; // if true, the gas density is considered flat in the TPC volume + unsigned int nFlatGasLoopers = 500; // number of loopers to be generated per event in case of flat gas [currently unused, kept for possible future debug developments] + float fraction_pairs = 0.08; // fraction of loopers [currently unused, kept for possible future debug developments] + float multiplier[2] = {1., 1.}; // multiplier for pairs and compton loopers for Poissonian and Gaussian sampling + unsigned int fixedNLoopers[2] = {1, 1}; // fixed number of loopers coming from pairs and compton electrons - valid if flat gas is false and both Poisson and Gaussian params files are empty + float adjust_flatgas = 0.f; // adjustment for the number of flat gas loopers per orbit (in percentage, e.g. -0.1 = -10%) [-1, inf)] O2ParamDef(GenTPCLoopersParam, "GenTPCLoopers"); }; diff --git a/Generators/include/TPCLoopers.h b/Generators/include/TPCLoopers.h index 8a4dc0030aa21..9addcf844e09d 100644 --- a/Generators/include/TPCLoopers.h +++ b/Generators/include/TPCLoopers.h @@ -26,33 +26,32 @@ extern Ort::Env global_env; // This class is responsible for loading the scaler parameters from a JSON file // and applying the inverse transformation to the generated data. -struct Scaler -{ - std::vector normal_min; - std::vector normal_max; - std::vector outlier_center; - std::vector outlier_scale; +struct Scaler { + std::vector normal_min; + std::vector normal_max; + std::vector outlier_center; + std::vector outlier_scale; - void load(const std::string &filename); + void load(const std::string& filename); - std::vector inverse_transform(const std::vector &input); + std::vector inverse_transform(const std::vector& input); -private: - std::vector jsonArrayToVector(const rapidjson::Value &jsonArray); + private: + std::vector jsonArrayToVector(const rapidjson::Value& jsonArray); }; // This class loads the ONNX model and generates samples using it. class ONNXGenerator { -public: - ONNXGenerator(Ort::Env &shared_env, const std::string &model_path); + public: + ONNXGenerator(Ort::Env& shared_env, const std::string& model_path); - std::vector generate_sample(); + std::vector generate_sample(); -private: - Ort::Env &env; - Ort::Session session; - TRandom3 rand_gen; + private: + Ort::Env& env; + Ort::Session session; + TRandom3 rand_gen; }; #endif // GENERATORS_WITH_TPCLOOPERS @@ -64,67 +63,67 @@ namespace eventgen #ifdef GENERATORS_WITH_TPCLOOPERS class GenTPCLoopers { - public: - GenTPCLoopers(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", - std::string poisson = "poisson.csv", std::string gauss = "gauss.csv", std::string scaler_pair = "scaler_pair.json", - std::string scaler_compton = "scaler_compton.json"); - - Bool_t generateEvent(); - - Bool_t generateEvent(double &time_limit); - - std::vector importParticles(); - - unsigned int PoissonPairs(); - - unsigned int GaussianElectrons(); - - void SetNLoopers(unsigned int &nsig_pair, unsigned int &nsig_compton); - - void SetMultiplier(std::array &mult); - - void setFlatGas(Bool_t& flat, const Int_t& number, const Int_t& nloopers_orbit); - - void setFractionPairs(float &fractionPairs); - - void SetRate(const std::string &rateFile, const bool &isPbPb, const int &intRate); - - void SetAdjust(const float &adjust); - - unsigned int getNLoopers() const { return (mNLoopersPairs + mNLoopersCompton); } - - private: - std::unique_ptr mONNX_pair = nullptr; - std::unique_ptr mONNX_compton = nullptr; - std::unique_ptr mScaler_pair = nullptr; - std::unique_ptr mScaler_compton = nullptr; - double mPoisson[3] = {0.0, 0.0, 0.0}; // Mu, Min and Max of Poissonian - double mGauss[4] = {0.0, 0.0, 0.0, 0.0}; // Mean, Std, Min, Max - std::vector> mGenPairs; - std::vector> mGenElectrons; - unsigned int mNLoopersPairs = -1; - unsigned int mNLoopersCompton = -1; - std::array mMultiplier = {1., 1.}; - bool mPoissonSet = false; - bool mGaussSet = false; - // Random number generator - TRandom3 mRandGen; - // Masses of the electrons and positrons - TDatabasePDG *mPDG = TDatabasePDG::Instance(); - double mMass_e = mPDG->GetParticle(11)->Mass(); - double mMass_p = mPDG->GetParticle(-11)->Mass(); - int mCurrentEvent = 0; // Current event number, used for adaptive loopers - TFile *mContextFile = nullptr; // Input collision context file - o2::steer::DigitizationContext *mCollisionContext = nullptr; // Pointer to the digitization context - std::vector mInteractionTimeRecords; // Interaction time records from collision context - Bool_t mFlatGas = false; // Flag to indicate if flat gas loopers are used - Bool_t mFlatGasOrbit = false; // Flag to indicate if flat gas loopers are per orbit - Int_t mFlatGasNumber = -1; // Number of flat gas loopers per event - double mIntTimeRecMean = 1.0; // Average interaction time record used for the reference - double mTimeLimit = 0.0; // Time limit for the current event - double mTimeEnd = 0.0; // Time limit for the last event - float mLoopsFractionPairs = 0.08; // Fraction of loopers from Pairs - int mInteractionRate = 50000; // Interaction rate in Hz + public: + GenTPCLoopers(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", + std::string poisson = "poisson.csv", std::string gauss = "gauss.csv", std::string scaler_pair = "scaler_pair.json", + std::string scaler_compton = "scaler_compton.json"); + + Bool_t generateEvent(); + + Bool_t generateEvent(double& time_limit); + + std::vector importParticles(); + + unsigned int PoissonPairs(); + + unsigned int GaussianElectrons(); + + void SetNLoopers(unsigned int& nsig_pair, unsigned int& nsig_compton); + + void SetMultiplier(std::array& mult); + + void setFlatGas(Bool_t& flat, const Int_t& number, const Int_t& nloopers_orbit); + + void setFractionPairs(float& fractionPairs); + + void SetRate(const std::string& rateFile, const bool& isPbPb, const int& intRate); + + void SetAdjust(const float& adjust); + + unsigned int getNLoopers() const { return (mNLoopersPairs + mNLoopersCompton); } + + private: + std::unique_ptr mONNX_pair = nullptr; + std::unique_ptr mONNX_compton = nullptr; + std::unique_ptr mScaler_pair = nullptr; + std::unique_ptr mScaler_compton = nullptr; + double mPoisson[3] = {0.0, 0.0, 0.0}; // Mu, Min and Max of Poissonian + double mGauss[4] = {0.0, 0.0, 0.0, 0.0}; // Mean, Std, Min, Max + std::vector> mGenPairs; + std::vector> mGenElectrons; + unsigned int mNLoopersPairs = -1; + unsigned int mNLoopersCompton = -1; + std::array mMultiplier = {1., 1.}; + bool mPoissonSet = false; + bool mGaussSet = false; + // Random number generator + TRandom3 mRandGen; + // Masses of the electrons and positrons + TDatabasePDG* mPDG = TDatabasePDG::Instance(); + double mMass_e = mPDG->GetParticle(11)->Mass(); + double mMass_p = mPDG->GetParticle(-11)->Mass(); + int mCurrentEvent = 0; // Current event number, used for adaptive loopers + TFile* mContextFile = nullptr; // Input collision context file + o2::steer::DigitizationContext* mCollisionContext = nullptr; // Pointer to the digitization context + std::vector mInteractionTimeRecords; // Interaction time records from collision context + Bool_t mFlatGas = false; // Flag to indicate if flat gas loopers are used + Bool_t mFlatGasOrbit = false; // Flag to indicate if flat gas loopers are per orbit + Int_t mFlatGasNumber = -1; // Number of flat gas loopers per event + double mIntTimeRecMean = 1.0; // Average interaction time record used for the reference + double mTimeLimit = 0.0; // Time limit for the current event + double mTimeEnd = 0.0; // Time limit for the last event + float mLoopsFractionPairs = 0.08; // Fraction of loopers from Pairs + int mInteractionRate = 50000; // Interaction rate in Hz }; #endif // GENERATORS_WITH_TPCLOOPERS diff --git a/Generators/share/egconfig/ScalerComptonParams.json b/Generators/share/egconfig/ScalerComptonParams.json index d8e654847f46e..157647fee2db7 100644 --- a/Generators/share/egconfig/ScalerComptonParams.json +++ b/Generators/share/egconfig/ScalerComptonParams.json @@ -1,28 +1,28 @@ { - "normal": { - "min": [ - -0.0108811147511005, - -0.0098758740350604, - -0.0103233363479375, - -260.0542297363281, - -259.80059814453125 - ], - "max": [ - 0.0108060473576188, - 0.0103057539090514, - 0.0106524610891938, - 260.0343933105469, - 259.62890625 - ] - }, - "outlier": { - "center": [ - -71.39387130737305, - 96791.23828125 - ], - "scale": [ - 265.9389114379883, - 230762.30981445312 - ] - } + "normal": { + "min": [ + -0.0108811147511005, + -0.0098758740350604, + -0.0103233363479375, + -260.0542297363281, + -259.80059814453125 + ], + "max": [ + 0.0108060473576188, + 0.0103057539090514, + 0.0106524610891938, + 260.0343933105469, + 259.62890625 + ] + }, + "outlier": { + "center": [ + -71.39387130737305, + 96791.23828125 + ], + "scale": [ + 265.9389114379883, + 230762.30981445312 + ] + } } \ No newline at end of file diff --git a/Generators/share/egconfig/ScalerPairParams.json b/Generators/share/egconfig/ScalerPairParams.json index 61434bfa2462e..57cdac421d3f6 100644 --- a/Generators/share/egconfig/ScalerPairParams.json +++ b/Generators/share/egconfig/ScalerPairParams.json @@ -1,34 +1,34 @@ { - "normal": { - "min": [ - -0.0073022879660129, - -0.0077305701561272, - -0.0076750442385673, - -0.0082916170358657, - -0.0079681202769279, - -0.0077468422241508, - -255.6164093017578, - -252.9441680908203 - ], - "max": [ - 0.007688719779253, - 0.0077241472899913, - 0.0075828479602932, - 0.00813714787364, - 0.0083825681358575, - 0.0073839174583554, - 256.2904968261719, - 253.4925842285156 - ] - }, - "outlier": { - "center": [ - -79.66580963134766, - 141535.640625 - ], - "scale": [ - 250.8921127319336, - 222363.16015625 - ] - } + "normal": { + "min": [ + -0.0073022879660129, + -0.0077305701561272, + -0.0076750442385673, + -0.0082916170358657, + -0.0079681202769279, + -0.0077468422241508, + -255.6164093017578, + -252.9441680908203 + ], + "max": [ + 0.007688719779253, + 0.0077241472899913, + 0.0075828479602932, + 0.00813714787364, + 0.0083825681358575, + 0.0073839174583554, + 256.2904968261719, + 253.4925842285156 + ] + }, + "outlier": { + "center": [ + -79.66580963134766, + 141535.640625 + ], + "scale": [ + 250.8921127319336, + 222363.16015625 + ] + } } \ No newline at end of file diff --git a/Generators/src/Generator.cxx b/Generators/src/Generator.cxx index 9c16c0dfb7e92..ce49254799587 100644 --- a/Generators/src/Generator.cxx +++ b/Generators/src/Generator.cxx @@ -170,7 +170,7 @@ bool Generator::initLoopersGen() try { // Create the TPC loopers generator with the provided parameters mLoopersGen = std::make_unique(model_pairs, model_compton, poisson, gauss, scaler_pair, scaler_compton); - const auto &intrate = loopersParam.intrate; + const auto& intrate = loopersParam.intrate; // Configure the generator with flat gas loopers defined per orbit with clusters/track info // If intrate is negative (default), automatic IR from collisioncontext.root will be used if (flat_gas) { @@ -209,7 +209,7 @@ Bool_t Generator::finalizeEvent() { #ifdef GENERATORS_WITH_TPCLOOPERS - if(mAddTPCLoopers) { + if (mAddTPCLoopers) { if (!mLoopersGen) { LOG(error) << "Loopers generator not initialized"; return kFALSE; @@ -268,7 +268,7 @@ Bool_t } /** Event finalization**/ - if(!finalizeEvent()) { + if (!finalizeEvent()) { LOG(error) << "ReadEvent failed in finalizeEvent"; return kFALSE; } diff --git a/Generators/src/TPCLoopers.cxx b/Generators/src/TPCLoopers.cxx index ac1123b8d0bbd..258b6cce07b5b 100644 --- a/Generators/src/TPCLoopers.cxx +++ b/Generators/src/TPCLoopers.cxx @@ -6,7 +6,7 @@ Ort::Env global_env(ORT_LOGGING_LEVEL_WARNING, "GlobalEnv"); // This class is responsible for loading the scaler parameters from a JSON file // and applying the inverse transformation to the generated data. -void Scaler::load(const std::string &filename) +void Scaler::load(const std::string& filename) { std::ifstream file(filename); if (!file.is_open()) { @@ -27,76 +27,73 @@ void Scaler::load(const std::string &filename) normal_max = jsonArrayToVector(doc["normal"]["max"]); outlier_center = jsonArrayToVector(doc["outlier"]["center"]); outlier_scale = jsonArrayToVector(doc["outlier"]["scale"]); -} +} -std::vector Scaler::inverse_transform(const std::vector &input) +std::vector Scaler::inverse_transform(const std::vector& input) { - std::vector output; - for (int i = 0; i < input.size(); ++i) - { - if (i < input.size() - 2) - output.push_back(input[i] * (normal_max[i] - normal_min[i]) + normal_min[i]); - else - output.push_back(input[i] * outlier_scale[i - (input.size() - 2)] + outlier_center[i - (input.size() - 2)]); - } + std::vector output; + for (int i = 0; i < input.size(); ++i) { + if (i < input.size() - 2) + output.push_back(input[i] * (normal_max[i] - normal_min[i]) + normal_min[i]); + else + output.push_back(input[i] * outlier_scale[i - (input.size() - 2)] + outlier_center[i - (input.size() - 2)]); + } - return output; + return output; } -std::vector Scaler::jsonArrayToVector(const rapidjson::Value &jsonArray) +std::vector Scaler::jsonArrayToVector(const rapidjson::Value& jsonArray) { - std::vector vec; - for (int i = 0; i < jsonArray.Size(); ++i) - { - vec.push_back(jsonArray[i].GetDouble()); - } - return vec; + std::vector vec; + for (int i = 0; i < jsonArray.Size(); ++i) { + vec.push_back(jsonArray[i].GetDouble()); + } + return vec; } // This class loads the ONNX model and generates samples using it. ONNXGenerator::ONNXGenerator(Ort::Env& shared_env, const std::string& model_path) -: env(shared_env), session(env, model_path.c_str(), Ort::SessionOptions{}) + : env(shared_env), session(env, model_path.c_str(), Ort::SessionOptions{}) { - // Create session options - Ort::SessionOptions session_options; - session = Ort::Session(env, model_path.c_str(), session_options); + // Create session options + Ort::SessionOptions session_options; + session = Ort::Session(env, model_path.c_str(), session_options); } std::vector ONNXGenerator::generate_sample() { - Ort::AllocatorWithDefaultOptions allocator; - - // Generate a latent vector (z) - std::vector z(100); - for (auto &v : z) - v = rand_gen.Gaus(0.0, 1.0); - - // Prepare input tensor - std::vector input_shape = {1, 100}; - // Get memory information - Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); - - // Create input tensor correctly - Ort::Value input_tensor = Ort::Value::CreateTensor( - memory_info, z.data(), z.size(), input_shape.data(), input_shape.size()); - // Run inference - const char *input_names[] = {"z"}; - const char *output_names[] = {"output"}; - auto output_tensors = session.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor, 1, output_names, 1); - - // Extract output - float *output_data = output_tensors.front().GetTensorMutableData(); - // Get the size of the output tensor - auto output_tensor_info = output_tensors.front().GetTensorTypeAndShapeInfo(); - size_t output_data_size = output_tensor_info.GetElementCount(); // Total number of elements in the tensor - std::vector output; - for (int i = 0; i < output_data_size; ++i) - { - output.push_back(output_data[i]); - } + Ort::AllocatorWithDefaultOptions allocator; + + // Generate a latent vector (z) + std::vector z(100); + for (auto& v : z) + v = rand_gen.Gaus(0.0, 1.0); + + // Prepare input tensor + std::vector input_shape = {1, 100}; + // Get memory information + Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); + + // Create input tensor correctly + Ort::Value input_tensor = Ort::Value::CreateTensor( + memory_info, z.data(), z.size(), input_shape.data(), input_shape.size()); + // Run inference + const char* input_names[] = {"z"}; + const char* output_names[] = {"output"}; + auto output_tensors = session.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor, 1, output_names, 1); + + // Extract output + float* output_data = output_tensors.front().GetTensorMutableData(); + // Get the size of the output tensor + auto output_tensor_info = output_tensors.front().GetTensorTypeAndShapeInfo(); + size_t output_data_size = output_tensor_info.GetElementCount(); // Total number of elements in the tensor + std::vector output; + for (int i = 0; i < output_data_size; ++i) { + output.push_back(output_data[i]); + } - return output; + return output; } namespace o2 @@ -105,79 +102,67 @@ namespace eventgen { GenTPCLoopers::GenTPCLoopers(std::string model_pairs, std::string model_compton, - std::string poisson, std::string gauss, std::string scaler_pair, - std::string scaler_compton) + std::string poisson, std::string gauss, std::string scaler_pair, + std::string scaler_compton) { - // Checking if the model files exist and are not empty - std::ifstream model_file[2]; - model_file[0].open(model_pairs); - model_file[1].open(model_compton); - if (!model_file[0].is_open() || model_file[0].peek() == std::ifstream::traits_type::eof()) - { - LOG(fatal) << "Error: Pairs model file is empty or does not exist!"; - exit(1); - } - if (!model_file[1].is_open() || model_file[1].peek() == std::ifstream::traits_type::eof()) - { - LOG(fatal) << "Error: Compton model file is empty or does not exist!"; - exit(1); - } - model_file[0].close(); - model_file[1].close(); - // Checking if the scaler files exist and are not empty - std::ifstream scaler_file[2]; - scaler_file[0].open(scaler_pair); - scaler_file[1].open(scaler_compton); - if (!scaler_file[0].is_open() || scaler_file[0].peek() == std::ifstream::traits_type::eof()) - { - LOG(fatal) << "Error: Pairs scaler file is empty or does not exist!"; - exit(1); - } - if (!scaler_file[1].is_open() || scaler_file[1].peek() == std::ifstream::traits_type::eof()) - { - LOG(fatal) << "Error: Compton scaler file is empty or does not exist!"; - exit(1); - } - scaler_file[0].close(); - scaler_file[1].close(); - // Checking if the poisson file exists and it's not empty - if (poisson != "" && poisson != "None" && poisson != "none") - { - std::ifstream poisson_file(poisson); - if (!poisson_file.is_open() || poisson_file.peek() == std::ifstream::traits_type::eof()) - { - LOG(fatal) << "Error: Poisson file is empty or does not exist!"; - exit(1); - } - else - { - poisson_file >> mPoisson[0] >> mPoisson[1] >> mPoisson[2]; - poisson_file.close(); - mPoissonSet = true; - } + // Checking if the model files exist and are not empty + std::ifstream model_file[2]; + model_file[0].open(model_pairs); + model_file[1].open(model_compton); + if (!model_file[0].is_open() || model_file[0].peek() == std::ifstream::traits_type::eof()) { + LOG(fatal) << "Error: Pairs model file is empty or does not exist!"; + exit(1); + } + if (!model_file[1].is_open() || model_file[1].peek() == std::ifstream::traits_type::eof()) { + LOG(fatal) << "Error: Compton model file is empty or does not exist!"; + exit(1); + } + model_file[0].close(); + model_file[1].close(); + // Checking if the scaler files exist and are not empty + std::ifstream scaler_file[2]; + scaler_file[0].open(scaler_pair); + scaler_file[1].open(scaler_compton); + if (!scaler_file[0].is_open() || scaler_file[0].peek() == std::ifstream::traits_type::eof()) { + LOG(fatal) << "Error: Pairs scaler file is empty or does not exist!"; + exit(1); + } + if (!scaler_file[1].is_open() || scaler_file[1].peek() == std::ifstream::traits_type::eof()) { + LOG(fatal) << "Error: Compton scaler file is empty or does not exist!"; + exit(1); + } + scaler_file[0].close(); + scaler_file[1].close(); + // Checking if the poisson file exists and it's not empty + if (poisson != "" && poisson != "None" && poisson != "none") { + std::ifstream poisson_file(poisson); + if (!poisson_file.is_open() || poisson_file.peek() == std::ifstream::traits_type::eof()) { + LOG(fatal) << "Error: Poisson file is empty or does not exist!"; + exit(1); + } else { + poisson_file >> mPoisson[0] >> mPoisson[1] >> mPoisson[2]; + poisson_file.close(); + mPoissonSet = true; } - // Checking if the gauss file exists and it's not empty - if (gauss != "" && gauss != "None" && gauss != "none") - { - std::ifstream gauss_file(gauss); - if (!gauss_file.is_open() || gauss_file.peek() == std::ifstream::traits_type::eof()) - { - LOG(fatal) << "Error: Gauss file is empty or does not exist!"; - exit(1); - } - else - { - gauss_file >> mGauss[0] >> mGauss[1] >> mGauss[2] >> mGauss[3]; - gauss_file.close(); - mGaussSet = true; - } + } + // Checking if the gauss file exists and it's not empty + if (gauss != "" && gauss != "None" && gauss != "none") { + std::ifstream gauss_file(gauss); + if (!gauss_file.is_open() || gauss_file.peek() == std::ifstream::traits_type::eof()) { + LOG(fatal) << "Error: Gauss file is empty or does not exist!"; + exit(1); + } else { + gauss_file >> mGauss[0] >> mGauss[1] >> mGauss[2] >> mGauss[3]; + gauss_file.close(); + mGaussSet = true; } - mONNX_pair = std::make_unique(global_env, model_pairs); - mScaler_pair = std::make_unique(); - mScaler_pair->load(scaler_pair); - mONNX_compton = std::make_unique(global_env, model_compton); - mScaler_compton = std::make_unique(); - mScaler_compton->load(scaler_compton); + } + mONNX_pair = std::make_unique(global_env, model_pairs); + mScaler_pair = std::make_unique(); + mScaler_pair->load(scaler_pair); + mONNX_compton = std::make_unique(global_env, model_compton); + mScaler_compton = std::make_unique(); + mScaler_compton->load(scaler_compton); } Bool_t GenTPCLoopers::generateEvent() @@ -352,17 +337,16 @@ void GenTPCLoopers::SetNLoopers(unsigned int& nsig_pair, unsigned int& nsig_comp void GenTPCLoopers::SetMultiplier(std::array& mult) { - // Multipliers will work only if the poissonian and gaussian parameters are set - // otherwise they will be ignored - if (mult[0] < 0 || mult[1] < 0) - { - LOG(fatal) << "Error: Multiplier values must be non-negative!"; - exit(1); - } else { - LOG(info) << "Multiplier values set to: Pair = " << mult[0] << ", Compton = " << mult[1]; - mMultiplier[0] = mult[0]; - mMultiplier[1] = mult[1]; - } + // Multipliers will work only if the poissonian and gaussian parameters are set + // otherwise they will be ignored + if (mult[0] < 0 || mult[1] < 0) { + LOG(fatal) << "Error: Multiplier values must be non-negative!"; + exit(1); + } else { + LOG(info) << "Multiplier values set to: Pair = " << mult[0] << ", Compton = " << mult[1]; + mMultiplier[0] = mult[0]; + mMultiplier[1] = mult[1]; + } } void GenTPCLoopers::setFlatGas(Bool_t& flat, const Int_t& number = -1, const Int_t& nloopers_orbit = -1) @@ -421,7 +405,7 @@ void GenTPCLoopers::setFractionPairs(float& fractionPairs) LOG(info) << "Pairs fraction set to: " << mLoopsFractionPairs; } -void GenTPCLoopers::SetRate(const std::string &rateFile, const bool &isPbPb = true, const int &intRate = 50000) +void GenTPCLoopers::SetRate(const std::string& rateFile, const bool& isPbPb = true, const int& intRate = 50000) { // Checking if the rate file exists and is not empty TFile rate_file(rateFile.c_str(), "READ");