Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F19251633
Herwig++.cc
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
Herwig++.cc
View Options
// -*- C++ -*-
//
// Herwig++.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2011 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#include
"herwigopts.h"
#include
<ThePEG/Persistency/PersistentIStream.h>
#include
<ThePEG/Repository/EventGenerator.h>
#include
<ThePEG/Utilities/DynamicLoader.h>
#include
<ThePEG/Repository/Repository.h>
#include
<ThePEG/Utilities/Exception.h>
#include
<ThePEG/Utilities/Debug.h>
#include
<ThePEG/Handlers/StandardEventHandler.h>
#include
<ThePEG/Handlers/SamplerBase.h>
#include
<iostream>
#include
<sstream>
#include
<cstdio>
#include
<unistd.h>
#include
<sys/wait.h>
#include
<boost/filesystem.hpp>
#include
"Herwig++/Utilities/RunDirectories.h"
using
namespace
ThePEG
;
void
printUsageAndExit
();
void
HerwigInit
(
string
infile
,
string
reponame
);
void
HerwigRead
(
string
reponame
,
string
runname
,
const
gengetopt_args_info
&
args_info
);
void
HerwigRun
(
string
runname
,
string
setupfile
,
int
seed
,
string
tag
,
long
N
,
bool
tics
,
bool
resume
,
int
jobs
,
bool
integrationJob
,
string
integrationList
);
void
setSearchPaths
(
const
gengetopt_args_info
&
args_info
);
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
// read command line options
gengetopt_args_info
args_info
;
if
(
cmdline_parser
(
argc
,
argv
,
&
args_info
)
!=
0
)
{
std
::
cerr
<<
"Could not parse command line.
\n
"
;
return
EXIT_FAILURE
;
}
// require one command
if
(
args_info
.
inputs_num
<
1
)
printUsageAndExit
();
// Interpret command status
enum
{
INIT
,
READ
,
BUILD
,
INTEGRATE
,
RUN
,
ERROR
}
status
;
std
::
string
runType
=
args_info
.
inputs
[
0
];
if
(
runType
==
"init"
)
{
status
=
INIT
;
SamplerBase
::
setRunLevel
(
SamplerBase
::
InitMode
);
}
else
if
(
runType
==
"read"
)
{
status
=
READ
;
SamplerBase
::
setRunLevel
(
SamplerBase
::
ReadMode
);
}
else
if
(
runType
==
"build"
)
{
status
=
BUILD
;
SamplerBase
::
setRunLevel
(
SamplerBase
::
BuildMode
);
}
else
if
(
runType
==
"integrate"
)
{
status
=
INTEGRATE
;
SamplerBase
::
setRunLevel
(
SamplerBase
::
IntegrationMode
);
}
else
if
(
runType
==
"run"
)
{
status
=
RUN
;
SamplerBase
::
setRunLevel
(
SamplerBase
::
RunMode
);
}
else
{
status
=
ERROR
;
printUsageAndExit
();
}
// Use second argument as input- or runfile name
string
runname
;
if
(
args_info
.
inputs_num
>
1
)
runname
=
args_info
.
inputs
[
1
];
// If status is RUN, we need a runname
if
(
(
status
==
RUN
||
status
==
INTEGRATE
)
&&
runname
.
empty
()
)
{
cerr
<<
"Error: You need to supply a runfile name.
\n
"
;
printUsageAndExit
();
}
// If status is INIT, we need a runname
if
(
status
==
INIT
&&
runname
.
empty
()
)
runname
=
"HerwigDefaults.in"
;
// Defaults for these filenames are set in the ggo file
std
::
string
reponame
=
args_info
.
repo_arg
;
// Number of events
long
N
=
-
1
;
if
(
args_info
.
numevents_given
)
N
=
args_info
.
numevents_arg
;
// RNG seed
int
seed
=
0
;
if
(
args_info
.
seed_given
)
{
seed
=
args_info
.
seed_arg
;
}
// run name tag (default given in ggo file)
string
tag
=
args_info
.
tag_arg
;
// run modifccation file
string
setupfile
=
""
;
if
(
args_info
.
setupfile_given
)
setupfile
=
args_info
.
setupfile_arg
;
// parallel jobs
int
jobs
=
1
;
if
(
args_info
.
jobs_given
)
jobs
=
args_info
.
jobs_arg
;
setSearchPaths
(
args_info
);
// Library search path for dlopen()
for
(
size_t
i
=
0
;
i
<
args_info
.
append_given
;
++
i
)
DynamicLoader
::
appendPath
(
args_info
.
append_arg
[
i
]
);
for
(
size_t
i
=
0
;
i
<
args_info
.
prepend_given
;
++
i
)
DynamicLoader
::
prependPath
(
args_info
.
prepend_arg
[
i
]
);
// Debugging level
if
(
args_info
.
debug_given
)
Debug
::
setDebug
(
args_info
.
debug_arg
);
// Floating point exceptions
if
(
args_info
.
debug_fpe_flag
)
Debug
::
unmaskFpuErrors
();
// Exit-on-error flag
if
(
!
args_info
.
noexitonerror_flag
)
Repository
::
exitOnError
()
=
1
;
// Tics
bool
tics
=
true
;
if
(
args_info
.
quiet_flag
)
tics
=
false
;
// integration list
string
integrationList
=
""
;
if
(
args_info
.
jobid_given
)
{
integrationList
=
"integrationJob"
+
string
(
args_info
.
jobid_arg
);
}
// job size
unsigned
int
jobsize
=
0
;
if
(
args_info
.
jobsize_given
)
{
jobsize
=
args_info
.
jobsize_arg
;
SamplerBase
::
setIntegratePerJob
(
jobsize
);
}
// max integration jobs
unsigned
int
maxjobs
=
0
;
if
(
args_info
.
maxjobs_given
)
{
maxjobs
=
args_info
.
maxjobs_arg
;
SamplerBase
::
setIntegrationJobs
(
maxjobs
);
}
// Resume
bool
resume
=
false
;
if
(
args_info
.
resume_flag
)
resume
=
true
;
// *** End of command line parsing ***
// Call mode
switch
(
status
)
{
case
INIT
:
HerwigInit
(
runname
,
reponame
);
break
;
case
READ
:
HerwigRead
(
reponame
,
runname
,
args_info
);
break
;
case
BUILD
:
HerwigRead
(
reponame
,
runname
,
args_info
);
break
;
case
INTEGRATE
:
HerwigRun
(
runname
,
setupfile
,
seed
,
tag
,
N
,
tics
,
resume
,
jobs
,
true
,
integrationList
);
break
;
case
RUN
:
HerwigRun
(
runname
,
setupfile
,
seed
,
tag
,
N
,
tics
,
resume
,
jobs
,
false
,
integrationList
);
break
;
default
:
printUsageAndExit
();
}
Repository
::
cleanup
();
cmdline_parser_free
(
&
args_info
);
return
EXIT_SUCCESS
;
}
catch
(
ThePEG
::
Exception
&
e
)
{
std
::
cerr
<<
argv
[
0
]
<<
": ThePEG::Exception caught. "
<<
"See logfile for details.
\n
"
;
Repository
::
cleanup
();
return
EXIT_FAILURE
;
}
catch
(
std
::
exception
&
e
)
{
std
::
cerr
<<
argv
[
0
]
<<
": "
<<
e
.
what
()
<<
'\n'
;
Repository
::
cleanup
();
return
EXIT_FAILURE
;
}
catch
(
const
char
*
what
)
{
std
::
cerr
<<
argv
[
0
]
<<
": caught exception: "
<<
what
<<
"
\n
"
;
Repository
::
cleanup
();
return
EXIT_FAILURE
;
}
catch
(...)
{
std
::
cerr
<<
argv
[
0
]
<<
": Unknown exception caught.
\n
"
;
Repository
::
cleanup
();
return
EXIT_FAILURE
;
}
}
void
setSearchPaths
(
const
gengetopt_args_info
&
args_info
)
{
// Search path for read command uses CWD first
string
cwd
=
boost
::
filesystem
::
current_path
().
string
();
Repository
::
prependReadDir
(
cwd
);
// append command line choices
for
(
size_t
i
=
0
;
i
<
args_info
.
append_read_given
;
++
i
)
Repository
::
appendReadDir
(
args_info
.
append_read_arg
[
i
]
);
for
(
size_t
i
=
0
;
i
<
args_info
.
prepend_read_given
;
++
i
)
Repository
::
prependReadDir
(
args_info
.
prepend_read_arg
[
i
]
);
}
void
printUsageAndExit
()
{
std
::
cerr
<<
gengetopt_args_info_usage
<<
'\n'
;
Repository
::
cleanup
();
exit
(
EXIT_FAILURE
);
}
void
HerwigInit
(
string
infile
,
string
reponame
)
{
breakThePEG
();
{
# ifdef HERWIG_PKGLIBDIR
DynamicLoader
::
appendPath
(
HERWIG_PKGLIBDIR
);
# endif
# ifdef THEPEG_PKGLIBDIR
DynamicLoader
::
appendPath
(
THEPEG_PKGLIBDIR
);
# endif
HoldFlag
<>
setup
(
InterfaceBase
::
NoReadOnly
);
string
msg
=
Repository
::
read
(
infile
,
cout
);
if
(
!
msg
.
empty
()
)
cerr
<<
msg
<<
'\n'
;
Repository
::
update
();
}
Repository
::
save
(
reponame
);
}
void
HerwigRead
(
string
reponame
,
string
runname
,
const
gengetopt_args_info
&
args_info
)
{
#ifdef HERWIG_PKGDATADIR
ifstream
test
(
reponame
.
c_str
());
if
(
!
test
)
{
reponame
=
string
(
HERWIG_PKGDATADIR
)
+
'/'
+
reponame
;
}
test
.
close
();
#endif
string
msg
=
Repository
::
load
(
reponame
);
if
(
!
msg
.
empty
()
)
cerr
<<
msg
<<
'\n'
;
setSearchPaths
(
args_info
);
breakThePEG
();
if
(
!
runname
.
empty
()
&&
runname
!=
"-"
)
{
string
msg
=
Repository
::
read
(
runname
,
std
::
cout
);
if
(
!
msg
.
empty
()
)
cerr
<<
msg
<<
'\n'
;
}
else
{
Repository
::
exitOnError
()
=
0
;
Repository
::
read
(
std
::
cin
,
std
::
cout
,
"Herwig++> "
);
}
}
void
HerwigRun
(
string
runname
,
string
setupfile
,
int
seed
,
string
tag
,
long
N
,
bool
tics
,
bool
resume
,
int
jobs
,
bool
integrationJob
,
string
integrationList
)
{
if
(
integrationJob
&&
jobs
>
1
)
{
std
::
cerr
<<
"parallel event generation is not applicable to integrate
\n
"
;
exit
(
EXIT_FAILURE
);
}
PersistentIStream
is
(
runname
);
ThePEG
::
EGPtr
eg
;
is
>>
eg
;
// debugging breakpoint
breakThePEG
();
if
(
!
eg
)
{
std
::
cerr
<<
"Herwig++: EventGenerator not available.
\n
"
<<
"Check if '"
<<
runname
<<
"' is a valid run file.
\n
"
;
Repository
::
cleanup
();
exit
(
EXIT_FAILURE
);
}
Herwig
::
RunDirectories
::
pushRunId
(
eg
->
runName
());
if
(
!
setupfile
.
empty
()
)
Herwig
::
RunDirectories
::
pushRunId
(
setupfile
);
if
(
!
tag
.
empty
()
)
Herwig
::
RunDirectories
::
pushRunId
(
tag
);
if
(
!
integrationList
.
empty
()
)
Herwig
::
RunDirectories
::
pushRunId
(
integrationList
);
if
(
seed
>
0
)
{
ostringstream
sseed
;
sseed
<<
seed
;
Herwig
::
RunDirectories
::
pushRunId
(
sseed
.
str
());
}
if
(
seed
>
0
)
eg
->
setSeed
(
seed
);
if
(
!
setupfile
.
empty
()
)
eg
->
addTag
(
"-"
+
setupfile
);
if
(
!
tag
.
empty
()
)
eg
->
addTag
(
tag
);
if
(
integrationJob
)
{
Ptr
<
StandardEventHandler
>::
tptr
eh
=
dynamic_ptr_cast
<
Ptr
<
StandardEventHandler
>::
tptr
>
(
eg
->
eventHandler
());
if
(
!
eh
)
{
std
::
cerr
<<
"Herwig++: Cannot set integration mode for a non-standard EventHandler.
\n
"
;
Repository
::
cleanup
();
exit
(
EXIT_FAILURE
);
}
if
(
!
integrationList
.
empty
()
)
eh
->
sampler
()
->
integrationList
(
integrationList
);
}
if
(
!
setupfile
.
empty
()
)
{
SamplerBase
::
setupFileUsed
();
string
msg
=
Repository
::
modifyEventGenerator
(
*
eg
,
setupfile
,
cout
,
true
);
if
(
!
msg
.
empty
()
)
cerr
<<
msg
<<
'\n'
;
if
(
integrationJob
)
return
;
}
if
(
integrationJob
)
{
Repository
::
resetEventGenerator
(
*
eg
);
return
;
}
if
(
jobs
<=
1
)
{
eg
->
go
(
resume
?
-
1
:
1
,
N
,
tics
);
if
(
tics
)
std
::
cout
<<
'\n'
;
}
else
{
// forked jobs
pid_t
pid
;
const
int
maxlen
=
log10
(
jobs
)
+
1
;
for
(
int
n
=
0
;
n
<
jobs
;
n
++
)
{
ostringstream
tmp
;
tmp
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
maxlen
)
<<
n
+
1
;
const
string
nstr
=
tmp
.
str
();
pid
=
fork
();
if
(
pid
==
-
1
)
{
// fork failed
std
::
perror
(
"Herwig++: fork"
);
Repository
::
cleanup
();
exit
(
EXIT_FAILURE
);
}
else
if
(
pid
==
0
)
{
// we're the child
if
(
tics
)
std
::
cout
<<
"Forked child "
<<
n
<<
", PID "
<<
getpid
()
<<
std
::
endl
;
eg
->
setSeed
(
seed
+
n
);
eg
->
addTag
(
tag
+
"-"
+
nstr
);
Herwig
::
RunDirectories
::
pushRunId
(
nstr
);
eg
->
go
(
resume
?
-
1
:
1
,
N
/
jobs
,
false
);
break
;
// avoid sub-forks
}
// nothing to do here if we're the parent
}
// children have nothing else to do
if
(
pid
==
0
)
return
;
if
(
tics
)
std
::
cout
<<
"Waiting for forked jobs."
<<
std
::
endl
;
int
status
;
pid_t
child
;
bool
cleanrun
=
true
;
while
(
true
)
{
child
=
wait
(
&
status
);
if
(
child
==
-
1
)
{
if
(
errno
==
ECHILD
)
{
if
(
tics
)
std
::
cout
<<
"No more forked jobs."
<<
std
::
endl
;
break
;
}
else
{
std
::
perror
(
"Herwig++: waitpid"
);
Repository
::
cleanup
();
exit
(
EXIT_FAILURE
);
}
}
if
(
WIFEXITED
(
status
))
{
if
(
WEXITSTATUS
(
status
)
!=
0
)
cleanrun
=
false
;
if
(
tics
)
std
::
cout
<<
"PID "
<<
child
<<
" exited, status="
<<
WEXITSTATUS
(
status
)
<<
std
::
endl
;
}
else
if
(
WIFSIGNALED
(
status
))
{
// a clean SIGTERM is handled in the child
// and will count as exit above, so...
cleanrun
=
false
;
if
(
tics
)
std
::
cout
<<
"PID "
<<
child
<<
" killed by signal "
<<
WTERMSIG
(
status
)
<<
std
::
endl
;
}
}
if
(
!
cleanrun
)
{
Repository
::
cleanup
();
exit
(
EXIT_FAILURE
);
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Tue, Sep 30, 6:08 AM (1 d, 10 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
6395804
Default Alt Text
Herwig++.cc (11 KB)
Attached To
Mode
rHERWIGHG herwighg
Attached
Detach File
Event Timeline
Log In to Comment