diff --git a/CLDConfig/CLDReconstruction.py b/CLDConfig/CLDReconstruction.py index bff1191..ec5f20e 100644 --- a/CLDConfig/CLDReconstruction.py +++ b/CLDConfig/CLDReconstruction.py @@ -33,6 +33,7 @@ parser_group.add_argument("--enableLCFIJet", action="store_true", help="Enable LCFIPlus jet clustering parts", default=False) parser_group.add_argument("--cms", action="store", help="Choose a Centre-of-Mass energy", default=240, choices=(91, 160, 240, 365), type=int) parser_group.add_argument("--compactFile", help="Compact detector file to use", type=str, default=os.environ["K4GEO"] + "/FCCee/CLD/compact/CLD_o2_v07/CLD_o2_v07.xml") +parser_group.add_argument("--native", action="store_true", help="Use the native EDM4hep tracking", default=False) tracking_group = parser_group.add_mutually_exclusive_group() tracking_group.add_argument("--conformalTracking", action="store_true", default=True, help="Use conformal tracking pattern recognition") tracking_group.add_argument("--truthTracking", action="store_true", default=False, help="Cheat tracking pattern recognition") @@ -41,6 +42,9 @@ evtsvc = EventDataSvc("EventDataSvc") iosvc = IOSvc() +if reco_args.native: + iosvc.Input = reco_args.inputFiles + iosvc.Output = f"{reco_args.outputBasename}_REC.edm4hep.root" svcList = [evtsvc, iosvc] algList = [] @@ -64,11 +68,12 @@ geoservice.EnableGeant4Geo = False svcList.append(geoservice) -cellIDSvc = TrackingCellIDEncodingSvc("CellIDSvc") -cellIDSvc.EncodingStringParameterName = "GlobalTrackerReadoutID" -cellIDSvc.GeoSvcName = geoservice.name() -cellIDSvc.OutputLevel = INFO -svcList.append(cellIDSvc) +if not reco_args.native: + cellIDSvc = TrackingCellIDEncodingSvc("CellIDSvc") + cellIDSvc.EncodingStringParameterName = "GlobalTrackerReadoutID" + cellIDSvc.GeoSvcName = geoservice.name() + cellIDSvc.OutputLevel = INFO + svcList.append(cellIDSvc) if len(geoservice.detectors) > 1: # we are making assumptions for reconstruction parameters based on the detector option, so we limit the possibilities @@ -90,28 +95,29 @@ }, ) -io_handler = IOHandlerHelper(algList, iosvc) -io_handler.add_reader(reco_args.inputFiles) - -MyAIDAProcessor = MarlinProcessorWrapper("MyAIDAProcessor") -MyAIDAProcessor.OutputLevel = WARNING -MyAIDAProcessor.ProcessorType = "AIDAProcessor" -MyAIDAProcessor.Parameters = { - "Compress": ["1"], - "FileName": [f"{reco_args.outputBasename}_aida"], - "FileType": ["root"] +if not reco_args.native: + io_handler = IOHandlerHelper(algList, iosvc) + io_handler.add_reader(reco_args.inputFiles) + + MyAIDAProcessor = MarlinProcessorWrapper("MyAIDAProcessor") + MyAIDAProcessor.OutputLevel = WARNING + MyAIDAProcessor.ProcessorType = "AIDAProcessor" + MyAIDAProcessor.Parameters = { + "Compress": ["1"], + "FileName": [f"{reco_args.outputBasename}_aida"], + "FileType": ["root"] + } + + EventNumber = MarlinProcessorWrapper("EventNumber") + EventNumber.OutputLevel = WARNING + EventNumber.ProcessorType = "Statusmonitor" + EventNumber.Parameters = { + "HowOften": ["1"] } -EventNumber = MarlinProcessorWrapper("EventNumber") -EventNumber.OutputLevel = WARNING -EventNumber.ProcessorType = "Statusmonitor" -EventNumber.Parameters = { - "HowOften": ["1"] - } - -# setup AIDA histogramming and add eventual background overlay -algList.append(MyAIDAProcessor) -sequenceLoader.load("Overlay/Overlay") + # setup AIDA histogramming and add eventual background overlay + algList.append(MyAIDAProcessor) + sequenceLoader.load("Overlay/Overlay") # tracker hit digitisation sequenceLoader.load("Tracking/TrackingDigi") @@ -130,15 +136,17 @@ sequenceLoader.load("ParticleFlow/Pandora") sequenceLoader.load("CaloDigi/LumiCal") # monitoring and Reco to MCTruth linking -sequenceLoader.load("HighLevelReco/RecoMCTruthLink") -sequenceLoader.load("Diagnostics/Tracking") +if not reco_args.native: + sequenceLoader.load("HighLevelReco/RecoMCTruthLink") + sequenceLoader.load("Diagnostics/Tracking") # pfo selector (might need re-optimisation) -if not reco_args.trackingOnly: +if not reco_args.trackingOnly and not reco_args.native: sequenceLoader.load("HighLevelReco/PFOSelector") sequenceLoader.load("HighLevelReco/JetClusteringOrRenaming") sequenceLoader.load("HighLevelReco/JetAndVertex") # event number processor, down here to attach the conversion back to edm4hep to it -algList.append(EventNumber) +if not reco_args.native: + algList.append(EventNumber) DST_KEEPLIST = ["MCParticlesSkimmed", "MCPhysicsParticles", "RecoMCTruthLink", "SiTracks", "SiTracks_Refitted", "PandoraClusters", "PandoraPFOs", "SelectedPandoraPFOs", "LooseSelectedPandoraPFOs", "TightSelectedPandoraPFOs", "RefinedVertexJets", "RefinedVertexJets_rel", "RefinedVertexJets_vtx", "RefinedVertexJets_vtx_RP", "BuildUpVertices", "BuildUpVertices_res", "BuildUpVertices_RP", "BuildUpVertices_res_RP", "BuildUpVertices_V0", "BuildUpVertices_V0_res", "BuildUpVertices_V0_RP", "BuildUpVertices_V0_res_RP", "PrimaryVertices", "PrimaryVertices_res", "PrimaryVertices_RP", "PrimaryVertices_res_RP", "RefinedVertices", "RefinedVertices_RP"] @@ -146,6 +154,8 @@ # TODO: replace all the ugly strings by something sensible like Enum if CONFIG["OutputMode"] == "LCIO": + if reco_args.native: + raise RuntimeError("LCIO output is not supported with --native") Output_REC = io_handler.add_lcio_writer("Output_REC") Output_REC.Parameters = { "LCIOOutputFile": [f"{reco_args.outputBasename}_REC.slcio"], @@ -163,7 +173,7 @@ "KeepCollectionNames": DST_KEEPLIST, } -if CONFIG["OutputMode"] == "EDM4Hep": +if CONFIG["OutputMode"] == "EDM4Hep" and not reco_args.native: # Make sure that all collections are always available by patching in missing ones on-the-fly collPatcherRec = MarlinProcessorWrapper( "CollPatcherREC", OutputLevel=INFO, ProcessorType="PatchCollections" @@ -179,7 +189,8 @@ # We need to attach all the necessary converters -io_handler.finalize_converters() +if not reco_args.native: + io_handler.finalize_converters() ApplicationMgr( TopAlg = algList, EvtSel = 'NONE', diff --git a/CLDConfig/CaloDigi/CaloDigi.py b/CLDConfig/CaloDigi/CaloDigi.py index e403afa..9deb956 100644 --- a/CLDConfig/CaloDigi/CaloDigi.py +++ b/CLDConfig/CaloDigi/CaloDigi.py @@ -17,117 +17,157 @@ # limitations under the License. # from Gaudi.Configuration import WARNING -from Configurables import MarlinProcessorWrapper +from Configurables import DDCaloDigi +from Configurables import CollectionMerger +from py_utils import toMarlinDict import sys +ECALCollections = ["ECalBarrelCollection", "ECalEndcapCollection"] +ECALOutputCollections = ["ECALBarrel", "ECALEndcap"] +HCALCollections = ["HCalBarrelCollection", "HCalEndcapCollection", "HCalRingCollection"] +HCALOutputCollections = ["HCALBarrel", "HCALEndcap", "HCALOther"] +ECALorHCAL = [True, True, False, False, False] + MyDDCaloDigiParameters = { - "Histograms": ["0"], - "RootFile": ["Digi_SiW.root"], - "RelationOutputCollection": ["RelationCaloHit"], - "energyPerEHpair": ["3.6"], - # ECAL - "ECALCollections": ["ECalBarrelCollection", "ECalEndcapCollection"], - "ECALOutputCollection0": ["ECALBarrel"], - "ECALOutputCollection1": ["ECALEndcap"], - "ECALOutputCollection2": [""], - "IfDigitalEcal": ["0"], - "ECALLayers": ["41", "100"], - "ECAL_default_layerConfig": ["000000000000000"], - "StripEcal_default_nVirtualCells": ["9"], - "CalibECALMIP": ["0.0001"], - "ECALThreshold": ["5e-05"], - "ECALThresholdUnit": ["GeV"], - "ECALGapCorrection": ["1"], - "ECALGapCorrectionFactor": ["1"], - "ECALModuleGapCorrectionFactor": ["0.0"], - "MapsEcalCorrection": ["0"], - "ECAL_PPD_N_Pixels": ["10000"], - "ECAL_PPD_N_Pixels_uncertainty": ["0.05"], - "ECAL_PPD_PE_per_MIP": ["7"], - "ECAL_apply_realistic_digi": ["0"], - "ECAL_deadCellRate": ["0"], - "ECAL_deadCell_memorise": ["false"], - "ECAL_elec_noise_mips": ["0"], - "ECAL_maxDynamicRange_MIP": ["2500"], - "ECAL_miscalibration_correl": ["0"], - "ECAL_miscalibration_uncorrel": ["0"], - "ECAL_miscalibration_uncorrel_memorise": ["false"], - "ECAL_pixel_spread": ["0.05"], - "ECAL_strip_absorbtionLength": ["1e+06"], - "UseEcalTiming": ["1"], - "ECALCorrectTimesForPropagation": ["1"], - "ECALTimeWindowMin": ["-1"], - "ECALSimpleTimingCut": ["true"], - "ECALDeltaTimeHitResolution": ["10"], - "ECALTimeResolution": ["10"], - # HCAL - "HCALCollections": ["HCalBarrelCollection", "HCalEndcapCollection", "HCalRingCollection"], - "HCALOutputCollection0": ["HCALBarrel"], - "HCALOutputCollection1": ["HCALEndcap"], - "HCALOutputCollection2": ["HCALOther"], - "IfDigitalHcal": ["0"], - "HCALLayers": ["100"], - "CalibHCALMIP": ["0.0001"], - "HCALThreshold": ["0.00025"], - "HCALThresholdUnit": ["GeV"], - "HCALEndcapCorrectionFactor": ["1.000"], - "HCALGapCorrection": ["1"], - "HCALModuleGapCorrectionFactor": ["0.5"], - "HCAL_PPD_N_Pixels": ["400"], - "HCAL_PPD_N_Pixels_uncertainty": ["0.05"], - "HCAL_PPD_PE_per_MIP": ["10"], - "HCAL_apply_realistic_digi": ["0"], - "HCAL_deadCellRate": ["0"], - "HCAL_deadCell_memorise": ["false"], - "HCAL_elec_noise_mips": ["0"], - "HCAL_maxDynamicRange_MIP": ["200"], - "HCAL_miscalibration_correl": ["0"], - "HCAL_miscalibration_uncorrel": ["0"], - "HCAL_miscalibration_uncorrel_memorise": ["false"], - "HCAL_pixel_spread": ["0"], - "UseHcalTiming": ["1"], - "HCALCorrectTimesForPropagation": ["1"], - "HCALTimeWindowMin": ["-1"], - "HCALSimpleTimingCut": ["true"], - "HCALDeltaTimeHitResolution": ["10"], - "HCALTimeResolution": ["10"], + "Histograms": 0, + "RootFile": "Digi_SiW.root", + "energyPerEHpair": 3.6, + # ECAL + "IfDigitalEcal": 0, + "ECALLayers": [41, 100], + "ECAL_default_layerConfig": "000000000000000", + "StripEcal_default_nVirtualCells": 9, + "CalibECALMIP": 0.0001, + "ECALThreshold": 5e-05, + "ECALThresholdUnit": "GeV", + "ECALGapCorrection": 1, + "ECALGapCorrectionFactor": 1, + "ECALModuleGapCorrectionFactor": 0.0, + "MapsEcalCorrection": 0, + "ECAL_PPD_N_Pixels": 10000, + "ECAL_PPD_N_Pixels_uncertainty": 0.05, + "ECAL_PPD_PE_per_MIP": 7, + "ECAL_apply_realistic_digi": 0, + "ECAL_deadCellRate": 0, + "ECAL_deadCell_memorise": False, + "ECAL_elec_noise_mips": 0, + "ECAL_maxDynamicRange_MIP": 2500, + "ECAL_miscalibration_correl": 0, + "ECAL_miscalibration_uncorrel": 0, + "ECAL_miscalibration_uncorrel_memorise": False, + "ECAL_pixel_spread": 0.05, + "ECAL_strip_absorbtionLength": 1e+06, + "UseEcalTiming": 1, + "ECALCorrectTimesForPropagation": 1, + "ECALTimeWindowMin": -1, + "ECALSimpleTimingCut": True, + "ECALDeltaTimeHitResolution": 10, + "ECALTimeResolution": 10, + # HCAL + "IfDigitalHcal": 0, + "HCALLayers": [100], + "CalibHCALMIP": 0.0001, + "HCALThreshold": [0.00025], + "HCALThresholdUnit": "GeV", + "HCALEndcapCorrectionFactor": 1.000, + "HCALGapCorrection": 1, + "HCALModuleGapCorrectionFactor": 0.5, + "HCAL_PPD_N_Pixels": 400, + "HCAL_PPD_N_Pixels_uncertainty": 0.05, + "HCAL_PPD_PE_per_MIP": 10, + "HCAL_apply_realistic_digi": 0, + "HCAL_deadCellRate": 0, + "HCAL_deadCell_memorise": False, + "HCAL_elec_noise_mips": 0, + "HCAL_maxDynamicRange_MIP": 200, + "HCAL_miscalibration_correl": 0, + "HCAL_miscalibration_uncorrel": 0, + "HCAL_miscalibration_uncorrel_memorise": False, + "HCAL_pixel_spread": 0, + "UseHcalTiming": 1, + "HCALCorrectTimesForPropagation": 1, + "HCALTimeWindowMin": -1, + "HCALSimpleTimingCut": True, + "HCALDeltaTimeHitResolution": 10, + "HCALTimeResolution": 10, } +parameters_10ns = { + "CalibrECAL": [37.5227197175, 37.5227197175], + "ECALEndcapCorrectionFactor": 1.03245503522, + "ECALBarrelTimeWindowMax": 10, + "ECALEndcapTimeWindowMax": 10, + "CalibrHCALBarrel": [45.9956826061], + "CalibrHCALEndcap": [46.9252540291], + "CalibrHCALOther": [57.4588011802], + "HCALBarrelTimeWindowMax": 10, + "HCALEndcapTimeWindowMax": 10, +} -MyDDCaloDigi = MarlinProcessorWrapper(f"MyDDCaloDigi_{CONFIG['CalorimeterIntegrationTimeWindow']}") -MyDDCaloDigi.OutputLevel = WARNING -MyDDCaloDigi.ProcessorType = "DDCaloDigi" -MyDDCaloDigi.Parameters = MyDDCaloDigiParameters.copy() +parameters_400ns = { + "CalibrECAL": [37.4591745147, 37.4591745147], + "ECALEndcapCorrectionFactor": 1.01463983425, + "ECALBarrelTimeWindowMax": 400, + "ECALEndcapTimeWindowMax": 400, + "CalibrHCALBarrel": [42.544403752], + "CalibrHCALEndcap": [42.9667604345], + "CalibrHCALOther": [51.3503963688], + "HCALBarrelTimeWindowMax": 400, + "HCALEndcapTimeWindowMax": 400, +} if CONFIG["CalorimeterIntegrationTimeWindow"] == "10ns": - MyDDCaloDigi.Parameters |= { - "CalibrECAL": ["37.5227197175", "37.5227197175"], - "ECALEndcapCorrectionFactor": ["1.03245503522"], - "ECALBarrelTimeWindowMax": ["10"], - "ECALEndcapTimeWindowMax": ["10"], - "CalibrHCALBarrel": ["45.9956826061"], - "CalibrHCALEndcap": ["46.9252540291"], - "CalibrHCALOther": ["57.4588011802"], - "HCALBarrelTimeWindowMax": ["10"], - "HCALEndcapTimeWindowMax": ["10"], - } - + MyDDCaloDigiParameters |= parameters_10ns elif CONFIG["CalorimeterIntegrationTimeWindow"] == "400ns": - MyDDCaloDigi.Parameters |= { - "CalibrECAL": ["37.4591745147", "37.4591745147"], - "ECALEndcapCorrectionFactor": ["1.01463983425"], - "ECALBarrelTimeWindowMax": ["400"], - "ECALEndcapTimeWindowMax": ["400"], - "CalibrHCALBarrel": ["42.544403752"], - "CalibrHCALEndcap": ["42.9667604345"], - "CalibrHCALOther": ["51.3503963688"], - "HCALBarrelTimeWindowMax": ["400"], - "HCALEndcapTimeWindowMax": ["400"], - } + MyDDCaloDigiParameters |= parameters_400ns else: print(f"The value {CONFIG['CalorimeterIntegrationTimeWindow']} " "for the calorimeter integration time window is not a valid choice") sys.exit(1) -CaloDigiSequence = [MyDDCaloDigi] + +if reco_args.native: + # Not implemented in the algorithm + for key in ["Histograms", "RootFile"]: + MyDDCaloDigiParameters.pop(key) + + final_parameters = MyDDCaloDigiParameters + MyDDCaloDigi = [] + collections = ECALCollections + HCALCollections + out_collections = ECALOutputCollections + HCALOutputCollections + for i, (incol, outcol) in enumerate(zip(collections, out_collections)): + MyDDCaloDigi.append( + DDCaloDigi( + f"{incol}Digitiser", + **final_parameters, + InputCaloHitCollection=[incol], + OutputCaloHitCollection=[outcol], + InputColIsECAL=ECALorHCAL[i], + RelationOutputCollection=[f"GaudiRelationCaloHit{outcol}"], + OutputLevel=WARNING, + ) + ) + merger = CollectionMerger( + "CollectionMerger", + InputCollections=[f"GaudiRelationCaloHit{outcol}" for outcol in out_collections], + OutputCollection=["RelationCaloHit"], + ) + MyDDCaloDigi.append(merger) +else: + from Configurables import MarlinProcessorWrapper + MyDDCaloDigiParameters["RelationOutputCollection"] = ["RelationCaloHit"] + MyDDCaloDigiParameters["ECALCollections"] = ECALCollections + for i in range(len(ECALCollections)): + MyDDCaloDigiParameters[f"ECALOutputCollection{i}"] = [ECALOutputCollections[i]] + MyDDCaloDigiParameters["HCALCollections"] = HCALCollections + for i in range(len(HCALCollections)): + MyDDCaloDigiParameters[f"HCALOutputCollection{i}"] = [HCALOutputCollections[i]] + + MyDDCaloDigi = [MarlinProcessorWrapper(f"MyDDCaloDigi_{CONFIG['CalorimeterIntegrationTimeWindow']}")] + MyDDCaloDigi[0].OutputLevel = WARNING + MyDDCaloDigi[0].ProcessorType = "DDCaloDigi" + MyDDCaloDigi[0].Parameters = toMarlinDict(MyDDCaloDigiParameters) + + +CaloDigiSequence = MyDDCaloDigi diff --git a/CLDConfig/CaloDigi/LumiCal.py b/CLDConfig/CaloDigi/LumiCal.py index 5b5a07f..a379004 100644 --- a/CLDConfig/CaloDigi/LumiCal.py +++ b/CLDConfig/CaloDigi/LumiCal.py @@ -16,36 +16,45 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from Configurables import GaudiLumiCalClusterer from Gaudi.Configuration import WARNING -from Configurables import MarlinProcessorWrapper +from py_utils import toMarlinDict +LumiCalParameters = { + "ClusterMinNumHits": 15, + "ElementsPercentInShowerPeakLayer": 0.03, + "EnergyCalibConst": 0.01213, + "LogWeigthConstant": 6.5, + "LumiCal_Clusters": "LumiCalClusters", + "LumiCal_Collection": "LumiCalCollection", + "LumiCal_RecoParticles": "LumiCalRecoParticles", + "MaxRecordNumber": 10, + "MemoryResidentTree": 0, + "MiddleEnergyHitBoundFrac": 0.01, + "MinClusterEngy": 2.0, + "MinHitEnergy": 20e-06, + "MoliereRadius": 20, + "NumEventsTree": 500, + "NumOfNearNeighbor": 6, + "OutDirName": "rootOut", + "OutRootFileName": "", + "SkipNEvents": 0, + "WeightingMethod": "LogMethod", + "ZLayerPhiOffset": 0.0 +} -LumiCalReco = MarlinProcessorWrapper("LumiCalReco") -LumiCalReco.OutputLevel = WARNING -LumiCalReco.ProcessorType = "MarlinLumiCalClusterer" -LumiCalReco.Parameters = { - "ClusterMinNumHits": ["15"], - "ElementsPercentInShowerPeakLayer": ["0.03"], - "EnergyCalibConst": ["0.01213"], - "LogWeigthConstant": ["6.5"], - "LumiCal_Clusters": ["LumiCalClusters"], - "LumiCal_Collection": ["LumiCalCollection"], - "LumiCal_RecoParticles": ["LumiCalRecoParticles"], - "MaxRecordNumber": ["10"], - "MemoryResidentTree": ["0"], - "MiddleEnergyHitBoundFrac": ["0.01"], - "MinClusterEngy": ["2.0"], - "MinHitEnergy": ["20e-06"], - "MoliereRadius": ["20"], - "NumEventsTree": ["500"], - "NumOfNearNeighbor": ["6"], - "OutDirName": ["rootOut"], - "OutRootFileName": [], - "SkipNEvents": ["0"], - "WeightingMethod": ["LogMethod"], - "ZLayerPhiOffset": ["0.0"] - } +if reco_args.native: + # Not used in the algorithm since this is controlled by Gaudi + LumiCalParameters.pop("SkipNEvents") + # Not used, as it is only used in the function removed in https://github.com/FCALSW/FCalClusterer/pull/75 + # that has been removed in the algorithm + LumiCalParameters.pop("ZLayerPhiOffset") + LumiCalReco = GaudiLumiCalClusterer("LumiCalReco", **LumiCalParameters) +else: + from Configurables import MarlinProcessorWrapper + LumiCalReco = MarlinProcessorWrapper("LumiCalReco") + LumiCalReco.OutputLevel = WARNING + LumiCalReco.ProcessorType = "MarlinLumiCalClusterer" + LumiCalReco.Parameters = toMarlinDict(LumiCalParameters) -LumiCalSequence = [ - LumiCalReco, -] +LumiCalSequence = [LumiCalReco] diff --git a/CLDConfig/CaloDigi/MuonDigi.py b/CLDConfig/CaloDigi/MuonDigi.py index 195bc96..2f684eb 100644 --- a/CLDConfig/CaloDigi/MuonDigi.py +++ b/CLDConfig/CaloDigi/MuonDigi.py @@ -16,22 +16,48 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from Configurables import DDSimpleMuonDigi +from Configurables import CollectionMerger from Gaudi.Configuration import WARNING -from Configurables import MarlinProcessorWrapper +from py_utils import toMarlinDict +input_collections = ["YokeBarrelCollection", "YokeEndcapCollection"] +output_collections = ["MuonYokeBarrelCollection", "MuonYokeEndcapCollection"] +output_relation = ["RelationMuonYokeBarrelHit", "RelationMuonYokeEndcapHit"] +names = ["Barrel", "Endcap"] +single_output_collection = "MUON" +single_output_relation = "RelationMuonHit" -MyDDSimpleMuonDigi = MarlinProcessorWrapper("MyDDSimpleMuonDigi") -MyDDSimpleMuonDigi.OutputLevel = WARNING -MyDDSimpleMuonDigi.ProcessorType = "DDSimpleMuonDigi" -MyDDSimpleMuonDigi.Parameters = { - "CalibrMUON": ["70.1"], - "MUONCollections": ["YokeBarrelCollection", "YokeEndcapCollection"], - "MUONOutputCollection": ["MUON"], - "MaxHitEnergyMUON": ["2.0"], - "MuonThreshold": ["1e-06"], - "RelationOutputCollection": ["RelationMuonHit"] - } +MyDDSimpleMuonDigiParameters = { + "CalibrMUON": 70.1, + "MaxHitEnergyMUON": 2.0, + "MuonThreshold": 1e-06, +} -MuonDigiSequence = [ - MyDDSimpleMuonDigi, -] +if reco_args.native: + MuonDigiSequence = [] + for i in range(len(input_collections)): + MyDDSimpleMuonDigi = DDSimpleMuonDigi(f"MyDDSimpleMuonDigi_{names[i]}", + MUONCollection=[input_collections[i]], + MUONOutputCollection=[output_collections[i]], + RelationOutputCollection=[output_relation[i]], + **MyDDSimpleMuonDigiParameters) + MuonDigiSequence.append(MyDDSimpleMuonDigi) + merger = CollectionMerger("MuonCollectionMerger") + merger.InputCollections = output_collections + merger.OutputCollection = [single_output_collection] + + relation_merger = CollectionMerger("MuonRelationMerger") + relation_merger.InputCollections = output_relation + relation_merger.OutputCollection = [single_output_relation] + MuonDigiSequence += [merger, relation_merger] +else: + from Configurables import MarlinProcessorWrapper + MyDDSimpleMuonDigiParameters["MUONCollections"] = input_collections + MyDDSimpleMuonDigiParameters["MUONOutputCollection"] = [single_output_collection] + MyDDSimpleMuonDigiParameters["RelationOutputCollection"] = [single_output_relation] + MyDDSimpleMuonDigi = MarlinProcessorWrapper("MyDDSimpleMuonDigi") + MyDDSimpleMuonDigi.OutputLevel = WARNING + MyDDSimpleMuonDigi.ProcessorType = "DDSimpleMuonDigi" + MyDDSimpleMuonDigi.Parameters = toMarlinDict(MyDDSimpleMuonDigiParameters) + MuonDigiSequence = [MyDDSimpleMuonDigi] diff --git a/CLDConfig/ParticleFlow/Pandora.py b/CLDConfig/ParticleFlow/Pandora.py index 1a4a556..720a7c7 100644 --- a/CLDConfig/ParticleFlow/Pandora.py +++ b/CLDConfig/ParticleFlow/Pandora.py @@ -17,138 +17,151 @@ # limitations under the License. # from Gaudi.Configuration import WARNING -from Configurables import MarlinProcessorWrapper +from Configurables import DDPandoraPFANewAlgorithm +from py_utils import toMarlinDict import sys +# Define Pandora parameters as a python dictionary (not everything is a string) MyDDMarlinPandoraParameters = { - "FinalEnergyDensityBin": ["110."], - "MaxClusterEnergyToApplySoftComp": ["200."], - "TrackCollections": ["SiTracks_Refitted"], - "ECalCaloHitCollections": ["ECALBarrel", "ECALEndcap"], - "HCalCaloHitCollections": ["HCALBarrel", "HCALEndcap", "HCALOther"], - "LCalCaloHitCollections": [], - "LHCalCaloHitCollections": [], - "MuonCaloHitCollections": ["MUON"], - "MCParticleCollections": ["MCParticle"], - "RelCaloHitCollections": ["RelationCaloHit", "RelationMuonHit"], - "RelTrackCollections": ["SiTracks_Refitted_Relation"], - "KinkVertexCollections": [], - "ProngVertexCollections": [], - "SplitVertexCollections": [], - "V0VertexCollections": [], - "ClusterCollectionName": ["PandoraClusters"], - "PFOCollectionName": ["PandoraPFOs"], - "NEventsToSkip": ["0"], - "CreateGaps": ["false"], - "MinBarrelTrackerHitFractionOfExpected": ["0"], - "MinFtdHitsForBarrelTrackerHitFraction": ["0"], - "MinFtdTrackHits": ["0"], - "MinMomentumForTrackHitChecks": ["0"], - "MinTrackECalDistanceFromIp": ["0"], - "MinTrackHits": ["0"], - "ReachesECalBarrelTrackerOuterDistance": ["-100"], - "ReachesECalBarrelTrackerZMaxDistance": ["-50"], - "ReachesECalFtdZMaxDistance": ["1"], - "ReachesECalMinFtdLayer": ["0"], - "ReachesECalNBarrelTrackerHits": ["0"], - "ReachesECalNFtdHits": ["0"], - "UnmatchedVertexTrackMaxEnergy": ["5"], - "UseNonVertexTracks": ["1"], - "UseUnmatchedNonVertexTracks": ["0"], - "UseUnmatchedVertexTracks": ["1"], - "Z0TrackCut": ["200"], - "Z0UnmatchedVertexTrackCut": ["5"], - "ZCutForNonVertexTracks": ["250"], - "MaxTrackHits": ["5000"], - "MaxTrackSigmaPOverP": ["0.15"], - "CurvatureToMomentumFactor": ["0.00015"], - "D0TrackCut": ["200"], - "D0UnmatchedVertexTrackCut": ["5"], - "StartVertexAlgorithmName": ["PandoraPFANew"], - "StartVertexCollectionName": ["PandoraStartVertices"], - "YokeBarrelNormalVector": ["0", "0", "1"], - "HCalBarrelNormalVector": ["0", "0", "1"], - "ECalBarrelNormalVector": ["0", "0", "1"], - "MuonBarrelBField": ["-1.0"], - "MuonEndCapBField": ["0.01"], - "EMConstantTerm": ["0.01"], - "EMStochasticTerm": ["0.17"], - "HadConstantTerm": ["0.03"], - "HadStochasticTerm": ["0.6"], - "InputEnergyCorrectionPoints": [], - "LayersFromEdgeMaxRearDistance": ["250"], - "NOuterSamplingLayers": ["3"], - "TrackStateTolerance": ["0"], - "MaxBarrelTrackerInnerRDistance": ["200"], - "MinCleanCorrectedHitEnergy": ["0.1"], - "MinCleanHitEnergy": ["0.5"], - "MinCleanHitEnergyFraction": ["0.01"], - "MuonHitEnergy": ["0.5"], - "ShouldFormTrackRelationships": ["1"], - "TrackCreatorName": ["DDTrackCreatorCLIC"], - "TrackSystemName": ["DDKalTest"], - "OutputEnergyCorrectionPoints": [], - "UseEcalScLayers": ["0"], - "ECalScMipThreshold": ["0"], - "ECalScToEMGeVCalibration": ["1"], - "ECalScToHadGeVCalibrationBarrel": ["1"], - "ECalScToHadGeVCalibrationEndCap": ["1"], - "ECalScToMipCalibration": ["1"], - "ECalSiMipThreshold": ["0"], - "ECalSiToEMGeVCalibration": ["1"], - "ECalSiToHadGeVCalibrationBarrel": ["1"], - "ECalSiToHadGeVCalibrationEndCap": ["1"], - "ECalSiToMipCalibration": ["1"], - "StripSplittingOn": ["0"], + "FinalEnergyDensityBin": 110.0, + "MaxClusterEnergyToApplySoftComp": 200.0, + "TrackCollections": ["SiTracks_Refitted"], + "ECalCaloHitCollections": ["ECALBarrel", "ECALEndcap"], + "HCalCaloHitCollections": ["HCALBarrel", "HCALEndcap", "HCALOther"], + "LCalCaloHitCollections": [], + "LHCalCaloHitCollections": [], + "MuonCaloHitCollections": ["MUON"], + "MCParticleCollections": ["MCParticles"], + "RelCaloHitCollections": ["RelationCaloHit", "RelationMuonHit"], + # "RelTrackCollections": ["SiTracks_Refitted_Relation"], + "KinkVertexCollections": [], + "ProngVertexCollections": [], + "SplitVertexCollections": [], + "V0VertexCollections": [], + "ClusterCollectionName": ["PandoraClusters"], + "PFOCollectionName": ["PandoraPFOs"], + "NEventsToSkip": 0, + "CreateGaps": False, + "MinBarrelTrackerHitFractionOfExpected": 0, + "MinFtdHitsForBarrelTrackerHitFraction": 0, + "MinFtdTrackHits": 0, + "MinMomentumForTrackHitChecks": 0, + "MinTrackECalDistanceFromIp": 0, + "MinTrackHits": 0, + "ReachesECalBarrelTrackerOuterDistance": -100, + "ReachesECalBarrelTrackerZMaxDistance": -50, + "ReachesECalFtdZMaxDistance": 1, + "ReachesECalMinFtdLayer": 0, + "ReachesECalNBarrelTrackerHits": 0, + "ReachesECalNFtdHits": 0, + "UnmatchedVertexTrackMaxEnergy": 5, + "UseNonVertexTracks": True, + "UseUnmatchedNonVertexTracks": False, + "UseUnmatchedVertexTracks": True, + "Z0TrackCut": 200, + "Z0UnmatchedVertexTrackCut": 5, + "ZCutForNonVertexTracks": 250, + "MaxTrackHits": 5000, + "MaxTrackSigmaPOverP": 0.15, + "CurvatureToMomentumFactor": 0.00015, + "D0TrackCut": 200, + "D0UnmatchedVertexTrackCut": 5, + "StartVertexAlgorithmName": "PandoraPFANew", + "StartVertexCollectionName": ["PandoraStartVertices"], + "YokeBarrelNormalVector": [0, 0, 1], + "HCalBarrelNormalVector": [0, 0, 1], + "ECalBarrelNormalVector": [0, 0, 1], + "MuonBarrelBField": -1.0, + "MuonEndCapBField": 0.01, + "EMConstantTerm": 0.01, + "EMStochasticTerm": 0.17, + "HadConstantTerm": 0.03, + "HadStochasticTerm": 0.6, + "InputEnergyCorrectionPoints": [], + "LayersFromEdgeMaxRearDistance": 250, + "NOuterSamplingLayers": 3, + "TrackStateTolerance": 0, + "MaxBarrelTrackerInnerRDistance": 200, + "MinCleanCorrectedHitEnergy": 0.1, + "MinCleanHitEnergy": 0.5, + "MinCleanHitEnergyFraction": 0.01, + "MuonHitEnergy": 0.5, + "ShouldFormTrackRelationships": True, + "TrackCreatorName": "DDTrackCreatorCLIC", + "TrackSystemName": "DDKalTest", + "OutputEnergyCorrectionPoints": [], + "UseEcalScLayers": False, + "ECalScMipThreshold": 0, + "ECalScToEMGeVCalibration": 1, + "ECalScToHadGeVCalibrationBarrel": 1, + "ECalScToHadGeVCalibrationEndCap": 1, + "ECalScToMipCalibration": 1, + "ECalSiMipThreshold": 0, + "ECalSiToEMGeVCalibration": 1, + "ECalSiToHadGeVCalibrationBarrel": 1, + "ECalSiToHadGeVCalibrationEndCap": 1, + "ECalSiToMipCalibration": 1, + "StripSplittingOn": False, } -MyDDMarlinPandora = MarlinProcessorWrapper(f"MyDDMarlinPandora_{CONFIG['CalorimeterIntegrationTimeWindow']}") -MyDDMarlinPandora.OutputLevel = WARNING -MyDDMarlinPandora.ProcessorType = "DDPandoraPFANewProcessor" -MyDDMarlinPandora.Parameters = MyDDMarlinPandoraParameters.copy() if CONFIG["CalorimeterIntegrationTimeWindow"] == "10ns": - MyDDMarlinPandora.Parameters |= { - "PandoraSettingsXmlFile": ["PandoraSettingsCLD/PandoraSettingsDefault.xml"], - "SoftwareCompensationWeights": ["2.40821", "-0.0515852", "0.000711414", "-0.0254891", "-0.0121505", "-1.63084e-05", "0.062149", "0.0690735", "-0.223064"], - "ECalToMipCalibration": ["175.439"], - "HCalToMipCalibration": ["45.6621"], - "ECalMipThreshold": ["0.5"], - "HCalMipThreshold": ["0.3"], - "ECalToEMGeVCalibration": ["1.01776966108"], - "HCalToEMGeVCalibration": ["1.01776966108"], - "ECalToHadGeVCalibrationBarrel": ["1.11490774181"], - "ECalToHadGeVCalibrationEndCap": ["1.11490774181"], - "HCalToHadGeVCalibration": ["1.00565042407"], - "MuonToMipCalibration": ["20703.9"], - "DigitalMuonHits": ["0"], - "MaxHCalHitHadronicEnergy": ["10000000."], - } + MyDDMarlinPandoraParameters |= { + "PandoraSettingsXmlFile": "PandoraSettingsCLD/PandoraSettingsDefault.xml", + "SoftwareCompensationWeights": [2.40821, -0.0515852, 0.000711414, -0.0254891, -0.0121505, -1.63084e-05, 0.062149, 0.0690735, -0.223064], + "ECalToMipCalibration": 175.439, + "HCalToMipCalibration": 45.6621, + "ECalMipThreshold": 0.5, + "HCalMipThreshold": 0.3, + "ECalToEMGeVCalibration": 1.01776966108, + "HCalToEMGeVCalibration": 1.01776966108, + "ECalToHadGeVCalibrationBarrel": 1.11490774181, + "ECalToHadGeVCalibrationEndCap": 1.11490774181, + "HCalToHadGeVCalibration": 1.00565042407, + "MuonToMipCalibration": 20703.9, + "DigitalMuonHits": 0, + "MaxHCalHitHadronicEnergy": 10000000.0, + } elif CONFIG["CalorimeterIntegrationTimeWindow"] == "400ns": - MyDDMarlinPandora.Parameters |= { - "PandoraSettingsXmlFile": ["PandoraSettingsCLD/PandoraSettingsDefault_400nsCalTimeWindow.xml"], - "SoftwareCompensationWeights": ["2.43375", "-0.0430951", "0.000244914", "-0.145478", "-0.00044577", "-8.37222e-05", "0.237484", "0.243491", "-0.0713701"], - "ECalToMipCalibration": ["175.439"], - "HCalToMipCalibration": ["49.7512"], - "ECalMipThreshold": ["0.5"], - "HCalMipThreshold": ["0.3"], - "ECalToEMGeVCalibration": ["1.02513816926"], - "HCalToEMGeVCalibration": ["1.02513816926"], - "ECalToHadGeVCalibrationBarrel": ["1.07276660331"], - "ECalToHadGeVCalibrationEndCap": ["1.07276660331"], - "HCalToHadGeVCalibration": ["1.01147686143"], - "MuonToMipCalibration": ["20703.9"], - "DigitalMuonHits": ["0"], - "MaxHCalHitHadronicEnergy": ["10000000."], - } + MyDDMarlinPandoraParameters |= { + "PandoraSettingsXmlFile": "PandoraSettingsCLD/PandoraSettingsDefault_400nsCalTimeWindow.xml", + "SoftwareCompensationWeights": [2.43375, -0.0430951, 0.000244914, -0.145478, -0.00044577, -8.37222e-05, 0.237484, 0.243491, -0.0713701], + "ECalToMipCalibration": 175.439, + "HCalToMipCalibration": 49.7512, + "ECalMipThreshold": 0.5, + "HCalMipThreshold": 0.3, + "ECalToEMGeVCalibration": 1.02513816926, + "HCalToEMGeVCalibration": 1.02513816926, + "ECalToHadGeVCalibrationBarrel": 1.07276660331, + "ECalToHadGeVCalibrationEndCap": 1.07276660331, + "HCalToHadGeVCalibration": 1.01147686143, + "MuonToMipCalibration": 20703.9, + "DigitalMuonHits": 0, + "MaxHCalHitHadronicEnergy": 10000000.0, + } else: print(f"The value {CONFIG['CalorimeterIntegrationTimeWindow']} " "for the calorimeter integration time window is not a valid choice") sys.exit(1) +if reco_args.native: + MyDDMarlinPandoraParameters.pop("NEventsToSkip") + MyDDMarlinPandora = DDPandoraPFANewAlgorithm(f"MyDDMarlinPandora_{CONFIG['CalorimeterIntegrationTimeWindow']}", **MyDDMarlinPandoraParameters) +else: + from Configurables import MarlinProcessorWrapper + MyDDMarlinPandoraParameters["MCParticleCollectionName"] = ["MCParticle"] + # These have been changed from int to True/False in the algorithm, so they have to be changed back + for var in ["UseNonVertexTracks", "UseUnmatchedNonVertexTracks", "UseUnmatchedVertexTracks", "ShouldFormTrackRelationships", "UseEcalScLayers", "StripSplittingOn"]: + MyDDMarlinPandoraParameters[var] = int(MyDDMarlinPandoraParameters[var]) + MyDDMarlinPandora = MarlinProcessorWrapper(f"MyDDMarlinPandora_{CONFIG['CalorimeterIntegrationTimeWindow']}") + MyDDMarlinPandora.OutputLevel = WARNING + MyDDMarlinPandora.ProcessorType = "DDPandoraPFANewProcessor" + MyDDMarlinPandora.Parameters = toMarlinDict(MyDDMarlinPandoraParameters) + + PandoraSequence = [MyDDMarlinPandora] diff --git a/CLDConfig/Tracking/ConformalTracking.py b/CLDConfig/Tracking/ConformalTracking.py index b712f7a..9f41329 100644 --- a/CLDConfig/Tracking/ConformalTracking.py +++ b/CLDConfig/Tracking/ConformalTracking.py @@ -17,88 +17,211 @@ # limitations under the License. # from Gaudi.Configuration import WARNING -from Configurables import MarlinProcessorWrapper +from k4FWCore.parseArgs import parser +from conformal_tracking_utils import configure_conformal_tracking_steps +from py_utils import toMarlinDict # geoservice comes from the `global_vars` of the SequenceLoader if any(small_vtx in geoservice.detectors[0] for small_vtx in ["_o2_", "_o3_", "_o4_"]): - CT_MAX_DIST = "0.05;" # semi-colon is important! + CT_MAX_DIST = 0.05 elif "_o1_" in geoservice.detectors[0]: - CT_MAX_DIST = "0.03;" # semi-colon is important! + CT_MAX_DIST = 0.03 else: raise RuntimeError("Unknown detector model to chose CT_MAX_DISTANCE") -MyConformalTracking = MarlinProcessorWrapper("MyConformalTracking") -MyConformalTracking.OutputLevel = WARNING -MyConformalTracking.ProcessorType = "ConformalTrackingV2" -MyConformalTracking.Parameters = { - "DebugHits": ["DebugHits"], - "DebugPlots": ["false"], - "DebugTiming": ["false"], - "MCParticleCollectionName": ["MCParticle"], - "MaxHitInvertedFit": ["0"], - "MinClustersOnTrackAfterFit": ["3"], - "RelationsNames": ["VXDTrackerHitRelations", "VXDEndcapTrackerHitRelations", "InnerTrackerBarrelHitsRelations", "OuterTrackerBarrelHitsRelations", "InnerTrackerEndcapHitsRelations", "OuterTrackerEndcapHitsRelations"], - "RetryTooManyTracks": ["false"], - "SiTrackCollectionName": ["SiTracksCT"], - "SortTreeResults": ["true"], - "Steps": - [ - "[VXDBarrel]", - "@Collections", ":", "VXDTrackerHits", - "@Parameters", ":", "MaxCellAngle", ":", "0.01;", "MaxCellAngleRZ", ":", "0.01;", "Chi2Cut", ":", "100;", "MinClustersOnTrack", ":", "4;", "MaxDistance", ":", CT_MAX_DIST, "SlopeZRange:", "10.0;", "HighPTCut:", "10.0;", - "@Flags", ":", "HighPTFit,", "VertexToTracker", - "@Functions", ":", "CombineCollections,", "BuildNewTracks", - "[VXDEncap]", - "@Collections", ":", "VXDEndcapTrackerHits", - "@Parameters", ":", "MaxCellAngle", ":", "0.01;", "MaxCellAngleRZ", ":", "0.01;", "Chi2Cut", ":", "100;", "MinClustersOnTrack", ":", "4;", "MaxDistance", ":", CT_MAX_DIST, "SlopeZRange:", "10.0;", "HighPTCut:", "10.0;", - "@Flags", ":", "HighPTFit,", "VertexToTracker", - "@Functions", ":", "CombineCollections,", "ExtendTracks", - "[LowerCellAngle1]", - "@Collections", ":", "VXDTrackerHits,", "VXDEndcapTrackerHits", - "@Parameters", ":", "MaxCellAngle", ":", "0.05;", "MaxCellAngleRZ", ":", "0.05;", "Chi2Cut", ":", "100;", "MinClustersOnTrack", ":", "4;", "MaxDistance", ":", CT_MAX_DIST, "SlopeZRange:", "10.0;", "HighPTCut:", "10.0;", - "@Flags", ":", "HighPTFit,", "VertexToTracker,", "RadialSearch", - "@Functions", ":", "CombineCollections,", "BuildNewTracks", - "[LowerCellAngle2]", - "@Collections", ":", - "@Parameters", ":", "MaxCellAngle", ":", "0.1;", "MaxCellAngleRZ", ":", "0.1;", "Chi2Cut", ":", "2000;", "MinClustersOnTrack", ":", "4;", "MaxDistance", ":", CT_MAX_DIST, "SlopeZRange:", "10.0;", "HighPTCut:", "10.0;", - "@Flags", ":", "HighPTFit,", "VertexToTracker,", "RadialSearch", - "@Functions", ":", "BuildNewTracks,", "SortTracks", - "[Tracker]", - "@Collections", ":", "ITrackerHits,", "OTrackerHits,", "ITrackerEndcapHits,", "OTrackerEndcapHits", - "@Parameters", ":", "MaxCellAngle", ":", "0.1;", "MaxCellAngleRZ", ":", "0.1;", "Chi2Cut", ":", "2000;", "MinClustersOnTrack", ":", "4;", "MaxDistance", ":", CT_MAX_DIST, "SlopeZRange:", "10.0;", "HighPTCut:", "1.0;", - "@Flags", ":", "HighPTFit,", "VertexToTracker,", "RadialSearch", - "@Functions", ":", "CombineCollections,", "ExtendTracks", - "[Displaced]", - "@Collections", ":", "VXDTrackerHits,", "VXDEndcapTrackerHits,", "ITrackerHits,", "OTrackerHits,", "ITrackerEndcapHits,", "OTrackerEndcapHits", - "@Parameters", ":", "MaxCellAngle", ":", "0.1;", "MaxCellAngleRZ", ":", "0.1;", "Chi2Cut", ":", "1000;", "MinClustersOnTrack", ":", "5;", "MaxDistance", ":", "0.015;", "SlopeZRange:", "10.0;", "HighPTCut:", "10.0;", - "@Flags", ":", "OnlyZSchi2cut,", "RadialSearch", - "@Functions", ":", "CombineCollections,", "BuildNewTracks" - ], - "ThetaRange": ["0.05"], - "TooManyTracks": ["100000"], - "TrackerHitCollectionNames": ["VXDTrackerHits", "VXDEndcapTrackerHits", "ITrackerHits", "OTrackerHits", "ITrackerEndcapHits", "OTrackerEndcapHits"], - "trackPurity": ["0.7"] - } - -ClonesAndSplitTracksFinder = MarlinProcessorWrapper("ClonesAndSplitTracksFinder") -ClonesAndSplitTracksFinder.OutputLevel = WARNING -ClonesAndSplitTracksFinder.ProcessorType = "ClonesAndSplitTracksFinder" -ClonesAndSplitTracksFinder.Parameters = { - "EnergyLossOn": ["true"], - "InputTrackCollectionName": ["SiTracksCT"], - "MultipleScatteringOn": ["true"], - "OutputTrackCollectionName": ["SiTracks"], - "SmoothOn": ["false"], - "extrapolateForward": ["true"], - "maxSignificancePhi": ["3"], - "maxSignificancePt": ["2"], - "maxSignificanceTheta": ["3"], - "mergeSplitTracks": ["false"], - "minTrackPt": ["1"] - } +args = parser.parse_known_args() + +# The keys are simply a name are not passed to ConformalTracking +parameters = { + "VXDBarrel": { + "collections": ["VXDTrackerHits"], + "params": { + "MaxCellAngle": 0.01, + "MaxCellAngleRZ": 0.01, + "Chi2Cut": 100, + "MinClustersOnTrack": 4, + "MaxDistance": CT_MAX_DIST, + "SlopeZRange": 10.0, + "HighPTCut": 10.0, + }, + "flags": ["HighPTFit", "VertexToTracker"], + "functions": ["CombineCollections", "BuildNewTracks"], + }, + "VXDEncap": { + "collections": ["VXDEndcapTrackerHits"], + "params": { + "MaxCellAngle": 0.01, + "MaxCellAngleRZ": 0.01, + "Chi2Cut": 100, + "MinClustersOnTrack": 4, + "MaxDistance": CT_MAX_DIST, + "SlopeZRange": 10.0, + "HighPTCut": 10.0, + }, + "flags": ["HighPTFit", "VertexToTracker"], + "functions": ["CombineCollections", "ExtendTracks"], + }, + "LowerCellAngle1": { + "collections": ["VXDTrackerHits", "VXDEndcapTrackerHits"], + "params": { + "MaxCellAngle": 0.05, + "MaxCellAngleRZ": 0.05, + "Chi2Cut": 100, + "MinClustersOnTrack": 4, + "MaxDistance": CT_MAX_DIST, + "SlopeZRange": 10.0, + "HighPTCut": 10.0, + }, + "flags": ["HighPTFit", "VertexToTracker", "RadialSearch"], + "functions": ["CombineCollections", "BuildNewTracks"], + }, + "LowerCellAngle2": { + "collections": [], + "params": { + "MaxCellAngle": 0.1, + "MaxCellAngleRZ": 0.1, + "Chi2Cut": 2000, + "MinClustersOnTrack": 4, + "MaxDistance": CT_MAX_DIST, + "SlopeZRange": 10.0, + "HighPTCut": 10.0, + }, + "flags": ["HighPTFit", "VertexToTracker", "RadialSearch"], + "functions": ["BuildNewTracks", "SortTracks"], + }, + "Tracker": { + "collections": ["ITrackerHits", "OTrackerHits", "ITrackerEndcapHits", "OTrackerEndcapHits"], + "params": { + "MaxCellAngle": 0.1, + "MaxCellAngleRZ": 0.1, + "Chi2Cut": 2000, + "MinClustersOnTrack": 4, + "MaxDistance": CT_MAX_DIST, + "SlopeZRange": 10.0, + "HighPTCut": 1.0, + }, + "flags": ["HighPTFit", "VertexToTracker", "RadialSearch"], + "functions": ["CombineCollections", "ExtendTracks"], + }, + "Displaced": { + "collections": ["VXDTrackerHits", "VXDEndcapTrackerHits", "ITrackerHits", "OTrackerHits", "ITrackerEndcapHits", "OTrackerEndcapHits"], + "params": { + "MaxCellAngle": 0.1, + "MaxCellAngleRZ": 0.1, + "Chi2Cut": 1000, + "MinClustersOnTrack": 5, + "MaxDistance": 0.015, + "SlopeZRange": 10.0, + "HighPTCut": 10.0, + }, + "flags": ["OnlyZSchi2cut", "RadialSearch"], + "functions": ["CombineCollections", "BuildNewTracks"], + }, + } + +steps_marlin = [] + +for name, param_dict in parameters.items(): + marlin_collections = [] + for i in range(len(param_dict["collections"])): + marlin_collections.append(f"{param_dict['collections'][i]}") + if i < len(param_dict["collections"]) - 1: + marlin_collections[-1] += "," + marlin_parameters = [] + for i, (k, v) in enumerate(param_dict["params"].items()): + marlin_parameters.extend([k, ":", f"{v};"]) + + marlin_flags = [] + for i in range(len(param_dict["flags"])): + marlin_flags.append(f"{param_dict['flags'][i]}") + if i < len(param_dict["flags"]) - 1: + marlin_flags[-1] += "," + marlin_functions = [] + for i in range(len(param_dict["functions"])): + marlin_functions.append(f"{param_dict['functions'][i]}") + if i < len(param_dict["functions"]) - 1: + marlin_functions[-1] += "," + current_step = [ + f"[{name}]", + "@Collections", ":", *marlin_collections, + "@Parameters", ":", *marlin_parameters, + "@Flags", ":", *marlin_flags, + "@Functions", ":", *marlin_functions, + ] + steps_marlin.extend(current_step) + +conformal_tracking_args = { + "DebugHits": ["DebugHits"], + "DebugPlots": False, + "DebugTiming": False, + "MCParticleCollectionName": ["MCParticles"], + "MaxHitInvertedFit": 0, + "MinClustersOnTrackAfterFit": 3, + "RelationsNames": ["VXDTrackerHitRelations", "VXDEndcapTrackerHitRelations", "InnerTrackerBarrelHitsRelations", "OuterTrackerBarrelHitsRelations", "InnerTrackerEndcapHitsRelations", "OuterTrackerEndcapHitsRelations"], + "RetryTooManyTracks": False, + "SiTrackCollectionName": "SiTracksCT", + "SortTreeResults": True, + "ThetaRange": 0.05, + "TooManyTracks": 100000, + "TrackerHitCollectionNames": ["VXDTrackerHits", "VXDEndcapTrackerHits", "ITrackerHits", "OTrackerHits", "ITrackerEndcapHits", "OTrackerEndcapHits"], + "trackPurity": 0.7 +} + +conformal_tracking_args_marlin = toMarlinDict(conformal_tracking_args) +conformal_tracking_args_marlin["MCParticleCollectionName"] = ["MCParticle"] + +if args[0].native: + # Not implemented in Gaudi + conformal_tracking_args.pop("DebugHits") +else: + conformal_tracking_args_marlin["Steps"] = steps_marlin + +clones_and_split_tracks_finder_args = { + "EnergyLossOn": True, + "InputTrackCollectionName": "SiTracksCT", + "MultipleScatteringOn": True, + "OutputTrackCollectionName": "SiTracks", + "SmoothOn": False, + "extrapolateForward": True, + "maxSignificancePhi": 3., + "maxSignificancePt": 2., + "maxSignificanceTheta": 3., + "mergeSplitTracks": False, + "minTrackPt": 1., +} + +clone_and_split_tracks_finder_args_marlin = toMarlinDict(clones_and_split_tracks_finder_args) + +if args[0].native: + from Configurables import ConformalTracking, ClonesAndSplitTracksFinder + + MyConformalTracking = ConformalTracking( + "ConformalTracking", + **conformal_tracking_args, + OutputLevel=WARNING, + ) + configure_conformal_tracking_steps(MyConformalTracking, parameters) + + clones_and_split_tracks_finder = ClonesAndSplitTracksFinder( + "ClonesAndSplitTracksFinder", + **clones_and_split_tracks_finder_args, + OutputLevel=WARNING, + ) + +else: + from Configurables import MarlinProcessorWrapper + MyConformalTracking = MarlinProcessorWrapper("MyConformalTracking") + MyConformalTracking.OutputLevel = WARNING + MyConformalTracking.ProcessorType = "ConformalTrackingV2" + MyConformalTracking.Parameters = conformal_tracking_args_marlin + + clones_and_split_tracks_finder = MarlinProcessorWrapper("ClonesAndSplitTracksFinder") + clones_and_split_tracks_finder.OutputLevel = WARNING + clones_and_split_tracks_finder.ProcessorType = "ClonesAndSplitTracksFinder" + clones_and_split_tracks_finder.Parameters = clone_and_split_tracks_finder_args_marlin ConformalTrackingSequence = [ MyConformalTracking, - ClonesAndSplitTracksFinder, + clones_and_split_tracks_finder, ] diff --git a/CLDConfig/Tracking/Refit.py b/CLDConfig/Tracking/Refit.py index f50da2d..0e5f462 100644 --- a/CLDConfig/Tracking/Refit.py +++ b/CLDConfig/Tracking/Refit.py @@ -17,25 +17,44 @@ # limitations under the License. # from Gaudi.Configuration import WARNING -from Configurables import MarlinProcessorWrapper +from k4FWCore.parseArgs import parser +from py_utils import toMarlinDict +args = parser.parse_known_args() +refit_args = { + "EnergyLossOn": True, + "InputTrackCollectionName": "SiTracks", + "InputRelationCollectionName": ["SiTrackRelations"], + "Max_Chi2_Incr": 1.79769e30, + "MinClustersOnTrackAfterFit": 3, + "MultipleScatteringOn": True, + "OutputRelationCollectionName": "SiTracks_Refitted_Relation", + "OutputTrackCollectionName": "SiTracks_Refitted", + "ReferencePoint": -1, + "SmoothOn": False, + "extrapolateForward": True, +} -Refit = MarlinProcessorWrapper("Refit") -Refit.OutputLevel = WARNING -Refit.ProcessorType = "RefitFinal" -Refit.Parameters = { - "EnergyLossOn": ["true"], - "InputRelationCollectionName": ["SiTrackRelations"], - "InputTrackCollectionName": ["SiTracks"], - "Max_Chi2_Incr": ["1.79769e+30"], - "MinClustersOnTrackAfterFit": ["3"], - "MultipleScatteringOn": ["true"], - "OutputRelationCollectionName": ["SiTracks_Refitted_Relation"], - "OutputTrackCollectionName": ["SiTracks_Refitted"], - "ReferencePoint": ["-1"], - "SmoothOn": ["false"], - "extrapolateForward": ["true"] - } +if args[0].native and not args[0].truthTracking: + refit_args["InputRelationCollectionName"] = [] + +refit_args_marlin = toMarlinDict(refit_args) + +if args[0].native: + from Configurables import RefitFinal + + Refit = RefitFinal( + "RefitFinal", + **refit_args, + OutputLevel=WARNING, + ) +else: + from Configurables import MarlinProcessorWrapper + + Refit = MarlinProcessorWrapper("Refit") + Refit.OutputLevel = WARNING + Refit.ProcessorType = "RefitFinal" + Refit.Parameters = refit_args_marlin RefitSequence = [ Refit, diff --git a/CLDConfig/Tracking/TrackingDigi.py b/CLDConfig/Tracking/TrackingDigi.py index 5d352ea..b936f1c 100644 --- a/CLDConfig/Tracking/TrackingDigi.py +++ b/CLDConfig/Tracking/TrackingDigi.py @@ -17,86 +17,161 @@ # limitations under the License. # from Gaudi.Configuration import WARNING -from Configurables import MarlinProcessorWrapper - - -VXDBarrelDigitiser = MarlinProcessorWrapper("VXDBarrelDigitiser") -VXDBarrelDigitiser.OutputLevel = WARNING -VXDBarrelDigitiser.ProcessorType = "DDPlanarDigiProcessor" -VXDBarrelDigitiser.Parameters = { - "IsStrip": ["false"], - "ResolutionU": ["0.003", "0.003", "0.003", "0.003", "0.003", "0.003"], - "ResolutionV": ["0.003", "0.003", "0.003", "0.003", "0.003", "0.003"], - "SimTrackHitCollectionName": ["VertexBarrelCollection"], - "SimTrkHitRelCollection": ["VXDTrackerHitRelations"], - "SubDetectorName": ["Vertex"], - "TrackerHitCollectionName": ["VXDTrackerHits"] - } - -VXDEndcapDigitiser = MarlinProcessorWrapper("VXDEndcapDigitiser") -VXDEndcapDigitiser.OutputLevel = WARNING -VXDEndcapDigitiser.ProcessorType = "DDPlanarDigiProcessor" -VXDEndcapDigitiser.Parameters = { - "IsStrip": ["false"], - "ResolutionU": ["0.003", "0.003", "0.003", "0.003", "0.003", "0.003"], - "ResolutionV": ["0.003", "0.003", "0.003", "0.003", "0.003", "0.003"], - "SimTrackHitCollectionName": ["VertexEndcapCollection"], - "SimTrkHitRelCollection": ["VXDEndcapTrackerHitRelations"], - "SubDetectorName": ["Vertex"], - "TrackerHitCollectionName": ["VXDEndcapTrackerHits"] - } - -InnerPlanarDigiProcessor = MarlinProcessorWrapper("InnerPlanarDigiProcessor") -InnerPlanarDigiProcessor.OutputLevel = WARNING -InnerPlanarDigiProcessor.ProcessorType = "DDPlanarDigiProcessor" -InnerPlanarDigiProcessor.Parameters = { - "IsStrip": ["false"], - "ResolutionU": ["0.007"], - "ResolutionV": ["0.09"], - "SimTrackHitCollectionName": ["InnerTrackerBarrelCollection"], - "SimTrkHitRelCollection": ["InnerTrackerBarrelHitsRelations"], - "SubDetectorName": ["InnerTrackers"], - "TrackerHitCollectionName": ["ITrackerHits"] - } - -InnerEndcapPlanarDigiProcessor = MarlinProcessorWrapper("InnerEndcapPlanarDigiProcessor") -InnerEndcapPlanarDigiProcessor.OutputLevel = WARNING -InnerEndcapPlanarDigiProcessor.ProcessorType = "DDPlanarDigiProcessor" -InnerEndcapPlanarDigiProcessor.Parameters = { - "IsStrip": ["false"], - "ResolutionU": ["0.005", "0.007", "0.007", "0.007", "0.007", "0.007", "0.007"], - "ResolutionV": ["0.005", "0.09", "0.09", "0.09", "0.09", "0.09", "0.09"], - "SimTrackHitCollectionName": ["InnerTrackerEndcapCollection"], - "SimTrkHitRelCollection": ["InnerTrackerEndcapHitsRelations"], - "SubDetectorName": ["InnerTrackers"], - "TrackerHitCollectionName": ["ITrackerEndcapHits"] - } - -OuterPlanarDigiProcessor = MarlinProcessorWrapper("OuterPlanarDigiProcessor") -OuterPlanarDigiProcessor.OutputLevel = WARNING -OuterPlanarDigiProcessor.ProcessorType = "DDPlanarDigiProcessor" -OuterPlanarDigiProcessor.Parameters = { - "IsStrip": ["false"], - "ResolutionU": ["0.007", "0.007", "0.007"], - "ResolutionV": ["0.09", "0.09", "0.09"], - "SimTrackHitCollectionName": ["OuterTrackerBarrelCollection"], - "SimTrkHitRelCollection": ["OuterTrackerBarrelHitsRelations"], - "SubDetectorName": ["OuterTrackers"], - "TrackerHitCollectionName": ["OTrackerHits"] - } - -OuterEndcapPlanarDigiProcessor = MarlinProcessorWrapper("OuterEndcapPlanarDigiProcessor") -OuterEndcapPlanarDigiProcessor.OutputLevel = WARNING -OuterEndcapPlanarDigiProcessor.ProcessorType = "DDPlanarDigiProcessor" -OuterEndcapPlanarDigiProcessor.Parameters = { - "IsStrip": ["false"], - "ResolutionU": ["0.007", "0.007", "0.007", "0.007", "0.007"], - "ResolutionV": ["0.09", "0.09", "0.09", "0.09", "0.09"], - "SimTrackHitCollectionName": ["OuterTrackerEndcapCollection"], - "SimTrkHitRelCollection": ["OuterTrackerEndcapHitsRelations"], - "SubDetectorName": ["OuterTrackers"], - "TrackerHitCollectionName": ["OTrackerEndcapHits"] - } +from k4FWCore.parseArgs import parser +from py_utils import toMarlinDict +args = parser.parse_known_args() + +vxd_barrel_digitiser_args = { + "IsStrip": False, + "ResolutionU": [0.003, 0.003, 0.003, 0.003, 0.003, 0.003], + "ResolutionV": [0.003, 0.003, 0.003, 0.003, 0.003, 0.003], + "SimTrackHitCollectionName": ["VertexBarrelCollection"], + "SimTrkHitRelCollection": ["VXDTrackerHitRelations"], + "SubDetectorName": "Vertex", + "TrackerHitCollectionName": ["VXDTrackerHits"], +} + +vxd_endcap_digitiser_args = { + "IsStrip": False, + "ResolutionU": [0.003, 0.003, 0.003, 0.003, 0.003, 0.003], + "ResolutionV": [0.003, 0.003, 0.003, 0.003, 0.003, 0.003], + "SimTrackHitCollectionName": ["VertexEndcapCollection"], + "SimTrkHitRelCollection": ["VXDEndcapTrackerHitRelations"], + "SubDetectorName": "Vertex", + "TrackerHitCollectionName": ["VXDEndcapTrackerHits"], +} + +inner_planar_digi_processor_args = { + "IsStrip": False, + "ResolutionU": [0.007], + "ResolutionV": [0.09], + "SimTrackHitCollectionName": ["InnerTrackerBarrelCollection"], + "SimTrkHitRelCollection": ["InnerTrackerBarrelHitsRelations"], + "SubDetectorName": "InnerTrackers", + "TrackerHitCollectionName": ["ITrackerHits"], +} + +inner_endcap_planar_digi_processor_args = { + "IsStrip": False, + "ResolutionU": [0.005, 0.007, 0.007, 0.007, 0.007, 0.007, 0.007], + "ResolutionV": [0.005, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09], + "SimTrackHitCollectionName": ["InnerTrackerEndcapCollection"], + "SimTrkHitRelCollection": ["InnerTrackerEndcapHitsRelations"], + "SubDetectorName": "InnerTrackers", + "TrackerHitCollectionName": ["ITrackerEndcapHits"], +} + +outer_planar_digi_processor_args = { + "IsStrip": False, + "ResolutionU": [0.007, 0.007, 0.007], + "ResolutionV": [0.09, 0.09, 0.09], + "SimTrackHitCollectionName": ["OuterTrackerBarrelCollection"], + "SimTrkHitRelCollection": ["OuterTrackerBarrelHitsRelations"], + "SubDetectorName": "OuterTrackers", + "TrackerHitCollectionName": ["OTrackerHits"], +} + +outer_endcap_planar_digi_processor_args = { + "IsStrip": False, + "ResolutionU": [0.007, 0.007, 0.007, 0.007, 0.007], + "ResolutionV": [0.09, 0.09, 0.09, 0.09, 0.09], + "SimTrackHitCollectionName": ["OuterTrackerEndcapCollection"], + "SimTrkHitRelCollection": ["OuterTrackerEndcapHitsRelations"], + "SubDetectorName": "OuterTrackers", + "TrackerHitCollectionName": ["OTrackerEndcapHits"], +} + + +vxd_barrel_digitiser_args_marlin = toMarlinDict(vxd_barrel_digitiser_args) +vxd_barrel_digitiser_args_marlin["SubDetectorName"] = [vxd_barrel_digitiser_args["SubDetectorName"]] + +vxd_endcap_digitiser_args_marlin = toMarlinDict(vxd_endcap_digitiser_args) +vxd_endcap_digitiser_args_marlin["SubDetectorName"] = [vxd_endcap_digitiser_args["SubDetectorName"]] + +inner_planar_digi_processor_args_marlin = toMarlinDict(inner_planar_digi_processor_args) +inner_planar_digi_processor_args_marlin["SubDetectorName"] = [inner_planar_digi_processor_args["SubDetectorName"]] + +inner_endcap_planar_digi_processor_args_marlin = toMarlinDict(inner_endcap_planar_digi_processor_args) +inner_endcap_planar_digi_processor_args_marlin["SubDetectorName"] = [inner_endcap_planar_digi_processor_args["SubDetectorName"]] + +outer_planar_digi_processor_args_marlin = toMarlinDict(outer_planar_digi_processor_args) +outer_planar_digi_processor_args_marlin["SubDetectorName"] = [outer_planar_digi_processor_args["SubDetectorName"]] + +outer_endcap_planar_digi_processor_args_marlin = toMarlinDict(outer_endcap_planar_digi_processor_args) +outer_endcap_planar_digi_processor_args_marlin["SubDetectorName"] = [outer_endcap_planar_digi_processor_args["SubDetectorName"]] + + +if args[0].native: + from Configurables import DDPlanarDigi + + VXDBarrelDigitiser = DDPlanarDigi( + "VXDBarrelDigitiser", + **vxd_barrel_digitiser_args, + OutputLevel=WARNING + ) + VXDEndcapDigitiser = DDPlanarDigi( + "VXDEndcapDigitiser", + **vxd_endcap_digitiser_args, + OutputLevel=WARNING + ) + InnerPlanarDigiProcessor = DDPlanarDigi( + "InnerPlanarDigiProcessor", + **inner_planar_digi_processor_args, + OutputLevel=WARNING + ) + InnerEndcapPlanarDigiProcessor = DDPlanarDigi( + "InnerEndcapPlanarDigiProcessor", + **inner_endcap_planar_digi_processor_args, + OutputLevel=WARNING + ) + OuterPlanarDigiProcessor = DDPlanarDigi( + "OuterPlanarDigiProcessor", + **outer_planar_digi_processor_args, + OutputLevel=WARNING + ) + + OuterEndcapPlanarDigiProcessor = DDPlanarDigi( + "OuterEndcapPlanarDigiProcessor", + **outer_endcap_planar_digi_processor_args, + OutputLevel=WARNING + ) + +else: + from Configurables import MarlinProcessorWrapper + + VXDBarrelDigitiser = MarlinProcessorWrapper("VXDBarrelDigitiser") + VXDBarrelDigitiser.OutputLevel = WARNING + VXDBarrelDigitiser.ProcessorType = "DDPlanarDigiProcessor" + VXDBarrelDigitiser.Parameters = vxd_barrel_digitiser_args_marlin + + VXDEndcapDigitiser = MarlinProcessorWrapper("VXDEndcapDigitiser") + VXDEndcapDigitiser.OutputLevel = WARNING + VXDEndcapDigitiser.ProcessorType = "DDPlanarDigiProcessor" + VXDEndcapDigitiser.Parameters = vxd_endcap_digitiser_args_marlin + + InnerPlanarDigiProcessor = MarlinProcessorWrapper("InnerPlanarDigiProcessor") + InnerPlanarDigiProcessor.OutputLevel = WARNING + InnerPlanarDigiProcessor.ProcessorType = "DDPlanarDigiProcessor" + InnerPlanarDigiProcessor.Parameters = inner_planar_digi_processor_args_marlin + + InnerEndcapPlanarDigiProcessor = MarlinProcessorWrapper( + "InnerEndcapPlanarDigiProcessor" + ) + InnerEndcapPlanarDigiProcessor.OutputLevel = WARNING + InnerEndcapPlanarDigiProcessor.ProcessorType = "DDPlanarDigiProcessor" + InnerEndcapPlanarDigiProcessor.Parameters = inner_endcap_planar_digi_processor_args_marlin + + OuterPlanarDigiProcessor = MarlinProcessorWrapper("OuterPlanarDigiProcessor") + OuterPlanarDigiProcessor.OutputLevel = WARNING + OuterPlanarDigiProcessor.ProcessorType = "DDPlanarDigiProcessor" + OuterPlanarDigiProcessor.Parameters = outer_planar_digi_processor_args_marlin + + OuterEndcapPlanarDigiProcessor = MarlinProcessorWrapper( + "OuterEndcapPlanarDigiProcessor" + ) + OuterEndcapPlanarDigiProcessor.OutputLevel = WARNING + OuterEndcapPlanarDigiProcessor.ProcessorType = "DDPlanarDigiProcessor" + OuterEndcapPlanarDigiProcessor.Parameters = outer_endcap_planar_digi_processor_args_marlin TrackingDigiSequence = [ VXDBarrelDigitiser, diff --git a/CLDConfig/Tracking/TruthTracking.py b/CLDConfig/Tracking/TruthTracking.py index 3907067..a3c2c35 100644 --- a/CLDConfig/Tracking/TruthTracking.py +++ b/CLDConfig/Tracking/TruthTracking.py @@ -17,21 +17,37 @@ # limitations under the License. # from Gaudi.Configuration import WARNING -from Configurables import MarlinProcessorWrapper +from k4FWCore.parseArgs import parser +from py_utils import toMarlinDict +args = parser.parse_known_args() +truth_track_finder_args = { + "FitForward": True, + "MCParticleCollectionName": ["MCParticles"], + "SiTrackCollectionName": ["SiTracks"], + "SiTrackRelationCollectionName": ["SiTrackRelations"], + "SimTrackerHitRelCollectionNames": ["VXDTrackerHitRelations", "InnerTrackerBarrelHitsRelations", "OuterTrackerBarrelHitsRelations", "VXDEndcapTrackerHitRelations", "InnerTrackerEndcapHitsRelations", "OuterTrackerEndcapHitsRelations"], + "TrackerHitCollectionNames": ["VXDTrackerHits", "ITrackerHits", "OTrackerHits", "VXDEndcapTrackerHits", "ITrackerEndcapHits", "OTrackerEndcapHits"], + "UseTruthInPrefit": False, +} +truth_track_finder_args_marlin = toMarlinDict(truth_track_finder_args) +truth_track_finder_args_marlin["MCParticleCollectionName"] = ["MCParticle"] -MyTruthTrackFinder = MarlinProcessorWrapper("MyTruthTrackFinder") -MyTruthTrackFinder.OutputLevel = WARNING -MyTruthTrackFinder.ProcessorType = "TruthTrackFinder" -MyTruthTrackFinder.Parameters = { - "FitForward": ["true"], - "MCParticleCollectionName": ["MCParticle"], - "SiTrackCollectionName": ["SiTracks"], - "SiTrackRelationCollectionName": ["SiTrackRelations"], - "SimTrackerHitRelCollectionNames": ["VXDTrackerHitRelations", "InnerTrackerBarrelHitsRelations", "OuterTrackerBarrelHitsRelations", "VXDEndcapTrackerHitRelations", "InnerTrackerEndcapHitsRelations", "OuterTrackerEndcapHitsRelations"], - "TrackerHitCollectionNames": ["VXDTrackerHits", "ITrackerHits", "OTrackerHits", "VXDEndcapTrackerHits", "ITrackerEndcapHits", "OTrackerEndcapHits"], - "UseTruthInPrefit": ["false"] - } +if args[0].native: + from Configurables import TruthTrackFinder + MyTruthTrackFinder = TruthTrackFinder( + "TruthTrackFinder", + **truth_track_finder_args, + OutputLevel=WARNING, + ) + +else: + from Configurables import MarlinProcessorWrapper + + MyTruthTrackFinder = MarlinProcessorWrapper("MyTruthTrackFinder") + MyTruthTrackFinder.OutputLevel = WARNING + MyTruthTrackFinder.ProcessorType = "TruthTrackFinder" + MyTruthTrackFinder.Parameters = truth_track_finder_args_marlin TruthTrackingSequence = [ MyTruthTrackFinder, diff --git a/CLDConfig/py_utils.py b/CLDConfig/py_utils.py index 1b2143a..cbd3093 100644 --- a/CLDConfig/py_utils.py +++ b/CLDConfig/py_utils.py @@ -228,3 +228,16 @@ def parse_collection_patch_file(patch_file: Union[str, os.PathLike]) -> List[str # Flatten the list of lists into one large list return [s for strings in patch_colls for s in strings] + + +def toMarlinDict(dict: Dict[str, Any]) -> Dict[str, Any]: + """Convert a dictionary to a Marlin-compatible format. + + Args: + dict (Dict[str, Any]): The dictionary to convert. + + Returns: + Dict[str, Any]: The converted dictionary. + """ + + return {k: [str(v).lower()] if isinstance(v, bool) else [str(elem) for elem in v] if isinstance(v, list) else [str(v)] if isinstance(v, float) or isinstance(v, int) else [v] if isinstance(v, str) else v for k, v in dict.items()} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1d77134..c17ec5d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -88,3 +88,27 @@ add_test(NAME marlin COMMAND Marlin --global.LCIOInputFiles=test.slcio --InitDD4hep.DD4hepXMLFile=${DETECTOR} CLDReconstruction.xml ) set_property(TEST marlin APPEND PROPERTY DEPENDS ddsim_lcio) + +add_test(NAME "remove_overlay_and_others" + WORKING_DIRECTORY ${CLDConfig_DIR} + COMMAND bash -c "sed -e '/Overlay.Overlay/d' -e '/HighLevelReco.RecoMCTruthLink/d' CLDReconstruction.py > CLDReconstruction_no_overlay.py" +) + +add_test(NAME edm4hep_input_no_overlay + WORKING_DIRECTORY ${CLDConfig_DIR} + COMMAND k4run --inputFiles=test.edm4hep.root --outputBasename=rec_test_edm4hep_no_overlay CLDReconstruction_no_overlay.py --GeoSvc.detectors=${DETECTOR} +) +set_property(TEST edm4hep_input_no_overlay APPEND PROPERTY DEPENDS "ddsim_edm4hep;remove_overlay_and_others") + + +add_test(NAME "run_wrapper_native" + WORKING_DIRECTORY ${CLDConfig_DIR} + COMMAND k4run CLDReconstruction.py --inputFiles test.edm4hep.root --native --outputBasename output_native +) +set_property(TEST "run_wrapper_native" APPEND PROPERTY DEPENDS "ddsim_edm4hep") + +add_test(NAME "compare_native" + WORKING_DIRECTORY ${CLDConfig_DIR} + COMMAND ${CMAKE_CURRENT_LIST_DIR}/scripts/compare-native.py --wrapped-file rec_test_edm4hep_no_overlay_REC.edm4hep.root --native-file output_native_REC.edm4hep.root +) +set_property(TEST compare_native APPEND PROPERTY DEPENDS "run_wrapper_native") diff --git a/test/scripts/compare-native.py b/test/scripts/compare-native.py new file mode 100755 index 0000000..41a9b13 --- /dev/null +++ b/test/scripts/compare-native.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +# A simple script to compare collections between the native and wrapped Marlin reconstruction output +import argparse +from podio.reading import get_reader + +parser = argparse.ArgumentParser(description="Compare hits from Gaudi and Marlin") +parser.add_argument( + "--native-file", default="output_native_REC.edm4hep.root", help="Gaudi native output file" +) +parser.add_argument( + "--wrapped-file", default="output_REC.edm4hep.root", help="Wrapped output file" +) + +args = parser.parse_args() + +reader_native = get_reader(args.native_file) +reader_wrapped = get_reader(args.wrapped_file) + +events_native = reader_native.get("events") +events_wrapped = reader_wrapped.get("events") + +EXPECTED_MISSING = set([]) +EXPECTED_EXTRA = set([]) + +for i, frame_native in enumerate(events_native): + frame_wrapped = events_wrapped[i] + collections_native = set(frame_native.getAvailableCollections()) + collections_wrapped = set(frame_wrapped.getAvailableCollections()) + extra = collections_native - collections_wrapped + missing = collections_wrapped - collections_native + common = collections_native & collections_wrapped + if missing: + print(f"Event {i}: Missing collections in native: {missing}") + if not missing.issubset(EXPECTED_MISSING): + print("Unexpected missing collections found!") + if extra: + print(f"Event {i}: Extra collections in native: {extra}") + if not extra.issubset(EXPECTED_EXTRA): + print("Unexpected extra collections found!") + are_sizes_different = False + for coll in common: + data_native = frame_native.get(coll) + data_wrapped = frame_wrapped.get(coll) + if len(data_native) != len(data_wrapped): + print(f"Event {i}: Collection '{coll}' has different lengths: " + f"{len(data_native)} in native, {len(data_wrapped)} in wrapped.") + are_sizes_different = True + if missing or extra: + raise ValueError("Collections do not match between Gaudi and wrapped Marlin output.") +