19 from ROOT
import Belle2
25 from ROOT
import gSystem
26 gSystem.Load(
'libtracking')
27 gSystem.Load(
'libtrackFindingCDC')
31 return logging.getLogger(__name__)
34 CONTACT =
"oliver.frost@desy.de"
38 """Generate, postprocess and inspect MC events for track segment-pair validation"""
40 segment_finder_module = basf2.register_module(
"TFCDC_SegmentCreatorMCTruth")
41 segment_finder_module.param({
"MinCDCHits": 4})
44 segment_pair_finder_module = basf2.register_module(
"TFCDC_TrackFinderSegmentPairAutomaton")
45 segment_pair_finder_module.param({
46 "WriteSegmentPairs":
True,
47 "SegmentPairFilter":
"all",
48 "SegmentPairRelationFilter":
"none",
54 output_file_name =
"SegmentPairCreationValidation.root"
57 """Convert command-line arguments to basf2 argument list"""
59 return argument_parser
63 Sets up a path that plays back pregenerated events or generates events
64 based on the properties in the base class.
66 main_path = super(SegmentPairCreationValidationRun, self).
create_path()
69 main_path.add_module(segment_finder_module)
71 main_path.add_module(
"TFCDC_SegmentFitter")
74 main_path.add_module(segment_pair_finder_module)
79 main_path.add_module(metamodules.PyProfilingModule(validation_module))
81 main_path.add_module(validation_module)
88 """Module to collect information about the generated segments and compose validation plots on terminate."""
92 super(SegmentPairCreationValidationModule, self).
__init__(foreach=
"CDCSegmentPairVector",
93 output_file_name=output_file_name)
102 """Receive signal at the start of event processing"""
103 super(SegmentPairCreationValidationModule, self).
initialize()
109 """Initialize the MC-hit lookup method"""
112 def pick(self, segment_pair_relation):
113 """Select segment pairs with 4 or more hit in each segments and a matching primary MC particle"""
115 start_segment = segment_pair_relation.getStartSegment()
116 end_segment = segment_pair_relation.getEndSegment()
117 mc_particle = mc_segment_lookup.getMCParticle(start_segment)
118 return (mc_particle
and
119 is_primary(mc_particle)
and
120 start_segment.size() > 3
and
121 end_segment.size() > 3)
123 def peel(self, segment_pair_relation):
124 """Aggregate the track and MC information for track segment-pair analysis"""
125 crops = self.
peel_targetpeel_target(segment_pair_relation)
126 crops.update(self.
peel_mcpeel_mc(segment_pair_relation))
127 crops.update(self.
peel_fitpeel_fit(segment_pair_relation))
131 """Create a dictionary of MC-truth (weight,decision) pairs"""
133 mc_decision = np.isfinite(mc_weight)
137 mc_decision=mc_decision,
141 """Create a dictionary of MC-truth (curvature,tanlambda) pairs"""
144 end_segment = segment_pair_relation.getEndSegment()
148 fit3d_truth = mc_segment_lookup.getTrajectory3D(end_segment)
151 curvature_truth=fit3d_truth.getCurvatureXY(),
152 tan_lambda_truth=fit3d_truth.getTanLambda(),
156 """Create a dictionary of track-segment-fit information"""
157 fitless_crops = self.
peel_fitlesspeel_fitless(segment_pair_relation)
159 select_fitless = fitless_crops[
"select_fitless"]
162 self.
fitfit(segment_pair_relation)
163 fit3d = segment_pair_relation.getTrajectory3D()
168 chi2 = fit3d.getChi2()
171 curvature_estimate = fit3d.getCurvatureXY()
172 curvature_variance = fit3d.getLocalVariance(i_curv)
174 tan_lambda_estimate = fit3d.getTanLambda()
175 tan_lambda_variance = fit3d.getLocalVariance(i_tan_lambda)
179 p_value = prob(chi2, ndf)
184 curvature_estimate = nan
185 curvature_variance = nan
187 tan_lambda_estimate = nan
188 tan_lambda_variance = nan
195 curvature_estimate=curvature_estimate,
196 curvature_variance=curvature_variance,
198 tan_lambda_estimate=tan_lambda_estimate,
199 tan_lambda_variance=tan_lambda_variance,
207 crops[
"select"] = self.
selectselect(crops)
209 crops[
"select"] =
False
211 crops.update(fitless_crops)
216 """Create a dictionary of track-segments-without-fit information"""
219 start_segment = segment_pair_relation.getStartSegment()
220 end_segment = segment_pair_relation.getEndSegment()
222 start_fit2d = start_segment.getTrajectory2D()
223 end_fit2d = end_segment.getTrajectory2D()
225 start_superlayer_id = start_segment.getISuperLayer()
226 end_superlayer_id = end_segment.getISuperLayer()
228 sorted_superlayer_ids = sorted([start_superlayer_id, end_superlayer_id])
230 superlayer_id_pair = 10.0 * sorted_superlayer_ids[1] + sorted_superlayer_ids[0]
232 fitless_crops = dict(
233 start_superlayer_id=start_superlayer_id,
234 end_superlayer_id=end_superlayer_id,
235 superlayer_id_pair=superlayer_id_pair,
237 start_size=start_segment.size(),
238 end_size=end_segment.size(),
240 start_curvature_estimate=start_fit2d.getCurvature(),
241 end_curvature_estimate=end_fit2d.getCurvature(),
243 delta_phi=segment_pair_relation.computeDeltaPhiAtSuperLayerBound(),
244 is_coaligned=segment_pair_relation.computeIsCoaligned(),
246 start_is_before_end=segment_pair_relation.computeStartIsBeforeEnd(),
247 end_is_after_start=segment_pair_relation.computeEndIsAfterStart(),
250 fitless_crops[
"select_fitless"] = self.
select_fitlessselect_fitless(fitless_crops)
253 def fit(self, segment_pair_relation):
254 """Fit the segment pair"""
255 self.
segment_pair_fusionsegment_pair_fusion.reconstructFuseTrajectories(segment_pair_relation,
True)
258 delta_phi_cut_value = 1.0
260 is_after_cut_value = 1.0
263 """Selection of track-segments-without-fit"""
264 delta_phi = fitless_crops[
"delta_phi"]
265 start_is_before_end = fitless_crops[
"start_is_before_end"]
266 end_is_after_start = fitless_crops[
"end_is_after_start"]
271 """Select every track-segment-pair"""
276 save_histograms = refiners.save_histograms(outlier_z_score=5.0, allow_discrete=
True)
278 save_tree = refiners.save_tree()
282 save_fitless_selection_variables_histograms = refiners.save_histograms(
283 select=[
"mc_decision",
"delta_phi",
"start_is_before_end",
"end_is_after_start",
"is_coaligned"],
286 stackby=
"mc_decision",
287 folder_name=
"fitless_selection_variables",
291 save_view_is_after_cut_histograms = refiners.save_histograms(
292 select=[
"mc_decision",
"start_is_before_end",
"end_is_after_start"],
293 lower_bound=-is_after_cut_value,
294 upper_bound=is_after_cut_value,
295 stackby=
"mc_decision",
296 folder_name=
"view_fitless_cuts",
300 save_view_delta_phi_cut_histograms = refiners.save_histograms(
301 select=[
"mc_decision",
"delta_phi"],
302 lower_bound=-delta_phi_cut_value,
303 upper_bound=delta_phi_cut_value,
304 stackby=
"mc_decision",
305 folder_name=
"view_fitless_cuts",
310 save_selection_variables_after_fitless_selection_histograms = refiners.save_histograms(
311 select=[
"mc_decision",
"chi2",
"ndf",
"p_value"],
314 stackby=
"mc_decision",
315 folder_name=
"selection_variables_after_fitless_selection",
316 filter_on=
"select_fitless",
321 save_p_value_over_curvature_profile = refiners.save_profiles(
322 select={
"p_value":
"p-value",
"curvature_truth":
"true curvature"},
324 folder_name=
"selection_variables_after_fitless_selection",
325 title=
r"$p$-value versus true curvature after fitless selection",
326 filter_on=
"select_fitless",
330 @refiners.context(groupby=[None, "superlayer_id_pair"], exclude_groupby=False)
333 """Print diagnostic information about the track-segment-pair selection"""
334 info = get_logger().info
339 superlayer_id_pair = crops[
"superlayer_id_pair"]
340 info(
"Number of pairs in superlayers %s : %s", np.unique(superlayer_id_pair), len(superlayer_id_pair))
342 mc_decisions = crops[
"mc_decision"]
343 n = len(mc_decisions)
344 n_signal = np.sum(mc_decisions)
345 n_background = n - n_signal
346 info(
"#Signal : %s", n_signal)
347 info(
"#Background : %s", n_background)
349 fitless_selections = np.nonzero(crops[
"select_fitless"])
350 info(
"#Signal after precut : %s", np.sum(mc_decisions[fitless_selections]))
351 info(
"#Background after precut : %s", np.sum(1 - mc_decisions[fitless_selections]))
356 run.configure_and_execute_from_commandline()
359 if __name__ ==
"__main__":
360 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 constuction 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)
string output_file_name
specify the output ROOT file
segment_finder_module
Use the SegmentFinderFacetAutomaton for track-segment creation with MC truth-matching.
bool py_profile
post-process with profiling validation
segment_pair_finder_module
use the TrackFinderSegmentPairAutomaton for track-segment finding
output_file_name
There is no default for the name of the output TFile.
int main(int argc, char **argv)
Run all tests.