Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-04 08:27:57

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 - 2025 Whitney Armstrong, Sylvester Joosten, Chao Peng, David Lawrence, Thomas Britton, Wouter Deconinck, Maria Zurek, Akshaya Vijay, Nathan Brei, Dmitry Kalinkin, Derek Anderson, Minho Kim
0003 
0004 #include <Evaluator/DD4hepUnits.h>
0005 #include <JANA/JApplication.h>
0006 #include <JANA/JApplicationFwd.h>
0007 #include <JANA/Utils/JTypeInfo.h>
0008 #include <edm4eic/unit_system.h>
0009 #include <edm4hep/SimCalorimeterHit.h>
0010 #include <cmath>
0011 #include <map>
0012 #include <memory>
0013 #include <string>
0014 #include <variant>
0015 #include <vector>
0016 
0017 #include "algorithms/calorimetry/CalorimeterHitDigiConfig.h"
0018 #include "algorithms/calorimetry/ImagingTopoClusterConfig.h"
0019 #include "algorithms/calorimetry/SimCalorimeterHitProcessorConfig.h"
0020 #include "algorithms/calorimetry/EdepToNpeConversionConfig.h"
0021 #include "algorithms/digi/CALOROCDigitizationConfig.h"
0022 #include "algorithms/digi/PulseCombinerConfig.h"
0023 #include "algorithms/digi/PulseGenerationConfig.h"
0024 #include "algorithms/digi/PulseNoiseConfig.h"
0025 #include "extensions/jana/JOmniFactoryGeneratorT.h"
0026 #include "factories/calorimetry/CalorimeterClusterRecoCoG_factory.h"
0027 #include "factories/calorimetry/CalorimeterClusterShape_factory.h"
0028 #include "factories/calorimetry/CalorimeterHitDigi_factory.h"
0029 #include "factories/calorimetry/CalorimeterHitReco_factory.h"
0030 #include "factories/calorimetry/CalorimeterIslandCluster_factory.h"
0031 #include "factories/calorimetry/EnergyPositionClusterMerger_factory.h"
0032 #include "factories/calorimetry/ImagingClusterReco_factory.h"
0033 #include "factories/calorimetry/ImagingTopoCluster_factory.h"
0034 #include "factories/calorimetry/SimCalorimeterHitProcessor_factory.h"
0035 #include "factories/calorimetry/EdepToNpeConversion_factory.h"
0036 #include "factories/calorimetry/TruthEnergyPositionClusterMerger_factory.h"
0037 #include "factories/digi/CALOROCDigitization_factory.h"
0038 #include "factories/digi/PulseCombiner_factory.h"
0039 #include "factories/digi/PulseGeneration_factory.h"
0040 #include "factories/digi/PulseNoise_factory.h"
0041 
0042 extern "C" {
0043 void InitPlugin(JApplication* app) {
0044 
0045   using namespace eicrecon;
0046 
0047   InitJANAPlugin(app);
0048 
0049   // Make sure left and right use the same value
0050   decltype(SimCalorimeterHitProcessorConfig::attenuationParameters) EcalBarrelScFi_attPars = {
0051       0.416212, 747.39875 * edm4eic::unit::mm, 7521.88383 * edm4eic::unit::mm};
0052   decltype(SimCalorimeterHitProcessorConfig::hitMergeFields) EcalBarrelScFi_hitMergeFields = {
0053       "fiber", "z"};
0054   decltype(SimCalorimeterHitProcessorConfig::contributionMergeFields)
0055       EcalBarrelScFi_contributionMergeFields = {"fiber"};
0056   decltype(SimCalorimeterHitProcessorConfig::inversePropagationSpeed)
0057       EcalBarrelScFi_inversePropagationSpeed = {(1. / 160) * edm4eic::unit::ns / edm4eic::unit::mm};
0058   decltype(SimCalorimeterHitProcessorConfig::fixedTimeDelay) EcalBarrelScFi_fixedTimeDelay = {
0059       2 * edm4eic::unit::ns};
0060   decltype(SimCalorimeterHitProcessorConfig::timeWindow) EcalBarrelScFi_timeWindow = {
0061       100 * edm4eic::unit::ns};
0062 
0063   decltype(EdepToNpeConversionConfig::edep_to_npe_fields) EcalBarrelScFi_edep_to_npe_fields = {
0064       "layer"};
0065   decltype(EdepToNpeConversionConfig::edep_to_npe_filename) EcalBarrelScFi_edep_to_npe_filename = {
0066       "calibrations/bic_edepToNpe_layer.lut"};
0067 
0068   decltype(PulseGenerationConfig::pulse_shape_function) EcalBarrelScFi_pulse_shape_function = {
0069       "LandauPulse"};
0070   decltype(PulseGenerationConfig::pulse_shape_params) EcalBarrelScFi_pulse_shape_params = {
0071       55.37, 10 * edm4eic::unit::ns};
0072   decltype(PulseGenerationConfig::ignore_thres) EcalBarrelScFi_ignore_thres = {1};
0073   decltype(PulseGenerationConfig::timestep) EcalBarrelScFi_timestep = {0.5 * edm4eic::unit::ns};
0074 
0075   decltype(PulseCombinerConfig::combine_field) EcalBarrelScFi_combine_field           = {"grid"};
0076   decltype(PulseCombinerConfig::minimum_separation) EcalBarrelScFi_minimum_separation = {
0077       100 * edm4eic::unit::ns};
0078   decltype(PulseNoiseConfig::poles) EcalBarrelScFi_poles                  = {2};
0079   decltype(PulseNoiseConfig::variance) EcalBarrelScFi_variance            = {0.5};
0080   decltype(PulseNoiseConfig::alpha) EcalBarrelScFi_alpha                  = {0};
0081   decltype(PulseNoiseConfig::scale) EcalBarrelScFi_scale                  = {5.4e-5};
0082   decltype(PulseNoiseConfig::pedestal) EcalBarrelScFi_pedestal            = {1.6e-4};
0083   decltype(CALOROCDigitizationConfig::adc_phase) EcalBarrelScFi_adc_phase = {10 *
0084                                                                              edm4eic::unit::ns};
0085   decltype(CALOROCDigitizationConfig::toa_thres) EcalBarrelScFi_toa_thres = {7};
0086   decltype(CALOROCDigitizationConfig::tot_thres) EcalBarrelScFi_tot_thres = {200};
0087   decltype(CALOROCDigitizationConfig::dyRangeSingleGainADC) EcalBarrelScFi_dyRangeSingleGainADC = {
0088       250};
0089   decltype(CALOROCDigitizationConfig::dyRangeHighGainADC) EcalBarrelScFi_dyRangeHighGainADC = {250};
0090   decltype(CALOROCDigitizationConfig::dyRangeLowGainADC) EcalBarrelScFi_dyRangeLowGainADC = {2500};
0091 
0092   // Make sure digi and reco use the same value
0093   decltype(CalorimeterHitDigiConfig::capADC) EcalBarrelScFi_capADC = 16384; //16384,  14bit ADC
0094   decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalBarrelScFi_dyRangeADC   = 1500 * dd4hep::MeV;
0095   decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalBarrelScFi_pedMeanADC   = 100;
0096   decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalBarrelScFi_pedSigmaADC = 1;
0097   decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalBarrelScFi_resolutionTDC =
0098       10 * dd4hep::picosecond;
0099   app->Add(new JOmniFactoryGeneratorT<SimCalorimeterHitProcessor_factory>(
0100       "EcalBarrelScFiPAttenuatedHits", {"EcalBarrelScFiHits"},
0101       {"EcalBarrelScFiPAttenuatedHits", "EcalBarrelScFiPAttenuatedHitContributions"},
0102       {
0103           .attenuationParameters            = EcalBarrelScFi_attPars,
0104           .readout                          = "EcalBarrelScFiHits",
0105           .attenuationReferencePositionName = "EcalBarrel_LightGuide_PositivePosZ",
0106           .hitMergeFields                   = EcalBarrelScFi_hitMergeFields,
0107           .contributionMergeFields          = EcalBarrelScFi_contributionMergeFields,
0108           .inversePropagationSpeed          = EcalBarrelScFi_inversePropagationSpeed,
0109           .fixedTimeDelay                   = EcalBarrelScFi_fixedTimeDelay,
0110           .timeWindow                       = EcalBarrelScFi_timeWindow,
0111       },
0112       app // TODO: Remove me once fixed
0113       ));
0114   app->Add(new JOmniFactoryGeneratorT<SimCalorimeterHitProcessor_factory>(
0115       "EcalBarrelScFiNAttenuatedHits", {"EcalBarrelScFiHits"},
0116       {"EcalBarrelScFiNAttenuatedHits", "EcalBarrelScFiNAttenuatedHitContributions"},
0117       {
0118           .attenuationParameters            = EcalBarrelScFi_attPars,
0119           .readout                          = "EcalBarrelScFiHits",
0120           .attenuationReferencePositionName = "EcalBarrel_LightGuide_NegativePosZ",
0121           .hitMergeFields                   = EcalBarrelScFi_hitMergeFields,
0122           .contributionMergeFields          = EcalBarrelScFi_contributionMergeFields,
0123           .inversePropagationSpeed          = EcalBarrelScFi_inversePropagationSpeed,
0124           .fixedTimeDelay                   = EcalBarrelScFi_fixedTimeDelay,
0125           .timeWindow                       = EcalBarrelScFi_timeWindow,
0126       },
0127       app // TODO: Remove me once fixed
0128       ));
0129   app->Add(new JOmniFactoryGeneratorT<EdepToNpeConversion_factory>(
0130       "EcalBarrelScFiPNpeHits", {"EventHeader", "EcalBarrelScFiPAttenuatedHits"},
0131       {"EcalBarrelScFiPNpeHits"},
0132       {
0133           .readout              = "EcalBarrelScFiHits",
0134           .edep_to_npe_fields   = EcalBarrelScFi_edep_to_npe_fields,
0135           .edep_to_npe_filename = EcalBarrelScFi_edep_to_npe_filename,
0136       },
0137       app // TODO: Remove me once fixed
0138       ));
0139   app->Add(new JOmniFactoryGeneratorT<EdepToNpeConversion_factory>(
0140       "EcalBarrelScFiNNpeHits", {"EventHeader", "EcalBarrelScFiNAttenuatedHits"},
0141       {"EcalBarrelScFiNNpeHits"},
0142       {
0143           .readout              = "EcalBarrelScFiHits",
0144           .edep_to_npe_fields   = EcalBarrelScFi_edep_to_npe_fields,
0145           .edep_to_npe_filename = EcalBarrelScFi_edep_to_npe_filename,
0146       },
0147       app // TODO: Remove me once fixed
0148       ));
0149   app->Add(new JOmniFactoryGeneratorT<PulseGeneration_factory<edm4hep::SimCalorimeterHit>>(
0150       "EcalBarrelScFiPPulses", {"EcalBarrelScFiPNpeHits"}, {"EcalBarrelScFiPPulses"},
0151       {
0152           .pulse_shape_function = EcalBarrelScFi_pulse_shape_function,
0153           .pulse_shape_params   = EcalBarrelScFi_pulse_shape_params,
0154           .ignore_thres         = EcalBarrelScFi_ignore_thres,
0155           .timestep             = EcalBarrelScFi_timestep,
0156       },
0157       app // TODO: Remove me once fixed
0158       ));
0159   app->Add(new JOmniFactoryGeneratorT<PulseGeneration_factory<edm4hep::SimCalorimeterHit>>(
0160       "EcalBarrelScFiNPulses", {"EcalBarrelScFiNNpeHits"}, {"EcalBarrelScFiNPulses"},
0161       {
0162           .pulse_shape_function = EcalBarrelScFi_pulse_shape_function,
0163           .pulse_shape_params   = EcalBarrelScFi_pulse_shape_params,
0164           .ignore_thres         = EcalBarrelScFi_ignore_thres,
0165           .timestep             = EcalBarrelScFi_timestep,
0166       },
0167       app // TODO: Remove me once fixed
0168       ));
0169   app->Add(new JOmniFactoryGeneratorT<PulseCombiner_factory>(
0170       "EcalBarrelScFiPCombinedPulses", {"EcalBarrelScFiPPulses"}, {"EcalBarrelScFiPCombinedPulses"},
0171       {
0172           .minimum_separation = EcalBarrelScFi_minimum_separation,
0173           .readout            = "EcalBarrelScFiHits",
0174           .combine_field      = EcalBarrelScFi_combine_field,
0175       },
0176       app // TODO: Remove me once fixed
0177       ));
0178   app->Add(new JOmniFactoryGeneratorT<PulseCombiner_factory>(
0179       "EcalBarrelScFiNCombinedPulses", {"EcalBarrelScFiNPulses"}, {"EcalBarrelScFiNCombinedPulses"},
0180       {
0181           .minimum_separation = EcalBarrelScFi_minimum_separation,
0182           .readout            = "EcalBarrelScFiHits",
0183           .combine_field      = EcalBarrelScFi_combine_field,
0184       },
0185       app // TODO: Remove me once fixed
0186       ));
0187   app->Add(new JOmniFactoryGeneratorT<PulseNoise_factory>(
0188       "EcalBarrelScFiPCombinedPulsesWithNoise", {"EventHeader", "EcalBarrelScFiPCombinedPulses"},
0189       {"EcalBarrelScFiPCombinedPulsesWithNoise"},
0190       {
0191           .poles    = EcalBarrelScFi_poles,
0192           .variance = EcalBarrelScFi_variance,
0193           .alpha    = EcalBarrelScFi_alpha,
0194           .scale    = EcalBarrelScFi_scale,
0195           .pedestal = EcalBarrelScFi_pedestal,
0196       },
0197       app // TODO: Remove me once fixed
0198       ));
0199   app->Add(new JOmniFactoryGeneratorT<PulseNoise_factory>(
0200       "EcalBarrelScFiNCombinedPulsesWithNoise", {"EventHeader", "EcalBarrelScFiNCombinedPulses"},
0201       {"EcalBarrelScFiNCombinedPulsesWithNoise"},
0202       {
0203           .poles    = EcalBarrelScFi_poles,
0204           .variance = EcalBarrelScFi_variance,
0205           .alpha    = EcalBarrelScFi_alpha,
0206           .scale    = EcalBarrelScFi_scale,
0207           .pedestal = EcalBarrelScFi_pedestal,
0208       },
0209       app // TODO: Remove me once fixed
0210       ));
0211   app->Add(new JOmniFactoryGeneratorT<CALOROCDigitization_factory>(
0212       "EcalBarrelScFiPCALOROCHits", {"EcalBarrelScFiPCombinedPulsesWithNoise"},
0213       {"EcalBarrelScFiPCALOROCHits"},
0214       {
0215           .adc_phase            = EcalBarrelScFi_adc_phase,
0216           .toa_thres            = EcalBarrelScFi_toa_thres,
0217           .tot_thres            = EcalBarrelScFi_tot_thres,
0218           .dyRangeSingleGainADC = EcalBarrelScFi_dyRangeSingleGainADC,
0219           .dyRangeHighGainADC   = EcalBarrelScFi_dyRangeHighGainADC,
0220           .dyRangeLowGainADC    = EcalBarrelScFi_dyRangeLowGainADC,
0221       },
0222       app // TODO: Remove me once fixed
0223       ));
0224   app->Add(new JOmniFactoryGeneratorT<CALOROCDigitization_factory>(
0225       "EcalBarrelScFiNCALOROCHits", {"EcalBarrelScFiNCombinedPulses"},
0226       {"EcalBarrelScFiNCALOROCHits"},
0227       {
0228           .adc_phase            = EcalBarrelScFi_adc_phase,
0229           .toa_thres            = EcalBarrelScFi_toa_thres,
0230           .tot_thres            = EcalBarrelScFi_tot_thres,
0231           .dyRangeSingleGainADC = EcalBarrelScFi_dyRangeSingleGainADC,
0232           .dyRangeHighGainADC   = EcalBarrelScFi_dyRangeHighGainADC,
0233           .dyRangeLowGainADC    = EcalBarrelScFi_dyRangeLowGainADC,
0234       },
0235       app // TODO: Remove me once fixed
0236       ));
0237   app->Add(new JOmniFactoryGeneratorT<CalorimeterHitDigi_factory>(
0238       "EcalBarrelScFiRawHits", {"EventHeader", "EcalBarrelScFiHits"},
0239       {"EcalBarrelScFiRawHits", "EcalBarrelScFiRawHitLinks", "EcalBarrelScFiRawHitAssociations"},
0240       {
0241           .eRes          = {0.0 * sqrt(dd4hep::GeV), 0.0, 0.0 * dd4hep::GeV},
0242           .tRes          = 0.0 * dd4hep::ns,
0243           .threshold     = 0.0 * dd4hep::keV, // threshold is set in ADC in reco
0244           .capADC        = EcalBarrelScFi_capADC,
0245           .dyRangeADC    = EcalBarrelScFi_dyRangeADC,
0246           .pedMeanADC    = EcalBarrelScFi_pedMeanADC,
0247           .pedSigmaADC   = EcalBarrelScFi_pedSigmaADC,
0248           .resolutionTDC = EcalBarrelScFi_resolutionTDC,
0249           .corrMeanScale = "1.0",
0250           .readout       = "EcalBarrelScFiHits",
0251           .fields        = {"fiber", "z"},
0252       },
0253       app // TODO: Remove me once fixed
0254       ));
0255   app->Add(new JOmniFactoryGeneratorT<CalorimeterHitReco_factory>(
0256       "EcalBarrelScFiRecHits", {"EcalBarrelScFiRawHits"}, {"EcalBarrelScFiRecHits"},
0257       {
0258           .capADC          = EcalBarrelScFi_capADC,
0259           .dyRangeADC      = EcalBarrelScFi_dyRangeADC,
0260           .pedMeanADC      = EcalBarrelScFi_pedMeanADC,
0261           .pedSigmaADC     = EcalBarrelScFi_pedSigmaADC, // not needed; use only thresholdValue
0262           .resolutionTDC   = EcalBarrelScFi_resolutionTDC,
0263           .thresholdFactor = 0.0, // use only thresholdValue
0264           .thresholdValue  = 5.0, // 16384 ADC counts/1500 MeV * 0.5 MeV (desired threshold) = 5.46
0265           .sampFrac        = "0.09285755",
0266           .readout         = "EcalBarrelScFiHits",
0267           .layerField      = "layer",
0268           .sectorField     = "sector",
0269           .localDetFields  = {"system", "sector"},
0270           // here we want to use grid center position (XY) but keeps the z information from fiber-segment
0271           // TODO: a more realistic way to get z is to reconstruct it from timing
0272           .maskPos       = "xy",
0273           .maskPosFields = {"fiber", "z"},
0274       },
0275       app // TODO: Remove me once fixed
0276       ));
0277   app->Add(new JOmniFactoryGeneratorT<CalorimeterIslandCluster_factory>(
0278       "EcalBarrelScFiProtoClusters", {"EcalBarrelScFiRecHits"}, {"EcalBarrelScFiProtoClusters"},
0279       {
0280           .adjacencyMatrix{},
0281           .peakNeighbourhoodMatrix{},
0282           .readout{},
0283           .sectorDist = 50. * dd4hep::mm,
0284           .localDistXY{},
0285           .localDistXZ = {80 * dd4hep::mm, 80 * dd4hep::mm},
0286           .localDistYZ{},
0287           .globalDistRPhi{},
0288           .globalDistEtaPhi{},
0289           .dimScaledLocalDistXY{},
0290           .splitCluster         = false,
0291           .minClusterHitEdep    = 5.0 * dd4hep::MeV,
0292           .minClusterCenterEdep = 100.0 * dd4hep::MeV,
0293           .transverseEnergyProfileMetric{},
0294           .transverseEnergyProfileScale{},
0295           .transverseEnergyProfileScaleUnits{},
0296       },
0297       app // TODO: Remove me once fixed
0298       ));
0299   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterRecoCoG_factory>(
0300       "EcalBarrelScFiClustersWithoutShapes",
0301       {
0302           "EcalBarrelScFiProtoClusters",     // edm4eic::ProtoClusterCollection
0303           "EcalBarrelScFiRawHitLinks",       // edm4eic::MCRecoCalorimeterHitLink
0304           "EcalBarrelScFiRawHitAssociations" // edm4eic::MCRecoCalorimeterHitAssociation
0305       },
0306       {"EcalBarrelScFiClustersWithoutShapes", // edm4eic::Cluster
0307        "EcalBarrelScFiClusterLinksWithoutShapes",
0308        "EcalBarrelScFiClusterAssociationsWithoutShapes"}, // edm4eic::MCRecoClusterParticleAssociation
0309       {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false},
0310       app // TODO: Remove me once fixed
0311       ));
0312   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterShape_factory>(
0313       "EcalBarrelScFiClusters",
0314       {"EcalBarrelScFiClustersWithoutShapes", "EcalBarrelScFiClusterLinksWithoutShapes"},
0315       {"EcalBarrelScFiClusters", "EcalBarrelScFiClusterLinks", "EcalBarrelScFiClusterAssociations"},
0316       {.longitudinalShowerInfoAvailable = true, .energyWeight = "log", .logWeightBase = 6.2}, app));
0317 
0318   // Imaging TopoClustering on ScFi
0319   app->Add(new JOmniFactoryGeneratorT<ImagingTopoCluster_factory>(
0320       "EcalBarrelScFiProtoTopoClusters", {"EcalBarrelScFiRecHits"},
0321       {"EcalBarrelScFiProtoTopoClusters"},
0322       {
0323           .neighbourLayersRange = 2, //  # id diff for adjacent layer
0324           .sameLayerDistXYZ     = {80.0 * dd4hep::mm, 80.0 * dd4hep::mm,
0325                                    40.0 * dd4hep::mm}, //  # same layer
0326           .diffLayerDistXYZ     = {80.0 * dd4hep::mm, 80.0 * dd4hep::mm, 40.0 * dd4hep::mm},
0327           .sameLayerMode        = eicrecon::ImagingTopoClusterConfig::ELayerMode::xyz,
0328           .diffLayerMode        = eicrecon::ImagingTopoClusterConfig::ELayerMode::xyz,
0329           .sectorDist           = 5.0 * dd4hep::cm,
0330           .minClusterHitEdep    = 0,
0331           .minClusterCenterEdep = 0,
0332           .minClusterEdep       = 100 * dd4hep::MeV,
0333           .minClusterNhits      = 10,
0334 
0335       },
0336       app // TODO: Remove me once fixed
0337       ));
0338 
0339   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterRecoCoG_factory>(
0340       "EcalBarrelScFiTopoClustersWithoutShapes",
0341       {"EcalBarrelScFiProtoTopoClusters",         // edm4eic::ProtoClusterCollection
0342        "EcalBarrelScFiRawHitLinks",               // edm4eic::MCRecoCalorimeterHitLink
0343        "EcalBarrelScFiRawHitAssociations"},       // edm4eic::MCRecoCalorimeterHitAssociation
0344       {"EcalBarrelScFiTopoClustersWithoutShapes", // edm4eic::Cluster
0345        "EcalBarrelScFiTopoClusterLinksWithoutShapes",
0346        "EcalBarrelScFiTopoClusterAssociationsWithoutShapes"}, // edm4eic::MCRecoClusterParticleAssociation
0347       {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false},
0348       app // TODO: Remove me once fixed
0349       ));
0350   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterShape_factory>(
0351       "EcalBarrelScFiTopoClusters",
0352       {"EcalBarrelScFiTopoClustersWithoutShapes", "EcalBarrelScFiTopoClusterLinksWithoutShapes"},
0353       {"EcalBarrelScFiTopoClusters", "EcalBarrelScFiTopoClusterLinks",
0354        "EcalBarrelScFiTopoClusterAssociations"},
0355       {.longitudinalShowerInfoAvailable = true, .energyWeight = "log", .logWeightBase = 6.2}, app));
0356 
0357   // Make sure digi and reco use the same value
0358   decltype(SimCalorimeterHitProcessorConfig::timeWindow) EcalBarrelImaging_timeWindow = {
0359       100 * edm4eic::unit::ns};
0360 
0361   decltype(CalorimeterHitDigiConfig::capADC) EcalBarrelImaging_capADC = 8192; //8192,  13bit ADC
0362   decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalBarrelImaging_dyRangeADC = 3 * dd4hep::MeV;
0363   decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalBarrelImaging_pedMeanADC =
0364       14; // Noise floor at 5 keV: 8192 / 3 * 0.005
0365   decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalBarrelImaging_pedSigmaADC =
0366       5; // Upper limit for sigma for AstroPix
0367   decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalBarrelImaging_resolutionTDC =
0368       3.25 * dd4hep::nanosecond;
0369   app->Add(new JOmniFactoryGeneratorT<SimCalorimeterHitProcessor_factory>(
0370       "EcalBarrelImagingProcessedHits", {"EcalBarrelImagingHits"},
0371       {"EcalBarrelImagingProcessedHits", "EcalBarrelImagingProcessedHitContributions"},
0372       {
0373           .readout    = "EcalBarrelImagingHits",
0374           .timeWindow = EcalBarrelImaging_timeWindow,
0375       },
0376       app // TODO: Remove me once fixed
0377       ));
0378   app->Add(new JOmniFactoryGeneratorT<CalorimeterHitDigi_factory>(
0379       "EcalBarrelImagingRawHits", {"EventHeader", "EcalBarrelImagingProcessedHits"},
0380       {"EcalBarrelImagingRawHits", "EcalBarrelImagingRawHitLinks",
0381        "EcalBarrelImagingRawHitAssociations"},
0382       {
0383           .eRes          = {0.0 * sqrt(dd4hep::GeV), 0.02, 0.0 * dd4hep::GeV},
0384           .tRes          = 0.0 * dd4hep::ns,
0385           .capADC        = EcalBarrelImaging_capADC,
0386           .dyRangeADC    = EcalBarrelImaging_dyRangeADC,
0387           .pedMeanADC    = EcalBarrelImaging_pedMeanADC,
0388           .pedSigmaADC   = EcalBarrelImaging_pedSigmaADC,
0389           .resolutionTDC = EcalBarrelImaging_resolutionTDC,
0390           .corrMeanScale = "1.0",
0391           .readout       = "EcalBarrelImagingHits",
0392       },
0393       app // TODO: Remove me once fixed
0394       ));
0395   app->Add(new JOmniFactoryGeneratorT<CalorimeterHitReco_factory>(
0396       "EcalBarrelImagingRecHits", {"EcalBarrelImagingRawHits"}, {"EcalBarrelImagingRecHits"},
0397       {
0398           .capADC          = EcalBarrelImaging_capADC,
0399           .dyRangeADC      = EcalBarrelImaging_dyRangeADC,
0400           .pedMeanADC      = EcalBarrelImaging_pedMeanADC,
0401           .pedSigmaADC     = EcalBarrelImaging_pedSigmaADC, // not needed; use only thresholdValue
0402           .resolutionTDC   = EcalBarrelImaging_resolutionTDC,
0403           .thresholdFactor = 0.0, // use only thresholdValue
0404           .thresholdValue  = 41,  // 8192 ADC counts/3 MeV * 0.015 MeV (desired threshold) = 41
0405           .sampFrac        = "0.00429453",
0406           .readout         = "EcalBarrelImagingHits",
0407           .layerField      = "layer",
0408           .sectorField     = "sector",
0409       },
0410       app // TODO: Remove me once fixed
0411       ));
0412   app->Add(new JOmniFactoryGeneratorT<ImagingTopoCluster_factory>(
0413       "EcalBarrelImagingProtoClusters", {"EcalBarrelImagingRecHits"},
0414       {"EcalBarrelImagingProtoClusters"},
0415       {
0416           .neighbourLayersRange = 2, //  # id diff for adjacent layer
0417           .sameLayerDistTZ      = {2.0 * dd4hep::mm, 2 * dd4hep::mm},     //  # same layer
0418           .diffLayerDistEtaPhi  = {10 * dd4hep::mrad, 10 * dd4hep::mrad}, //  # adjacent layer
0419           .sameLayerMode        = eicrecon::ImagingTopoClusterConfig::ELayerMode::tz,
0420           .diffLayerMode        = eicrecon::ImagingTopoClusterConfig::ELayerMode::etaphi,
0421           .sectorDist           = 3.0 * dd4hep::cm,
0422           .minClusterHitEdep    = 0,
0423           .minClusterCenterEdep = 0,
0424           .minClusterEdep       = 100 * dd4hep::MeV,
0425           .minClusterNhits      = 10,
0426       },
0427       app // TODO: Remove me once fixed
0428       ));
0429 
0430   app->Add(new JOmniFactoryGeneratorT<ImagingClusterReco_factory>(
0431       "EcalBarrelImagingClustersWithoutShapes",
0432       {"EcalBarrelImagingProtoClusters", "EcalBarrelImagingRawHitLinks",
0433        "EcalBarrelImagingRawHitAssociations"},
0434       {"EcalBarrelImagingClustersWithoutShapes", "EcalBarrelImagingClusterLinksWithoutShapes",
0435        "EcalBarrelImagingClusterAssociationsWithoutShapes", "EcalBarrelImagingLayers"},
0436       {
0437           .trackStopLayer = 6,
0438       },
0439       app // TODO: Remove me once fixed
0440       ));
0441   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterShape_factory>(
0442       "EcalBarrelImagingClusters",
0443       {"EcalBarrelImagingClustersWithoutShapes", "EcalBarrelImagingClusterLinksWithoutShapes"},
0444       {"EcalBarrelImagingClusters", "EcalBarrelImagingClusterLinks",
0445        "EcalBarrelImagingClusterAssociations"},
0446       {.longitudinalShowerInfoAvailable = false, .energyWeight = "log", .logWeightBase = 6.2},
0447       app));
0448   app->Add(new JOmniFactoryGeneratorT<EnergyPositionClusterMerger_factory>(
0449       "EcalBarrelClustersWithoutShapes",
0450       {"EcalBarrelScFiClusters", "EcalBarrelScFiClusterAssociations", "EcalBarrelImagingClusters",
0451        "EcalBarrelImagingClusterAssociations"},
0452       {"EcalBarrelClustersWithoutShapes", "EcalBarrelClusterLinksWithoutShapes",
0453        "EcalBarrelClusterAssociationsWithoutShapes"},
0454       {
0455           .energyRelTolerance = 0.5,
0456           .phiTolerance       = 0.1,
0457           .etaTolerance       = 0.2,
0458       },
0459       app // TODO: Remove me once fixed
0460       ));
0461   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterShape_factory>(
0462       "EcalBarrelClusters",
0463       {"EcalBarrelClustersWithoutShapes", "EcalBarrelClusterLinksWithoutShapes"},
0464       {"EcalBarrelClusters", "EcalBarrelClusterLinks", "EcalBarrelClusterAssociations"},
0465       {.longitudinalShowerInfoAvailable = true, .energyWeight = "log", .logWeightBase = 6.2}, app));
0466   app->Add(new JOmniFactoryGeneratorT<TruthEnergyPositionClusterMerger_factory>(
0467       "EcalBarrelTruthClustersWithoutShapes",
0468       {"MCParticles", "EcalBarrelScFiClusters", "EcalBarrelScFiClusterAssociations",
0469        "EcalBarrelImagingClusters", "EcalBarrelImagingClusterAssociations"},
0470       {"EcalBarrelTruthClustersWithoutShapes", "EcalBarrelTruthClusterLinksWithoutShapes",
0471        "EcalBarrelTruthClusterAssociationsWithoutShapes"},
0472       app // TODO: Remove me once fixed
0473       ));
0474   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterShape_factory>(
0475       "EcalBarrelTruthClusters",
0476       {"EcalBarrelTruthClustersWithoutShapes", "EcalBarrelTruthClusterLinksWithoutShapes"},
0477       {"EcalBarrelTruthClusters", "EcalBarrelTruthClusterLinks",
0478        "EcalBarrelTruthClusterAssociations"},
0479       {.longitudinalShowerInfoAvailable = true, .energyWeight = "log", .logWeightBase = 6.2}, app));
0480 }
0481 }