ATLAS Offline Software
Loading...
Searching...
No Matches
StepArrayBM.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#include<algorithm> /*count_if,max_element*/
6#include<cassert>
7#include<limits> /*epsilon*/
8#include<numeric> /*accumulate*/
9#include "UtilityFuncs.h"
10#include "StepArrayBM.h"
11
12StepArrayBM::StepArrayBM(const std::string& name,ISvcLocator* svc)
13 : base_class(name,svc)
15 , m_t0Offset(0)
19 , m_ipLength(1)
20 , m_spLength(1)
21 , m_intensityPattern(new double[m_ipLength])
22 , m_signalPattern(new bool[m_spLength])
24{
25 declareProperty("MaxBunchCrossingPerOrbit", m_maxBunchCrossingPerOrbit, "The number of slots in each LHC beam. Default: 3564.");
26 declareProperty("IntensityPattern", m_intensityPatternProp,
27 "An array of floats containing the beam intensity distribution as a function of time in bins of 25ns. ArrayBM normalizes the distribution and uses it as a stencil to determine the relative intensity at each beam xing in the simulated range"
28 );
29 declareProperty("SignalPattern", m_signalPatternProp, "An array of booleans to complement the IntensityPattern to indicate where the signal event should happen (i.e. which events to actually simulate). Default behaviour is to do EVERY bunch crossing."
30 );
31 m_intensityPattern[0]=1.0;
32 m_signalPattern[0]=true;
33}
34
36{
37 delete [] m_intensityPattern;
38 delete [] m_signalPattern;
39}
40
42{
43 const std::vector<float>& rProp(m_intensityPatternProp.value());
44 const std::vector<float>& sProp(m_signalPatternProp.value());
45 std::vector<float>::const_iterator pBegin(rProp.begin());
46 std::vector<float>::const_iterator pEnd(rProp.end());
47 m_ipLength = rProp.size();
48 //Consistency checks
50 {
51 ATH_MSG_ERROR("IntensityPattern length (" << m_ipLength << "), exceeds the maximum number of bunch crossings per orbit (" << m_maxBunchCrossingPerOrbit << ").");
52 return StatusCode::FAILURE;
53 }
54
55 // Normalise the pattern so that the non-zero elements average to 1.0
56 float nonZeroElementCount(static_cast<float>(std::count_if(pBegin, pEnd, IsNonZero)));
57 if(nonZeroElementCount<1.0)
58 {
59 ATH_MSG_ERROR("IntensityPattern has no non-zero elements!");
60 return StatusCode::FAILURE;
61 }
62 float elementSum(static_cast<float>(std::accumulate(pBegin, pEnd,0.0)));
63 float denominator(elementSum/nonZeroElementCount);
64
65 // Normalise the pattern so that the highest element value is 1.0
66 float maxElement(*(std::max_element(pBegin, pEnd)));
67 float inv_maxElement = maxElement != 0 ? 1. / maxElement : 1;
68
69 //copy normalized intensity pattern from the property, and match signal pattern if requested
70 delete [] m_intensityPattern;
71 m_intensityPattern = new double[m_ipLength];
72
73 for (unsigned int i(0); i<m_ipLength; ++i)
74 {
75 if (rProp[i]<0.0)
76 {
77 ATH_MSG_ERROR("All IntensityPattern elements must be >=0. Please fix element #" << i );
78 return StatusCode::FAILURE;
79 }
80 m_intensityPattern[i] = rProp[i] * inv_maxElement;
81 }
82
83 // Will be used to convert values in the m_intensityPattern
84 // from having max value 1.0 to having mean value 1.0
85 if (denominator != 0) {
86 m_largestElementInPattern = (maxElement/denominator);
87 }
88
89 //FIXME add a check that entry 0 is zero? In data, BCID=1 is always the first filled bunch.
90
91 //get the signal pattern from the property
92 m_spLength = sProp.size();
93 delete [] m_signalPattern;
94 m_signalPattern = new bool[m_spLength];
95 bool isOk=false;
96 for (unsigned int i(0); i<m_spLength; ++i)
97 {
98 m_signalPattern[i] = (sProp[i]>0.0);
99 if(m_signalPattern[i]) { isOk=true; }
100 }
101 if(!isOk)
102 {
103 ATH_MSG_ERROR("SignalPattern MUST have at least one non-zero value in it.");
104 return StatusCode::FAILURE;
105 }
106
107 //start the t0Offset and signalOffset at the LAST entry in the arrays, so that the first event is for the FIRST entry in the arrays
110
111 return StatusCode::SUCCESS;
112}
113
114void StepArrayBM::selectT0(unsigned int /*run*/, unsigned long long /*event*/)
115{
116 //move to the next xing as dictated by the signalPattern, for each incremember, shift the t0Offset
117 do {
119 m_t0Offset = (unsigned int)((m_t0Offset+1) % m_ipLength);
121
122
123 //assert(m_intensityPattern[m_t0Offset % m_ipLength]>0.0); //commented out to allow events with no intensity
124
125 ATH_MSG_DEBUG( "selectT0 offset for this event " << m_t0Offset );
126}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
A IBeamIntensity service configured with an intensity array and an optional signal pattern array The ...
Holds helper functions used by FixedArrayBM and ArrayBM.
static bool IsNonZero(float lumi)
unsigned int m_spLength
length of the signal pattern
Definition StepArrayBM.h:68
StepArrayBM(const std::string &name, ISvcLocator *svc)
unsigned int m_ipLength
length of the intensity pattern
Definition StepArrayBM.h:66
unsigned int m_maxBunchCrossingPerOrbit
max bunch crossings per orbit
Definition StepArrayBM.h:56
bool * m_signalPattern
locally stored siganlPattern
Definition StepArrayBM.h:72
double * m_intensityPattern
normalized intensity pattern. C array to make clhep RandGeneral happy
Definition StepArrayBM.h:70
Gaudi::Property< std::vector< float > > m_intensityPatternProp
user-defined intensity pattern
Definition StepArrayBM.h:62
virtual ~StepArrayBM()
Gaudi::Hive::ContextSpecificData< unsigned int > m_t0Offset
offset of the t0 wrto our intensity pattern
Definition StepArrayBM.h:58
virtual StatusCode initialize() override final
virtual void selectT0(unsigned int run, unsigned long long event) override final
Gaudi::Hive::ContextSpecificData< unsigned int > m_signalOffset
offset of the current xing wrto the signal pattern
Definition StepArrayBM.h:60
float m_largestElementInPattern
The largest value in the pattern assuming that the pattern has mean value 1.0.
Definition StepArrayBM.h:77
Gaudi::Property< std::vector< float > > m_signalPatternProp
user-defined signal pattern - non zero numbers means "Do Signal"
Definition StepArrayBM.h:64