ATLAS Offline Software
Classes | Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
MM_StripsResponseSimulation Class Reference

#include <MM_StripsResponseSimulation.h>

Inheritance diagram for MM_StripsResponseSimulation:
Collaboration diagram for MM_StripsResponseSimulation:

Classes

struct  ConfigModule
 
struct  DataCache
 

Public Member Functions

 MM_StripsResponseSimulation (ConfigModule &&cfg)
 
virtual ~MM_StripsResponseSimulation ()
 
MM_StripToolOutput GetResponseFrom (const MM_DigitToolInput &digiInput, double gainFraction, double stripPitch, CLHEP::HepRandomEngine *rndmEngine) const
 
float getQThreshold () const
 
float getDriftGapWidth () const
 
double getDriftVelocity () const
 
float getInteractionDensityMean () const
 
float getInteractionDensitySigma () const
 
float getLongitudinalDiffusionSigma () const
 
float getTransversDiffusionSigma () const
 
bool msgLvl (const MSG::Level lvl) const
 Test the output level. More...
 
MsgStream & msg () const
 The standard message stream. More...
 
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream. More...
 
void setLevel (MSG::Level lvl)
 Change the current logging level. More...
 

Protected Member Functions

float generateTransverseDiffusion (float posY, CLHEP::HepRandomEngine *rndmEngine) const
 
float getTransverseDiffusion (float posY, CLHEP::HepRandomEngine *rndmEngine) const
 
float getLongitudinalDiffusion (float posY, CLHEP::HepRandomEngine *rndmEngine) const
 
float getEffectiveCharge (CLHEP::HepRandomEngine *rndmEngine) const
 
float getPathLengthTraveled (CLHEP::HepRandomEngine *rndmEngine) const
 

Private Member Functions

void initHistos ()
 
void writeHistos ()
 
void whichStrips (DataCache &cache, const MM_DigitToolInput &digiInput, double gainFraction, double stripPitch, CLHEP::HepRandomEngine *rndmEngine) const
 
void initMessaging () const
 Initialize our message level and MessageSvc. More...
 

Private Attributes

const ConfigModule m_cfg {}
 
std::map< std::string, std::unique_ptr< TH1F > > m_mapOfHistograms {}
 
std::map< std::string, std::unique_ptr< TH2F > > m_mapOf2DHistograms {}
 
std::unique_ptr< CLHEP::RandGeneral > m_randNelectrons {}
 
std::unique_ptr< TFile > m_outputFile {nullptr}
 
std::string m_nm
 Message source name. More...
 
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels) More...
 
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer. More...
 
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level. More...
 
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging) More...
 

Static Private Attributes

static constexpr unsigned int s_NelectronPropBins {300}
 

Detailed Description

Definition at line 61 of file MM_StripsResponseSimulation.h.

Constructor & Destructor Documentation

◆ MM_StripsResponseSimulation()

MM_StripsResponseSimulation::MM_StripsResponseSimulation ( ConfigModule &&  cfg)

Definition at line 40 of file MM_StripsResponseSimulation.cxx.

40  :
41  AthMessaging("MMStripResponseSimulation"),
42  m_cfg{std::move(mod)} {
43 
44  initHistos();
45  // initialization for the random number generator for the number of secondary electrons
46  // values are from G. Iakovidis
47  std::vector<double> NelectronProb{65.6, 15., 6.4, 3.5, 2.25, 1.55, 1.05, 0.81, 0.61, 0.49, 0.39, 0.3,
48  0.25, 0.2, 0.16, 0.12, 0.095, 0.075, 0.063, 0.054, 0.049, 0.045, 0.044};
49  NelectronProb.reserve(s_NelectronPropBins);
50  for (unsigned int Nelectron = NelectronProb.size(); Nelectron < s_NelectronPropBins; ++Nelectron)
51  NelectronProb.push_back(21.6 / ((Nelectron) * (Nelectron)));
52 
53  m_randNelectrons = std::make_unique<CLHEP::RandGeneral>(NelectronProb.data(), NelectronProb.size(), 1); // 1 means non-continious random numbers
54 
55  ATH_MSG_DEBUG("MM_StripsResponseSimulation::initializationFrom set values");
56  }

◆ ~MM_StripsResponseSimulation()

MM_StripsResponseSimulation::~MM_StripsResponseSimulation ( )
virtual

Definition at line 348 of file MM_StripsResponseSimulation.cxx.

348  {
349  if (m_outputFile) { writeHistos(); }
350 }

Member Function Documentation

◆ generateTransverseDiffusion()

float MM_StripsResponseSimulation::generateTransverseDiffusion ( float  posY,
CLHEP::HepRandomEngine *  rndmEngine 
) const
protected

Definition at line 276 of file MM_StripsResponseSimulation.cxx.

276  {
277  // this is a helper function used in getTransverseDiffusion, generating double gaussian distributions
278 
279  // avoid division by zero in calculation of scale if ypos is 0
280  // also protect against negative values of ypos which should never happen
281  if (posY <= 0.) posY = 0.001;
282 
283  // need to scale weigths since initial distributions were not normalized
284  const double scale = 0.001 / (posY * m_cfg.transverseDiffusionSigma);
285 
286  const double uni = CLHEP::RandFlat::shoot(rndmEngine, 0, 1.0 + scale);
287  if (uni < scale) return CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, 1.0);
288  return CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0., m_cfg.transverseDiffusionSigma * posY);
289 }

◆ getDriftGapWidth()

float MM_StripsResponseSimulation::getDriftGapWidth ( ) const
inline

Definition at line 92 of file MM_StripsResponseSimulation.h.

92 { return m_cfg.driftGapWidth; };

◆ getDriftVelocity()

double MM_StripsResponseSimulation::getDriftVelocity ( ) const
inline

Definition at line 93 of file MM_StripsResponseSimulation.h.

93 { return m_cfg.driftVelocity; };

◆ getEffectiveCharge()

float MM_StripsResponseSimulation::getEffectiveCharge ( CLHEP::HepRandomEngine *  rndmEngine) const
protected

Definition at line 327 of file MM_StripsResponseSimulation.cxx.

327  {
328  // charge fluctuatation is described by Polya function
329  // To calculate the gain from polya distibution we replace "alpha = 1+theta and beta = 1+theta/mean" in gamma PDF. With this gamma PDF
330  // gives us same sampling values as we get from polya PDF. Idea taken from MR 40547
331  return CLHEP::RandGamma::shoot(rndmEngine, 1. + polyaTheta, (1. + polyaTheta) / m_cfg.avalancheGain);
332 }

◆ getInteractionDensityMean()

float MM_StripsResponseSimulation::getInteractionDensityMean ( ) const
inline

Definition at line 94 of file MM_StripsResponseSimulation.h.

94 { return m_cfg.interactionDensityMean; }

◆ getInteractionDensitySigma()

float MM_StripsResponseSimulation::getInteractionDensitySigma ( ) const
inline

Definition at line 95 of file MM_StripsResponseSimulation.h.

◆ getLongitudinalDiffusion()

float MM_StripsResponseSimulation::getLongitudinalDiffusion ( float  posY,
CLHEP::HepRandomEngine *  rndmEngine 
) const
protected

Definition at line 317 of file MM_StripsResponseSimulation.cxx.

317  {
318  float diffusion{0.};
319  // We only want random numbers between -5 and 5
320  do {
321  diffusion= CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, posY * m_cfg.longitudinalDiffusionSigma);
322  ATH_MSG_VERBOSE("getLongitudinalDiffusion() -- posY: "<<posY<<" engine seed: "<<rndmEngine->getSeed()<<" "<<rndmEngine->flat()<<" diffusion "<<diffusion);
323  } while (std::abs(diffusion) > 5);
324  return diffusion;
325 }

◆ getLongitudinalDiffusionSigma()

float MM_StripsResponseSimulation::getLongitudinalDiffusionSigma ( ) const
inline

Definition at line 96 of file MM_StripsResponseSimulation.h.

◆ getPathLengthTraveled()

float MM_StripsResponseSimulation::getPathLengthTraveled ( CLHEP::HepRandomEngine *  rndmEngine) const
protected

Definition at line 334 of file MM_StripsResponseSimulation.cxx.

334  {
335  // Probability of having an interaction (per unit length traversed) is sampled from a gaussian provided by G. Iakovidis
336  float rndGaus{0.};
337 
338  // gaussian random number should be in the range from 0 to 10
339  do {
340  rndGaus = CLHEP::RandGaussZiggurat::shoot(rndmEngine, m_cfg.interactionDensityMean, m_cfg.interactionDensitySigma);
341  ATH_MSG_VERBOSE("getPathLengthTraveled() -- engine seed: "<<rndmEngine->getSeed()<<" "<<rndmEngine->flat()<<" rndGaus: "<<rndGaus);
342  } while (rndGaus < 0. || rndGaus > 10.) ;
343 
344  return (1. / rndGaus) * -1. * std::log(CLHEP::RandFlat::shoot(rndmEngine));
345 }

◆ getQThreshold()

float MM_StripsResponseSimulation::getQThreshold ( ) const
inline

Definition at line 91 of file MM_StripsResponseSimulation.h.

91 { return m_cfg.qThreshold; };

◆ GetResponseFrom()

MM_StripToolOutput MM_StripsResponseSimulation::GetResponseFrom ( const MM_DigitToolInput digiInput,
double  gainFraction,
double  stripPitch,
CLHEP::HepRandomEngine *  rndmEngine 
) const

Definition at line 102 of file MM_StripsResponseSimulation.cxx.

104  {
105  ATH_MSG_DEBUG("Starting to get response from strips");
106  DataCache cache{};
107  whichStrips(cache, digiInput, gainFraction, stripPitch, rndmEngine);
108 
109  ATH_MSG_DEBUG("Creating MmDigitToolOutput object");
110 
111  MM_StripToolOutput tmpStripToolOutput(std::move(cache.finalNumberofStrip),
112  std::move(cache.finalqStrip),
113  std::move(cache.finaltStrip));
114 
115  return tmpStripToolOutput;
116 }

◆ getTransversDiffusionSigma()

float MM_StripsResponseSimulation::getTransversDiffusionSigma ( ) const
inline

Definition at line 97 of file MM_StripsResponseSimulation.h.

◆ getTransverseDiffusion()

float MM_StripsResponseSimulation::getTransverseDiffusion ( float  posY,
CLHEP::HepRandomEngine *  rndmEngine 
) const
protected

Definition at line 291 of file MM_StripsResponseSimulation.cxx.

291  {
292  // the random numbers are generate from the following function:
293  // "1.*TMath::Exp(-TMath::Power(x,2.)/(2.*[0]*[0])) + 0.001*TMath::Exp(-TMath::Power(x,2)/(2.*[1]*[1]))"
294  // in the range from -1 to 1
295  // Since sampling from a TF1 where its parameters are changed for every random number is slow,
296  // the following approach is used to generate random numbers from the mixture of two Gaussian:
297  // https://stats.stackexchange.com/questions/226834/sampling-from-a-mixture-of-two-gamma-distributions/226837#226837
298  // this approach seems to be around 20000 times faster
299 
300  // if one of the diffusions is off, the tail is not present
301  float diffusion{0.};
303  // limit random number to be -1 < x < 1
304  do {
305  diffusion = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, posY * m_cfg.transverseDiffusionSigma);
306  ATH_MSG_VERBOSE("getTransverseDiffusion() -- posY x transverseSigma: "<<(posY* m_cfg.transverseDiffusionSigma)<<" engine seed: "<<rndmEngine->getSeed()<<" "<<rndmEngine->flat()<<" diffusion "<<diffusion);
307  } while (std::abs(diffusion) > 1.);
308  return diffusion;
309  }
310  do {
311  diffusion = generateTransverseDiffusion(posY, rndmEngine);
312  ATH_MSG_VERBOSE("getTransverseDiffusion() -- posY: "<<posY<<" engine seed: "<<rndmEngine->getSeed()<<" "<<rndmEngine->flat()<<" diffusion "<<diffusion);
313  } while (std::abs(diffusion)> 1.);
314  return diffusion;
315 }

◆ initHistos()

void MM_StripsResponseSimulation::initHistos ( )
private

Definition at line 59 of file MM_StripsResponseSimulation.cxx.

59  {
60  if (m_cfg.writeOutputFile) {
61  m_outputFile = std::make_unique<TFile>("MM_StripsResponse_Plots.root", "RECREATE");
62  if (m_outputFile) m_outputFile->cd();
63 
64  m_mapOfHistograms["nInteractions"] = std::make_unique<TH1F>("nInteractions", "nInteractions", 200, 0, 200);
65  m_mapOfHistograms["nElectrons"] = std::make_unique<TH1F>("nElectrons", "nElectrons", 200, 0, 200);
66  m_mapOfHistograms["lorentzAngle"] = std::make_unique<TH1F>("lorentzAngle", "lorentzAngle", 100, 0, 3);
67  m_mapOfHistograms["effectiveCharge"] = std::make_unique<TH1F>("effectiveCharge", "effectiveCharge", 100, 0, 1e5);
68  m_mapOfHistograms["effectiveNElectrons"] = std::make_unique<TH1F>("effectiveNElectrons", "effectiveNElectrons", 200, 0, 200);
69  m_mapOfHistograms["totalEffectiveCharge"] = std::make_unique<TH1F>("totalEffectiveCharge", "totalEffectiveCharge", 400, 0, 200);
70  m_mapOf2DHistograms["totalEffectiveChargeVsTheta"] = std::make_unique<TH2F>("totalEffectiveChargeVsTheta", "totalEffectiveChargeVsTheta", 17, 0, 35, 300, 0, 300);
71 
72  m_mapOf2DHistograms["pathLengthVsTheta"] = std::make_unique<TH2F>("pathLengthVsTheta", "pathLengthVsTheta", 100, 0, 10, 100, -3, 3);
73  m_mapOf2DHistograms["pathLengthVsAlpha"] = std::make_unique<TH2F>("pathLengthVsAlpha", "pathLengthVsAlpha", 100, 0, 10, 100, -3, 3);
74 
75  m_mapOf2DHistograms["lorentzAngleVsTheta"] = std::make_unique<TH2F>("lorentzAngleVsTheta", "lorentzAngleVsTheta", 100, -3, 3, 100, -3, 3);
76  m_mapOf2DHistograms["lorentzAngleVsBy"] = std::make_unique<TH2F>("lorentzAngleVsBy", "lorentzAngleVsBy", 100, -3, 3, 100, -2., 2.);
77 
78  m_mapOf2DHistograms["deltaLorentzAngleVsByForPosTheta"] =
79  std::make_unique<TH2F>("deltaLorentzAngleVsByForPosTheta", "deltaLorentzAngleVsByForPosTheta", 100, -3, 3, 100, -2., 2.);
80  m_mapOf2DHistograms["deltaLorentzAngleVsByForNegTheta"] =
81  std::make_unique<TH2F>("deltaLorentzAngleVsByForNegTheta", "deltaLorentzAngleVsByForNegTheta", 100, -3, 3, 100, -2., 2.);
82 
83  m_mapOf2DHistograms["driftDistanceVsDriftTime"] =
84  std::make_unique<TH2F>("driftDistanceVsDriftTime", "driftDistanceVsDriftTime", 100, 0, 10, 100, 0, 200);
85  }
86 }

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40 {
42  m_lvl = m_imsg ?
43  static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
44  MSG::INFO;
45 }

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 164 of file AthMessaging.h.

165 {
166  MsgStream* ms = m_msg_tls.get();
167  if (!ms) {
168  if (!m_initialized.test_and_set()) initMessaging();
169  ms = new MsgStream(m_imsg,m_nm);
170  m_msg_tls.reset( ms );
171  }
172 
173  ms->setLevel (m_lvl);
174  return *ms;
175 }

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level  lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 179 of file AthMessaging.h.

180 { return msg() << lvl; }

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level  lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152 {
153  if (!m_initialized.test_and_set()) initMessaging();
154  if (m_lvl <= lvl) {
155  msg() << lvl;
156  return true;
157  } else {
158  return false;
159  }
160 }

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level  lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29 {
30  m_lvl = lvl;
31 }

◆ whichStrips()

void MM_StripsResponseSimulation::whichStrips ( DataCache cache,
const MM_DigitToolInput digiInput,
double  gainFraction,
double  stripPitch,
CLHEP::HepRandomEngine *  rndmEngine 
) const
private

Definition at line 122 of file MM_StripsResponseSimulation.cxx.

125  {
126  ATH_MSG_DEBUG("Starting to calculate strips that got fired");
127  const float hitx = digiInput.positionWithinStrip();
128  const int stripID = digiInput.stripIDLocal();
129  const float incidentAngleXZ = digiInput.incomingAngleXZ(); // degrees
130  const float incidentAngleYZ = digiInput.incomingAngleYZ(); // degrees
131  const int stripMinID = digiInput.stripMinID();
132  const int stripMaxID = digiInput.stripMaxID();
133 
134  CLHEP::RandGeneral* randDist ATLAS_THREAD_SAFE = m_randNelectrons.get();
135  const float eventTime = digiInput.eventTime();
136  const float theta = incidentAngleXZ * Gaudi::Units::degree; // Important for path length and strip distribution
137  const float alpha = incidentAngleYZ * Gaudi::Units::degree; // Important for path length
138 
139  int nPrimaryIons = 0;
140 
141  Amg::Vector3D b = digiInput.magneticField() * 1000.;
142 
143  // Still need to understand which sign is which... But I think this is correct...
144 
145  float lorentzAngle = (b.y() > 0. ? 1. : -1.) * m_cfg.lorentzAngleFunction(std::abs(b.y())) * Gaudi::Units::deg; // in radians
146  if (m_cfg.writeOutputFile) {
147  std::lock_guard guard{fillMutex};
148  m_mapOf2DHistograms.at("lorentzAngleVsTheta")->Fill(lorentzAngle, theta);
149  m_mapOf2DHistograms.at("lorentzAngleVsBy")->Fill(lorentzAngle, b.y());
150  }
151 
152  ATH_MSG_DEBUG("LorentzAngle vs theta: " << lorentzAngle << " " << theta);
153 
154  float pathLengthTraveled = getPathLengthTraveled(rndmEngine);
155 
156  float pathLength = m_cfg.driftGapWidth / std::cos(theta); // Increasing path length based on XZ angle
157  pathLength /= std::cos(alpha); // Further increasing path length for YZ angle
158 
159  if (m_cfg.writeOutputFile) {
160  std::lock_guard guard{fillMutex};
161  m_mapOf2DHistograms.at("pathLengthVsTheta")->Fill(pathLength, theta);
162  m_mapOf2DHistograms.at("pathLengthVsAlpha")->Fill(pathLength, alpha);
163 
164  if (theta > 0)
165  m_mapOf2DHistograms.at("deltaLorentzAngleVsByForPosTheta")->Fill(lorentzAngle - theta, b.y());
166  else
167  m_mapOf2DHistograms.at("deltaLorentzAngleVsByForNegTheta")->Fill(lorentzAngle - theta, b.y());
168  }
169  while (pathLengthTraveled < pathLength) {
170  // N.B. Needs correction from alpha angle still...
171  std::unique_ptr<MM_IonizationCluster> IonizationCluster =
172  std::make_unique<MM_IonizationCluster>(hitx, pathLengthTraveled * std::sin(theta), pathLengthTraveled * std::cos(theta));
173 
174  // +1 since first entry in electron probability vector corresponds to 1 electron and not to 0 electrons
175  int nElectrons = s_NelectronPropBins * randDist->shoot(rndmEngine) + 1;
176  IonizationCluster->createElectrons(nElectrons);
177 
178  const Amg::Vector2D& initialPosition = IonizationCluster->getIonizationStart();
179 
180  ATH_MSG_DEBUG("New interaction starting at x,y, pathLengthTraveled: " << initialPosition.x() << " " << initialPosition.y() << " "
181  << pathLengthTraveled);
182 
183  for (auto& Electron : IonizationCluster->getElectrons()) {
184  Electron->setOffsetPosition(getTransverseDiffusion(initialPosition.y(), rndmEngine),
185  getLongitudinalDiffusion(initialPosition.y(), rndmEngine));
186  }
187 
188  IonizationCluster->propagateElectrons(lorentzAngle, m_cfg.driftVelocity);
189 
190  int tmpEffectiveNElectrons = 0;
191 
192  for (auto& Electron : IonizationCluster->getElectrons()) {
193  float effectiveCharge = getEffectiveCharge(rndmEngine) * gainFraction;
194 
195  Electron->setCharge(effectiveCharge);
196 
197  ATH_MSG_DEBUG("Electron's effective charge is " << effectiveCharge);
198 
199  if (m_cfg.writeOutputFile) {
200  std::lock_guard guard{fillMutex};
201  m_mapOfHistograms.at("effectiveCharge")->Fill(effectiveCharge);
202  m_mapOf2DHistograms.at("driftDistanceVsDriftTime")->Fill(Electron->getOffsetPosition().mag(), Electron->getTime());
203  }
204  // Add eventTime in Electron time
205  Electron->setTime(Electron->getTime() + eventTime);
206 
207  tmpEffectiveNElectrons += effectiveCharge;
208  }
209 
210  if (m_cfg.writeOutputFile) {
211  std::lock_guard guard{fillMutex};
212  m_mapOfHistograms.at("effectiveNElectrons")->Fill(tmpEffectiveNElectrons / m_cfg.avalancheGain);
213  }
214  //---
215  cache.IonizationClusters.push_back(std::move(IonizationCluster));
216 
217  pathLengthTraveled += getPathLengthTraveled(rndmEngine);
218 
219  ATH_MSG_DEBUG("Path length traveled: " << pathLengthTraveled);
220 
221  ++nPrimaryIons;
222  if (nPrimaryIons >= m_cfg.maxPrimaryIons) break; // don't create more than "MaxPrimaryIons" along a track....
223 
224  } // end of clusters loop
225 
226  float timeresolution = 0.01; // ns
227 
228  MM_StripResponse stripResponseObject(cache.IonizationClusters, timeresolution, stripPitch, stripID, stripMinID, stripMaxID);
229  stripResponseObject.timeOrderElectrons();
230  stripResponseObject.calculateTimeSeries(incidentAngleXZ, digiInput.gasgap());
231  stripResponseObject.simulateCrossTalk(m_cfg.crossTalk1, m_cfg.crossTalk2);
232  stripResponseObject.calculateSummaries(m_cfg.qThreshold);
233 
234  // Connect the output with the rest of the existing code
235  //
236  cache.finalNumberofStrip = stripResponseObject.getStripVec();
237  cache.finalqStrip = stripResponseObject.getTotalChargeVec();
238  cache.finaltStrip = stripResponseObject.getTimeThresholdVec();
239  cache.tStripElectronicsAbThr = stripResponseObject.getTimeMaxChargeVec();
240  cache.qStripElectronics = stripResponseObject.getMaxChargeVec();
241 
242  // Output diagnostic hists and graphs
243  //
244  if (m_cfg.writeOutputFile) {
245  std::lock_guard guard{fillMutex};
246  m_mapOfHistograms.at("nInteractions")->Fill(nPrimaryIons);
247  m_mapOfHistograms.at("nElectrons")->Fill(stripResponseObject.getNElectrons());
248  m_mapOfHistograms.at("totalEffectiveCharge")->Fill(stripResponseObject.totalCharge() * electronsToFC);
249  m_mapOf2DHistograms.at("totalEffectiveChargeVsTheta")->Fill(std::abs(incidentAngleXZ),
250  stripResponseObject.totalCharge() * electronsToFC);
251  ATH_MSG_DEBUG("incidentAngleXZ" << incidentAngleXZ << "charge [fC]" << stripResponseObject.totalCharge() / 6241.);
252  m_mapOfHistograms.at("lorentzAngle")->Fill(lorentzAngle);
253  }
254 
256  std::lock_guard guard{fillMutex};
257  static std::atomic<unsigned> written{0};
258  TGraph grIonizationXZ(cache.IonizationClusters.size());
259  for (size_t iIonization = 0; iIonization < cache.IonizationClusters.size(); ++iIonization) {
260  Amg::Vector2D ionizationPosition(cache.IonizationClusters.at(iIonization)->getIonizationStart());
261  grIonizationXZ.SetPoint(iIonization, ionizationPosition.x(), ionizationPosition.y());
262  }
263  m_outputFile->WriteObject(&grIonizationXZ, Form("ionizationXZ_%u", ++written));
264 
265  TGraph grElectronsXZ(stripResponseObject.getNElectrons());
266  int iElectron = 0;
267  for (const auto& electron : stripResponseObject.getElectrons()) {
268  grElectronsXZ.SetPoint(iElectron, electron->getX(), electron->getY());
269  iElectron++;
270  }
271  m_outputFile->WriteObject(&grElectronsXZ, Form("electronsXZ_%u", ++written));
272  }
273 
274 } // end of whichStrips()

◆ writeHistos()

void MM_StripsResponseSimulation::writeHistos ( )
private

Definition at line 88 of file MM_StripsResponseSimulation.cxx.

88  {
89  if (!m_outputFile) {
90  return;
91  }
92  for (auto& [histo_name, histo] : m_mapOfHistograms) {
93  m_outputFile->WriteObject(histo.get(), histo_name.c_str());
94  }
95  for (auto& [histo_name, histo] : m_mapOf2DHistograms) {
96  m_outputFile->WriteObject(histo.get(), histo_name.c_str());
97  }
98  m_mapOf2DHistograms.clear();
99  m_mapOfHistograms.clear();
100 }

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging)

Definition at line 141 of file AthMessaging.h.

◆ m_cfg

const ConfigModule MM_StripsResponseSimulation::m_cfg {}
private

Definition at line 102 of file MM_StripsResponseSimulation.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

◆ m_mapOf2DHistograms

std::map<std::string, std::unique_ptr<TH2F> > MM_StripsResponseSimulation::m_mapOf2DHistograms {}
private

Definition at line 120 of file MM_StripsResponseSimulation.h.

◆ m_mapOfHistograms

std::map<std::string, std::unique_ptr<TH1F> > MM_StripsResponseSimulation::m_mapOfHistograms {}
private

Definition at line 119 of file MM_StripsResponseSimulation.h.

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_outputFile

std::unique_ptr<TFile> MM_StripsResponseSimulation::m_outputFile {nullptr}
private

Definition at line 127 of file MM_StripsResponseSimulation.h.

◆ m_randNelectrons

std::unique_ptr<CLHEP::RandGeneral> MM_StripsResponseSimulation::m_randNelectrons {}
private

Definition at line 122 of file MM_StripsResponseSimulation.h.

◆ s_NelectronPropBins

constexpr unsigned int MM_StripsResponseSimulation::s_NelectronPropBins {300}
staticconstexprprivate

Definition at line 124 of file MM_StripsResponseSimulation.h.


The documentation for this class was generated from the following files:
MM_IonizationCluster::createElectrons
void createElectrons(int nElectrons)
Definition: MM_IonizationCluster.cxx:10
AthMessaging::m_lvl
std::atomic< MSG::Level > m_lvl
Current logging level.
Definition: AthMessaging.h:138
NSWCalib::MicroMegaGas::lorentzAngleFunction
angleFunction lorentzAngleFunction
Definition: INSWCalibTool.h:48
NSWCalib::MicroMegaGas::longitudinalDiffusionSigma
float longitudinalDiffusionSigma
// 0.350/10 diffusSigma=transverse diffusion (350 microm per 1cm ) for 93:7 @ 600 V/cm,...
Definition: INSWCalibTool.h:36
MM_StripsResponseSimulation::ConfigModule::writeEventDisplays
bool writeEventDisplays
Definition: MM_StripsResponseSimulation.h:81
MM_DigitToolInput::stripMaxID
int stripMaxID() const
Definition: MM_DigitToolInput.h:48
MM_IonizationCluster::getIonizationStart
const Amg::Vector2D & getIonizationStart() const
Definition: MM_IonizationCluster.h:25
NSWCalib::MicroMegaGas::interactionDensityMean
float interactionDensityMean
Definition: INSWCalibTool.h:38
MM_StripsResponseSimulation::writeHistos
void writeHistos()
Definition: MM_StripsResponseSimulation.cxx:88
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:71
MM_StripsResponseSimulation::m_cfg
const ConfigModule m_cfg
Definition: MM_StripsResponseSimulation.h:102
MM_StripsResponseSimulation::ConfigModule::crossTalk1
float crossTalk1
crosstalk of neighbor strips, it's 15%
Definition: MM_StripsResponseSimulation.h:70
MM_StripsResponseSimulation::whichStrips
void whichStrips(DataCache &cache, const MM_DigitToolInput &digiInput, double gainFraction, double stripPitch, CLHEP::HepRandomEngine *rndmEngine) const
Definition: MM_StripsResponseSimulation.cxx:122
deg
#define deg
Definition: SbPolyhedron.cxx:17
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
NSWCalib::MicroMegaGas::driftVelocity
float driftVelocity
//0.050 drift velocity in [mm/ns], driftGap=5 mm +0.128 mm (the amplification gap)
Definition: INSWCalibTool.h:34
MM_DigitToolInput::stripMinID
int stripMinID() const
Definition: MM_DigitToolInput.h:47
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
AthMessaging::m_imsg
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
Definition: AthMessaging.h:135
python.SystemOfUnits.ms
int ms
Definition: SystemOfUnits.py:132
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
MM_StripsResponseSimulation::m_outputFile
std::unique_ptr< TFile > m_outputFile
Definition: MM_StripsResponseSimulation.h:127
AthMessaging::ATLAS_THREAD_SAFE
std::atomic_flag m_initialized ATLAS_THREAD_SAFE
Messaging initialized (initMessaging)
Definition: AthMessaging.h:141
MM_StripsResponseSimulation::ConfigModule::maxPrimaryIons
int maxPrimaryIons
Definition: MM_StripsResponseSimulation.h:78
MM_DigitToolInput::eventTime
float eventTime() const
Definition: MM_DigitToolInput.h:51
MM_StripsResponseSimulation::ConfigModule::driftGapWidth
float driftGapWidth
Definition: MM_StripsResponseSimulation.h:74
MM_DigitToolInput::magneticField
const Amg::Vector3D & magneticField() const
Definition: MM_DigitToolInput.h:46
AthMessaging::AthMessaging
AthMessaging()
Default constructor:
MM_DigitToolInput::gasgap
int gasgap() const
Definition: MM_DigitToolInput.h:49
NSWCalib::MicroMegaGas::interactionDensitySigma
float interactionDensitySigma
Definition: INSWCalibTool.h:39
TrigConf::MSGTC::Level
Level
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:21
maskDeadModules.mod
mod
Definition: maskDeadModules.py:36
MM_DigitToolInput::incomingAngleYZ
double incomingAngleYZ() const
Definition: MM_DigitToolInput.h:45
MM_StripsResponseSimulation::m_randNelectrons
std::unique_ptr< CLHEP::RandGeneral > m_randNelectrons
Definition: MM_StripsResponseSimulation.h:122
MM_DigitToolInput::incomingAngleXZ
double incomingAngleXZ() const
Definition: MM_DigitToolInput.h:44
MM_StripsResponseSimulation::s_NelectronPropBins
static constexpr unsigned int s_NelectronPropBins
Definition: MM_StripsResponseSimulation.h:124
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MM_IonizationCluster::getElectrons
std::vector< std::unique_ptr< MM_Electron > > & getElectrons()
Definition: MM_IonizationCluster.cxx:21
AthMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AthMessaging.h:164
MM_StripsResponseSimulation::getLongitudinalDiffusion
float getLongitudinalDiffusion(float posY, CLHEP::HepRandomEngine *rndmEngine) const
Definition: MM_StripsResponseSimulation.cxx:317
MM_StripsResponseSimulation::ConfigModule::qThreshold
float qThreshold
qThreshold=2e, we accept a good strip if the charge is >=2e
Definition: MM_StripsResponseSimulation.h:67
MM_StripsResponseSimulation::getEffectiveCharge
float getEffectiveCharge(CLHEP::HepRandomEngine *rndmEngine) const
Definition: MM_StripsResponseSimulation.cxx:327
MM_IonizationCluster::propagateElectrons
void propagateElectrons(float lorentzAngle, float driftVel)
Definition: MM_IonizationCluster.cxx:16
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
MM_StripsResponseSimulation::getTransverseDiffusion
float getTransverseDiffusion(float posY, CLHEP::HepRandomEngine *rndmEngine) const
Definition: MM_StripsResponseSimulation.cxx:291
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MM_StripToolOutput
Definition: MM_StripToolOutput.h:9
beamspotman.posY
posY
Definition: beamspotman.py:1624
MM_StripsResponseSimulation::ConfigModule::writeOutputFile
bool writeOutputFile
Definition: MM_StripsResponseSimulation.h:80
NSWCalib::MicroMegaGas::transverseDiffusionSigma
float transverseDiffusionSigma
Definition: INSWCalibTool.h:37
MM_StripsResponseSimulation::ConfigModule::avalancheGain
float avalancheGain
Definition: MM_StripsResponseSimulation.h:77
MM_DigitToolInput::stripIDLocal
int stripIDLocal() const
Definition: MM_DigitToolInput.h:42
MM_StripsResponseSimulation::ConfigModule::crossTalk2
float crossTalk2
// crosstalk of second neighbor strips, it's 6%
Definition: MM_StripsResponseSimulation.h:72
MM_DigitToolInput::positionWithinStrip
double positionWithinStrip() const
Definition: MM_DigitToolInput.h:43
AthMessaging::m_nm
std::string m_nm
Message source name.
Definition: AthMessaging.h:129
Electron
Class describing an electron.
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
MM_StripsResponseSimulation::initHistos
void initHistos()
Definition: MM_StripsResponseSimulation.cxx:59
MM_StripResponse
Definition: MM_StripResponse.h:20
MM_StripsResponseSimulation::m_mapOfHistograms
std::map< std::string, std::unique_ptr< TH1F > > m_mapOfHistograms
Definition: MM_StripsResponseSimulation.h:119
MM_StripsResponseSimulation::m_mapOf2DHistograms
std::map< std::string, std::unique_ptr< TH2F > > m_mapOf2DHistograms
Definition: MM_StripsResponseSimulation.h:120
MM_StripsResponseSimulation::getPathLengthTraveled
float getPathLengthTraveled(CLHEP::HepRandomEngine *rndmEngine) const
Definition: MM_StripsResponseSimulation.cxx:334
AthMessaging::initMessaging
void initMessaging() const
Initialize our message level and MessageSvc.
Definition: AthMessaging.cxx:39
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
AthMessaging::m_msg_tls
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
Definition: AthMessaging.h:132
plotBeamSpotCompare.histo
histo
Definition: plotBeamSpotCompare.py:415
python.SystemOfUnits.degree
tuple degree
Definition: SystemOfUnits.py:106
MM_StripsResponseSimulation::generateTransverseDiffusion
float generateTransverseDiffusion(float posY, CLHEP::HepRandomEngine *rndmEngine) const
Definition: MM_StripsResponseSimulation.cxx:276