From 61646f7101da7993f7034077ef44c9ae330e4c43 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Mon, 31 Mar 2025 15:14:35 +0100 Subject: [PATCH 01/14] rich_reconstruction: Add flags to enable 4D reconstruction --- .../python/RecoConf/rich_reconstruction.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py index a2eddf3a5bf..9663d6075cc 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py @@ -117,6 +117,8 @@ def default_rich_reco_options(init_override_opts={}): ], # The RICH radiators to use "RichGases": ["Rich1Gas", "Rich2Gas"], + # enable 4D reco in each radiator + "Enable4DReco": (False, False), # Maximum number of clusters GEC cut "MaxPixelClusters": 200000, # Maximum number of tracks GEC cut @@ -135,6 +137,10 @@ def default_rich_reco_options(init_override_opts={}): "ApplyPixelClustering": (False, False), # Activate pixels in specific panels in each RICH only. "ActivatePanel": (True, True), + # Average hit time expected in each RICH (for 4D reco) + "averageHitTime": (13.03, 52.94), + # Course time window for hit selection (in ns) (for 4D reco) + "pixelTimeWindow": (1.0, 1.0), # =========================================================== # Track treatment options # =========================================================== @@ -174,6 +180,9 @@ def default_rich_reco_options(init_override_opts={}): "MinMaxTrackROICuts": defaultMinMaxTrackROICuts(), # Min Photon Probability cuts "MinPhotonProbabilityCuts": defaultMinPhotonProbabilityCuts(), + # Timing window for photon reconstruction (in ns) for (inner,outer) regions + # Only used if 4D reconstruction is active + "photonTimeWindow": ((0.25, 0.25), (0.25, 0.25)), # =========================================================== # Settings for the global PID minimisation # =========================================================== @@ -299,6 +308,10 @@ def make_rich_pixels(options, make_raw=default_raw_banks): MaxClusters=options["MaxPixelClusters"], DecodedDataLocation=richDecode.DecodedDataLocation, Detectors=det_opts, + # 4D reco + Enable4D=options["Enable4DReco"], + AvHitTime=options["averageHitTime"], + TimeWindow=options["pixelTimeWindow"], ) results["RichClusters"] = richClus.RichPixelClustersLocation @@ -307,6 +320,12 @@ def make_rich_pixels(options, make_raw=default_raw_banks): name="RichSIMDPixels_{hash}", NoClustering=(not doClus[0] and not doClus[1]), RichPixelClustersLocation=richClus.RichPixelClustersLocation, + # 4D reco + Enable4D=options["Enable4DReco"], + AvHitTime=options["averageHitTime"], + CourseTimeWindow=options["pixelTimeWindow"], + InnerFineTimeWindow=options["photonTimeWindow"][0], + OuterFineTimeWindow=options["photonTimeWindow"][1], ) results["RichSIMDPixels"] = simdPixels.RichSIMDPixelSummariesLocation @@ -564,6 +583,8 @@ def make_rich_photons(track_name, input_tracks, options, make_raw=default_raw_ba RichSIMDPixelSummariesLocation=pixel_conf["RichSIMDPixels"], RejectAmbiguousPhotons=options["RejectAmbiguousPhotons"], SaveMirrorData=options["SaveMirrorData"], + # 4D reco + Enable4D=options["Enable4DReco"], ) results["CherenkovPhotons"] = photReco.CherenkovPhotonLocation results["PhotonToParents"] = photReco.PhotonToParentsLocation @@ -581,6 +602,8 @@ def make_rich_photons(track_name, input_tracks, options, make_raw=default_raw_ba CherenkovAnglesLocation=track_conf["SignalCKAngles"], CherenkovResolutionsLocation=track_conf["CherenkovResolutions"], PhotonYieldLocation=track_conf["DetectableYields"], + # 4D reco + Enable4D=options["Enable4DReco"], ) results["PhotonSignals"] = photPredSig.PhotonSignalsLocation @@ -691,6 +714,8 @@ def make_rich_pids( GeomEffsPerPDLocation=track_conf["GeomEffsPerPD"], DetectablePhotonYieldLocation=track_conf["DetectableYields"], RichSIMDPixelSummariesLocation=pixel_conf["RichSIMDPixels"], + # 4D Reco + Enable4D=options["Enable4DReco"], ) # Likelihood minimiser -- GitLab From 62dbe0e7d06339b205c235c6ca905af86f30318e Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 1 Apr 2025 15:03:21 +0100 Subject: [PATCH 02/14] rich_reconstruction.py: Break up configurables into smaller units --- .../python/RecoConf/rich_reconstruction.py | 519 +++++++++++++----- 1 file changed, 383 insertions(+), 136 deletions(-) diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py index 9663d6075cc..7ed1b412e38 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py @@ -264,9 +264,9 @@ def shortTrackType(track_name): @configurable -def make_rich_pixels(options, make_raw=default_raw_banks): +def decode_rich_raw(options, make_raw=default_raw_banks): """ - Return pixel specific RICH data. + Configures the RICH raw bank decoding Args: options (dict): The processing options to use @@ -276,9 +276,6 @@ def make_rich_pixels(options, make_raw=default_raw_banks): dict of useful data locations. """ - # Configure the particle properties - configure_rich_particle_properties(options) - # The conf dict to return results = {} @@ -292,40 +289,89 @@ def make_rich_pixels(options, make_raw=default_raw_banks): results["RawBanks"] = rawBanks # Decode the Raw event to RichSmartIDs - richDecode = RichDecoder( + results["RichDecodedData"] = RichDecoder( name="RichRawDecoder_{hash}", RawBanks=rawBanks, Detectors=det_opts, Panels=options["ActivatePanel"], - ) - results["RichDecodedData"] = richDecode.DecodedDataLocation + ).DecodedDataLocation + + return results + + +@configurable +def make_rich_clusters(options, decode=decode_rich_raw): + """ + Configures the RICH pixel clustering + + Args: + options (dict): The processing options to use + decode : raw decoder to use + + Returns: + dict of useful data locations. + """ + + # Get the detector options + det_opts = get_detector_bool_opts(options) + + # The conf dict to return + results = {} + + # Raw Bank decoding + results.update(decode(options)) # Run clustering - doClus = options["ApplyPixelClustering"] - richClus = RichClustering( + results["RichClusters"] = RichClustering( name="RichPixelClustering_{hash}", - ApplyPixelClustering=doClus, + ApplyPixelClustering=options["ApplyPixelClustering"], MaxClusters=options["MaxPixelClusters"], - DecodedDataLocation=richDecode.DecodedDataLocation, + DecodedDataLocation=results["RichDecodedData"], Detectors=det_opts, # 4D reco Enable4D=options["Enable4DReco"], AvHitTime=options["averageHitTime"], TimeWindow=options["pixelTimeWindow"], - ) - results["RichClusters"] = richClus.RichPixelClustersLocation + ).RichPixelClustersLocation + + return results + + +@configurable +def make_rich_pixels(options, clusters=make_rich_clusters): + """ + Return all pixel specific RICH data. + + Args: + options (dict): The processing options to use + clusters : Cluster maker to use + + Returns: + dict of useful data locations. + """ + + # Configure the particle properties + configure_rich_particle_properties(options) + + # The conf dict to return + results = {} + + # Clustering + results.update(clusters(options)) # Make the SIMD pixel objects + doClus = options["ApplyPixelClustering"] + timeWin = options["photonTimeWindow"] simdPixels = RichSIMDPixels( name="RichSIMDPixels_{hash}", NoClustering=(not doClus[0] and not doClus[1]), - RichPixelClustersLocation=richClus.RichPixelClustersLocation, + RichPixelClustersLocation=results["RichClusters"], # 4D reco Enable4D=options["Enable4DReco"], AvHitTime=options["averageHitTime"], CourseTimeWindow=options["pixelTimeWindow"], - InnerFineTimeWindow=options["photonTimeWindow"][0], - OuterFineTimeWindow=options["photonTimeWindow"][1], + InnerFineTimeWindow=timeWin[0], + OuterFineTimeWindow=timeWin[1], ) results["RichSIMDPixels"] = simdPixels.RichSIMDPixelSummariesLocation @@ -333,32 +379,17 @@ def make_rich_pixels(options, make_raw=default_raw_banks): @configurable -def make_rich_tracks(track_name, input_tracks, options): +def make_rich_track_segments(track_name, input_tracks, options, results): """ - Return tracking specific RICH data from input tracks. + Make RICH track radiator segments Args: - track_name (str): The track name to assign to this configuration + track_name (str): The track name to assign to this configuration input_tracks (dict): Input track objects to process. - n_ring_point (3-tuple of int): Number points for mass hypothesis ring ray tracing (Aero,R1Gas,R2Gas). - options (dict): The processing options to use - - Returns: - dict of useful data locations. + options (dict): The processing options to use + results (dict): The results dict to fill """ - # Configure the particle properties - configure_rich_particle_properties(options) - - # The conf map to return - results = {} - - # save the name for this set of results - results["TrackName"] = track_name - - # Keep tabs on the input tracks used for this conf. - results["InputTracks"] = input_tracks - # The detector options det_opts = get_detector_bool_opts(options, track_name) @@ -377,25 +408,55 @@ def make_rich_tracks(track_name, input_tracks, options): results["InitialTrackToSegments"] = segments.TrackToSegmentsLocation results["SegmentToTracks"] = segments.SegmentToTrackLocation + +@configurable +def make_rich_segment_panel_points(track_name, options, results): + """ + Determine RICH track panel points + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) + # Intersections of segments with PD panels tkGloPnts = TkPanelGlobalPoints( name="RichTrackGloPoints" + track_name + "_{hash}", Detectors=det_opts, - TrackSegmentsLocation=segments.TrackSegmentsLocation, + TrackSegmentsLocation=results["TrackSegments"], ) tkLocPnts = TkPanelLocalPoints( name="RichTrackLocPoints" + track_name + "_{hash}", TrackGlobalPointsLocation=tkGloPnts.TrackGlobalPointsLocation, - TrackSegmentsLocation=segments.TrackSegmentsLocation, + TrackSegmentsLocation=results["TrackSegments"], ) results["TrackGlobalPoints"] = tkGloPnts.TrackGlobalPointsLocation results["TrackLocalPoints"] = tkLocPnts.TrackLocalPointsLocation + +@configurable +def make_emitted_track_info(track_name, options, results): + """ + Build the track emitted level information + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) + # Emitted photon yields emitY = EmittedYields( name="RichEmittedYields" + track_name + "_{hash}", Detectors=det_opts, - TrackSegmentsLocation=segments.TrackSegmentsLocation, + TrackSegmentsLocation=results["TrackSegments"], ) results["EmittedYields"] = emitY.EmittedPhotonYieldLocation results["EmittedSpectra"] = emitY.EmittedPhotonSpectraLocation @@ -404,7 +465,7 @@ def make_rich_tracks(track_name, input_tracks, options): emitChAngles = EmittedCKAngles( name="RichEmittedCKAngles" + track_name + "_{hash}", Detectors=det_opts, - TrackSegmentsLocation=segments.TrackSegmentsLocation, + TrackSegmentsLocation=results["TrackSegments"], EmittedPhotonYieldLocation=emitY.EmittedPhotonYieldLocation, EmittedPhotonSpectraLocation=emitY.EmittedPhotonSpectraLocation, ) @@ -417,11 +478,25 @@ def make_rich_tracks(track_name, input_tracks, options): NRingPointsMin=options["NRayTracingRingPointsMin"], NRingPointsMax=options["NRayTracingRingPointsMax"], NewCKRingTol=options["RayTracingNewCKRingTol"], - TrackSegmentsLocation=segments.TrackSegmentsLocation, + TrackSegmentsLocation=results["TrackSegments"], CherenkovAnglesLocation=emitChAngles.EmittedCherenkovAnglesLocation, ) results["EmittedCKRings"] = emitMassCones.MassHypothesisRingsLocation + +@configurable +def make_detectable_track_info(track_name, options, results): + """ + Build the track detectable level information + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) # Detectable photon yields if options["DetectableYieldsPrecision"] == "Full": from PyConf.Algorithms import ( @@ -440,41 +515,62 @@ def make_rich_tracks(track_name, input_tracks, options): detY = DetectableYields( name="RichDetectableYields" + track_name + "_{hash}", Detectors=det_opts, - TrackSegmentsLocation=segments.TrackSegmentsLocation, - EmittedSpectraLocation=emitY.EmittedPhotonSpectraLocation, - MassHypothesisRingsLocation=emitMassCones.MassHypothesisRingsLocation, + TrackSegmentsLocation=results["TrackSegments"], + EmittedSpectraLocation=results["EmittedSpectra"], + MassHypothesisRingsLocation=results["EmittedCKRings"], ) results["DetectableYields"] = detY.DetectablePhotonYieldLocation results["DetectableSpectra"] = detY.DetectablePhotonSpectraLocation + +@configurable +def make_geom_eff_info(track_name, options, results): + """ + Build the track geometrical efficiency information + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) + # Geometrical Eff. geomEff = GeomEff( name="RichGeomEff" + track_name + "_{hash}", Detectors=det_opts, - TrackSegmentsLocation=segments.TrackSegmentsLocation, - CherenkovAnglesLocation=emitChAngles.EmittedCherenkovAnglesLocation, - MassHypothesisRingsLocation=emitMassCones.MassHypothesisRingsLocation, + TrackSegmentsLocation=results["TrackSegments"], + CherenkovAnglesLocation=results["EmittedCKAngles"], + MassHypothesisRingsLocation=results["EmittedCKRings"], ) results["GeomEffs"] = geomEff.GeomEffsLocation results["GeomEffsPerPD"] = geomEff.GeomEffsPerPDLocation results["SegmentPhotonFlags"] = geomEff.SegmentPhotonFlagsLocation - # Select final track segments - tkSel = SelectTrackSegments( - name="RichTkSegmentSel" + track_name + "_{hash}", - Detectors=det_opts, - InTrackToSegmentsLocation=segments.TrackToSegmentsLocation, - GeomEffsLocation=geomEff.GeomEffsLocation, - ) - results["SelectedTrackToSegments"] = tkSel.OutTrackToSegmentsLocation + +@configurable +def make_signal_track_info(track_name, options, results): + """ + Build the track signal level information + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) # Signal Photon Yields sigYields = SignalYields( name="RichSignalYields" + track_name + "_{hash}", Detectors=det_opts, - DetectablePhotonYieldLocation=detY.DetectablePhotonYieldLocation, - DetectablePhotonSpectraLocation=detY.DetectablePhotonSpectraLocation, - GeomEffsLocation=geomEff.GeomEffsLocation, + DetectablePhotonYieldLocation=results["DetectableYields"], + DetectablePhotonSpectraLocation=results["DetectableSpectra"], + GeomEffsLocation=results["GeomEffs"], ) results["SignalYields"] = sigYields.SignalPhotonYieldLocation results["SignalSpectra"] = sigYields.SignalPhotonSpectraLocation @@ -483,12 +579,27 @@ def make_rich_tracks(track_name, input_tracks, options): sigChAngles = SignalCherenkovAngles( name="RichSignalCKAngles" + track_name + "_{hash}", Detectors=det_opts, - TrackSegmentsLocation=segments.TrackSegmentsLocation, + TrackSegmentsLocation=results["TrackSegments"], SignalPhotonSpectraLocation=sigYields.SignalPhotonSpectraLocation, SignalPhotonYieldLocation=sigYields.SignalPhotonYieldLocation, ) results["SignalCKAngles"] = sigChAngles.SignalCherenkovAnglesLocation + +@configurable +def make_track_resolution_info(track_name, options, results): + """ + Build the track CK theta resolution information + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) + # Track Resolutions tktype = shortTrackType(track_name) if options["TkCKResTreatment"] == "Functional": @@ -496,9 +607,9 @@ def make_rich_tracks(track_name, input_tracks, options): name="RichCKResolutions" + track_name + "_{hash}", Detectors=det_opts, MaxCKThetaRes=defaultMaxCKThetaResolutions()[tktype], - TrackSegmentsLocation=segments.TrackSegmentsLocation, - SignalCherenkovAnglesLocation=sigChAngles.SignalCherenkovAnglesLocation, - MassHypothesisRingsLocation=emitMassCones.MassHypothesisRingsLocation, + TrackSegmentsLocation=results["TrackSegments"], + SignalCherenkovAnglesLocation=results["SignalCKAngles"], + MassHypothesisRingsLocation=results["EmittedCKRings"], ) elif options["TkCKResTreatment"] == "Parameterised": tkRes = ParamTrackCKRes( @@ -506,8 +617,8 @@ def make_rich_tracks(track_name, input_tracks, options): Detectors=det_opts, TrackType=track_name, MaxCKThetaRes=defaultMaxCKThetaResolutions()[tktype], - TrackSegmentsLocation=segments.TrackSegmentsLocation, - SignalCherenkovAnglesLocation=sigChAngles.SignalCherenkovAnglesLocation, + TrackSegmentsLocation=results["TrackSegments"], + SignalCherenkovAnglesLocation=results["SignalCKAngles"], ) else: raise ValueError( @@ -517,19 +628,34 @@ def make_rich_tracks(track_name, input_tracks, options): ) results["CherenkovResolutions"] = tkRes.CherenkovResolutionsLocation - return results - @configurable -def make_rich_photons(track_name, input_tracks, options, make_raw=default_raw_banks): +def make_rich_tracks( + track_name, + input_tracks, + options, + segments=make_rich_track_segments, + panel_points=make_rich_segment_panel_points, + emitted_info=make_emitted_track_info, + detectable_info=make_detectable_track_info, + geom_effs=make_geom_eff_info, + signal_info=make_signal_track_info, + track_resolutions=make_track_resolution_info, +): """ - Return reconstructed photon specific RICH data. + Return tracking specific RICH data from input tracks. Args: - track_name (str): The name to assign to this configuration - input_tracks (dict): The input tracks to process - options (dict): The processing options to use - make_raw : The entity that provides the RawBanks to use (??) + track_name (str): The track name to assign to this configuration + input_tracks (dict): Input track objects to process. + options (dict): The processing options to use + segments : Segment builder to use + panel_points : Builds for the track PD panel points + emitted_info : Builds the track emitted level information + detectable_info : Builds the track detectable level information + geom_effs : Builds the track geometrical efficiencies + signal_info : Builds the track signal level information + track_resolutions : Builds the track CK theta resolutions Returns: dict of useful data locations. @@ -538,21 +664,61 @@ def make_rich_photons(track_name, input_tracks, options, make_raw=default_raw_ba # Configure the particle properties configure_rich_particle_properties(options) - # The conf dict to return + # The conf map to return results = {} # save the name for this set of results results["TrackName"] = track_name - # pixel and track reco - pixel_conf = make_rich_pixels(make_raw=make_raw, options=options) - track_conf = make_rich_tracks( - track_name=track_name, input_tracks=input_tracks, options=options + # Keep tabs on the input tracks used for this conf. + results["InputTracks"] = input_tracks + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) + + # Create radiator segments from input tracks + segments(track_name, input_tracks, options, results) + + # Determine PD panel points + panel_points(track_name, options, results) + + # Emitted info + emitted_info(track_name, options, results) + + # Detectable info + detectable_info(track_name, options, results) + + # Geom Effs + geom_effs(track_name, options, results) + + # Signal info + signal_info(track_name, options, results) + + # Track resolutions + track_resolutions(track_name, options, results) + + # Select final track segments + tkSel = SelectTrackSegments( + name="RichTkSegmentSel" + track_name + "_{hash}", + Detectors=det_opts, + InTrackToSegmentsLocation=results["InitialTrackToSegments"], + GeomEffsLocation=results["GeomEffs"], ) + results["SelectedTrackToSegments"] = tkSel.OutTrackToSegmentsLocation + + return results - # include in returned configuration - results.update(pixel_conf) - results.update(track_conf) + +@configurable +def make_photon_candidates(track_name, options, results): + """ + Build the CK photon candidates + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ # The detector options det_opts = get_detector_bool_opts(options, track_name) @@ -574,13 +740,13 @@ def make_rich_photons(track_name, input_tracks, options, make_raw=default_raw_ba MinAllowedCherenkovTheta=minMaxCKTheta["Min"], MaxAllowedCherenkovTheta=minMaxCKTheta["Max"], TruncateCKAngles=options["TruncateCKAngles"], - TrackSegmentsLocation=track_conf["TrackSegments"], - CherenkovAnglesLocation=track_conf["SignalCKAngles"], - CherenkovResolutionsLocation=track_conf["CherenkovResolutions"], - TrackLocalPointsLocation=track_conf["TrackLocalPoints"], - TrackToSegmentsLocation=track_conf["SelectedTrackToSegments"], - SegmentPhotonFlagsLocation=track_conf["SegmentPhotonFlags"], - RichSIMDPixelSummariesLocation=pixel_conf["RichSIMDPixels"], + TrackSegmentsLocation=results["TrackSegments"], + CherenkovAnglesLocation=results["SignalCKAngles"], + CherenkovResolutionsLocation=results["CherenkovResolutions"], + TrackLocalPointsLocation=results["TrackLocalPoints"], + TrackToSegmentsLocation=results["SelectedTrackToSegments"], + SegmentPhotonFlagsLocation=results["SegmentPhotonFlags"], + RichSIMDPixelSummariesLocation=results["RichSIMDPixels"], RejectAmbiguousPhotons=options["RejectAmbiguousPhotons"], SaveMirrorData=options["SaveMirrorData"], # 4D reco @@ -590,29 +756,125 @@ def make_rich_photons(track_name, input_tracks, options, make_raw=default_raw_ba results["PhotonToParents"] = photReco.PhotonToParentsLocation results["PhotonMirrorData"] = photReco.PhotonMirrorDataLocation + +@configurable +def make_photon_signals(track_name, options, results): + """ + Build the CK photon signal information + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) + # Predicted pixel signals + photSel = options["PhotonSelection"] photPredSig = PhotonPredSignal( name="RichPredPixelSignal" + track_name + "_{hash}", Detectors=det_opts, MinPhotonProbability=options["MinPhotonProbabilityCuts"][photSel], - RichSIMDPixelSummariesLocation=pixel_conf["RichSIMDPixels"], - TrackSegmentsLocation=track_conf["TrackSegments"], - CherenkovPhotonLocation=photReco.CherenkovPhotonLocation, - PhotonToParentsLocation=photReco.PhotonToParentsLocation, - CherenkovAnglesLocation=track_conf["SignalCKAngles"], - CherenkovResolutionsLocation=track_conf["CherenkovResolutions"], - PhotonYieldLocation=track_conf["DetectableYields"], + RichSIMDPixelSummariesLocation=results["RichSIMDPixels"], + TrackSegmentsLocation=results["TrackSegments"], + CherenkovPhotonLocation=results["CherenkovPhotons"], + PhotonToParentsLocation=results["PhotonToParents"], + CherenkovAnglesLocation=results["SignalCKAngles"], + CherenkovResolutionsLocation=results["CherenkovResolutions"], + PhotonYieldLocation=results["DetectableYields"], # 4D reco Enable4D=options["Enable4DReco"], ) results["PhotonSignals"] = photPredSig.PhotonSignalsLocation + +@configurable +def make_rich_photons( + track_name, + input_tracks, + options, + photon_candidates=make_photon_candidates, + photon_signals=make_photon_signals, +): + """ + Return reconstructed photon specific RICH data. + + Args: + track_name (str): The name to assign to this configuration + input_tracks (dict): The input tracks to process + options (dict): The processing options to use + photon_candidates : Photon candidate builder + photon_signals : Builds the photon signal information + + Returns: + dict of useful data locations. + """ + + # Configure the particle properties + configure_rich_particle_properties(options) + + # The conf dict to return + results = {} + + # save the name for this set of results + results["TrackName"] = track_name + + # Configure track and pixel level reco + results.update(make_rich_pixels(options=options)) + results.update( + make_rich_tracks( + track_name=track_name, input_tracks=input_tracks, options=options + ) + ) + + # Make photon candidates + photon_candidates(track_name, options, results) + + # Photon signals + photon_signals(track_name, options, results) + return results +@configurable +def make_reco_summaries(track_name, options, results): + """ + Build the reconstruction summary objects + + Args: + track_name (str): The track name to assign to this configuration + options (dict): The processing options to use + results (dict): The results dict to fill + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) + + # Create working event summary of reco info + recSum = RecSummary( + name="RichRecSummary" + track_name + "_{hash}", + Detectors=det_opts, + TrackSegmentsLocation=results["TrackSegments"], + TrackToSegmentsLocation=results["SelectedTrackToSegments"], + PhotonToParentsLocation=results["PhotonToParents"], + DetectablePhotonYieldLocation=results["DetectableYields"], + SignalPhotonYieldLocation=results["SignalYields"], + PhotonSignalsLocation=results["PhotonSignals"], + RichSIMDPixelSummariesLocation=results["RichSIMDPixels"], + ) + results["SummaryTracks"] = recSum.SummaryTracksLocation + results["Summarypixels"] = recSum.SummaryPixelsLocation + + @configurable def make_rich_pids( - track_name, input_tracks, options, make_raw=default_raw_banks, location=None + track_name, + input_tracks, + options, + location=None, + reco_summaries=make_reco_summaries, ): """ Return RICH PID data. @@ -621,7 +883,6 @@ def make_rich_pids( track_name (str): The name to assign to this configuration input_tracks (dict): The input tracks to process options (dict): The processing options to use - make_raw : The entity that provides the RawBanks to use (??) Returns: dict of useful data locations. @@ -641,39 +902,25 @@ def make_rich_pids( results["TrackName"] = track_name # pixel and track reco - pixel_conf = make_rich_pixels(make_raw=make_raw, options=options) - track_conf = make_rich_tracks( - track_name=track_name, input_tracks=input_tracks, options=options + results.update(make_rich_pixels(options=options)) + results.update( + make_rich_tracks( + track_name=track_name, input_tracks=input_tracks, options=options + ) ) - photon_conf = make_rich_photons( - track_name=track_name, - input_tracks=input_tracks, - make_raw=make_raw, - options=options, + results.update( + make_rich_photons( + track_name=track_name, + input_tracks=input_tracks, + options=options, + ) ) - # include in returned configuration - results.update(pixel_conf) - results.update(track_conf) - results.update(photon_conf) - # The detector options det_opts = get_detector_bool_opts(options, track_name) - # Create working event summary of reco info - recSum = RecSummary( - name="RichRecSummary" + track_name + "_{hash}", - Detectors=det_opts, - TrackSegmentsLocation=track_conf["TrackSegments"], - TrackToSegmentsLocation=track_conf["SelectedTrackToSegments"], - PhotonToParentsLocation=photon_conf["PhotonToParents"], - DetectablePhotonYieldLocation=track_conf["DetectableYields"], - SignalPhotonYieldLocation=track_conf["SignalYields"], - PhotonSignalsLocation=photon_conf["PhotonSignals"], - RichSIMDPixelSummariesLocation=pixel_conf["RichSIMDPixels"], - ) - results["SummaryTracks"] = recSum.SummaryTracksLocation - results["Summarypixels"] = recSum.SummaryPixelsLocation + # Reco summary objects + reco_summaries(track_name, options, results) # ================================================================== # RICH Global PID @@ -683,7 +930,7 @@ def make_rich_pids( gpidInit = GPIDInit( name="RichGPIDInit" + track_name + "_{hash}", Detectors=det_opts, - SummaryTracksLocation=recSum.SummaryTracksLocation, + SummaryTracksLocation=results["SummaryTracks"], ) # Cache PID and DLL locations by iteration @@ -709,11 +956,11 @@ def make_rich_pids( ThresholdBackground=options["PDBackThresholds"][it], # Input data TrackPIDHyposLocation=PIDs[it], - TrackToSegmentsLocation=track_conf["SelectedTrackToSegments"], - TrackSegmentsLocation=track_conf["TrackSegments"], - GeomEffsPerPDLocation=track_conf["GeomEffsPerPD"], - DetectablePhotonYieldLocation=track_conf["DetectableYields"], - RichSIMDPixelSummariesLocation=pixel_conf["RichSIMDPixels"], + TrackToSegmentsLocation=results["SelectedTrackToSegments"], + TrackSegmentsLocation=results["TrackSegments"], + GeomEffsPerPDLocation=results["GeomEffsPerPD"], + DetectablePhotonYieldLocation=results["DetectableYields"], + RichSIMDPixelSummariesLocation=results["RichSIMDPixels"], # 4D Reco Enable4D=options["Enable4DReco"], ) @@ -730,13 +977,13 @@ def make_rich_pids( MaxTrackChangesPerIt=options["MaxTrackChangesPerIt"][it], MinSignalForNoLLCalc=options["MinSignalForNoLLCalc"][it], # Input data - SummaryTracksLocation=recSum.SummaryTracksLocation, - SummaryPixelsLocation=recSum.SummaryPixelsLocation, + SummaryTracksLocation=results["SummaryTracks"], + SummaryPixelsLocation=results["Summarypixels"], PixelBackgroundsLocation=pixBkgs.PixelBackgroundsLocation, TrackDLLsInputLocation=DLLs[it], TrackPIDHyposInputLocation=PIDs[it], - PhotonToParentsLocation=photon_conf["PhotonToParents"], - PhotonSignalsLocation=photon_conf["PhotonSignals"], + PhotonToParentsLocation=results["PhotonToParents"], + PhotonSignalsLocation=results["PhotonSignals"], ) # Save the outputs for the next it @@ -753,8 +1000,8 @@ def make_rich_pids( Detectors=det_opts, PIDVersion=options["PIDVersion"], # Inputs - TracksLocation=track_conf["InputTracks"], - SummaryTracksLocation=recSum.SummaryTracksLocation, + TracksLocation=results["InputTracks"], + SummaryTracksLocation=results["SummaryTracks"], TrackPIDHyposInputLocation=PIDs[options["nLikelihoodIterations"]], TrackDLLsInputLocation=DLLs[options["nLikelihoodIterations"]], outputs={"RichPIDsLocation": location}, -- GitLab From 0583eea9ce7b976a35a21b3b469429026018a5f3 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Mon, 7 Apr 2025 10:09:20 +0100 Subject: [PATCH 03/14] data_from_file.py: Add support for spillover MC data --- .../python/RecoConf/data_from_file.py | 76 +++++++++++-------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/Hlt/RecoConf/python/RecoConf/data_from_file.py b/Hlt/RecoConf/python/RecoConf/data_from_file.py index acfaf65fe08..638e7b436b1 100644 --- a/Hlt/RecoConf/python/RecoConf/data_from_file.py +++ b/Hlt/RecoConf/python/RecoConf/data_from_file.py @@ -62,7 +62,9 @@ from PyConf.Tools import ( def __packed_location_for_(unpacked): - m = {"/Event/MC": "/Event/pSim", "/Event/Rec": "/Event/pRec"} + m = {"/Event/Rec": "/Event/pRec"} + for spill in ["", "PrevPrev/", "Prev/", "Next/", "NextNext/", "LHCBackground/"]: + m["/Event/" + spill + "MC"] = "/Event/" + spill + "pSim" for k, v in m.items(): if unpacked.startswith(k): return v + unpacked.removeprefix(k) @@ -88,13 +90,15 @@ def _unpacker(forced_type, unpacked_loc, **kwargs): "LHCb::PackedMCRichOpticalPhotons": MCRichOpticalPhotonUnpacker, "LHCb::PackedMCRichDigitSummarys": MCRichDigitSummaryUnpacker, } + input_data = input_from_root_file( + __packed_location_for_(unpacked_loc), forced_type=forced_type + ) + output_data = force_location(unpacked_loc) return Algorithm( _unpack_configurable[forced_type], name=f"Unpack_{unpacked_loc.replace('/', '_')}", - outputs={"OutputName": force_location(unpacked_loc)}, - InputName=input_from_root_file( - __packed_location_for_(unpacked_loc), forced_type=forced_type - ), + outputs={"OutputName": output_data}, + InputName=input_data, **kwargs, ) @@ -209,48 +213,54 @@ def _get_mc_unpackers(): ), } - def _mc_unpacker(key, **kwargs): + def _mc_unpacker(key, spill, **kwargs): """Return unpacker that reads from file and unpacks to a forced output location.""" packed_type, location = _packed_mc_from_file[key] # The SmartRefs held by the unpacked MC objects only work if we unpack to these specific locations return _unpacker( - packed_type, "/Event/MC/" + location.removeprefix("MC"), **kwargs + packed_type, + "/Event/" + spill + "MC/" + location.removeprefix("MC"), + **kwargs, ) # Ordered so that dependents are unpacked first # Make sure that MC particles and MC vertices are unpacked together, # see https://gitlab.cern.ch/lhcb/LHCb/issues/57 for details. - return collections.OrderedDict( + unps = collections.OrderedDict( [ - ("MCRichDigitSummaries", _mc_unpacker("MCRichDigitSummaries")), ("MCParticles", get_mc_particles("/Event/MC/Particles")), ("MCVertices", get_mc_vertices("/Event/MC/Vertices")), - ("MCVPHits", _mc_unpacker("MCVPHits")), - ("MCUTHits", _mc_unpacker("MCUTHits")), - ("MCFTHits", _mc_unpacker("MCFTHits")), - ("MCRichHits", _mc_unpacker("MCRichHits")), - ("MCRichSegments", _mc_unpacker("MCRichSegments")), - ("MCRichTracks", _mc_unpacker("MCRichTracks")), - ("MCRichOpticalPhotons", _mc_unpacker("MCRichOpticalPhotons")), - ("MCEcalHits", _mc_unpacker("MCEcalHits")), - ("MCHcalHits", _mc_unpacker("MCHcalHits")), - ("MCMuonHits", _mc_unpacker("MCMuonHits")), ] ) + for spill in ["", "PrevPrev/", "Prev/", "NextNext/", "Next/", "LHCBackground/"]: + unps.update( + [ + (spill + "MCVPHits", _mc_unpacker("MCVPHits", spill)), + (spill + "MCUTHits", _mc_unpacker("MCUTHits", spill)), + (spill + "MCFTHits", _mc_unpacker("MCFTHits", spill)), + ( + spill + "MCRichDigitSummaries", + _mc_unpacker("MCRichDigitSummaries", spill), + ), + (spill + "MCRichHits", _mc_unpacker("MCRichHits", spill)), + (spill + "MCRichSegments", _mc_unpacker("MCRichSegments", spill)), + (spill + "MCRichTracks", _mc_unpacker("MCRichTracks", spill)), + ( + spill + "MCRichOpticalPhotons", + _mc_unpacker("MCRichOpticalPhotons", spill), + ), + (spill + "MCEcalHits", _mc_unpacker("MCEcalHits", spill)), + (spill + "MCHcalHits", _mc_unpacker("MCHcalHits", spill)), + (spill + "MCMuonHits", _mc_unpacker("MCMuonHits", spill)), + ] + ) + return unps # precomputed dict of mc unpackers, will be filled on first use _mc_unpackers = None -def reco_unpacker(key): - """Returns the adequate unpacker for the given key""" - global _reco_unpackers - if _reco_unpackers is None: - _reco_unpackers = _get_reco_unpackers() - return _reco_unpackers[key] - - def reco_unpackers(): global _reco_unpackers if _reco_unpackers is None: @@ -258,12 +268,9 @@ def reco_unpackers(): return _reco_unpackers -def mc_unpacker(key): +def reco_unpacker(key): """Returns the adequate unpacker for the given key""" - global _mc_unpackers - if _mc_unpackers is None: - _mc_unpackers = _get_mc_unpackers() - return _mc_unpackers[key] + return reco_unpackers()[key] def mc_unpackers(): @@ -273,6 +280,11 @@ def mc_unpackers(): return _mc_unpackers +def mc_unpacker(key): + """Returns the adequate unpacker for the given key""" + return mc_unpackers()[key] + + def boole_links_digits_mcparticles(key): """Return a dict of locations for MC linker tables (to mcparticles) created by Boole.""" locations = { -- GitLab From ec9a72828dca21306406432429784080e68155bf Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Mon, 7 Apr 2025 10:10:17 +0100 Subject: [PATCH 04/14] mc_checking.py: Set Link locations for MC hits to match properly original hits --- Hlt/RecoConf/python/RecoConf/mc_checking.py | 28 ++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Hlt/RecoConf/python/RecoConf/mc_checking.py b/Hlt/RecoConf/python/RecoConf/mc_checking.py index df6396d7798..9c40f33e585 100644 --- a/Hlt/RecoConf/python/RecoConf/mc_checking.py +++ b/Hlt/RecoConf/python/RecoConf/mc_checking.py @@ -40,6 +40,7 @@ from PyConf.Algorithms import ( VPFullCluster2MCParticleLinker, ) from PyConf.application import make_odin +from PyConf.components import force_location from PyConf.dataflow import DataHandle from PyConf.reading import get_mc_header, get_mc_track_info from PyConf.tonic import configurable @@ -525,14 +526,29 @@ def make_default_IdealStateCreator(public=False): uthits = mc_unpacker("MCUTHits") fthits = mc_unpacker("MCFTHits") - link_vp_hits = MCParticle2MCHitAlg(MCParticles=mcpart, MCHitPath=vphits) - link_ut_hits = MCParticle2MCHitAlg(MCParticles=mcpart, MCHitPath=uthits) - link_ft_hits = MCParticle2MCHitAlg(MCParticles=mcpart, MCHitPath=fthits) + vplinkloc = "Link/" + vphits.OutputName.location.replace("/Event/", "") + link_vp_hits = MCParticle2MCHitAlg( + MCParticles=mcpart, + MCHitPath=vphits.OutputName, + outputs={"OutputData": force_location(vplinkloc)}, + ) + utlinkloc = "Link/" + uthits.OutputName.location.replace("/Event/", "") + link_ut_hits = MCParticle2MCHitAlg( + MCParticles=mcpart, + MCHitPath=uthits, + outputs={"OutputData": force_location(utlinkloc)}, + ) + ftlinkloc = "Link/" + fthits.OutputName.location.replace("/Event/", "") + link_ft_hits = MCParticle2MCHitAlg( + MCParticles=mcpart, + MCHitPath=fthits, + outputs={"OutputData": force_location(ftlinkloc)}, + ) return IdealStateCreator( - Extrapolator=TrackMasterExtrapolator( - ExtraSelector=TrackDistanceExtraSelector(shortDist=0) - ), + # Extrapolator=TrackMasterExtrapolator( + # ExtraSelector=TrackDistanceExtraSelector(shortDist=0) + # ), MCVertices=mcvert, VPMCHits=vphits, VPMCHitLinks=link_vp_hits, -- GitLab From 5d3d97f815b2d82c1bcde18175da15697402a76d Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Mon, 7 Apr 2025 10:11:47 +0100 Subject: [PATCH 05/14] rich_reconstruction.py: Update copyright date --- Hlt/RecoConf/python/RecoConf/rich_reconstruction.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py index 7ed1b412e38..faa889384c4 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py @@ -1,5 +1,5 @@ ############################################################################### -# (c) Copyright 2019-2022 CERN for the benefit of the LHCb Collaboration # +# (c) Copyright 2019-2025 CERN for the benefit of the LHCb Collaboration # # # # This software is distributed under the terms of the GNU General Public # # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # @@ -8,6 +8,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # # or submit itself to any jurisdiction. # ############################################################################### + from Configurables import Rich__Future__ParticleProperties as PartProps from GaudiKernel.SystemOfUnits import GeV from PyConf import configurable -- GitLab From 1b4df6aee095f85f2996c4e252b9e7ce5b1cbc9c Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 8 Apr 2025 09:33:40 +0100 Subject: [PATCH 06/14] rich_mc_checking.py: Fix checkers for 4D support --- .../python/RecoConf/rich_mc_checking.py | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py b/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py index a685418967f..b79e87652fc 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py +++ b/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py @@ -26,6 +26,9 @@ from PyConf.Algorithms import Rich__Future__Rec__MC__Moni__PIDQC as PIDQC from PyConf.Algorithms import ( Rich__Future__Rec__MC__Moni__SIMDPhotonCherenkovAngles as MCCKAngles, ) +from PyConf.Algorithms import ( + Rich__Future__Rec__MC__Moni__SIMDPhotonTime as MCTime, +) from PyConf.Algorithms import Rich__Future__Rec__MC__Moni__TrackResolution as MCTkRes from PyConf.Tools import TrackSelector from PyConf.utilities import ConfigurationError @@ -78,20 +81,19 @@ def default_rich_checkers(moni_set="Standard"): # To Do: Add time monitors here for 4D support monitors = { - "Expert": # Activates all montiors - [ + "Expert": [ "RichHits", "PIDPerformance", "PhotonCherenkovAngles", "CherenkovResolution", - "CKResParameterisation", "TrackResolution", "MCOpticalPhotons", + "Time", ], "Standard": # The default set of monitors - ["PIDPerformance", "PhotonCherenkovAngles", "TrackResolution"], + ["PIDPerformance", "PhotonCherenkovAngles", "TrackResolution", "Time"], "OnlineMonitoring": # For monitoring at the pit - ["PIDPerformance", "PhotonCherenkovAngles", "TrackResolution"], + ["PIDPerformance", "PhotonCherenkovAngles", "TrackResolution", "Time"], "RefractiveIndex": # For ref index task [ "RichHits", @@ -99,7 +101,9 @@ def default_rich_checkers(moni_set="Standard"): "CherenkovResolution", "TrackResolution", "MCOpticalPhotons", + "Time", ], + "ResolutionParameterisation": ["CKResParameterisation"], "None": [], } @@ -147,14 +151,17 @@ def make_rich_checkers(conf, reco_opts, check_opts, moni_set="Standard"): richSummaries = mc_unpacker("MCRichDigitSummaries") # Track linker stuff - if check_opts["UseUT"]: - links_to_lhcbids = make_links_lhcbids_mcparticles_tracking_system() + if "RichTrackMCPartLinks" not in conf.keys(): + # Build Track -> MCP links ourselves + if check_opts["UseUT"]: + links_to_lhcbids = make_links_lhcbids_mcparticles_tracking_system() + else: + links_to_lhcbids = make_links_lhcbids_mcparticles_VP_FT() + links_to_tracks = make_links_tracks_mcparticles( + InputTracks=conf["OriginalV1Tracks"], LinksToLHCbIDs=links_to_lhcbids + ) else: - links_to_lhcbids = make_links_lhcbids_mcparticles_VP_FT() - - links_to_tracks = make_links_tracks_mcparticles( - InputTracks=conf["OriginalV1Tracks"], LinksToLHCbIDs=links_to_lhcbids - ) + links_to_tracks = conf["RichTrackMCPartLinks"] # Make the RICH Track -> MCParticle relations table tkMCPRels = TkToMCPRels( @@ -240,6 +247,8 @@ def make_rich_checkers(conf, reco_opts, check_opts, moni_set="Standard"): Detectors=det_opts, MinP=pCuts["MinP"], MaxP=pCuts["MaxP"], + TracksLocation=conf["InputTracks"], + RichDigitSummariesLocation=richSummaries, TrackSegmentsLocation=conf["TrackSegments"], CherenkovPhotonLocation=conf["CherenkovPhotons"], CherenkovAnglesLocation=conf["SignalCKAngles"], @@ -286,4 +295,21 @@ def make_rich_checkers(conf, reco_opts, check_opts, moni_set="Standard"): PhotonYieldLocation=conf["SignalYields"], ) + # 4D Time + key = "Time" + is4d = reco_opts["Enable4DReco"] + if key in checkers and (is4d[0] or is4d[1]): + results[key] = MCTime( + name="RiCKMCTime" + track_name, + Detectors=det_opts, + TrackSegmentsLocation=conf["TrackSegments"], + CherenkovPhotonLocation=conf["CherenkovPhotons"], + SummaryTracksLocation=conf["SummaryTracks"], + PhotonToParentsLocation=conf["PhotonToParents"], + TrackToMCParticlesRelations=tkMCPRels.TrackToMCParticlesRelations, + RichPixelClustersLocation=conf["RichClusters"], + RichSIMDPixelSummariesLocation=conf["RichSIMDPixels"], + TracksLocation=conf["InputTracks"], + ) + return results -- GitLab From 10f8aa71cd9c2628a4216387314523f50ce9d81d Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 8 Apr 2025 09:34:23 +0100 Subject: [PATCH 07/14] rich_data_monitoring.py: Add SIMD efficiency monitor --- .../python/RecoConf/rich_data_monitoring.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Hlt/RecoConf/python/RecoConf/rich_data_monitoring.py b/Hlt/RecoConf/python/RecoConf/rich_data_monitoring.py index 1fcb0d842c1..701d52fd58d 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_data_monitoring.py +++ b/Hlt/RecoConf/python/RecoConf/rich_data_monitoring.py @@ -17,6 +17,9 @@ from PyConf.Algorithms import ( Rich__Future__Rec__Moni__GeometricalEfficiencies as GeomEffs, ) from PyConf.Algorithms import Rich__Future__Rec__Moni__MassHypoRings as MassRings +from PyConf.Algorithms import ( + Rich__Future__Rec__Moni__PhotonSIMDEfficiency as PhotSIMDEff, +) from PyConf.Algorithms import Rich__Future__Rec__Moni__PhotonYield as PhotonYield from PyConf.Algorithms import Rich__Future__Rec__Moni__PixelBackgrounds as PixBackgrds from PyConf.Algorithms import Rich__Future__Rec__Moni__PixelClusters as ClusterMoni @@ -253,6 +256,7 @@ def default_rich_monitors(moni_set="Standard"): "GeomEffs", "MassRings", "DumpDervDets", + "SIMDPerf", ], # The default set of monitors. "Standard": [ @@ -552,6 +556,17 @@ def make_rich_track_monitors( CherenkovAnglesLocation=conf["SignalCKAngles"], ) + # SIMD Eff + key = "SIMDPerf" + if key in monitors: + results[key] = PhotSIMDEff( + name="RichPhotonSIMDEff" + track_name, + Detectors=det_opts, + CherenkovPhotonLocation=conf["CherenkovPhotons"], + PhotonToParentsLocation=conf["PhotonToParents"], + TrackSegmentsLocation=conf["TrackSegments"], + ) + # RICH alignment histogram production and/or optionally, others tasks key = "MirrorAlign" if key in monitors: -- GitLab From 07c42afa7d83684a30059081b7032b21773d2c5a Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 8 Apr 2025 09:36:19 +0100 Subject: [PATCH 08/14] rich_reconstruction_mc_cheat.py: New module with support for MC cheating various aspects of the RICH reco --- .../python/RecoConf/rich_mc_checking.py | 20 +- .../python/RecoConf/rich_reconstruction.py | 3 + .../RecoConf/rich_reconstruction_mc_cheat.py | 171 ++++++++++++++++++ 3 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py diff --git a/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py b/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py index b79e87652fc..9f194932ae6 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py +++ b/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py @@ -67,6 +67,17 @@ def default_rich_checking_options(): ############################################################################### +def make_track_links(tracks, useUT=True): + if useUT: + links_to_lhcbids = make_links_lhcbids_mcparticles_tracking_system() + else: + links_to_lhcbids = make_links_lhcbids_mcparticles_VP_FT() + return make_links_tracks_mcparticles(tracks, LinksToLHCbIDs=links_to_lhcbids) + + +############################################################################### + + @configurable def default_rich_checkers(moni_set="Standard"): """ @@ -153,12 +164,8 @@ def make_rich_checkers(conf, reco_opts, check_opts, moni_set="Standard"): # Track linker stuff if "RichTrackMCPartLinks" not in conf.keys(): # Build Track -> MCP links ourselves - if check_opts["UseUT"]: - links_to_lhcbids = make_links_lhcbids_mcparticles_tracking_system() - else: - links_to_lhcbids = make_links_lhcbids_mcparticles_VP_FT() - links_to_tracks = make_links_tracks_mcparticles( - InputTracks=conf["OriginalV1Tracks"], LinksToLHCbIDs=links_to_lhcbids + links_to_tracks = make_track_links( + conf["OriginalV1Tracks"], check_opts["UseUT"] ) else: links_to_tracks = conf["RichTrackMCPartLinks"] @@ -309,6 +316,7 @@ def make_rich_checkers(conf, reco_opts, check_opts, moni_set="Standard"): TrackToMCParticlesRelations=tkMCPRels.TrackToMCParticlesRelations, RichPixelClustersLocation=conf["RichClusters"], RichSIMDPixelSummariesLocation=conf["RichSIMDPixels"], + RichDigitSummariesLocation=richSummaries, TracksLocation=conf["InputTracks"], ) diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py index faa889384c4..0d9241d6a42 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py @@ -145,6 +145,8 @@ def default_rich_reco_options(init_override_opts={}): # =========================================================== # Track treatment options # =========================================================== + # Use UT ? + "UseUT": True, # Track Extrapolator type "TrackExtrapolator": TrackSTEPExtrapolator, # Tay tracing ring points (Max) @@ -297,6 +299,7 @@ def decode_rich_raw(options, make_raw=default_raw_banks): Panels=options["ActivatePanel"], ).DecodedDataLocation + # finally return the results dict return results diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py new file mode 100644 index 00000000000..bfcad157e1a --- /dev/null +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py @@ -0,0 +1,171 @@ +############################################################################### +# (c) Copyright 2019-2025 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### + +from PyConf import configurable +from PyConf.Algorithms import ( + Rich__Future__MC__DecodedDataAddMCInfo as DecodedDataAddMCInfo, +) +from PyConf.Algorithms import ( + Rich__Future__MC__DecodedDataFromMCRichHits as RichMCDecoder, +) +from PyConf.Algorithms import ( + Rich__Future__Rec__MC__RichSegmentAddTimeFromMC as AddSegTimeMC, +) +from PyConf.Algorithms import ( + Rich__Future__Rec__MC__TrSegMakerFromMCRichTracks as MCSegmentCreator, +) +from PyConf.components import force_location +from PyConf.reading import get_mc_track_info + +from RecoConf.data_from_file import mc_unpacker +from RecoConf.mc_checking import make_default_IdealStateCreator +from RecoConf.rich_mc_checking import make_track_links +from RecoConf.rich_reconstruction import ( + decode_rich_raw, + get_detector_bool_opts, + make_rich_track_segments, +) + + +@configurable +def default_mc_reco_cheat_options(): + """ + Returns a dict of the default RICH 'MC cheated' reconstruction options + """ + + opts = { + "IsDetDescMC": True, + "pixUsePosFromMC": False, + "pixUseTimeFromMC": False, + "ReadoutEfficiency": (0.95, 0.95), + } + + return opts + + +@configurable +def emulated_raw_from_MC(options): + """ + Emulates RawBank decoding from MC Hits + """ + + # The conf dict to return + results = {} + + results["RichDecodedData"] = RichMCDecoder( + name="RichDecodeFromMC_{hash}", + IsDetDescMC=options["IsDetDescMC"], + RejectAllBackgrounds=False, + RejectScintillation=False, + IncludeTimeInfo=True, + AllowMultipleHits=True, + MaxHitsPerChannel=(99999, 99999), + ReadoutEfficiency=options["ReadoutEfficiency"], + MCRichHitsLocation=mc_unpacker("MCRichHits"), + PrevMCRichHitsLocation=mc_unpacker("Prev/MCRichHits"), + PrevPrevMCRichHitsLocation=mc_unpacker("PrevPrev/MCRichHits"), + NextMCRichHitsLocation=mc_unpacker("Next/MCRichHits"), + NextNextMCRichHitsLocation=mc_unpacker("NextNext/MCRichHits"), + LHCBackgroundMCRichHitsLocation=mc_unpacker("LHCBackground/MCRichHits"), + ).DecodedDataLocation + + return results + + +@configurable +def decoded_data_add_MC_time(options): + """ + Adds time information from MC to existing decoded data + """ + + # First run regular decoding + results = decode_rich_raw(options) + + # Add time info + addTime = DecodedDataAddMCInfo( + name="RichDecodedDataAddMCInfo_{hash}", + InDecodedDataLocation=results["RichDecodedData"], + MCRichHitsLocation=mc_unpacker("MCRichHits"), + PrevMCRichHitsLocation=mc_unpacker("Prev/MCRichHits"), + PrevPrevMCRichHitsLocation=mc_unpacker("PrevPrev/MCRichHits"), + NextMCRichHitsLocation=mc_unpacker("Next/MCRichHits"), + NextNextMCRichHitsLocation=mc_unpacker("NextNext/MCRichHits"), + LHCBackgroundMCRichHitsLocation=mc_unpacker("LHCBackground/MCRichHits"), + ) + + # Set output to be main decoded data + results["RichDecodedData"] = addTime.OutDecodedDataLocation + + # finally return the results dict + return results + + +@configurable +def make_rich_track_segments_from_MC(track_name, input_tracks, options, results): + """ + Make track segments from MC + """ + + # The detector options + det_opts = get_detector_bool_opts(options, track_name) + + # Create radiator segments from input tracks + segments = MCSegmentCreator( + name="RichTrackSegments" + track_name + "_{hash}", + MCParticlesLocation=mc_unpacker("MCParticles"), + MCVerticesLocation=mc_unpacker("MCVertices"), + MCRichHitsLocation=mc_unpacker("MCRichHits"), + MCRichSegmentsLocation=mc_unpacker("MCRichSegments"), + MCRichTracksLocation=mc_unpacker("MCRichTracks"), + MCRichOpticalPhotonsLocation=mc_unpacker("MCRichOpticalPhotons"), + MCPropertyLocation=get_mc_track_info(), + IdealStateCreator=make_default_IdealStateCreator(), + MinP=options["MinP"], + MaxP=options["MaxP"], + MinPt=options["MinPt"], + Detectors=det_opts, + outputs={ + "OutputTracksLocation": force_location(str(input_tracks)), + "MCParticlesLinkLocation": force_location("Link/" + str(input_tracks)), + "TrackSegmentsLocation": None, + "TrackToSegmentsLocation": None, + "SegmentToTrackLocation": None, + }, + ) + results["TrackSegments"] = segments.TrackSegmentsLocation + results["InitialTrackToSegments"] = segments.TrackToSegmentsLocation + results["SegmentToTracks"] = segments.SegmentToTrackLocation + results["InputTracks"] = segments.OutputTracksLocation + results["OriginalV1Tracks"] = segments.OutputTracksLocation + results["RichTrackMCPartLinks"] = segments.MCParticlesLinkLocation + + +@configurable +def make_rich_track_segments_add_MC_time(track_name, input_tracks, options, results): + """ + Add timestamps to existing (reco) track segments using MC + """ + + # First make regular reco segments + make_rich_track_segments(track_name, input_tracks, options, results) + + # Add MC time + addSegTime = AddSegTimeMC( + name="RichAddSegTimeFromMC" + track_name + "_{hash}", + InTrackSegmentsLocation=results["TrackSegments"], + TracksLocation=input_tracks, + SegmentToTrackLocation=results["SegmentToTracks"], + MCParticlesLinkLocation=make_track_links(input_tracks, options["UseUT"]), + MCParticlesLocation=mc_unpacker("MCParticles"), + ) + + # set new segments as main ones to use + results["TrackSegments"] = addSegTime.OutTrackSegmentsLocation -- GitLab From cdd8c71bb989bc3f5eb341dff607cbe3fa32eecf Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Thu, 10 Apr 2025 14:32:55 +0100 Subject: [PATCH 09/14] rich_mc_checking.py: Move create of Track to MCParticle relations to own method --- .../python/RecoConf/rich_mc_checking.py | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py b/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py index 9f194932ae6..a1ce03ef081 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py +++ b/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py @@ -68,6 +68,10 @@ def default_rich_checking_options(): def make_track_links(tracks, useUT=True): + """ + Returns appropriate track to MC links + """ + if useUT: links_to_lhcbids = make_links_lhcbids_mcparticles_tracking_system() else: @@ -78,6 +82,30 @@ def make_track_links(tracks, useUT=True): ############################################################################### +def track_to_MCP_rels(conf, useUT=True): + """ + Creates useful relations from painful linkers + """ + + # Track linker stuff + if "RichTrackMCPartLinks" not in conf.keys(): + # Build Track -> MCP links ourselves + links_to_tracks = make_track_links(conf["OriginalV1Tracks"], useUT) + else: + links_to_tracks = conf["RichTrackMCPartLinks"] + + # Make the RICH Track -> MCParticle relations table + return TkToMCPRels( + name="RichTkToMCPRelations_{hash}", + TracksLocation=conf["OriginalV1Tracks"], + MCParticlesLinkLocation=links_to_tracks, + MCParticlesLocation=mc_unpacker("MCParticles"), + ) + + +############################################################################### + + @configurable def default_rich_checkers(moni_set="Standard"): """ @@ -158,25 +186,10 @@ def make_rich_checkers(conf, reco_opts, check_opts, moni_set="Standard"): checkers = default_rich_checkers(moni_set) # MC Info - mcps = mc_unpacker("MCParticles") richSummaries = mc_unpacker("MCRichDigitSummaries") - # Track linker stuff - if "RichTrackMCPartLinks" not in conf.keys(): - # Build Track -> MCP links ourselves - links_to_tracks = make_track_links( - conf["OriginalV1Tracks"], check_opts["UseUT"] - ) - else: - links_to_tracks = conf["RichTrackMCPartLinks"] - - # Make the RICH Track -> MCParticle relations table - tkMCPRels = TkToMCPRels( - name="RichTkToMCPRelations_{hash}", - TracksLocation=conf["OriginalV1Tracks"], - MCParticlesLinkLocation=links_to_tracks, - MCParticlesLocation=mcps, - ) + # Track to MCP relations + tkMCPRels = track_to_MCP_rels(conf, check_opts["UseUT"]) # Momentum cuts for plotting etc (by radiator) pCuts = {"MinP": (0.5 * GeV, 0.5 * GeV), "MaxP": (120.0 * GeV, 120.0 * GeV)} -- GitLab From 6de2d55130a1a24845a79cc2e5cf1ddab5607d47 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Thu, 10 Apr 2025 14:34:14 +0100 Subject: [PATCH 10/14] rich_reconstruction_mc_cheat.py: Add two new MC cheating options --- .../python/RecoConf/rich_reconstruction.py | 30 +++--- .../RecoConf/rich_reconstruction_mc_cheat.py | 95 ++++++++++++++++++- 2 files changed, 109 insertions(+), 16 deletions(-) diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py index 0d9241d6a42..3c38aae93b6 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py @@ -165,6 +165,8 @@ def default_rich_reco_options(init_override_opts={}): "MaxP": (9e90 * GeV, 9e90 * GeV), # Minimum transverse momentum cut "MinPt": 0 * GeV, + # Track resolution scale factors + "TkCKResScaleFactors": (1.0, 1.0), # =========================================================== # Photon treatment options # =========================================================== @@ -614,6 +616,7 @@ def make_track_resolution_info(track_name, options, results): TrackSegmentsLocation=results["TrackSegments"], SignalCherenkovAnglesLocation=results["SignalCKAngles"], MassHypothesisRingsLocation=results["EmittedCKRings"], + ScaleFactor=options["TkCKResScaleFactors"], ) elif options["TkCKResTreatment"] == "Parameterised": tkRes = ParamTrackCKRes( @@ -623,6 +626,7 @@ def make_track_resolution_info(track_name, options, results): MaxCKThetaRes=defaultMaxCKThetaResolutions()[tktype], TrackSegmentsLocation=results["TrackSegments"], SignalCherenkovAnglesLocation=results["SignalCKAngles"], + ScaleFactor=options["TkCKResScaleFactors"], ) else: raise ValueError( @@ -801,9 +805,11 @@ def make_rich_photons( options, photon_candidates=make_photon_candidates, photon_signals=make_photon_signals, + pixels=make_rich_pixels, + tracks=make_rich_tracks, ): """ - Return reconstructed photon specific RICH data. + Return RICH reconstructed photon candidates Args: track_name (str): The name to assign to this configuration @@ -826,13 +832,16 @@ def make_rich_photons( results["TrackName"] = track_name # Configure track and pixel level reco - results.update(make_rich_pixels(options=options)) + results.update(pixels(options=options)) results.update( - make_rich_tracks( - track_name=track_name, input_tracks=input_tracks, options=options - ) + tracks(track_name=track_name, input_tracks=input_tracks, options=options) ) + # Ensure original tracks are in results dict + v1tkkey = "OriginalV1Tracks" + if v1tkkey in options.keys() and v1tkkey not in results.keys(): + results[v1tkkey] = options[v1tkkey] + # Make photon candidates photon_candidates(track_name, options, results) @@ -879,6 +888,7 @@ def make_rich_pids( options, location=None, reco_summaries=make_reco_summaries, + photons=make_rich_photons, ): """ Return RICH PID data. @@ -905,15 +915,9 @@ def make_rich_pids( # save the name for this set of results results["TrackName"] = track_name - # pixel and track reco - results.update(make_rich_pixels(options=options)) - results.update( - make_rich_tracks( - track_name=track_name, input_tracks=input_tracks, options=options - ) - ) + # photon reco results.update( - make_rich_photons( + photons( track_name=track_name, input_tracks=input_tracks, options=options, diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py index bfcad157e1a..039848fcc81 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py @@ -16,6 +16,12 @@ from PyConf.Algorithms import ( from PyConf.Algorithms import ( Rich__Future__MC__DecodedDataFromMCRichHits as RichMCDecoder, ) +from PyConf.Algorithms import ( + Rich__Future__Rec__MC__RichPhotonUseMCInfo as PhotonUseMCInfo, +) +from PyConf.Algorithms import ( + Rich__Future__Rec__MC__RichPixelUseMCInfo as PixUseMCInfo, +) from PyConf.Algorithms import ( Rich__Future__Rec__MC__RichSegmentAddTimeFromMC as AddSegTimeMC, ) @@ -27,10 +33,13 @@ from PyConf.reading import get_mc_track_info from RecoConf.data_from_file import mc_unpacker from RecoConf.mc_checking import make_default_IdealStateCreator -from RecoConf.rich_mc_checking import make_track_links +from RecoConf.rich_mc_checking import make_track_links, track_to_MCP_rels from RecoConf.rich_reconstruction import ( decode_rich_raw, get_detector_bool_opts, + make_photon_candidates, + make_rich_clusters, + make_rich_pixels, make_rich_track_segments, ) @@ -43,9 +52,24 @@ def default_mc_reco_cheat_options(): opts = { "IsDetDescMC": True, - "pixUsePosFromMC": False, - "pixUseTimeFromMC": False, "ReadoutEfficiency": (0.95, 0.95), + "InnerPixelQuantization": (2.8, 2.8), + "OuterPixelQuantization": (5.6, 5.6), + "InnerPixelEff": (1.0, 1.0), + "OuterPixelEff": (1.0, 1.0), + "UseMCPhotonCKThetaValues": False, + "photEmulatedResMC": ( + # Inner (R1,R2) + ( + "(0.00078+0.0012*(std::tanh(-x/5000.0)+1.0))", + "(0.00065+0.0011*(std::tanh(-x/5000.0)+1.0))", + ), + # Outer (R1,R2) + ( + "(0.00078+0.0012*(std::tanh(-x/5000.0)+1.0))", + "(0.00065+0.0011*(std::tanh(-x/5000.0)+1.0))", + ), + ), } return opts @@ -169,3 +193,68 @@ def make_rich_track_segments_add_MC_time(track_name, input_tracks, options, resu # set new segments as main ones to use results["TrackSegments"] = addSegTime.OutTrackSegmentsLocation + + +@configurable +def make_rich_pixels_with_mc_positions(options, clusters=make_rich_clusters): + """ + Make SIMD pixels with MC cheated positions + """ + + # First make regular SIMD pixels + results = make_rich_pixels(options, clusters) + + # Then cheat positions + mcPos = PixUseMCInfo( + name="RichSIMDPixelsUseMCInfo_{hash}", + UseMCPosition=True, + UseMCTime=False, + InnerPixelQuantization=options["InnerPixelQuantization"], + OuterPixelQuantization=options["OuterPixelQuantization"], + InnerPixelEff=options["InnerPixelEff"], + OuterPixelEff=options["OuterPixelEff"], + InRichSIMDPixelSummariesLocation=results["RichSIMDPixels"], + MCRichHitsLocation=mc_unpacker("MCRichHits"), + PrevMCRichHitsLocation=mc_unpacker("Prev/MCRichHits"), + PrevPrevMCRichHitsLocation=mc_unpacker("PrevPrev/MCRichHits"), + NextMCRichHitsLocation=mc_unpacker("Next/MCRichHits"), + NextNextMCRichHitsLocation=mc_unpacker("NextNext/MCRichHits"), + LHCBackgroundMCRichHitsLocation=mc_unpacker("LHCBackground/MCRichHits"), + ) + + # redirect downstream algorithms to updated SIMD pixels + results["RichSIMDPixels"] = mcPos.OutRichSIMDPixelSummariesLocation + + # finally return the results dict + return results + + +@configurable +def make_photon_candidates_with_mc_info(track_name, options, results): + """ + Return RICH reconstructed photon candidates with some MC cheating + """ + + # first make regular photons + make_photon_candidates(track_name, options, results) + + # Then update with MC + mcPhotInfo = PhotonUseMCInfo( + name="RichPhotonUseMCInfo_{hash}", + InCherenkovPhotonLocation=results["CherenkovPhotons"], + TrackToMCParticlesRelations=track_to_MCP_rels(results), + TracksLocation=results["InputTracks"], + SegmentToTrackLocation=results["SegmentToTracks"], + PhotonToParentsLocation=results["PhotonToParents"], + SignalCherenkovAnglesLocation=results["SignalCKAngles"], + RichSIMDPixelSummariesLocation=results["RichSIMDPixels"], + RichDigitSummariesLocation=mc_unpacker("MCRichDigitSummaries"), + MCRichHitsLocation=mc_unpacker("MCRichHits"), + MCRichOpticalPhotonsLocation=mc_unpacker("MCRichOpticalPhotons"), + CKThetaSmearFuncInner=options["photEmulatedResMC"][0], + CKThetaSmearFuncOuter=options["photEmulatedResMC"][1], + UseMCPhotonCKThetaValues=options["UseMCPhotonCKThetaValues"], + ) + + # Finally update the photon data handle to use downstream + results["CherenkovPhotons"] = mcPhotInfo.OutCherenkovPhotonLocation -- GitLab From 09d8e2ba94dba99c67f9e3807be79fd5fd07368a Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 15 Apr 2025 14:54:30 +0100 Subject: [PATCH 11/14] rich_reconstruction: Add more options and settings to the defaults --- Hlt/RecoConf/python/RecoConf/rich_reconstruction.py | 8 ++++++++ .../python/RecoConf/rich_reconstruction_mc_cheat.py | 2 ++ 2 files changed, 10 insertions(+) diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py index 3c38aae93b6..167388c5dd9 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py @@ -142,6 +142,10 @@ def default_rich_reco_options(init_override_opts={}): "averageHitTime": (13.03, 52.94), # Course time window for hit selection (in ns) (for 4D reco) "pixelTimeWindow": (1.0, 1.0), + # Inner/Outer region override options + "pixOverrideRegions": False, + "InnerRegionsX": (250, 999999), + "InnerRegionsY": (300, 300), # =========================================================== # Track treatment options # =========================================================== @@ -378,6 +382,10 @@ def make_rich_pixels(options, clusters=make_rich_clusters): CourseTimeWindow=options["pixelTimeWindow"], InnerFineTimeWindow=timeWin[0], OuterFineTimeWindow=timeWin[1], + # Emulation support + OverrideRegions=options["pixOverrideRegions"], + InnerPixelsX=options["InnerRegionsX"], + InnerPixelsY=options["InnerRegionsY"], ) results["RichSIMDPixels"] = simdPixels.RichSIMDPixelSummariesLocation diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py index 039848fcc81..eb314c08c15 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py @@ -51,6 +51,8 @@ def default_mc_reco_cheat_options(): """ opts = { + "EmulateRawFromMC": False, + "EmulateTracksFromMC": False, "IsDetDescMC": True, "ReadoutEfficiency": (0.95, 0.95), "InnerPixelQuantization": (2.8, 2.8), -- GitLab From 89327a049a4c86d9a4f95767ff50756d953a7520 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 15 Apr 2025 16:00:02 +0100 Subject: [PATCH 12/14] rich_mc_checking.py: Add option to create PID tuple --- .../python/RecoConf/rich_mc_checking.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py b/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py index a1ce03ef081..ccfd0db4f70 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py +++ b/Hlt/RecoConf/python/RecoConf/rich_mc_checking.py @@ -23,6 +23,9 @@ from PyConf.Algorithms import ( from PyConf.Algorithms import Rich__Future__Rec__MC__Moni__DetectorHits as DetectorHits from PyConf.Algorithms import Rich__Future__Rec__MC__Moni__OpticalPhotons as MCOptPhots from PyConf.Algorithms import Rich__Future__Rec__MC__Moni__PIDQC as PIDQC +from PyConf.Algorithms import ( + Rich__Future__Rec__MC__Moni__RichPIDTupleCreatorAlg as RichPIDTuple, +) from PyConf.Algorithms import ( Rich__Future__Rec__MC__Moni__SIMDPhotonCherenkovAngles as MCCKAngles, ) @@ -128,6 +131,7 @@ def default_rich_checkers(moni_set="Standard"): "TrackResolution", "MCOpticalPhotons", "Time", + "PIDTuple", ], "Standard": # The default set of monitors ["PIDPerformance", "PhotonCherenkovAngles", "TrackResolution", "Time"], @@ -333,4 +337,19 @@ def make_rich_checkers(conf, reco_opts, check_opts, moni_set="Standard"): TracksLocation=conf["InputTracks"], ) + # PID tuple + key = "PIDTuple" + if key in checkers: + # Momentum cuts for plotting etc (by radiator) + pCutsPID = [2.0 * GeV, 100 * GeV] + # Make a PID monitor for this selection + results[key] = RichPIDTuple( + name="RichPIDTuple", + NTupleLUN="RICHTUPLE1", + TrackSelector=TrackSelector(MinPCut=pCutsPID[0], MaxPCut=pCutsPID[1]), + TracksLocation=conf["InputTracks"], + RichPIDsLocation=conf["RichPIDs"], + TrackToMCParticlesRelations=track_to_MCP_rels(conf), + ) + return results -- GitLab From 78ecaca059746d0a19ee3eb94701398919fb784b Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 16 Apr 2025 11:53:05 +0100 Subject: [PATCH 13/14] rich_reconstruction.py: Fix default value for pixOverrideRegions --- Hlt/RecoConf/python/RecoConf/rich_reconstruction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py index 167388c5dd9..e79c6e83fc3 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction.py @@ -143,7 +143,7 @@ def default_rich_reco_options(init_override_opts={}): # Course time window for hit selection (in ns) (for 4D reco) "pixelTimeWindow": (1.0, 1.0), # Inner/Outer region override options - "pixOverrideRegions": False, + "pixOverrideRegions": (False, False), "InnerRegionsX": (250, 999999), "InnerRegionsY": (300, 300), # =========================================================== -- GitLab From eb4804aa838c787536581a2ddc7a97bdd261c120 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 16 Apr 2025 15:01:58 +0100 Subject: [PATCH 14/14] Add some more settings to rich_reconstruction_mc_cheat default options dict --- .../RecoConf/rich_reconstruction_mc_cheat.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py b/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py index eb314c08c15..a4b03448779 100644 --- a/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py +++ b/Hlt/RecoConf/python/RecoConf/rich_reconstruction_mc_cheat.py @@ -52,7 +52,12 @@ def default_mc_reco_cheat_options(): opts = { "EmulateRawFromMC": False, + "RejectAllPixelBackgrounds": False, + "RejectScintillation": False, "EmulateTracksFromMC": False, + "IncludeTimeInfo": True, + "AllowMultipleHits": True, + "MaxHitsPerChannel": (99999, 99999), "IsDetDescMC": True, "ReadoutEfficiency": (0.95, 0.95), "InnerPixelQuantization": (2.8, 2.8), @@ -89,11 +94,11 @@ def emulated_raw_from_MC(options): results["RichDecodedData"] = RichMCDecoder( name="RichDecodeFromMC_{hash}", IsDetDescMC=options["IsDetDescMC"], - RejectAllBackgrounds=False, - RejectScintillation=False, - IncludeTimeInfo=True, - AllowMultipleHits=True, - MaxHitsPerChannel=(99999, 99999), + RejectAllBackgrounds=options["RejectAllPixelBackgrounds"], + RejectScintillation=options["RejectScintillation"], + IncludeTimeInfo=options["IncludeTimeInfo"], + AllowMultipleHits=options["AllowMultipleHits"], + MaxHitsPerChannel=options["MaxHitsPerChannel"], ReadoutEfficiency=options["ReadoutEfficiency"], MCRichHitsLocation=mc_unpacker("MCRichHits"), PrevMCRichHitsLocation=mc_unpacker("Prev/MCRichHits"), -- GitLab