Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:07:27

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/digi/PulseGenerationConfig.h"
0021 #include "extensions/jana/JOmniFactoryGeneratorT.h"
0022 #include "factories/calorimetry/CalorimeterClusterRecoCoG_factory.h"
0023 #include "factories/calorimetry/CalorimeterClusterShape_factory.h"
0024 #include "factories/calorimetry/CalorimeterHitDigi_factory.h"
0025 #include "factories/calorimetry/CalorimeterHitReco_factory.h"
0026 #include "factories/calorimetry/CalorimeterIslandCluster_factory.h"
0027 #include "factories/calorimetry/EnergyPositionClusterMerger_factory.h"
0028 #include "factories/calorimetry/ImagingClusterReco_factory.h"
0029 #include "factories/calorimetry/ImagingTopoCluster_factory.h"
0030 #include "factories/calorimetry/SimCalorimeterHitProcessor_factory.h"
0031 #include "factories/calorimetry/TruthEnergyPositionClusterMerger_factory.h"
0032 #include "factories/digi/PulseGeneration_factory.h"
0033 
0034 extern "C" {
0035 void InitPlugin(JApplication* app) {
0036 
0037   using namespace eicrecon;
0038 
0039   InitJANAPlugin(app);
0040 
0041   // Make sure left and right use the same value
0042   decltype(SimCalorimeterHitProcessorConfig::attenuationParameters) EcalBarrelScFi_attPars = {
0043       0.416212, 747.39875 * edm4eic::unit::mm, 7521.88383 * edm4eic::unit::mm};
0044   decltype(SimCalorimeterHitProcessorConfig::hitMergeFields) EcalBarrelScFi_hitMergeFields = {
0045       "fiber", "z"};
0046   decltype(SimCalorimeterHitProcessorConfig::contributionMergeFields)
0047       EcalBarrelScFi_contributionMergeFields = {"fiber"};
0048   decltype(SimCalorimeterHitProcessorConfig::inversePropagationSpeed)
0049       EcalBarrelScFi_inversePropagationSpeed = {(1. / 160) * edm4eic::unit::ns / edm4eic::unit::mm};
0050   decltype(SimCalorimeterHitProcessorConfig::fixedTimeDelay) EcalBarrelScFi_fixedTimeDelay = {
0051       2 * edm4eic::unit::ns};
0052   decltype(SimCalorimeterHitProcessorConfig::timeWindow) EcalBarrelScFi_timeWindow = {
0053       100 * edm4eic::unit::ns};
0054 
0055   decltype(PulseGenerationConfig::pulse_shape_function) EcalBarrelScFi_pulse_shape_function = {
0056       "LandauPulse"};
0057   decltype(PulseGenerationConfig::pulse_shape_params) EcalBarrelScFi_pulse_shape_params = {
0058       1.0, 2 * edm4eic::unit::ns};
0059   decltype(PulseGenerationConfig::ignore_thres) EcalBarrelScFi_ignore_thres = {1.0e-5};
0060   decltype(PulseGenerationConfig::timestep) EcalBarrelScFi_timestep = {0.5 * edm4eic::unit::ns};
0061 
0062   // Make sure digi and reco use the same value
0063   decltype(CalorimeterHitDigiConfig::capADC) EcalBarrelScFi_capADC = 16384; //16384,  14bit ADC
0064   decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalBarrelScFi_dyRangeADC   = 1500 * dd4hep::MeV;
0065   decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalBarrelScFi_pedMeanADC   = 100;
0066   decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalBarrelScFi_pedSigmaADC = 1;
0067   decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalBarrelScFi_resolutionTDC =
0068       10 * dd4hep::picosecond;
0069   app->Add(new JOmniFactoryGeneratorT<SimCalorimeterHitProcessor_factory>(
0070       "EcalBarrelScFiPAttenuatedHits", {"EcalBarrelScFiHits"},
0071       {"EcalBarrelScFiPAttenuatedHits", "EcalBarrelScFiPAttenuatedHitContributions"},
0072       {
0073           .attenuationParameters            = EcalBarrelScFi_attPars,
0074           .readout                          = "EcalBarrelScFiHits",
0075           .attenuationReferencePositionName = "EcalBarrel_Readout_zmax",
0076           .hitMergeFields                   = EcalBarrelScFi_hitMergeFields,
0077           .contributionMergeFields          = EcalBarrelScFi_contributionMergeFields,
0078           .inversePropagationSpeed          = EcalBarrelScFi_inversePropagationSpeed,
0079           .fixedTimeDelay                   = EcalBarrelScFi_fixedTimeDelay,
0080           .timeWindow                       = EcalBarrelScFi_timeWindow,
0081       },
0082       app // TODO: Remove me once fixed
0083       ));
0084   app->Add(new JOmniFactoryGeneratorT<SimCalorimeterHitProcessor_factory>(
0085       "EcalBarrelScFiNAttenuatedHits", {"EcalBarrelScFiHits"},
0086       {"EcalBarrelScFiNAttenuatedHits", "EcalBarrelScFiNAttenuatedHitContributions"},
0087       {
0088           .attenuationParameters            = EcalBarrelScFi_attPars,
0089           .readout                          = "EcalBarrelScFiHits",
0090           .attenuationReferencePositionName = "EcalBarrel_Readout_zmin",
0091           .hitMergeFields                   = EcalBarrelScFi_hitMergeFields,
0092           .contributionMergeFields          = EcalBarrelScFi_contributionMergeFields,
0093           .inversePropagationSpeed          = EcalBarrelScFi_inversePropagationSpeed,
0094           .fixedTimeDelay                   = EcalBarrelScFi_fixedTimeDelay,
0095           .timeWindow                       = EcalBarrelScFi_timeWindow,
0096       },
0097       app // TODO: Remove me once fixed
0098       ));
0099   app->Add(new JOmniFactoryGeneratorT<PulseGeneration_factory<edm4hep::SimCalorimeterHit>>(
0100       "EcalBarrelScFiPPulses", {"EcalBarrelScFiPAttenuatedHits"}, {"EcalBarrelScFiPPulses"},
0101       {
0102           .pulse_shape_function = EcalBarrelScFi_pulse_shape_function,
0103           .pulse_shape_params   = EcalBarrelScFi_pulse_shape_params,
0104           .ignore_thres         = EcalBarrelScFi_ignore_thres,
0105           .timestep             = EcalBarrelScFi_timestep,
0106       },
0107       app // TODO: Remove me once fixed
0108       ));
0109   app->Add(new JOmniFactoryGeneratorT<PulseGeneration_factory<edm4hep::SimCalorimeterHit>>(
0110       "EcalBarrelScFiNPulses", {"EcalBarrelScFiNAttenuatedHits"}, {"EcalBarrelScFiNPulses"},
0111       {
0112           .pulse_shape_function = EcalBarrelScFi_pulse_shape_function,
0113           .pulse_shape_params   = EcalBarrelScFi_pulse_shape_params,
0114           .ignore_thres         = EcalBarrelScFi_ignore_thres,
0115           .timestep             = EcalBarrelScFi_timestep,
0116       },
0117       app // TODO: Remove me once fixed
0118       ));
0119   app->Add(new JOmniFactoryGeneratorT<CalorimeterHitDigi_factory>(
0120       "EcalBarrelScFiRawHits", {"EventHeader", "EcalBarrelScFiHits"},
0121       {"EcalBarrelScFiRawHits", "EcalBarrelScFiRawHitAssociations"},
0122       {
0123           .eRes          = {0.0 * sqrt(dd4hep::GeV), 0.0, 0.0 * dd4hep::GeV},
0124           .tRes          = 0.0 * dd4hep::ns,
0125           .threshold     = 0.0 * dd4hep::keV, // threshold is set in ADC in reco
0126           .capADC        = EcalBarrelScFi_capADC,
0127           .dyRangeADC    = EcalBarrelScFi_dyRangeADC,
0128           .pedMeanADC    = EcalBarrelScFi_pedMeanADC,
0129           .pedSigmaADC   = EcalBarrelScFi_pedSigmaADC,
0130           .resolutionTDC = EcalBarrelScFi_resolutionTDC,
0131           .corrMeanScale = "1.0",
0132           .readout       = "EcalBarrelScFiHits",
0133           .fields        = {"fiber", "z"},
0134       },
0135       app // TODO: Remove me once fixed
0136       ));
0137   app->Add(new JOmniFactoryGeneratorT<CalorimeterHitReco_factory>(
0138       "EcalBarrelScFiRecHits", {"EcalBarrelScFiRawHits"}, {"EcalBarrelScFiRecHits"},
0139       {
0140           .capADC          = EcalBarrelScFi_capADC,
0141           .dyRangeADC      = EcalBarrelScFi_dyRangeADC,
0142           .pedMeanADC      = EcalBarrelScFi_pedMeanADC,
0143           .pedSigmaADC     = EcalBarrelScFi_pedSigmaADC, // not needed; use only thresholdValue
0144           .resolutionTDC   = EcalBarrelScFi_resolutionTDC,
0145           .thresholdFactor = 0.0, // use only thresholdValue
0146           .thresholdValue  = 5.0, // 16384 ADC counts/1500 MeV * 0.5 MeV (desired threshold) = 5.46
0147           .sampFrac        = "0.09285755",
0148           .readout         = "EcalBarrelScFiHits",
0149           .layerField      = "layer",
0150           .sectorField     = "sector",
0151           .localDetFields  = {"system"},
0152           // here we want to use grid center position (XY) but keeps the z information from fiber-segment
0153           // TODO: a more realistic way to get z is to reconstruct it from timing
0154           .maskPos       = "xy",
0155           .maskPosFields = {"fiber", "z"},
0156       },
0157       app // TODO: Remove me once fixed
0158       ));
0159   app->Add(new JOmniFactoryGeneratorT<CalorimeterIslandCluster_factory>(
0160       "EcalBarrelScFiProtoClusters", {"EcalBarrelScFiRecHits"}, {"EcalBarrelScFiProtoClusters"},
0161       {
0162           .adjacencyMatrix{},
0163           .peakNeighbourhoodMatrix{},
0164           .readout{},
0165           .sectorDist = 50. * dd4hep::mm,
0166           .localDistXY{},
0167           .localDistXZ = {80 * dd4hep::mm, 80 * dd4hep::mm},
0168           .localDistYZ{},
0169           .globalDistRPhi{},
0170           .globalDistEtaPhi{},
0171           .dimScaledLocalDistXY{},
0172           .splitCluster         = false,
0173           .minClusterHitEdep    = 5.0 * dd4hep::MeV,
0174           .minClusterCenterEdep = 100.0 * dd4hep::MeV,
0175           .transverseEnergyProfileMetric{},
0176           .transverseEnergyProfileScale{},
0177           .transverseEnergyProfileScaleUnits{},
0178       },
0179       app // TODO: Remove me once fixed
0180       ));
0181   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterRecoCoG_factory>(
0182       "EcalBarrelScFiClustersWithoutShapes",
0183       {"EcalBarrelScFiProtoClusters",         // edm4eic::ProtoClusterCollection
0184        "EcalBarrelScFiRawHitAssociations"},   // edm4eic::MCRecoCalorimeterHitAssociation
0185       {"EcalBarrelScFiClustersWithoutShapes", // edm4eic::Cluster
0186        "EcalBarrelScFiClusterAssociationsWithoutShapes"}, // edm4eic::MCRecoClusterParticleAssociation
0187       {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false},
0188       app // TODO: Remove me once fixed
0189       ));
0190   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterShape_factory>(
0191       "EcalBarrelScFiClusters",
0192       {"EcalBarrelScFiClustersWithoutShapes", "EcalBarrelScFiClusterAssociationsWithoutShapes"},
0193       {"EcalBarrelScFiClusters", "EcalBarrelScFiClusterAssociations"},
0194       {.longitudinalShowerInfoAvailable = true, .energyWeight = "log", .logWeightBase = 6.2}, app));
0195 
0196   // Make sure digi and reco use the same value
0197   decltype(CalorimeterHitDigiConfig::capADC) EcalBarrelImaging_capADC = 8192; //8192,  13bit ADC
0198   decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalBarrelImaging_dyRangeADC = 3 * dd4hep::MeV;
0199   decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalBarrelImaging_pedMeanADC =
0200       14; // Noise floor at 5 keV: 8192 / 3 * 0.005
0201   decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalBarrelImaging_pedSigmaADC =
0202       5; // Upper limit for sigma for AstroPix
0203   decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalBarrelImaging_resolutionTDC =
0204       3.25 * dd4hep::nanosecond;
0205   app->Add(new JOmniFactoryGeneratorT<CalorimeterHitDigi_factory>(
0206       "EcalBarrelImagingRawHits", {"EventHeader", "EcalBarrelImagingHits"},
0207       {"EcalBarrelImagingRawHits", "EcalBarrelImagingRawHitAssociations"},
0208       {
0209           .eRes          = {0.0 * sqrt(dd4hep::GeV), 0.02, 0.0 * dd4hep::GeV},
0210           .tRes          = 0.0 * dd4hep::ns,
0211           .capADC        = EcalBarrelImaging_capADC,
0212           .dyRangeADC    = EcalBarrelImaging_dyRangeADC,
0213           .pedMeanADC    = EcalBarrelImaging_pedMeanADC,
0214           .pedSigmaADC   = EcalBarrelImaging_pedSigmaADC,
0215           .resolutionTDC = EcalBarrelImaging_resolutionTDC,
0216           .corrMeanScale = "1.0",
0217           .readout       = "EcalBarrelImagingHits",
0218       },
0219       app // TODO: Remove me once fixed
0220       ));
0221   app->Add(new JOmniFactoryGeneratorT<CalorimeterHitReco_factory>(
0222       "EcalBarrelImagingRecHits", {"EcalBarrelImagingRawHits"}, {"EcalBarrelImagingRecHits"},
0223       {
0224           .capADC          = EcalBarrelImaging_capADC,
0225           .dyRangeADC      = EcalBarrelImaging_dyRangeADC,
0226           .pedMeanADC      = EcalBarrelImaging_pedMeanADC,
0227           .pedSigmaADC     = EcalBarrelImaging_pedSigmaADC, // not needed; use only thresholdValue
0228           .resolutionTDC   = EcalBarrelImaging_resolutionTDC,
0229           .thresholdFactor = 0.0, // use only thresholdValue
0230           .thresholdValue  = 41,  // 8192 ADC counts/3 MeV * 0.015 MeV (desired threshold) = 41
0231           .sampFrac        = "0.00429453",
0232           .readout         = "EcalBarrelImagingHits",
0233           .layerField      = "layer",
0234           .sectorField     = "sector",
0235       },
0236       app // TODO: Remove me once fixed
0237       ));
0238   app->Add(new JOmniFactoryGeneratorT<ImagingTopoCluster_factory>(
0239       "EcalBarrelImagingProtoClusters", {"EcalBarrelImagingRecHits"},
0240       {"EcalBarrelImagingProtoClusters"},
0241       {
0242           .neighbourLayersRange = 2, //  # id diff for adjacent layer
0243           .sameLayerDistTZ      = {2.0 * dd4hep::mm, 2 * dd4hep::mm},     //  # same layer
0244           .diffLayerDistEtaPhi  = {10 * dd4hep::mrad, 10 * dd4hep::mrad}, //  # adjacent layer
0245           .sameLayerMode        = eicrecon::ImagingTopoClusterConfig::ELayerMode::tz,
0246           .diffLayerMode        = eicrecon::ImagingTopoClusterConfig::ELayerMode::etaphi,
0247           .sectorDist           = 3.0 * dd4hep::cm,
0248           .minClusterHitEdep    = 0,
0249           .minClusterCenterEdep = 0,
0250           .minClusterEdep       = 100 * dd4hep::MeV,
0251           .minClusterNhits      = 10,
0252       },
0253       app // TODO: Remove me once fixed
0254       ));
0255 
0256   app->Add(new JOmniFactoryGeneratorT<ImagingClusterReco_factory>(
0257       "EcalBarrelImagingClustersWithoutShapes",
0258       {"EcalBarrelImagingProtoClusters", "EcalBarrelImagingRawHitAssociations"},
0259       {"EcalBarrelImagingClustersWithoutShapes",
0260        "EcalBarrelImagingClusterAssociationsWithoutShapes", "EcalBarrelImagingLayers"},
0261       {
0262           .trackStopLayer = 6,
0263       },
0264       app // TODO: Remove me once fixed
0265       ));
0266   app->Add(new JOmniFactoryGeneratorT<CalorimeterClusterShape_factory>(
0267       "EcalBarrelImagingClusters",
0268       {"EcalBarrelImagingClustersWithoutShapes",
0269        "EcalBarrelImagingClusterAssociationsWithoutShapes"},
0270       {"EcalBarrelImagingClusters", "EcalBarrelImagingClusterAssociations"},
0271       {.longitudinalShowerInfoAvailable = false, .energyWeight = "log", .logWeightBase = 6.2},
0272       app));
0273   app->Add(new JOmniFactoryGeneratorT<EnergyPositionClusterMerger_factory>(
0274       "EcalBarrelClusters",
0275       {"EcalBarrelScFiClusters", "EcalBarrelScFiClusterAssociations", "EcalBarrelImagingClusters",
0276        "EcalBarrelImagingClusterAssociations"},
0277       {"EcalBarrelClusters", "EcalBarrelClusterAssociations"},
0278       {
0279           .energyRelTolerance = 0.5,
0280           .phiTolerance       = 0.1,
0281           .etaTolerance       = 0.2,
0282       },
0283       app // TODO: Remove me once fixed
0284       ));
0285   app->Add(new JOmniFactoryGeneratorT<TruthEnergyPositionClusterMerger_factory>(
0286       "EcalBarrelTruthClusters",
0287       {"MCParticles", "EcalBarrelScFiClusters", "EcalBarrelScFiClusterAssociations",
0288        "EcalBarrelImagingClusters", "EcalBarrelImagingClusterAssociations"},
0289       {"EcalBarrelTruthClusters", "EcalBarrelTruthClusterAssociations"},
0290       app // TODO: Remove me once fixed
0291       ));
0292 }
0293 }