459 def terminate(self):
460 """Receive signal at the end of event processing"""
461 name = self.validation_name
462 contact = self.contact
463
464
465
466
467 mc_matched_primaries = np.logical_and(self.mc_primaries, self.mc_matches)
468
469 charge_asymmetry = np.average(self.mc_charge_asymmetry, weights=self.mc_charge_asymmetry_weights)
470 if len(mc_matched_primaries) > 0 and sum(mc_matched_primaries) > 0:
471 charge_efficiency = np.average(self.mc_charge_matches, weights=mc_matched_primaries)
472 hit_efficiency = np.average(self.mc_hit_efficiencies, weights=mc_matched_primaries)
473 else:
474 charge_efficiency = float('nan')
475 hit_efficiency = float('nan')
476 finding_charge_efficiency = np.average(self.mc_charge_matches, weights=self.mc_primaries)
477 finding_efficiency = np.average(self.mc_matches, weights=self.mc_primaries)
478 fake_rate = 1.0 - np.mean(self.pr_clones_and_matches)
479
480 if len(self.pr_clones_and_matches) > 0 and sum(self.pr_clones_and_matches) > 0:
481 clone_rate = 1.0 - np.average(self.pr_matches,
482 weights=self.pr_clones_and_matches)
483 else:
484 clone_rate = float('nan')
485
486 figures_of_merit = ValidationFiguresOfMerit(f'{name}_figures_of_merit')
487 figures_of_merit['finding_charge_efficiency'] = finding_charge_efficiency
488 figures_of_merit['finding_efficiency'] = finding_efficiency
489 figures_of_merit['charge_efficiency'] = charge_efficiency
490 figures_of_merit['charge_asymmetry'] = charge_asymmetry
491 figures_of_merit['fake_rate'] = fake_rate
492 figures_of_merit['clone_rate'] = clone_rate
493 figures_of_merit['hit_efficiency'] = hit_efficiency
494
495 figures_of_merit.description = \
496 """
497finding_efficiency - the ratio of matched Monte Carlo tracks to all primary Monte Carlo tracks <br/>
498charge_efficiency - the ratio of matched Monte Carlo tracks with correct charge to matched primary Monte Carlo tracks <br/>
499finding_charge_efficiency - the ratio of matched Monte Carlo tracks with correct charge to all primary Monte Carlo tracks <br/>
500fake_rate - ratio of pattern recognition tracks that are not related to a particle
501 (background, ghost) to all pattern recognition tracks <br/>
502clone_rate - ratio of clones divided the number of tracks that are related to a particle (clones and matches) <br/>
503
504"""
505 figures_of_merit.check = 'Compare for degradations with respect to the reference'
506 figures_of_merit.contact = contact
507 print(figures_of_merit)
508
509
510
511 validation_plots = []
512 pull_analyses = []
513
514
515
516 plots = self.profiles_by_mc_parameters(self.mc_matches,
517 'finding efficiency',
518 make_hist=False,
519 weights=self.mc_primaries)
520
521 validation_plots.extend(plots)
522
523
524
525
526
527 print('fake list: ' + str(self.pr_fakes.count(1)))
528 plots = self.profiles_by_pr_parameters(self.pr_fakes, 'fake rate',
529 make_hist=False)
530
531 validation_plots.extend(plots)
532
533
534
535 plots = self.profiles_by_mc_parameters(self.mc_charge_matches,
536 'charge efficiency for matched primary tracks',
537 weights=mc_matched_primaries)
538
539 validation_plots.extend(plots)
540
541
542
543 plots = self.profiles_by_mc_parameters(self.mc_charge_matches,
544 'finding and charge efficiency for primary tracks',
545 weights=self.mc_primaries)
546
547 validation_plots.extend(plots)
548
549
550
551 plots = self.profiles_by_mc_parameters(self.mc_charge_asymmetry,
552 'charge asymmetry for primary tracks',
553 weights=self.mc_charge_asymmetry_weights,
554 is_asymmetry=True)
555
556 validation_plots.extend(plots)
557
558
559
560 plots = self.profiles_by_mc_parameters(self.mc_hit_efficiencies,
561 'hit efficiency with matched tracks',
562 weights=mc_matched_primaries)
563
564 validation_plots.extend(plots)
565
566
567
568 if self.pulls:
569 all_but_diagonal_plots = list(PullAnalysis.default_which_plots)
570 all_but_diagonal_plots.remove("diag_profile")
571 all_but_diagonal_plots.remove("diag_scatter")
572
573 plot_name_prefix = name + self.plot_name_postfix
574 if not self.fit:
575 plot_name_prefix += '_seed'
576
577
578 pr_omega_truths = np.array(self.pr_omega_truths)
579 pr_omega_estimates = np.array(self.pr_omega_estimates)
580 pr_omega_variances = np.array(self.pr_omega_variances)
581
582 curvature_pull_analysis = PullAnalysis('#omega', unit='1/cm',
583 plot_name_prefix=plot_name_prefix + '_omega',
584 plot_title_postfix=self.plot_title_postfix,
585 referenceFileName=self.referenceFileName)
586
587 curvature_pull_analysis.analyse(pr_omega_truths,
588 pr_omega_estimates,
589 pr_omega_variances,
590 which_plots=all_but_diagonal_plots)
591
592 curvature_pull_analysis.contact = contact
593 pull_analyses.append(curvature_pull_analysis)
594
595
596 pr_tan_lambda_truths = np.array(self.pr_tan_lambda_truths)
597 pr_tan_lambda_estimates = np.array(self.pr_tan_lambda_estimates)
598 pr_tan_lambda_variances = np.array(self.pr_tan_lambda_variances)
599
600 curvature_pull_analysis = PullAnalysis('tan #lambda',
601 plot_name_prefix=plot_name_prefix + '_tan_lambda',
602 plot_title_postfix=self.plot_title_postfix,
603 referenceFileName=self.referenceFileName)
604
605 curvature_pull_analysis.analyse(pr_tan_lambda_truths,
606 pr_tan_lambda_estimates,
607 pr_tan_lambda_variances,
608 which_plots=all_but_diagonal_plots)
609
610 curvature_pull_analysis.contact = contact
611 pull_analyses.append(curvature_pull_analysis)
612
613
614 curvature_pull_analysis = PullAnalysis('d0',
615 plot_name_prefix=plot_name_prefix + '_d0',
616 plot_title_postfix=self.plot_title_postfix,
617 referenceFileName=self.referenceFileName)
618
619 curvature_pull_analysis.analyse(np.array(self.pr_d0_truths),
620 np.array(self.pr_d0_estimates),
621 np.array(self.pr_d0_variances),
622 which_plots=all_but_diagonal_plots)
623
624 curvature_pull_analysis.contact = contact
625 pull_analyses.append(curvature_pull_analysis)
626
627
628
629 if self.resolution:
630
631 d0_resolution_analysis = ResolutionAnalysis('d0_res',
632 self.resolution_pt_binning,
633 'Pt',
634 plot_name_prefix=plot_name_prefix + '_d0_res',
635 plot_title_postfix=self.plot_title_postfix,
636 referenceFileName=self.referenceFileName)
637 d0_resolution_analysis.analyse(np.array(self.pr_bining_pt),
638 np.array(self.pr_d0_truths),
639 np.array(self.pr_d0_estimates))
640 d0_resolution_analysis.contact = contact
641 pull_analyses.append(d0_resolution_analysis)
642
643
644 z0_resolution_analysis = ResolutionAnalysis('z0_res',
645 self.resolution_pt_binning,
646 "Pt",
647 plot_name_prefix=plot_name_prefix + '_z0_res',
648 plot_title_postfix=self.plot_title_postfix,
649 referenceFileName=self.referenceFileName)
650 z0_resolution_analysis.analyse(np.array(self.pr_bining_pt),
651 np.array(self.pr_z0_truths),
652 np.array(self.pr_z0_estimates))
653 z0_resolution_analysis.contact = contact
654 pull_analyses.append(z0_resolution_analysis)
655
656
657 omega_resolution_analysis = ResolutionAnalysis('omega_res',
658 self.resolution_pt_binning,
659 "Pt",
660 plot_name_prefix=plot_name_prefix + '_omega_res',
661 plot_title_postfix=self.plot_title_postfix,
662 referenceFileName=self.referenceFileName)
663 omega_resolution_analysis.analyse(np.array(self.pr_bining_pt),
664 np.array(self.pr_omega_truths),
665 np.array(self.pr_omega_estimates))
666 omega_resolution_analysis.contact = contact
667 pull_analyses.append(omega_resolution_analysis)
668
669
670 pt_resolution_analysis = ResolutionAnalysis('pt_res',
671 self.resolution_pt_binning,
672 "Pt",
673 plot_name_prefix=plot_name_prefix + '_pt_res',
674 plot_title_postfix=self.plot_title_postfix,
675 referenceFileName=self.referenceFileName)
676 pt_resolution_analysis.analyse(np.array(self.pr_bining_pt),
677 np.array(self.pr_pt_truths),
678 np.array(self.pr_pt_estimates))
679 pt_resolution_analysis.contact = contact
680 pull_analyses.append(pt_resolution_analysis)
681
682
683
684
685
686 output_tfile = ROOT.TFile(self.output_file_name, 'recreate')
687
688
689
690 opt_fit = 0o112
691 ROOT.gStyle.SetOptFit(opt_fit)
692
693 figures_of_merit.write()
694
695 for validation_plot in validation_plots:
696 validation_plot.write()
697
698 if self.use_expert_folder:
699 expert_tdirectory = output_tfile.mkdir('expert', 'Expert')
700 expert_tdirectory.cd()
701 ROOT.gStyle.SetOptFit(opt_fit)
702
703 for pull_analysis in pull_analyses:
704 pull_analysis.write()
705
706 output_tfile.Close()
707