11#!/pbs/throng/creatis/cl7/opengate/venv/bin/python
22
33import os
4- import tempfile
54import shutil
6- import click
75import socket
8- import subprocess
9- import colorama
10- import numpy as np
11- import sys
6+ import tempfile
127import time
8+
9+ import click
10+ import colorama
11+
1312import gatetools
1413
14+
1515def 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 (' \n commands: \n ' )
176+ # Create file to write commands in it
177+ paramFile .write (" \n commands: \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
151227if __name__ == "__main__" :
0 commit comments