diff --git a/compile.sh b/compile.sh new file mode 100755 index 0000000000..6f82645703 --- /dev/null +++ b/compile.sh @@ -0,0 +1,4 @@ +if [[ -n $1 ]]; then + rm -rf build +fi +cmake -B build -S . -DCMAKE_INSTALL_PREFIX=install && cmake --build build -j10; cmake --install build diff --git a/src/algorithms/reco/FarForwardNeutralsReconstruction.cc b/src/algorithms/reco/FarForwardNeutralsReconstruction.cc index 80e3e0a666..6aa36864b5 100644 --- a/src/algorithms/reco/FarForwardNeutralsReconstruction.cc +++ b/src/algorithms/reco/FarForwardNeutralsReconstruction.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "FarForwardNeutralsReconstruction.h" @@ -46,6 +47,8 @@ bool FarForwardNeutralsReconstruction::isGamma(const edm4eic::Cluster& cluster) cluster.getPosition().x * sin(m_cfg.globalToProtonRotation)) * dd4hep::mm; + double E = cluster.getEnergy(); + trace("z recon = {}", z); trace("l1 = {}, l2 = {}, l3 = {}", l1, l2, l3); @@ -56,8 +59,10 @@ bool FarForwardNeutralsReconstruction::isGamma(const edm4eic::Cluster& cluster) static_cast(l2 > m_cfg.gammaMaxWidth) + static_cast(l3 > m_cfg.gammaMaxWidth) >= 2; - - return !(isZMoreThanMax || isLengthMoreThanMax || areWidthsMoreThanMax); + // max number of hits for a photon shower for a given energy E is of the form a*E+b*sqrt(E) + bool hasMoreHitsThanMax = + cluster.getNhits() > m_cfg.gammaMaxNhitsCoeffLin * E + m_cfg.gammaMaxNhitsCoeffSqrt * sqrt(E); + return !(isZMoreThanMax || isLengthMoreThanMax || areWidthsMoreThanMax || hasMoreHitsThanMax); } double FarForwardNeutralsReconstruction::corrPower(double E, const std::vector& coeffs) { @@ -75,10 +80,8 @@ int FarForwardNeutralsReconstruction::processNeutralCalo( edm4eic::ReconstructedParticleCollection* out_neutrals, const std::vector& gammaScaleCoeff, const std::vector& neutronScaleCoeff, bool canDetectGammas, bool canDetectNeutrons, const CorrFunc& gammaCorr, - const CorrFunc& neutronCorr, GammaMode gammaMode, double gammaLeaderFracMin, double clusterEmin, - NeutronMode neutronMode, bool associateAllClustersToNeutron) const { - - (void)gammaLeaderFracMin; + const CorrFunc& neutronCorr, GammaMode gammaMode, double clusterEmin, NeutronMode neutronMode, + bool associateAllClustersToNeutron) const { const double m_neutron = m_particleSvc.particle(2112).mass; @@ -248,67 +251,35 @@ void FarForwardNeutralsReconstruction::process( const FarForwardNeutralsReconstruction::Output& output) const { // Unpacking - const auto [clustersHcal, clustersB0, clustersEcalEndcapP, clustersLFHCAL] = input; - auto [out_neutralsHcal, out_neutralsB0, out_neutralsEcalEndcapP, out_neutralsLFHCAL] = output; - - // Global - int n_neutrons = 0; - - // ZDC-Hcal - n_neutrons += processNeutralCalo(clustersHcal, out_neutralsHcal, - /*gammaScaleCoeff=*/m_cfg.gammaScaleCorrCoeffHcalZDC, - /*neutronScaleCoeff=*/m_cfg.neutronScaleCorrCoeffHcalZDC, - /*canDetectGammas=*/true, - /*canDetectNeutrons=*/true, - /*gammaCorr=*/corrPower, - /*neutronCorr=*/corrPower, - /*gammaMode=*/GammaMode::AllPassing, - /*gammaLeaderFracMin=*/0.0, - /*clusterEmin=*/m_cfg.clusterEminHcalZDC, - /*neutronMode=*/NeutronMode::SumAll, - /*associateAllClustersToNeutron=*/true); - - // B0-Ecal - n_neutrons += processNeutralCalo(clustersB0, out_neutralsB0, - /*gammaScaleCoeff=*/m_cfg.gammaScaleCorrCoeffB0Ecal, - /*neutronScaleCoeff=*/m_cfg.neutronScaleCorrCoeffB0Ecal, - /*canDetectGammas=*/true, - /*canDetectNeutrons=*/false, - /*gammaCorr=*/corrPower, - /*neutronCorr=*/corrPower, - /*gammaMode=*/GammaMode::LeaderOnly, - /*gammaLeaderFracMin=*/0.0, - /*clusterEmin=*/m_cfg.clusterEminB0Ecal, - /*neutronMode=*/NeutronMode::None, - /*associateAllClustersToNeutron=*/false); - - // EndcapP-Ecal - n_neutrons += processNeutralCalo(clustersEcalEndcapP, out_neutralsEcalEndcapP, - /*gammaScaleCoeff=*/m_cfg.gammaScaleCorrCoeffEcalEndcapP, - /*neutronScaleCoeff=*/m_cfg.neutronScaleCorrCoeffEcalEndcapP, - /*canDetectGammas=*/true, - /*canDetectNeutrons=*/false, - /*gammaCorr=*/corrPower, - /*neutronCorr=*/corrPower, - /*gammaMode=*/GammaMode::LeaderOnly, - /*gammaLeaderFracMin=*/0.0, - /*clusterEmin=*/m_cfg.clusterEminEcalEndcapP, - /*neutronMode=*/NeutronMode::None, - /*associateAllClustersToNeutron=*/false); - - // LFHCAL - n_neutrons += processNeutralCalo(clustersLFHCAL, out_neutralsLFHCAL, - /*gammaScaleCoeff=*/m_cfg.gammaScaleCorrCoeffLFHCAL, - /*neutronScaleCoeff=*/m_cfg.neutronScaleCorrCoeffLFHCAL, - /*canDetectGammas=*/false, - /*canDetectNeutrons=*/true, - /*gammaCorr=*/corrPower, - /*neutronCorr=*/corrPower, - /*gammaMode=*/GammaMode::None, - /*gammaLeaderFracMin=*/0.0, - /*clusterEmin=*/m_cfg.clusterEminLFHCAL, - /*neutronMode=*/NeutronMode::LeaderOnly, - /*associateAllClustersToNeutron=*/false); + const auto [clusters] = input; + auto [out_neutrals] = output; + + GammaMode gammaMode = GammaMode::None; + if (m_cfg.gammaMode == "LeaderOnly") { + gammaMode = GammaMode::LeaderOnly; + } else if (m_cfg.gammaMode == "AllPassing") { + gammaMode = GammaMode::AllPassing; + } + + NeutronMode neutronMode = NeutronMode::None; + if (m_cfg.neutronMode == "SumAll") { + neutronMode = NeutronMode::SumAll; + } else if (m_cfg.neutronMode == "LeaderOnly") { + neutronMode = NeutronMode::LeaderOnly; + } + + const int n_neutrons = + processNeutralCalo(clusters, out_neutrals, + /*gammaScaleCoeff=*/m_cfg.gammaScaleCorrCoeff, + /*neutronScaleCoeff=*/m_cfg.neutronScaleCorrCoeff, + /*canDetectGammas=*/m_cfg.canDetectGammas, + /*canDetectNeutrons=*/m_cfg.canDetectNeutrons, + /*gammaCorr=*/corrPower, + /*neutronCorr=*/corrPower, + /*gammaMode=*/gammaMode, + /*clusterEmin=*/m_cfg.clusterEmin, + /*neutronMode=*/neutronMode, + /*associateAllClustersToNeutron=*/m_cfg.associateAllClustersToNeutron); debug("Found {} neutron candidates", n_neutrons); } diff --git a/src/algorithms/reco/FarForwardNeutralsReconstruction.h b/src/algorithms/reco/FarForwardNeutralsReconstruction.h index 2963e14928..5425ed5a58 100644 --- a/src/algorithms/reco/FarForwardNeutralsReconstruction.h +++ b/src/algorithms/reco/FarForwardNeutralsReconstruction.h @@ -21,18 +21,8 @@ namespace eicrecon { using FarForwardNeutralsReconstructionAlgorithm = - - algorithms::Algorithm< - algorithms::Input, // clusters LFHCAL - - algorithms::Output< - edm4eic::ReconstructedParticleCollection, // neutrons/gamma in ZDC-Hcal - edm4eic::ReconstructedParticleCollection, // neutrons/gamma in B0-Ecal - edm4eic::ReconstructedParticleCollection, // neutrons/gamma in EndcapP-Ecal - edm4eic::ReconstructedParticleCollection>>; // neutrons/gamma in LFHCAL + algorithms::Algorithm, + algorithms::Output>; /** * Reconstructs far-forward neutral candidates from multiple calorimeter cluster collections. * @@ -59,12 +49,8 @@ class FarForwardNeutralsReconstruction FarForwardNeutralsReconstruction(std::string_view name) : FarForwardNeutralsReconstructionAlgorithm{ name, - - {"clustersHcal", "clustersB0", "clustersEcalEndCapP", "clustersLFHCAL"}, - - {"outputNeutralsHcal", "outputNeutralsB0", "outputNeutralsEcalEndCapP", - "outputNeutralsLFHCAL"}, - + {"clusters"}, + {"outputNeutrals"}, "Convert EMCal and HCal clusters into neutron or photon candidates"} {} void init() final; @@ -89,9 +75,8 @@ class FarForwardNeutralsReconstruction const std::vector& gammaScaleCoeff, const std::vector& neutronScaleCoeff, bool canDetectGammas, bool canDetectNeutrons, const CorrFunc& gammaCorr, - const CorrFunc& neutronCorr, GammaMode gammaMode, - double gammaLeaderFracMin, double clusterEmin, NeutronMode neutronMode, - bool associateAllClustersToNeutron) const; + const CorrFunc& neutronCorr, GammaMode gammaMode, double clusterEmin, + NeutronMode neutronMode, bool associateAllClustersToNeutron) const; }; } // namespace eicrecon diff --git a/src/algorithms/reco/FarForwardNeutralsReconstructionConfig.h b/src/algorithms/reco/FarForwardNeutralsReconstructionConfig.h index 1c3f40d341..7063bad085 100644 --- a/src/algorithms/reco/FarForwardNeutralsReconstructionConfig.h +++ b/src/algorithms/reco/FarForwardNeutralsReconstructionConfig.h @@ -3,39 +3,42 @@ #pragma once #include #include +#include +#include namespace eicrecon { struct FarForwardNeutralsReconstructionConfig { - /** detector constant describing distance to the ZDC */ + /** detector constant describing distance reference position */ std::string offsetPositionName = "HcalFarForwardZDC_SiPMonTile_r_pos"; - /** Correction factors for neutrons in the Hcal (ZDC) */ - std::vector neutronScaleCorrCoeffHcalZDC = {2.4, 0.89}; - /** Correction factors for gammas in the Hcal (ZDC) */ - std::vector gammaScaleCorrCoeffHcalZDC = {1.1, 0.98}; - /** Correction factors for neutrons in the LFHCAL */ - std::vector neutronScaleCorrCoeffLFHCAL = {2.55, 0.95}; - /** Correction factors for gammas in the LFHCAL */ - std::vector gammaScaleCorrCoeffLFHCAL = {0., 0.}; - /** Correction factors for neutrons in the B0-Ecal */ - std::vector neutronScaleCorrCoeffB0Ecal = {0., 0.}; - /** Correction factors for gammas in the B0-Ecal */ - std::vector gammaScaleCorrCoeffB0Ecal = {0.99, 1.14}; - /** Correction factors for neutrons in the Endcap-Ecal */ - std::vector neutronScaleCorrCoeffEcalEndcapP = {0., 0.}; - /** Correction factors for gammas in the Endcap-Ecal */ - std::vector gammaScaleCorrCoeffEcalEndcapP = {1.05, 1.01}; - /** Cluster thresholds */ - double clusterEminHcalZDC = 0.0; // GeV - double clusterEminB0Ecal = 1.0; // GeV - double clusterEminEcalEndcapP = 1.0; // GeV - double clusterEminLFHCAL = 7.0; // GeV + + /** Correction factors */ + std::vector neutronScaleCorrCoeff = {0.0, 0.0}; + std::vector gammaScaleCorrCoeff = {0.0, 0.0}; + + /** Detector capabilities */ + bool canDetectGammas = true; + bool canDetectNeutrons = true; + + /** Reconstruction modes */ + std::string gammaMode = "None"; + std::string neutronMode = "None"; + + /** Cluster threshold */ + double clusterEmin = 0.0; // GeV + + /** Whether all non-gamma clusters are summed into one neutron candidate */ + bool associateAllClustersToNeutron = false; + /** rotation from global to local coordinates */ double globalToProtonRotation = -0.025; - /** Neutron-photon separation in HcalFarForwardZDC */ - double gammaZMaxOffset = 400; - double gammaMaxLength = 100; - double gammaMaxWidth = 12; + + /** Neutron-photon separation used for ZDC */ + double gammaZMaxOffset = 400; + double gammaMaxLength = 100; + double gammaMaxWidth = 12; + double gammaMaxNhitsCoeffLin = 0.3; + double gammaMaxNhitsCoeffSqrt = 30; }; } // namespace eicrecon diff --git a/src/algorithms/reco/LambdaReconstruction.cc b/src/algorithms/reco/LambdaReconstruction.cc index 846c32a05d..6d81d664bf 100644 --- a/src/algorithms/reco/LambdaReconstruction.cc +++ b/src/algorithms/reco/LambdaReconstruction.cc @@ -373,10 +373,6 @@ void LambdaReconstruction::process(const LambdaReconstruction::Input& input, const double mL = std::sqrt(m2L); const double dL = mL - m_lambda; - if (std::abs(dL) > m_cfg.lambdaMassWindow * m_lambda) { - continue; - } - const double pi0_term = pp.dmpi0_cand / (m_cfg.pi0Window * m_pi0); const double lambda_term = dL / (m_cfg.lambdaMassWindow * m_lambda); @@ -417,36 +413,41 @@ void LambdaReconstruction::process(const LambdaReconstruction::Input& input, // -------------------------------------------------------------------------- auto better = [&](const LambdaCandidate& a, const LambdaCandidate& b) -> bool { + // Primary criterion: physical compatibility. + if (a.chi2 != b.chi2) { + return a.chi2 < b.chi2; + } + // Tie-breakers only: prefer ZDC information when candidates are similarly good. if (a.n_cat != b.n_cat) { - return static_cast(a.n_cat) < static_cast(b.n_cat); + return a.n_cat == NeutronCategory::ZDC; } if (a.g_cat != b.g_cat) { return static_cast(a.g_cat) < static_cast(b.g_cat); } - if (a.chi2 != b.chi2) { - return a.chi2 < b.chi2; - } if (a.pz != b.pz) { return a.pz > b.pz; } return a.E > b.E; }; - int best_k = 0; - for (int k = 1; k < static_cast(cands.size()); ++k) { - if (better(cands[k], cands[best_k])) { - best_k = k; - } - } + std::sort(cands.begin(), cands.end(), better); + + const int max_trials = cands.size(); - const auto& best = cands[best_k]; + for (int k = 0; k < max_trials; ++k) { + const auto& best = cands[k]; - const auto& g1 = gamma_pool[best.g_i]; - const auto& g2 = gamma_pool[best.g_j]; - const auto& n = - (best.n_cat == NeutronCategory::ZDC) ? neutrons_zdc[best.n_idx] : neutrons_other[best.n_idx]; + const auto& g1 = gamma_pool[best.g_i]; + const auto& g2 = gamma_pool[best.g_j]; + const auto& n = (best.n_cat == NeutronCategory::ZDC) ? neutrons_zdc[best.n_idx] + : neutrons_other[best.n_idx]; - reconstruct_from_triplet(n, g1, g2, out_lambdas, out_decay_products); + if (!reconstruct_from_triplet(n, g1, g2, out_lambdas, out_decay_products)) { + continue; + } + + break; + } } } // namespace eicrecon diff --git a/src/factories/reco/FarForwardNeutralsReconstruction_factory.h b/src/factories/reco/FarForwardNeutralsReconstruction_factory.h index d5b7c0c429..7f4d6ac7ba 100644 --- a/src/factories/reco/FarForwardNeutralsReconstruction_factory.h +++ b/src/factories/reco/FarForwardNeutralsReconstruction_factory.h @@ -20,52 +20,30 @@ class FarForwardNeutralsReconstruction_factory private: std::unique_ptr m_algo; - PodioInput m_clusters_hcal_input{this}; - PodioInput m_clusters_b0_input{this}; - PodioInput m_clusters_ecalendcapp_input{this}; - PodioInput m_clusters_lfhcal_input{this}; - - PodioOutput m_hcal_neutrals_output{this}; - PodioOutput m_b0_neutrals_output{this}; - PodioOutput m_ecalendcapp_neutrals_output{this}; - PodioOutput m_lfhcal_neutrals_output{this}; + PodioInput m_clusters_input{this}; + PodioOutput m_neutrals_output{this}; ParameterRef m_offset_position_name{this, "offsetPositionName", config().offsetPositionName}; - ParameterRef> m_n_scale_corr_coeff_hcal_zdc{ - this, "neutronScaleCorrCoeffHcalZDC", config().neutronScaleCorrCoeffHcalZDC}; - - ParameterRef> m_gamma_scale_corr_coeff_hcal_zdc{ - this, "gammaScaleCorrCoeffHcalZDC", config().gammaScaleCorrCoeffHcalZDC}; - - ParameterRef> m_n_scale_corr_coeff_b0ecal{ - this, "neutronScaleCorrCoeffB0Ecal", config().neutronScaleCorrCoeffB0Ecal}; - - ParameterRef> m_gamma_scale_corr_coeff_b0ecal{ - this, "gammaScaleCorrCoeffB0Ecal", config().gammaScaleCorrCoeffB0Ecal}; + ParameterRef> m_neutron_scale_corr_coeff{this, "neutronScaleCorrCoeff", + config().neutronScaleCorrCoeff}; - ParameterRef> m_n_scale_corr_coeff_ecalendcapp{ - this, "neutronScaleCorrCoeffEcalEndcapP", config().neutronScaleCorrCoeffEcalEndcapP}; + ParameterRef> m_gamma_scale_corr_coeff{this, "gammaScaleCorrCoeff", + config().gammaScaleCorrCoeff}; - ParameterRef> m_gamma_scale_corr_coeff_ecalendcapp{ - this, "gammaScaleCorrCoeffEcalEndcapP", config().gammaScaleCorrCoeffEcalEndcapP}; + ParameterRef m_can_detect_gammas{this, "canDetectGammas", config().canDetectGammas}; - ParameterRef> m_n_scale_corr_coeff_lfhcal{ - this, "neutronScaleCorrCoeffLFHCAL", config().neutronScaleCorrCoeffLFHCAL}; + ParameterRef m_can_detect_neutrons{this, "canDetectNeutrons", config().canDetectNeutrons}; - ParameterRef> m_gamma_scale_corr_coeff_lfhcal{ - this, "gammaScaleCorrCoeffLFHCAL", config().gammaScaleCorrCoeffLFHCAL}; + ParameterRef m_gamma_mode{this, "gammaMode", config().gammaMode}; - ParameterRef m_cluster_emin_hcal_zdc{this, "clusterEminHcalZDC", - config().clusterEminHcalZDC}; + ParameterRef m_neutron_mode{this, "neutronMode", config().neutronMode}; - ParameterRef m_cluster_emin_b0ecal{this, "clusterEminB0Ecal", config().clusterEminB0Ecal}; + ParameterRef m_cluster_emin{this, "clusterEmin", config().clusterEmin}; - ParameterRef m_cluster_emin_ecalendcapp{this, "clusterEminEcalEndcapP", - config().clusterEminEcalEndcapP}; - - ParameterRef m_cluster_emin_lfhcal{this, "clusterEminLFHCAL", config().clusterEminLFHCAL}; + ParameterRef m_associate_all_clusters_to_neutron{this, "associateAllClustersToNeutron", + config().associateAllClustersToNeutron}; ParameterRef m_global_to_proton_rotation{this, "globalToProtonRotation", config().globalToProtonRotation}; @@ -76,6 +54,12 @@ class FarForwardNeutralsReconstruction_factory ParameterRef m_gamma_max_width{this, "gammaMaxWidth", config().gammaMaxWidth}; + ParameterRef m_gamma_max_nhits_coeff_lin{this, "gammaMaxNhitsCoeffLin", + config().gammaMaxNhitsCoeffLin}; + + ParameterRef m_gamma_max_nhits_coeff_sqrt{this, "gammaMaxNhitsCoeffSqrt", + config().gammaMaxNhitsCoeffSqrt}; + Service m_algorithmsInit{this}; public: @@ -90,17 +74,11 @@ class FarForwardNeutralsReconstruction_factory void Process(int32_t /* run_number */, uint64_t /* event_number */) { m_algo->process( { - m_clusters_hcal_input(), - m_clusters_b0_input(), - m_clusters_ecalendcapp_input(), - m_clusters_lfhcal_input(), + m_clusters_input(), }, { - m_hcal_neutrals_output().get(), - m_b0_neutrals_output().get(), - m_ecalendcapp_neutrals_output().get(), - m_lfhcal_neutrals_output().get(), + m_neutrals_output().get(), }); } diff --git a/src/global/reco/reco.cc b/src/global/reco/reco.cc index e79ff0f3c2..0d4b06b426 100644 --- a/src/global/reco/reco.cc +++ b/src/global/reco/reco.cc @@ -230,27 +230,76 @@ void InitPlugin(JApplication* app) { {"ReconstructedBreitFrameParticles"}, {}, app)); app->Add(new JOmniFactoryGeneratorT( - "ReconstructedFarForwardNeutrals", - {"HcalFarForwardZDCClusters", "B0ECalClusters", "EcalEndcapPClusters", "LFHCALClusters"}, - {"ReconstructedHcalFarForwardZDCNeutrals", "ReconstructedB0EcalNeutrals", - "ReconstructedEcalEndcapPNeutrals", "ReconstructedLFHCALNeutrals"}, - {.offsetPositionName = "HcalFarForwardZDC_SiPMonTile_r_pos", - .neutronScaleCorrCoeffHcalZDC = {2.4, 0.89}, - .gammaScaleCorrCoeffHcalZDC = {1.1, 0.98}, - .neutronScaleCorrCoeffLFHCAL = {2.55, 0.95}, - .gammaScaleCorrCoeffLFHCAL = {0., 0.}, - .neutronScaleCorrCoeffB0Ecal = {0., 0.}, - .gammaScaleCorrCoeffB0Ecal = {0.99, 1.14}, - .neutronScaleCorrCoeffEcalEndcapP = {0., 0.}, - .gammaScaleCorrCoeffEcalEndcapP = {1.05, 1.01}, - .clusterEminHcalZDC = 0.0, - .clusterEminB0Ecal = 1.0, - .clusterEminEcalEndcapP = 1.0, - .clusterEminLFHCAL = 7.0, - .globalToProtonRotation = -0.025, - .gammaZMaxOffset = 400, - .gammaMaxLength = 100, - .gammaMaxWidth = 12}, + "ReconstructedHcalFarForwardZDCNeutrals", {"HcalFarForwardZDCClusters"}, + {"ReconstructedHcalFarForwardZDCNeutrals"}, + {.offsetPositionName = "HcalFarForwardZDC_SiPMonTile_r_pos", + .neutronScaleCorrCoeff = {2.4, 0.89}, + .gammaScaleCorrCoeff = {1.1, 0.98}, + .canDetectGammas = true, + .canDetectNeutrons = true, + .gammaMode = "AllPassing", + .neutronMode = "SumAll", + .clusterEmin = 0.0, + .associateAllClustersToNeutron = true, + .globalToProtonRotation = -0.025, + .gammaZMaxOffset = 400, + .gammaMaxLength = 100, + .gammaMaxWidth = 12, + .gammaMaxNhitsCoeffLin = 0.3, + .gammaMaxNhitsCoeffSqrt = 30}, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "ReconstructedB0EcalNeutrals", {"B0ECalClusters"}, {"ReconstructedB0EcalNeutrals"}, + {.offsetPositionName = "HcalFarForwardZDC_SiPMonTile_r_pos", + .neutronScaleCorrCoeff = {0., 0.}, + .gammaScaleCorrCoeff = {0.99, 1.14}, + .canDetectGammas = true, + .canDetectNeutrons = false, + .gammaMode = "LeaderOnly", + .neutronMode = "None", + .clusterEmin = 1.0, + .associateAllClustersToNeutron = false, + .globalToProtonRotation = -0.025, + .gammaZMaxOffset = 400, + .gammaMaxLength = 100, + .gammaMaxWidth = 12}, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "ReconstructedEcalEndcapPNeutrals", {"EcalEndcapPClusters"}, + {"ReconstructedEcalEndcapPNeutrals"}, + {.offsetPositionName = "HcalFarForwardZDC_SiPMonTile_r_pos", + .neutronScaleCorrCoeff = {0., 0.}, + .gammaScaleCorrCoeff = {1.05, 1.01}, + .canDetectGammas = true, + .canDetectNeutrons = false, + .gammaMode = "LeaderOnly", + .neutronMode = "None", + .clusterEmin = 1.0, + .associateAllClustersToNeutron = false, + .globalToProtonRotation = -0.025, + .gammaZMaxOffset = 400, + .gammaMaxLength = 100, + .gammaMaxWidth = 12}, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "ReconstructedLFHCALNeutrals", {"LFHCALClusters"}, {"ReconstructedLFHCALNeutrals"}, + {.offsetPositionName = "HcalFarForwardZDC_SiPMonTile_r_pos", + .neutronScaleCorrCoeff = {2.55, 0.95}, + .gammaScaleCorrCoeff = {0., 0.}, + .canDetectGammas = false, + .canDetectNeutrons = true, + .gammaMode = "None", + .neutronMode = "LeaderOnly", + .clusterEmin = 7.0, + .associateAllClustersToNeutron = false, + .globalToProtonRotation = -0.025, + .gammaZMaxOffset = 400, + .gammaMaxLength = 100, + .gammaMaxWidth = 12}, + app)); app->Add(new JOmniFactoryGeneratorT(