ATLAS Offline Software
Sherpa_i.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "AtlasHepMC/GenEvent.h"
6 #include "GaudiKernel/MsgStream.h"
9 
10 #include "Sherpa_i/Sherpa_i.h"
11 
12 
13 #include "ATOOLS/Org/CXXFLAGS_PACKAGES.H"
14 #ifdef HEPMC3
15 #undef USING__HEPMC2
16 #else
17 #undef USING__HEPMC3
18 #endif
19 #include "SHERPA/Main/Sherpa.H"
20 #include "SHERPA/Initialization/Initialization_Handler.H"
21 #ifdef IS_SHERPA_3
22 #include "ATOOLS/Phys/Variations.H"
23 #else
24 #include "SHERPA/Tools/Variations.H"
25 #endif
26 #include "ATOOLS/Org/Exception.H"
27 #include "ATOOLS/Org/Run_Parameter.H"
28 
29 #include <cstdio>
30 #include <cstring>
31 #include <signal.h>
32 #include <stdlib.h>
33 #include <sys/stat.h>
34 #include "CLHEP/Random/RandFlat.h"
35 
36 CLHEP::HepRandomEngine* p_rndEngine{};
37 
38 Sherpa_i::Sherpa_i(const std::string& name, ISvcLocator* pSvcLocator)
39  : GenModule(name, pSvcLocator)
40 {
41  #ifdef IS_SHERPA_3
42  declareProperty("BaseFragment", m_inputfiles["Base.yaml"] = "");
43  declareProperty("RunCard", m_inputfiles["Sherpa.yaml"] = "");
44  #endif
45 }
46 
47 
48 
50  if (m_plugincode != "") {
51  compilePlugin(m_plugincode);
52  #ifndef IS_SHERPA_3
53  m_params.value().push_back("SHERPA_LDADD=Sherpa_iPlugin");
54  #endif
55  }
56 
57  ATH_MSG_INFO("Sherpa initialising...");
58 
59  #ifdef IS_SHERPA_3
60  for (auto& inputfile : m_inputfiles) {
61  // remove first line and last character containing '"'
62  // TODO fix Python/C++ string passing, to not contain " in first place
63  inputfile.second.erase(0, inputfile.second.find("\n") + 1);
64  inputfile.second.pop_back();
65  }
66  #endif
67 
68  ATH_MSG_DEBUG("... compiling plugin code");
69  if (m_plugincode != "") {
70  compilePlugin(m_plugincode);
71  #ifdef IS_SHERPA_3
72  m_inputfiles["Base.yaml"] += "SHERPA_LDADD: Sherpa_iPlugin \n";
73  #else
74  m_params.value().push_back("SHERPA_LDADD=Sherpa_iPlugin");
75  #endif
76  }
77 
78  ATH_MSG_DEBUG("... seeding Athena random number generator");
79  p_rndEngine = getRandomEngineDuringInitialize("SHERPA", m_randomSeed, m_dsid); // NOT THREAD-SAFE
80 
81  #ifdef IS_SHERPA_3
82  ATH_MSG_DEBUG("... adapting output level");
83  if( msg().level()==MSG::FATAL || msg().level()==MSG::ERROR || msg().level()==MSG::WARNING ){
84  m_inputfiles["Base.yaml"] += "\nEVT_OUTPUT: 0 \n";
85  }
86  else if(msg().level()==MSG::INFO){
87  m_inputfiles["Base.yaml"] += "\nEVT_OUTPUT: 2 \n";
88  }
89  else if(msg().level()==MSG::DEBUG){
90  m_inputfiles["Base.yaml"] += "\nEVT_OUTPUT: 15 \n";
91  }
92  else{
93  m_inputfiles["Base.yaml"] += "\nEVT_OUTPUT: 15 \n";
94  }
95 
96  ATH_MSG_DEBUG("... writing input files to directory");
97  for (auto& inputfile : m_inputfiles) {
98  // write input content to file in working directory
99  FILE *file = fopen(inputfile.first.c_str(),"w");
100  fputs(inputfile.second.c_str(),file);
101  fclose(file);
102  ATH_MSG_INFO("Sherpa_i using the following settings in "+inputfile.first);
103  ATH_MSG_INFO("\n"+inputfile.second+"\n");
104  }
105 
106  ATH_MSG_DEBUG("... go Sherpa!");
107  int argc = 2;
108  char** argv = new char*[2];
109  argv[0] = new char[7];
110  argv[1] = new char[34];
111  strcpy(argv[0], "Sherpa");
112  strcpy(argv[1], "RUNDATA: [Base.yaml, Sherpa.yaml]");
113  p_sherpa = new SHERPA::Sherpa(argc, argv);
114  delete [] argv;
115  #else
116  p_sherpa = new SHERPA::Sherpa();
117  #endif
118 
119 
120  /***
121  translate ATOOLS:SignalHandler
122  ***/
123  std::set_terminate(ATOOLS::Terminate);
124  std::set_unexpected(ATOOLS::Terminate);
125  #ifdef IS_SHERPA_3
126  signal(SIGSEGV,ATOOLS::HandleSignal);
127  signal(SIGINT,ATOOLS::HandleSignal);
128  signal(SIGPIPE,ATOOLS::HandleSignal);
129  signal(SIGBUS,ATOOLS::HandleSignal);
130  signal(SIGFPE,ATOOLS::HandleSignal);
131  signal(SIGABRT,ATOOLS::HandleSignal);
132  signal(SIGTERM,ATOOLS::HandleSignal);
133  signal(SIGXCPU,ATOOLS::HandleSignal);
134  signal(SIGUSR1,ATOOLS::HandleSignal);
135 
136  try {
137  p_sherpa->InitializeTheRun();
138  p_sherpa->InitializeTheEventHandler();
139  }
140  catch (const ATOOLS::normal_exit& exception) {
141  ATH_MSG_ERROR("Normal exit caught, this probably means:");
142  ATH_MSG_ERROR("Have to compile Amegic libraries");
143  ATH_MSG_ERROR("You probably want to run ./makelibs");
144  return StatusCode::FAILURE;
145  }
146  catch (const ATOOLS::Exception& exception) {
147  ATH_MSG_ERROR("Unwanted ATOOLS::exception caught.");
149  return StatusCode::FAILURE;
150  }
151  #else
152  signal(SIGSEGV,ATOOLS::SignalHandler);
153  signal(SIGINT,ATOOLS::SignalHandler);
154  signal(SIGBUS,ATOOLS::SignalHandler);
155  signal(SIGFPE,ATOOLS::SignalHandler);
156  signal(SIGABRT,ATOOLS::SignalHandler);
157  signal(SIGTERM,ATOOLS::SignalHandler);
158  signal(SIGXCPU,ATOOLS::SignalHandler);
159 
160  try {
161  int argc;
162  char** argv;
163  getParameters(argc, argv);
164  p_sherpa->InitializeTheRun(argc,(char **)argv);
165  delete [] argv;
166 
167  p_sherpa->InitializeTheEventHandler();
168  }
169  catch (const ATOOLS::Exception& exception) {
170  if (exception.Class()=="Matrix_Element_Handler" && exception.Type()==ATOOLS::ex::normal_exit) {
171  ATH_MSG_ERROR("Have to compile Amegic libraries");
172  ATH_MSG_ERROR("You probably want to run ./makelibs");
173  }
174  else {
175  ATH_MSG_ERROR("Unwanted ATOOLS::exception caught.");
177  }
178  return StatusCode::FAILURE;
179  }
180  #endif
181  catch (const std::exception& exception) {
182  ATH_MSG_ERROR("std::exception caught.");
183  return StatusCode::FAILURE;
184  }
185 
186  #ifdef HEPMC3
187  m_runinfo = std::make_shared<HepMC3::GenRunInfo>();
189  struct HepMC3::GenRunInfo::ToolInfo generator = {
190  std::string("SHERPA"),
191  std::string(SHERPA_VERSION)+ "." + std::string(SHERPA_SUBVERSION),
192  std::string("Used generator")
193  };
194  m_runinfo->tools().push_back(generator);
195  #endif
196  return StatusCode::SUCCESS;
197 }
198 
199 
201  ATH_MSG_DEBUG("Sherpa_i in callGenerator()");
202  //Re-seed the random number stream
203  long seeds[7];
204  const EventContext& ctx = Gaudi::Hive::currentContext();
205  ATHRNG::calculateSeedsMC21(seeds, "SHERPA", ctx.eventID().event_number(), m_dsid, m_randomSeed);
206  p_rndEngine->setSeeds(seeds, 0); // NOT THREAD-SAFE
207 
208  do {
209  ATH_MSG_DEBUG("Trying to generate event with Sherpa");
210  } while (p_sherpa->GenerateOneEvent()==false);
211 
212  const size_t genEvents = ATOOLS::rpa->gen.NumberOfGeneratedEvents();
213  if (genEvents%1000==0) {
214  ATH_MSG_INFO("Passed "<<genEvents<<" events.");
215  }
216 
217  return StatusCode::SUCCESS;
218 }
219 
220 StatusCode Sherpa_i::fillEvt(HepMC::GenEvent* event) {
221  ATH_MSG_DEBUG( "Sherpa_i Filling event");
222 #ifdef HEPMC3
223  if (!event->run_info()) event->set_run_info(m_runinfo);
224 #endif
225  p_sherpa->FillHepMCEvent(*event);
226 
227 
228 #ifdef HEPMC3
229 //Weight, MEWeight, WeightNormalisation, NTrials
230  if (event->weights().size()>2) {
231  double nominal = event->weight("Weight");
232  for (const auto& name: event->weight_names()) {
233  if (name == "WeightNormalisation") continue;
234  if (name == "NTrials") continue;
235  if (name == "Weight") continue;
236  if (name == "NTrials") continue;
237  if (std::abs(event->weight(name)) > m_variation_weight_cap*std::abs(nominal)) {
238  ATH_MSG_INFO("Capping variation" << name << " = " << event->weight(name)/nominal << "*nominal");
239  event->weight(name) *= m_variation_weight_cap*std::abs(nominal)/std::abs(event->weight(name));
240  }
241  ATH_MSG_DEBUG("Sherpa WEIGHT " << name << " value="<< event->weight(name));
242  }
243  }
244 #else
245  if (event->weights().size()>2) {
246  for (size_t i=0; i<event->weights().size(); ++i) {
247  if (i>3) { // cap variation weights
248  // cap variation weights at m_variation_weight_cap*nominal to avoid spikes from numerical instability
249  if (std::abs(event->weights()[i]) > m_variation_weight_cap*std::abs(event->weights()[0])) {
250  ATH_MSG_INFO("Capping variation" << i << " = " << event->weights()[i]/event->weights()[0] << "*nominal");
251  event->weights()[i] *= m_variation_weight_cap*std::abs(event->weights()[0])/std::abs(event->weights()[i]);
252  }
253  }
254  ATH_MSG_DEBUG("Sherpa WEIGHT " << i << " value="<< event->weights()[i]);
255  }
256  }
257 #endif
258 
259 #ifdef HEPMC3
260  event->set_units(HepMC3::Units::MEV, HepMC3::Units::MM);
261 #else
262  GeVToMeV(event); //unit check
263 #endif
264 
265 
266  return StatusCode::SUCCESS;
267 }
268 
270 
271  ATH_MSG_INFO("Sherpa_i finalize()");
272 
273  std::cout << "MetaData: generator = Sherpa" << SHERPA_VERSION << "." << SHERPA_SUBVERSION << std::endl;
274  std::cout << "MetaData: cross-section (nb)= " << p_sherpa->TotalXS()/1000.0*m_xsscale << std::endl;
275 
276  std::cout << "MetaData: PDF = " << p_sherpa->PDFInfo() << std::endl;
277 
278  std::cout << "Named variations initialised by Sherpa:" << std::endl;
279  std::cout << *p_sherpa->GetInitHandler()->GetVariations() << std::endl;
280 
281  p_sherpa->SummarizeRun();
282  delete p_sherpa;
283 
284  if (m_cleanup) {
285  ATH_MSG_INFO("Deleting left-over files from working directory.");
286  system("rm -rf Results.db Process MIG_*.db MPI_*.dat libSherpa*.so libProc*.so");
287  }
288 
289  return StatusCode::SUCCESS;
290 }
291 
292 
293 #ifndef IS_SHERPA_3
294 void Sherpa_i::getParameters(int &argc, char** &argv) {
295  std::vector<std::string> params;
296 
297  // set some ATLAS specific default values as a starting point
298  params.push_back("EXTERNAL_RNG=Atlas_RNG");
299 
300  /***
301  Adopt Atlas Debug Level Scheme
302  ***/
303 
304  std::string verbose_arg;
305  MsgStream log(msgSvc(), name());
306  if( log.level()==MSG::FATAL || log.level()==MSG::ERROR || log.level()==MSG::WARNING ){
307  params.push_back("OUTPUT=0");
308  }
309  else if(log.level()==MSG::INFO){
310  params.push_back("OUTPUT=2");
311  }
312  else if(log.level()==MSG::DEBUG){
313  params.push_back("OUTPUT=3");
314  }
315  else{
316  params.push_back("OUTPUT=15");
317  }
318 
319  // disregard manual RUNDATA setting if run card given in JO
320  if (m_runcard != "") m_params.value().push_back("RUNDATA=Run.dat");
321 
322  // allow to overwrite all parameters from JO file
323  params.insert(params.begin()+params.size(), m_params.begin(), m_params.end());
324 
325  // create Run.dat file if runcard explicitely given
326  if (m_runcard != "") {
327  FILE *file = fopen("Run.dat","w");
328  fputs(m_runcard.value().c_str(),file);
329  fclose(file);
330  }
331 
332  /***
333  Convert into Sherpas argc/argv arguments
334  ***/
335  argc = 1+params.size();
336  argv = new char * [ 1+params.size() ];
337  argv[0] = new char[7];
338  strcpy(argv[0], "Sherpa");
339 
340  ATH_MSG_INFO("Sherpa_i using the following Arguments");
341  ATH_MSG_INFO(m_runcard);
342  for(size_t i=0; i<params.size(); i++) {
343  ATH_MSG_INFO(" [ " << params[i] << " ] ");
344  argv[i+1] = new char[params[i].size()+1];
345  strcpy(argv[i+1], params[i].c_str());
346  }
347  ATH_MSG_INFO("End Sherpa_i Argument List");
348  ATH_MSG_INFO("Further Sherpa initialisation output will be redirected to the LOG_FILE specified above.");
349 
350 }
351 #endif
352 
353 void Sherpa_i::compilePlugin(std::string pluginCode) {
354  // TODO: not very pretty, should we eventually do this in Python instead (base fragment)
355  FILE *file = fopen("Sherpa_iPlugin.C","w");
356  fputs(pluginCode.c_str(),file);
357  fclose(file);
358  std::string command;
359  // Python -> C++ string conversion seems to add quote character as first
360  // and last line if the string contains quotes (like always in a plugin)
361  // thus removing them here
362  command += "tail -n +2 Sherpa_iPlugin.C | head -n -1 > Sherpa_iPlugin.C.tmp; mv Sherpa_iPlugin.C.tmp Sherpa_iPlugin.C; ";
363  command += "g++ -shared -std=c++0x -g ";
364  command += "-I`Sherpa-config --incdir` ";
365  command += "`Sherpa-config --ldflags` ";
366  command += "-I$FASTJETPATH/include ";
367  command += "-fPIC -o libSherpa_iPlugin.so Sherpa_iPlugin.C";
368  ATH_MSG_INFO("Now compiling plugin library using: "+command);
369  if (system(command.c_str())!=0) {
370  ATH_MSG_ERROR("Error compiling plugin library.");
371  }
372 }
373 
377 using namespace ATOOLS;
378 
379 Atlas_RNG::Atlas_RNG(CLHEP::HepRandomEngine* engine) :
380  External_RNG(), p_engine(engine), m_filename("Config.conf")
381 {
382  const int nMax = 26;
383  char alphabet[nMax] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
384  'h', 'i', 'j', 'k', 'l', 'm', 'n',
385  'o', 'p', 'q', 'r', 's', 't', 'u',
386  'v', 'w', 'x', 'y', 'z' };
387 
388  struct stat info;
389  if ( !stat("/dev/shm", &info)) {
390  m_filename = "/dev/shm/Config.conf.";
391  for (size_t i = 0; i < 6; ++i)
392  m_filename += alphabet[rand() % nMax];
393  }
394  std::cout << "RNG state being saved to: " << m_filename << std::endl;
395 }
396 
398 
399 double Atlas_RNG::Get(){
400 
401  return CLHEP::RandFlat::shoot(p_engine);
402 
403 }
404 
405 void Atlas_RNG::SaveStatus() { p_engine->saveStatus(m_filename.c_str()); }
406 
407 void Atlas_RNG::RestoreStatus() { p_engine->restoreStatus(m_filename.c_str()); }
408 
409 // some getter magic to make this random number generator available to sherpa
410 // DECLARE_GETTER doesn't compile with c++20 in Sherpa versions before 3.
411 #ifdef IS_SHERPA_3
412 DECLARE_GETTER(Atlas_RNG,"Atlas_RNG",External_RNG,RNG_Key);
413 #else
414 namespace ATOOLS {
415 template <> class Getter<External_RNG,RNG_Key,Atlas_RNG,std::less<std::string>>:
416  public Getter_Function<External_RNG,RNG_Key,std::less<std::string>> {
417 private:
418  static Getter<External_RNG,RNG_Key,Atlas_RNG,std::less<std::string>> s_initializer;
419 protected:
420  void PrintInfo(std::ostream &str,const size_t width) const;
421  Object_Type *operator()(const Parameter_Type &parameters) const;
422 public:
423  Getter(const bool &d=true):
424  Getter_Function<External_RNG,RNG_Key,std::less<std::string>>("Atlas_RNG")
425  { SetDisplay(d); }
426 };
427 }
428 ATOOLS::Getter<External_RNG,RNG_Key,Atlas_RNG>
429 ATOOLS::Getter<External_RNG,RNG_Key,Atlas_RNG>::s_initializer(true);
430 #endif
431 
432 External_RNG *ATOOLS::Getter<External_RNG,RNG_Key,Atlas_RNG>::operator()(const RNG_Key &) const
433 { return new Atlas_RNG(p_rndEngine); }
434 
435 void ATOOLS::Getter<External_RNG,RNG_Key,Atlas_RNG>::PrintInfo(std::ostream &str,const size_t) const
436 { str<<"Atlas RNG interface"; }
grepfile.info
info
Definition: grepfile.py:38
ATOOLS::Getter< External_RNG, RNG_Key, Atlas_RNG, std::less< std::string > >::Getter
Getter(const bool &d=true)
Definition: Sherpa_i.cxx:423
Atlas_RNG::Get
double Get()
Definition: Sherpa_i.cxx:399
Sherpa_i::getParameters
void getParameters(int &argc, char **&argv)
Definition: Sherpa_i.cxx:294
GenEvent.h
Atlas_RNG::m_filename
std::string m_filename
Definition: Sherpa_i.h:79
python.Constants.FATAL
int FATAL
Definition: Control/AthenaCommon/python/Constants.py:19
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
AthMsgStreamMacros.h
Sherpa_i::fillEvt
StatusCode fillEvt(HepMC::GenEvent *evt)
For filling the HepMC event object.
Definition: Sherpa_i.cxx:220
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
hist_file_dump.d
d
Definition: hist_file_dump.py:137
MM
@ MM
Definition: RegSelEnums.h:38
Cut::signal
@ signal
Definition: SUSYToolsAlg.cxx:67
Atlas_RNG
Definition: Sherpa_i.h:77
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
ATOOLS::Getter< External_RNG, RNG_Key, Atlas_RNG, std::less< std::string > >::PrintInfo
void PrintInfo(std::ostream &str, const size_t width) const
GenModule
Base class for common behaviour of generator interfaces.
Definition: GenModule.h:39
PixelModuleFeMask_create_db.remove
string remove
Definition: PixelModuleFeMask_create_db.py:83
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
ATOOLS::Getter< External_RNG, RNG_Key, Atlas_RNG, std::less< std::string > >::s_initializer
static Getter< External_RNG, RNG_Key, Atlas_RNG, std::less< std::string > > s_initializer
Definition: Sherpa_i.cxx:418
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
LArG4FSStartPointFilter.rand
rand
Definition: LArG4FSStartPointFilter.py:80
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
lumiFormat.i
int i
Definition: lumiFormat.py:85
LArCellNtuple.argv
argv
Definition: LArCellNtuple.py:152
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Sherpa_i::Sherpa_i
Sherpa_i(const std::string &name, ISvcLocator *pSvcLocator)
Definition: Sherpa_i.cxx:38
calibdata.exception
exception
Definition: calibdata.py:496
file
TFile * file
Definition: tile_monitor.h:29
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
Atlas_RNG::p_engine
CLHEP::HepRandomEngine * p_engine
Definition: Sherpa_i.h:78
Atlas_RNG::~Atlas_RNG
~Atlas_RNG()
Definition: Sherpa_i.cxx:397
beamspotman.stat
stat
Definition: beamspotman.py:266
Sherpa_i::genFinalize
StatusCode genFinalize()
For finalising the generator, if required.
Definition: Sherpa_i.cxx:269
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
CxxUtils::fpcompare::less
bool less(double a, double b)
Compare two FP numbers, working around x87 precision issues.
Definition: fpcompare.h:166
RNGWrapper.h
Sherpa_i::compilePlugin
void compilePlugin(std::string)
Definition: Sherpa_i.cxx:353
mc.generator
generator
Configure Herwig7 These are the commands corresponding to what would go into the regular Herwig infil...
Definition: mc.MGH7_FxFx_H71-DEFAULT_test.py:18
Atlas_RNG::Atlas_RNG
Atlas_RNG(CLHEP::HepRandomEngine *)
Definition: Sherpa_i.cxx:379
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
Sherpa_i::genInitialize
StatusCode genInitialize()
For initializing the generator, if required.
Definition: Sherpa_i.cxx:49
ATOOLS::Getter< External_RNG, RNG_Key, Atlas_RNG, std::less< std::string > >::operator()
Object_Type * operator()(const Parameter_Type &parameters) const
FullCPAlgorithmsTest_CA.inputfile
dictionary inputfile
Definition: FullCPAlgorithmsTest_CA.py:59
DEBUG
#define DEBUG
Definition: page_access.h:11
ATOOLS
Definition: Sherpa_i.cxx:414
Sherpa_i.h
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
ATHRNG::calculateSeedsMC21
void calculateSeedsMC21(long *seeds, const std::string &algName, uint64_t ev, uint64_t run, uint64_t offset=0)
Set the random seed using a string (e.g.
Definition: RNGWrapper.cxx:37
physics_parameters.parameters
parameters
Definition: physics_parameters.py:144
Atlas_RNG::RestoreStatus
void RestoreStatus()
Definition: Sherpa_i.cxx:407
str
Definition: BTagTrackIpAccessor.cxx:11
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
get_generator_info.command
string command
Definition: get_generator_info.py:38
Sherpa_i::callGenerator
StatusCode callGenerator()
For calling the generator on each iteration of the event loop.
Definition: Sherpa_i.cxx:200
Atlas_RNG::SaveStatus
void SaveStatus()
Definition: Sherpa_i.cxx:405
p_rndEngine
CLHEP::HepRandomEngine * p_rndEngine
Definition: Sherpa_i.cxx:36