From f610b7e6cf2b9f13742beeed9363ab50cbdceeed Mon Sep 17 00:00:00 2001 From: mmusich Date: Mon, 29 Jul 2024 17:44:28 +0200 Subject: [PATCH] add a unit tests for BeamSpotCompatibilityChecker --- .../BeamSpotProducer/test/BuildFile.xml | 9 ++ .../test/testBeamSpotCompatibility.cc | 63 +++++++++++ .../test/testBeamSpotCompatibility.sh | 33 ++++++ .../test/testBeamSpotCompatibility_cfg.py | 102 ++++++++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility.cc create mode 100755 RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility.sh create mode 100644 RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility_cfg.py diff --git a/RecoVertex/BeamSpotProducer/test/BuildFile.xml b/RecoVertex/BeamSpotProducer/test/BuildFile.xml index f1160ea481f24..2c75914b38196 100644 --- a/RecoVertex/BeamSpotProducer/test/BuildFile.xml +++ b/RecoVertex/BeamSpotProducer/test/BuildFile.xml @@ -11,7 +11,16 @@ + + + + + + + + + diff --git a/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility.cc b/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility.cc new file mode 100644 index 0000000000000..de5515318e718 --- /dev/null +++ b/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility.cc @@ -0,0 +1,63 @@ +#include "FWCore/TestProcessor/interface/TestProcessor.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "RecoVertex/BeamSpotProducer/plugins/BeamSpotCompatibilityChecker.cc" + +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +//_________________________________________________________ +TEST_CASE("Significance Calculation", "[Significance]") { + double a = 10.0; + double b = 12.0; + double errA = 1.0; + double errB = 1.5; + + Significance sig(a, b, errA, errB); + float significance = sig.getSig(false); + + // Correct the expected value based on actual calculation + REQUIRE(significance == Approx(1.1094).epsilon(10e-6)); +} + +//_________________________________________________________ +TEST_CASE("BeamSpot Compatibility Checker", "[compareBS]") { + reco::BeamSpot::Point pointA(1.0, 2.0, 3.0); + reco::BeamSpot::Point pointB(1.1, 2.1, 3.1); + + reco::BeamSpot::CovarianceMatrix matrixA; + reco::BeamSpot::CovarianceMatrix matrixB; + + // Initialize matrices with non-zero values + for (int i = 0; i < reco::BeamSpot::dimension; ++i) { + for (int j = 0; j < reco::BeamSpot::dimension; ++j) { + matrixA(i, j) = 0.01 * (i + 1) * (j + 1); + matrixB(i, j) = 0.02 * (i + 1) * (j + 1); + } + } + + reco::BeamSpot beamSpotA(pointA, 4.0, 0.01, 0.01, 0.1, matrixA); + reco::BeamSpot beamSpotB(pointB, 4.2, 0.01, 0.01, 0.12, matrixB); + + // Create the edm::ParameterSet with the required parameters + edm::ParameterSet pset; + pset.addParameter("warningThr", 1.0); + pset.addParameter("errorThr", 2.0); + pset.addParameter("bsFromEvent", edm::InputTag("")); + pset.addParameter("dbFromEvent", false); + pset.addParameter("bsFromDB", edm::InputTag("")); + + BeamSpotCompatibilityChecker checker(pset); + auto significances = checker.compareBS(beamSpotA, beamSpotB); + + // Print significances + for (size_t i = 0; i < significances.size(); ++i) { + std::cout << "Significance[" << i << "]: " << significances[i] << std::endl; + } + + REQUIRE(significances[0] == Approx(0.57735).epsilon(10e-6)); // x0 significance + REQUIRE(significances[1] == Approx(0.288675).epsilon(10e-6)); // y0 significance + REQUIRE(significances[2] == Approx(0.19245).epsilon(10e-6)); // z0 significance + REQUIRE(significances[3] == Approx(0.0164957).epsilon(10e-6)); // sigmaX significance + REQUIRE(significances[4] == Approx(0.0164957).epsilon(10e-6)); // sigmaY significance + REQUIRE(significances[5] == Approx(0.288675).epsilon(10e-6)); // sigmaZ significance +} diff --git a/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility.sh b/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility.sh new file mode 100755 index 0000000000000..5012061e68975 --- /dev/null +++ b/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +check_for_success() { + "${@}" && echo -e "\n ---> Passed test of '${@}'\n\n" || exit 1 +} + +check_for_failure() { + "${@}" && exit 1 || echo -e "\n ---> Passed test of '${@}'\n\n" +} + +echo "TESTING BeamSpot compatibility check code ..." + + +echo "========================================" +echo "testing failing comparison" +echo "----------------------------------------" +echo + +check_for_failure cmsRun ${SCRAM_TEST_PATH}/testBeamSpotCompatibility_cfg.py + +echo "========================================" +echo "testing successful comparison (with warning)" +echo "----------------------------------------" +echo + +check_for_success cmsRun ${SCRAM_TEST_PATH}/testBeamSpotCompatibility_cfg.py errorThreshold=100000 + +echo "========================================" +echo "testing failed comparison (DB from event)" +echo "----------------------------------------" +echo + +check_for_failure cmsRun ${SCRAM_TEST_PATH}/testBeamSpotCompatibility_cfg.py dbFromEvent=True diff --git a/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility_cfg.py b/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility_cfg.py new file mode 100644 index 0000000000000..0c4af58624401 --- /dev/null +++ b/RecoVertex/BeamSpotProducer/test/testBeamSpotCompatibility_cfg.py @@ -0,0 +1,102 @@ +import sys +FLOAT_MAX = 3.402823466E+38 + +import FWCore.ParameterSet.VarParsing as VarParsing + +#################################################################### +# Options +#################################################################### +options = VarParsing.VarParsing() +options.register('dbFromEvent', + False, # default value + VarParsing.VarParsing.multiplicity.singleton, # singleton or list + VarParsing.VarParsing.varType.bool, # string, int, or float + "use the Event for reading the DB?") +options.register('warningThreshold', + 1., # default value + VarParsing.VarParsing.multiplicity.singleton, # singleton or list + VarParsing.VarParsing.varType.float, # string, int, or float + "threshold to emit a warning") +options.register('errorThreshold', + 3., # default value + VarParsing.VarParsing.multiplicity.singleton, # singleton or list + VarParsing.VarParsing.varType.float, # string, int, or float + "threshold to emit a warning") +options.parseArguments() + +import FWCore.ParameterSet.Config as cms +process = cms.Process("testBeamSpotCompatibility") + +#################################################################### +# Load source +#################################################################### +readFiles = cms.untracked.vstring() +readFiles.extend(['/store/data/Run2023D/HLTPhysics/ALCARECO/TkAlMinBias-PromptReco-v1/000/370/580/00000/acdddb09-046c-4375-82f3-678138106ac7.root']) +process.source = cms.Source("PoolSource", + fileNames = readFiles , + duplicateCheckMode = cms.untracked.string('checkAllFilesOpened') + ) + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(1) +) + +process.options = cms.untracked.PSet( + wantSummary = cms.untracked.bool(False), + Rethrow = cms.untracked.vstring("ProductNotFound"), # make this exception fatal + fileMode = cms.untracked.string('NOMERGE') # no ordering needed, but calls endRun/beginRun etc. at file boundaries +) + +#################################################################### +# Load and configure Message Logger +#################################################################### +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.MessageLogger.cerr.FwkReport.reportEvery = 1000 + +process.load("RecoVertex.BeamSpotProducer.BeamSpot_cff") +#from RecoVertex.BeamSpotProducer.BeamSpot_cfi import offlineBeamSpot +#process.myOfflineBeamSpot = offlineBeamSpot.clone() + +#################################################################### +# Load and configure refitting includes +#################################################################### +process.load("Configuration.Geometry.GeometryDB_cff") +process.load('Configuration.StandardSequences.Services_cff') +process.load("Configuration.StandardSequences.MagneticField_cff") +process.load("TrackingTools.TransientTrack.TransientTrackBuilder_cfi") + +#################################################################### +# Load and Configure TrackRefitter +#################################################################### +process.load("RecoTracker.TrackProducer.TrackRefitters_cff") +import RecoTracker.TrackProducer.TrackRefitters_cff +process.FinalTrackRefitter = RecoTracker.TrackProducer.TrackRefitter_cfi.TrackRefitter.clone() +process.FinalTrackRefitter.src = "ALCARECOTkAlMinBias" +process.FinalTrackRefitter.TrajectoryInEvent = True +process.FinalTrackRefitter.NavigationSchool = '' +process.FinalTrackRefitter.TTRHBuilder = "WithAngleAndTemplate" + +#################################################################### +#Global tag +#################################################################### +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, "140X_dataRun3_v4") ## DO NOT CHANGE (it will change the behaviour of the test)! + +process.BeamSpotChecker = cms.EDAnalyzer("BeamSpotCompatibilityChecker", + bsFromEvent = cms.InputTag("offlineBeamSpot::RECO"), # source of the event beamspot (in the ALCARECO files) + #bsFromEvent = cms.InputTag("offlineBeamSpot"), # source of the event beamspot (in the ALCARECO files) + bsFromDB = cms.InputTag("offlineBeamSpot"), # source of the DB beamspot (from Global Tag) NOTE: only if dbFromEvent is True! + dbFromEvent = cms.bool(options.dbFromEvent), # take the DB beamspot from the event + warningThr = cms.double(options.warningThreshold), # significance threshold to emit a warning message + errorThr = cms.double(options.errorThreshold), # significance threshold to abort the job + verbose = cms.untracked.bool(False) # verbose mode + ) + +process.p = cms.Path( + #process.myOfflineBeamSpot* + process.offlineBeamSpot* + process.FinalTrackRefitter* + process.BeamSpotChecker) + +print("Done")