ATLAS Offline Software
Loading...
Searching...
No Matches
BeamSpotReweightingAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// class header
7
8// Athena headers
12
13// HepMC includes
14#include "AtlasHepMC/GenEvent.h"
16
17// CLHEP includes
18#include "CLHEP/Vector/LorentzVector.h"
19
20namespace Simulation
21{
22
23 BeamSpotReweightingAlg::BeamSpotReweightingAlg( const std::string& name, ISvcLocator* pSvcLocator )
24 : AthReentrantAlgorithm( name, pSvcLocator )
25 {
26 }
27
30 {
31 // This will check that the properties were initialized
32 // properly by job configuration.
33 ATH_CHECK( m_inputMcEventCollection.initialize() );
34 ATH_CHECK( m_beamSpotWeight.initialize() );
35 ATH_CHECK( m_beamSpotKey.initialize() );
36 ATH_CHECK( m_eventInfo.initialize() );
37
38 ATH_MSG_INFO("Input_beam_sigma_z="<<m_input_beam_sigma_z);
39
40 return StatusCode::SUCCESS;
41 }
42
43 StatusCode BeamSpotReweightingAlg::execute(const EventContext& ctx) const
44 {
45 float weight=1;
47 ATH_MSG_DEBUG("Input_beam_sigma_z="<<m_input_beam_sigma_z<<"<0, do nothing");
48 return StatusCode::SUCCESS;
49 }
50
51 if(msgLvl(MSG::DEBUG)) {
53 if (!evt.isValid()) {
54 ATH_MSG_FATAL( "Could not find event info" );
55 return(StatusCode::FAILURE);
56 }
57 ATH_MSG_DEBUG( "EventInfo before adding the weight: " << evt->eventNumber()
58 << " run: " << evt->runNumber()
59 << " hasBeamSpotWeight: "<< evt->hasBeamSpotWeight()
60 << " beamSpotWeight: "<< evt->beamSpotWeight() );
61 }
62
63 // Construct handles from the keys.
64 SG::ReadHandle<McEventCollection> h_inputMcEventCollection (m_inputMcEventCollection, ctx);
65 if(!h_inputMcEventCollection.isValid()) {
66 ATH_MSG_FATAL("No input McEventCollection called " << h_inputMcEventCollection.name() << " in StoreGate.");
67 return StatusCode::FAILURE;
68 }
69
70 // loop over the event in the mc collection
71 //loop only executes once, there is no iterator increment
72 //coverity[unreachable]
73 for (const auto currentGenEvent : *h_inputMcEventCollection) {
74 // skip empty events
75 if ( !currentGenEvent ) {
76 //the hard scatter event is always the first one. If not present, do nothing
77 ATH_MSG_WARNING("No first event found in the McEventCollection input collection, use default weight="<<weight);
78 break;
79 }
80 auto signalVertex = GetSignalProcessVertex(*currentGenEvent);
81
82 if(signalVertex) {
83 //now calculate weight
84 weight=1.0;
85 float z=signalVertex->position().z();
87 float beamz=beamSpotHandle->beamPos().z();
88 float newsigmaz=beamSpotHandle->beamSigma(2);
89 float pullold=(z-beamz)/m_input_beam_sigma_z;
90 float pullnew=(z-beamz)/newsigmaz;
91
92 ATH_MSG_DEBUG("Beamspot z="<<beamz<<", z="<<z<<"; old sigma_z="<<m_input_beam_sigma_z<<", old pull="<<pullold<<"; new sigma_z="<<newsigmaz<<", new pull="<<pullnew);
93
94 if(std::abs(pullold)<10 && std::abs(pullnew)<10) {
95 //Use Gauss probability ratio to calculate the weight:
96 //weight=TMath::Gaus(z,0,35,true)/TMath::Gaus(z,0,42,true);
97 //This can be simplified to:
98 weight=m_input_beam_sigma_z/newsigmaz * std::exp(0.5*(pullold*pullold - pullnew*pullnew));
99 } else {
100 ATH_MSG_WARNING("Large pull of beamspot: Beamspot z="<<beamz<<", z="<<z<<"; old sigma_z="<<m_input_beam_sigma_z<<", old pull="<<pullold<<"; new sigma_z="<<newsigmaz<<", new pull="<<pullnew<<" => use default weight="<<weight);
101 }
102 } else {
103 ATH_MSG_WARNING("No signal vertex found, use default weight="<<weight);
104 }
105
106 ATH_MSG_DEBUG("Beam weight="<<weight);
107 break;
108 }
109
111 if (!BeamSpotWeight.isPresent()) {
112 ATH_MSG_ERROR( "BeamSpotWeight.isPresent check fails" );
113 return StatusCode::FAILURE;
114 }
115 if (!BeamSpotWeight.isAvailable()) {
116 BeamSpotWeight(0) = weight;
117 }
118
119 if(msgLvl(MSG::DEBUG)) {
121 if (!evt.isValid()) {
122 ATH_MSG_FATAL( "Could not find event info" );
123 return(StatusCode::FAILURE);
124 }
125 ATH_MSG_DEBUG( "EventInfo after adding the weight: " << evt->eventNumber()
126 << " run: " << evt->runNumber()
127 << " hasBeamSpotWeight: "<< evt->hasBeamSpotWeight()
128 << " beamSpotWeight: "<< evt->beamSpotWeight() );
129 }
130
131 return StatusCode::SUCCESS;
132 }
133
135 {
136 //Ensure that we have a valid signal_process_vertex
137#ifdef HEPMC3
138 if( !HepMC::signal_process_vertex(&ge) ) {
139 if (!ge.vertices().empty()) {
140 ATH_MSG_DEBUG("No signal_process_vertex found - using the first GenVertex in the event.");
141 auto signalVertex = ge.vertices().front();
142 return signalVertex;
143 }
144 if( !HepMC::signal_process_vertex(&ge) ) { // Insanity check
145 if (!ge.vertices().empty()) {
146 ATH_MSG_ERROR("Failed to set signal_process_vertex for GenEvent!!");
147 return nullptr;
148 }
149 ATH_MSG_WARNING("No signal_process_vertex found. Empty GenEvent!");
150 return nullptr;
151 }
152 }
153 else {
154 ATH_MSG_DEBUG("signal_process_vertex set by Generator.");
156 }
157#else
158 if( !ge.signal_process_vertex() ) {
159 if (!ge.vertices_empty()) {
160 ATH_MSG_DEBUG("No signal_process_vertex found - using the first GenVertex in the event.");
161 HepMC::GenVertex *signalVertex = *(ge.vertices_begin());
162 return signalVertex;
163 }
164 if( !ge.signal_process_vertex() ) { // Insanity check
165 if (!ge.vertices_empty()) {
166 ATH_MSG_ERROR("Failed to set signal_process_vertex for GenEvent!!");
167 return nullptr;
168 }
169 ATH_MSG_WARNING("No signal_process_vertex found. Empty GenEvent!");
170 return nullptr;
171 }
172 }
173 else {
174 ATH_MSG_DEBUG("signal_process_vertex set by Generator.");
175 return ge.signal_process_vertex();
176 }
177#endif
178 return nullptr;
179 }
180
181} // namespace Simulation
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
Handle class for recording to StoreGate.
#define z
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const std::string & name() const
Return the StoreGate ID for the referenced object.
Handle class for adding a decoration to an object.
bool isAvailable()
Test to see if this variable exists in the store, for the referenced object.
bool isPresent() const
Is the referenced container present in SG?
SG::ReadHandleKey< McEventCollection > m_inputMcEventCollection
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo
virtual StatusCode execute(const EventContext &ctx) const override final
Athena algorithm's interface method execute()
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
virtual StatusCode initialize() override final
Athena algorithm's interface method initialize()
Gaudi::Property< float > m_input_beam_sigma_z
HepMC::ConstGenVertexPtr GetSignalProcessVertex(const HepMC::GenEvent &ge) const
Ensure that the GenEvent::signal_process_vertex has been set.
BeamSpotReweightingAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::WriteDecorHandleKey< xAOD::EventInfo > m_beamSpotWeight
GenVertex * signal_process_vertex(const GenEvent *e)
Definition GenEvent.h:625
const HepMC::GenVertex * ConstGenVertexPtr
Definition GenVertex.h:60