18from ROOT
import Belle2
24from ROOT
import gSystem
25gSystem.Load(
'libtracking')
26gSystem.Load(
'libtrackFindingCDC')
30 return logging.getLogger(__name__)
33CONTACT =
"oliver.frost@desy.de"
37 """Generate, postprocess and inspect MC events for track segment-pair validation"""
39 segment_finder_module = basf2.register_module(
"TFCDC_SegmentCreatorMCTruth")
40 segment_finder_module.param({
"MinCDCHits": 4})
43 segment_pair_finder_module = basf2.register_module(
"TFCDC_TrackFinderSegmentPairAutomaton")
44 segment_pair_finder_module.param({
45 "WriteSegmentPairs":
True,
46 "SegmentPairFilter":
"all",
47 "SegmentPairRelationFilter":
"none",
53 output_file_name =
"SegmentPairCreationValidation.root"
56 """Convert command-line arguments to basf2 argument list"""
58 return argument_parser
60 def create_path(self):
62 Sets up a path that plays back pregenerated events or generates events
63 based on the properties
in the base
class.
65 main_path = super().create_path()
68 main_path.add_module(segment_finder_module)
70 main_path.add_module("TFCDC_SegmentFitter")
73 main_path.add_module(segment_pair_finder_module)
78 main_path.add_module(metamodules.PyProfilingModule(validation_module))
80 main_path.add_module(validation_module)
87 """Module to collect information about the generated segments and compose validation plots on terminate."""
91 super().__init__(foreach="CDCSegmentPairVector",
92 output_file_name=output_file_name)
101 """Receive signal at the start of event processing"""
108 """Initialize the MC-hit lookup method"""
111 def pick(self, segment_pair_relation):
112 """Select segment pairs with 4 or more hit in each segments and a matching primary MC particle"""
114 start_segment = segment_pair_relation.getStartSegment()
115 end_segment = segment_pair_relation.getEndSegment()
116 mc_particle = mc_segment_lookup.getMCParticle(start_segment)
117 return (mc_particle
and
118 is_primary(mc_particle)
and
119 start_segment.size() > 3
and
120 end_segment.size() > 3)
122 def peel(self, segment_pair_relation):
123 """Aggregate the track and MC information for track segment-pair analysis"""
125 crops.update(self.
peel_mc(segment_pair_relation))
126 crops.update(self.
peel_fit(segment_pair_relation))
130 """Create a dictionary of MC-truth (weight,decision) pairs"""
132 mc_decision = np.isfinite(mc_weight)
136 mc_decision=mc_decision,
140 """Create a dictionary of MC-truth (curvature,tanlambda) pairs"""
143 end_segment = segment_pair_relation.getEndSegment()
147 fit3d_truth = mc_segment_lookup.getTrajectory3D(end_segment)
150 curvature_truth=fit3d_truth.getCurvatureXY(),
151 tan_lambda_truth=fit3d_truth.getTanLambda(),
155 """Create a dictionary of track-segment-fit information"""
156 fitless_crops = self.
peel_fitless(segment_pair_relation)
158 select_fitless = fitless_crops[
"select_fitless"]
161 self.
fit(segment_pair_relation)
162 fit3d = segment_pair_relation.getTrajectory3D()
167 chi2 = fit3d.getChi2()
170 curvature_estimate = fit3d.getCurvatureXY()
171 curvature_variance = fit3d.getLocalVariance(i_curv)
173 tan_lambda_estimate = fit3d.getTanLambda()
174 tan_lambda_variance = fit3d.getLocalVariance(i_tan_lambda)
178 p_value = prob(chi2, ndf)
183 curvature_estimate = nan
184 curvature_variance = nan
186 tan_lambda_estimate = nan
187 tan_lambda_variance = nan
194 curvature_estimate=curvature_estimate,
195 curvature_variance=curvature_variance,
197 tan_lambda_estimate=tan_lambda_estimate,
198 tan_lambda_variance=tan_lambda_variance,
206 crops[
"select"] = self.
select(crops)
208 crops[
"select"] =
False
210 crops.update(fitless_crops)
215 """Create a dictionary of track-segments-without-fit information"""
218 start_segment = segment_pair_relation.getStartSegment()
219 end_segment = segment_pair_relation.getEndSegment()
221 start_fit2d = start_segment.getTrajectory2D()
222 end_fit2d = end_segment.getTrajectory2D()
224 start_superlayer_id = start_segment.getISuperLayer()
225 end_superlayer_id = end_segment.getISuperLayer()
227 sorted_superlayer_ids = sorted([start_superlayer_id, end_superlayer_id])
229 superlayer_id_pair = 10.0 * sorted_superlayer_ids[1] + sorted_superlayer_ids[0]
231 fitless_crops = dict(
232 start_superlayer_id=start_superlayer_id,
233 end_superlayer_id=end_superlayer_id,
234 superlayer_id_pair=superlayer_id_pair,
236 start_size=start_segment.size(),
237 end_size=end_segment.size(),
239 start_curvature_estimate=start_fit2d.getCurvature(),
240 end_curvature_estimate=end_fit2d.getCurvature(),
242 delta_phi=segment_pair_relation.computeDeltaPhiAtSuperLayerBound(),
243 is_coaligned=segment_pair_relation.computeIsCoaligned(),
245 start_is_before_end=segment_pair_relation.computeStartIsBeforeEnd(),
246 end_is_after_start=segment_pair_relation.computeEndIsAfterStart(),
249 fitless_crops[
"select_fitless"] = self.
select_fitless(fitless_crops)
252 def fit(self, segment_pair_relation):
253 """Fit the segment pair"""
257 delta_phi_cut_value = 1.0
259 is_after_cut_value = 1.0
262 """Selection of track-segments-without-fit"""
263 delta_phi = fitless_crops[
"delta_phi"]
264 start_is_before_end = fitless_crops[
"start_is_before_end"]
265 end_is_after_start = fitless_crops[
"end_is_after_start"]
270 """Select every track-segment-pair"""
275 save_histograms = refiners.save_histograms(outlier_z_score=5.0, allow_discrete=
True)
277 save_tree = refiners.save_tree()
281 save_fitless_selection_variables_histograms = refiners.save_histograms(
282 select=[
"mc_decision",
"delta_phi",
"start_is_before_end",
"end_is_after_start",
"is_coaligned"],
285 stackby=
"mc_decision",
286 folder_name=
"fitless_selection_variables",
290 save_view_is_after_cut_histograms = refiners.save_histograms(
291 select=[
"mc_decision",
"start_is_before_end",
"end_is_after_start"],
292 lower_bound=-is_after_cut_value,
293 upper_bound=is_after_cut_value,
294 stackby=
"mc_decision",
295 folder_name=
"view_fitless_cuts",
299 save_view_delta_phi_cut_histograms = refiners.save_histograms(
300 select=[
"mc_decision",
"delta_phi"],
301 lower_bound=-delta_phi_cut_value,
302 upper_bound=delta_phi_cut_value,
303 stackby=
"mc_decision",
304 folder_name=
"view_fitless_cuts",
309 save_selection_variables_after_fitless_selection_histograms = refiners.save_histograms(
310 select=[
"mc_decision",
"chi2",
"ndf",
"p_value"],
313 stackby=
"mc_decision",
314 folder_name=
"selection_variables_after_fitless_selection",
315 filter_on=
"select_fitless",
320 save_p_value_over_curvature_profile = refiners.save_profiles(
321 select={
"p_value":
"p-value",
"curvature_truth":
"true curvature"},
323 folder_name=
"selection_variables_after_fitless_selection",
324 title=
r"$p$-value versus true curvature after fitless selection",
325 filter_on=
"select_fitless",
329 @refiners.context(groupby=[None, "superlayer_id_pair"], exclude_groupby=False)
332 """Print diagnostic information about the track-segment-pair selection"""
333 info = get_logger().info
338 superlayer_id_pair = crops[
"superlayer_id_pair"]
339 info(
"Number of pairs in superlayers %s : %s", np.unique(superlayer_id_pair), len(superlayer_id_pair))
341 mc_decisions = crops[
"mc_decision"]
342 n = len(mc_decisions)
343 n_signal = np.sum(mc_decisions)
344 n_background = n - n_signal
345 info(
"#Signal : %s", n_signal)
346 info(
"#Background : %s", n_background)
348 fitless_selections = np.nonzero(crops[
"select_fitless"])
349 info(
"#Signal after precut : %s", np.sum(mc_decisions[fitless_selections]))
350 info(
"#Background after precut : %s", np.sum(1 - mc_decisions[fitless_selections]))
355 run.configure_and_execute_from_commandline()
358if __name__ ==
"__main__":
359 logging.basicConfig(stream=sys.stdout, level=logging.INFO, format=
'%(levelname)s:%(message)s')
Utility class implementing the Kalmanesk combination of to two dimensional trajectories to one three ...
static const CDCMCHitLookUp & getInstance()
Getter for the singletone instance.
static const CDCMCSegment2DLookUp & getInstance()
Getter for the singletone instance.
Filter for the construction of axial to stereo segment pairs based on MC information.
def peel_target(self, segment_pair_relation)
def peel_fitless(self, segment_pair_relation)
float delta_phi_cut_value
default selection for the delta-phi of the segment pair
def peel_mc(self, segment_pair_relation)
def pick(self, segment_pair_relation)
mc_segment_pair_filter
defer reference to MCSegmentPairFilter until after it is constructed
segment_pair_fusion
defer reference to CDCAxialStereoFusion until after it is constructed
mc_segment_lookup
defer reference to CDCMCSegment2dLookUp singleton until after it is constructed
def peel_fit(self, segment_pair_relation)
def select_fitless(self, fitless_crops)
def print_signal_number(self, crops, tdirectory, **kwds)
float is_after_cut_value
default selection for the ordering of the segment pair
def fit(self, segment_pair_relation)
def peel(self, segment_pair_relation)
def __init__(self, output_file_name)
def create_argument_parser(self, **kwds)
basf2 segment_finder_module
Use the SegmentFinderFacetAutomaton for track-segment creation with MC truth-matching.
basf2 segment_pair_finder_module
use the TrackFinderSegmentPairAutomaton for track-segment finding
bool py_profile
post-process with profiling validation
str output_file_name
specify the output ROOT file
None output_file_name
There is no default for the name of the output TFile.