Skip to content

Commit 590206a

Browse files
committed
Update submission script for opengate
Link data instead of copy for ccIn2p3 lint
1 parent 5beef91 commit 590206a

2 files changed

Lines changed: 146 additions & 70 deletions

File tree

gatetools/clustertools/opengate_job_ccin2p3.slurm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ cd $TMPDIR
5959
LOCALMACRODIR=$(mktemp -d -p .)
6060
trap "wait ; transferJobData ; exit 1" 1 2 3 15
6161
cd ${LOCALMACRODIR}
62-
cp -r -L "${MACRODIR}"/* .
62+
ln -s "${MACRODIR}"/* .
6363
rm -rf output
6464
mkdir output
6565

gatetools/clustertools/opengate_run.py

Lines changed: 145 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,215 @@
11
#!/pbs/throng/creatis/cl7/opengate/venv/bin/python
22

33
import os
4-
import tempfile
54
import shutil
6-
import click
75
import socket
8-
import subprocess
9-
import colorama
10-
import numpy as np
11-
import sys
6+
import tempfile
127
import time
8+
9+
import click
10+
import colorama
11+
1312
import gatetools
1413

14+
1515
def get_dns_domain():
16-
domain = socket.getfqdn().split('.', 1)
16+
domain = socket.getfqdn().split(".", 1)
1717
if len(domain) >= 2:
1818
return domain[1]
1919
else:
2020
return domain[0]
2121

22-
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
22+
23+
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
24+
25+
2326
@click.command(context_settings=CONTEXT_SETTINGS)
24-
@click.argument('script', nargs=1)
25-
@click.option('-j', '--jobs', default=1, help='Number of jobs/core')
26-
@click.option('-o', '--output', default='', help='Output folder path (default: run.XXX)')
27-
@click.option('-p', '--param', default='', help='click parameter to pass to the python script (-p " --angle 10 --nbParticles 1e8"')
28-
@click.option('--copydata', is_flag=True, help='Hard copy data into run.XXX folder (default: symbolic link)')
29-
@click.option('-d', '--dry', is_flag=True, help='If dry is set, copy all files, write the submission command lines but do not execute them')
30-
@click.option('--env', default='', help='Bash script to set environment variables during job. This file is source at the beginning.')
31-
@click.option('--jobfile', default='', help='Job file for the cluster allowing to modify submission parameters (--jobfile="current" display the path of the current job file and exit)')
32-
def runJobs_click(script, jobs, env, output, param, copydata, dry, jobfile):
27+
@click.argument("script", nargs=1)
28+
@click.option("-j", "--jobs", default=1, help="Number of jobs/core")
29+
@click.option(
30+
"-o", "--output", default="", help="Output folder path (default: run.XXX)"
31+
)
32+
@click.option(
33+
"-p",
34+
"--param",
35+
default="",
36+
help='click parameter to pass to the python script (-p " --angle 10 --nbParticles 1e8"',
37+
)
38+
@click.option(
39+
"-d",
40+
"--dry",
41+
is_flag=True,
42+
help="If dry is set, write the submission command lines but do not execute them",
43+
)
44+
@click.option(
45+
"--env",
46+
default="",
47+
help="Bash script to set environment variables during job. This file is source at the beginning.",
48+
)
49+
@click.option(
50+
"--jobfile",
51+
default="",
52+
help='Job file for the cluster allowing to modify submission parameters (--jobfile="current" display the path of the current job file and exit)',
53+
)
54+
def runJobs_click(script, jobs, env, output, param, dry, jobfile):
3355
"""
3456
\b
35-
Run python Gate jobs
57+
Run python opengate jobs
3658
37-
script: input python script filename
59+
!!! Your python script must write all the outputs inside the folder called output !!!
3860
39-
"""
40-
runJobs_opengate(script, jobs, env, output, param, copydata, dry, jobfile)
61+
example to run 10 jobs with the script script.py:
62+
opengate_run -j 10 script.py
63+
64+
example in bash to run 1 job with different angles with the script script.py and write outputs in different folders:
65+
for angle in 10 20 30; do
66+
opengate_run -j 1 -p " --angle $angle --nbParticles 1e8" -o output_angle_$angle script.py
4167
68+
Then you can merge the results with the command opengate_power_merge
69+
"""
70+
runJobs_opengate(script, jobs, env, output, param, dry, jobfile)
4271

4372

44-
def runJobs_opengate(script, jobs=1, env='', output='', param='', copydata=False, dry=False, jobfile=''):
45-
directoryJobFiles = os.path.join(os.path.dirname(os.path.realpath(gatetools.__file__)), "clustertools")
73+
def runJobs_opengate(
74+
script, jobs=1, env="", output="", param="", dry=False, jobfile=""
75+
):
76+
directoryJobFiles = os.path.join(
77+
os.path.dirname(os.path.realpath(gatetools.__file__)), "clustertools"
78+
)
4679

4780
# Source env file
48-
envCommand = ''
49-
if not env == '':
81+
envCommand = ""
82+
if not env == "":
5083
if not os.path.isabs(env):
51-
env = os.path.join(os.getcwd(), env)
84+
env = os.path.join(os.getcwd(), env)
5285
if not os.path.isfile(env):
53-
print(colorama.Fore.RED + 'ERROR: No env found : ' + env + colorama.Style.RESET_ALL)
86+
print(
87+
colorama.Fore.RED
88+
+ "ERROR: No env found : "
89+
+ env
90+
+ colorama.Style.RESET_ALL
91+
)
5492
exit(1)
5593
else:
5694
envCommand = env
5795
else:
58-
envCommand = 'NONE'
96+
envCommand = "NONE"
5997

6098
jobFile = ""
6199
# Take the correct job file according to the cluster name and jobfile option
62-
if jobfile == '' or jobfile == "current":
63-
if get_dns_domain() == 'in2p3.fr':
64-
jobFile = os.path.join(directoryJobFiles, 'opengate_job_ccin2p3.slurm')
100+
if jobfile == "" or jobfile == "current":
101+
if get_dns_domain() == "in2p3.fr":
102+
jobFile = os.path.join(directoryJobFiles, "opengate_job_ccin2p3.slurm")
65103
if jobfile == "current":
66-
print(colorama.Fore.GREEN + 'Path to the job file: ' + colorama.Style.RESET_ALL)
104+
print(
105+
colorama.Fore.GREEN
106+
+ "Path to the job file: "
107+
+ colorama.Style.RESET_ALL
108+
)
67109
print(jobFile)
68110
exit(1)
69111
else:
70112
jobFile = jobfile
71113
if not os.path.isabs(jobFile):
72-
jobFile = os.path.join(os.getcwd(), jobFile)
114+
jobFile = os.path.join(os.getcwd(), jobFile)
73115
if not os.path.isfile(jobFile):
74-
print(colorama.Fore.RED + 'ERROR: The job file does not exist: ' + jobFile + colorama.Style.RESET_ALL)
116+
print(
117+
colorama.Fore.RED
118+
+ "ERROR: The job file does not exist: "
119+
+ jobFile
120+
+ colorama.Style.RESET_ALL
121+
)
75122
exit(1)
76123

77124
# Get python folder and files
78125
fullMacroDir = os.path.join(os.getcwd(), os.path.dirname(os.path.dirname(script)))
79126
fullScriptFile = os.path.join(fullMacroDir, os.path.basename(script))
80127
if not os.path.isfile(script):
81-
print(colorama.Fore.RED + 'ERROR: The python file does not exist: ' + script + colorama.Style.RESET_ALL)
128+
print(
129+
colorama.Fore.RED
130+
+ "ERROR: The python file does not exist: "
131+
+ script
132+
+ colorama.Style.RESET_ALL
133+
)
82134
exit(1)
83135

84136
# Check output path is absolute or relative
85137
outputDir = output
86-
if not outputDir == '' and not os.path.isabs(outputDir):
87-
outputDir = os.path.join(os.getcwd(), outputDir)
138+
if not outputDir == "" and not os.path.isabs(outputDir):
139+
outputDir = os.path.join(os.getcwd(), outputDir)
88140
# Create output directory
89-
if not outputDir == '' and os.path.isdir(outputDir):
90-
print(colorama.Fore.YELLOW + 'WARNING: The output folder already exist: ' + outputDir + colorama.Style.RESET_ALL)
91-
print(colorama.Fore.YELLOW + 'Evereything will be overwritten' + colorama.Style.RESET_ALL)
92-
if outputDir == '':
93-
outputDir = tempfile.mkdtemp(prefix='run.', dir=fullMacroDir)
141+
if not outputDir == "" and os.path.isdir(outputDir):
142+
print(
143+
colorama.Fore.YELLOW
144+
+ "WARNING: The output folder already exist: "
145+
+ outputDir
146+
+ colorama.Style.RESET_ALL
147+
)
148+
print(
149+
colorama.Fore.YELLOW
150+
+ "Evereything will be overwritten"
151+
+ colorama.Style.RESET_ALL
152+
)
153+
if outputDir == "":
154+
outputDir = tempfile.mkdtemp(prefix="run.", dir=fullMacroDir)
94155
elif not os.path.isdir(outputDir):
95156
os.makedirs(outputDir)
96-
runId = os.path.basename(outputDir)[os.path.basename(outputDir).find('.') +1:]
97-
if runId == '':
157+
runId = os.path.basename(outputDir)[os.path.basename(outputDir).find(".") + 1 :]
158+
if runId == "":
98159
runId == os.path.basename(outputDir)
99-
print('Run Id is: ' + runId)
160+
print("Run Id is: " + runId)
100161

101162
# Find qsub
102-
qsub = shutil.which('qsub')
163+
qsub = shutil.which("qsub")
103164
if qsub is None:
104-
qsub = shutil.which('sbatch')
165+
qsub = shutil.which("sbatch")
105166
if qsub is None:
106-
print('No qsub, run Gate on multiple cores.')
167+
print("No qsub, run Gate on multiple cores.")
107168

108169
# Parameter files
109-
paramFileName = os.path.join(outputDir, 'run.log')
170+
paramFileName = os.path.join(outputDir, "run.log")
110171
paramFile = open(paramFileName, "w")
111-
paramFile.write('number of jobs = ' + str(jobs) + '\n')
112-
paramFile.write('script = ' + script + '\n')
113-
paramFile.write('runId = ' + runId + '\n')
172+
paramFile.write("number of jobs = " + str(jobs) + "\n")
173+
paramFile.write("script = " + script + "\n")
174+
paramFile.write("runId = " + runId + "\n")
114175

115-
#Create file to write commands in it
116-
paramFile.write('\ncommands: \n')
176+
# Create file to write commands in it
177+
paramFile.write("\ncommands: \n")
117178

118179
# Run jobs
119180
for i in range(0, jobs):
120-
#Set paramtogate with param for each job
181+
# Set paramtogate with param for each job
121182
paramtogateJob = param
122183

123-
if get_dns_domain() == 'in2p3.fr':
124-
tempParamFile = tempfile.NamedTemporaryFile(mode='w+t', delete=False, prefix='var.', dir=outputDir)
184+
command = ""
185+
if get_dns_domain() == "in2p3.fr":
186+
tempParamFile = tempfile.NamedTemporaryFile(
187+
mode="w+t", delete=False, prefix="var.", dir=outputDir
188+
)
125189
tempParamFile.write(paramtogateJob)
126190
tempParamFile.close()
127-
command = 'sbatch -L sps -J gate.' + runId + \
128-
' -D ' + outputDir + \
129-
' --export=ALL,PARAM=\"' + tempParamFile.name + \
130-
'\",INDEX=' + str(i) + \
131-
',INDEXMAX=' + str(jobs) + \
132-
',OUTPUTDIR=' + outputDir + \
133-
',MACROFILE=' + fullScriptFile + \
134-
',MACRODIR=' + os.path.dirname(fullScriptFile) + \
135-
',ENVCOMMAND=' + envCommand + \
136-
' ' + jobFile
191+
command = (
192+
"sbatch -L sps -J gate."
193+
+ runId
194+
+ " -D "
195+
+ outputDir
196+
+ ' --export=ALL,PARAM="'
197+
+ tempParamFile.name
198+
+ '",INDEX='
199+
+ str(i)
200+
+ ",INDEXMAX="
201+
+ str(jobs)
202+
+ ",OUTPUTDIR="
203+
+ outputDir
204+
+ ",MACROFILE="
205+
+ fullScriptFile
206+
+ ",MACRODIR="
207+
+ os.path.dirname(fullScriptFile)
208+
+ ",ENVCOMMAND="
209+
+ envCommand
210+
+ " "
211+
+ jobFile
212+
)
137213
paramFile.write(command)
138214
paramFile.write("\n")
139215
if dry:
@@ -144,8 +220,8 @@ def runJobs_opengate(script, jobs=1, env='', output='', param='', copydata=False
144220
time.sleep(1)
145221

146222
paramFile.close()
147-
print(str(jobs) + ' jobs running')
148-
print('Run folder is: ' + outputDir)
223+
print(str(jobs) + " jobs running")
224+
print("Run folder is: " + outputDir)
149225

150226

151227
if __name__ == "__main__":

0 commit comments

Comments
 (0)