@@ -195,8 +195,40 @@ def run_fast(input_file, fastExe=None, wait=True, showOutputs=False, showCommand
195195 return run_cmd (input_file , fastExe , wait = wait , showOutputs = showOutputs , showCommand = showCommand )
196196
197197
198- def writeBatch (batchfile , fastfiles , fastExe = None , nBatches = 1 , pause = False , flags = '' , flags_after = '' ):
199- """ Write batch file, everything is written relative to the batch file"""
198+ def writeBatch (batchfile , fastfiles , fastExe = None , nBatches = 1 , pause = False , flags = '' , flags_after = '' ,
199+ run_if_ext_missing = None ,
200+ discard_if_ext_present = None ,
201+ dispatch = False ,
202+ stdOutToFile = False ,
203+ echo = True ):
204+ """ Write one or several batch file, all paths are written relative to the batch file directory.
205+ The batch file will consist of lines of the form:
206+ [CONDITION] EXE [FLAGS] FILENAME [FLAGS_AFTER]
207+
208+ INPUTS:
209+ - batchfile: path of the batch file to be written.
210+ If several files are requested (using nBatches) _i is inserted before the extension
211+ - nBatches: split into nBatches files.
212+ - pause: insert a pause statement at the end so that batch file is not closed after execution
213+ - flags: flags (string) to be placed between the executable and the filename
214+ - flags_after: flags (string) to be placed after the filename
215+ - run_if_ext_missing: add a line in the batch file so that the command is only run if
216+ the file `f.EXT` is missing, where .EXT is specified in run_if_ext_missing
217+ If None, the command is always run
218+ - discard_if_ext_present: similar to run_if_ext_missing, but this time, the lines are not written to the batch file
219+ The test for existing outputs is done before writing the batch file
220+ - dispatch: if True, the input files are dispatched (the first nBatches files are dispathced on the nBatches)
221+ - stdOutToFile: if True, the output of the command is redirected to filename.stdout
222+
223+ example:
224+ writeBatch('dir/MyBatch.bat', ['dir/c1.fst','dir/c2.fst'], 'op.exe', flags='-v', run_if_ext_missing='.outb')
225+
226+ will generate a file with the following content:
227+ if not exist c1.outb (../of.exe c1.fst) else (echo "Skipping c1.fst")
228+ if not exist c2.outb (../of.exe c2.fst) else (echo "Skipping c2.fst")
229+
230+
231+ """
200232 if fastExe is None :
201233 fastExe = FAST_EXE
202234 fastExe_abs = os .path .abspath (fastExe )
@@ -207,20 +239,54 @@ def writeBatch(batchfile, fastfiles, fastExe=None, nBatches=1, pause=False, flag
207239 flags = ' ' + flags
208240 if len (flags_after )> 0 :
209241 flags_after = ' ' + flags_after
242+
243+ # Remove commandlines if outputs are already present
244+ if discard_if_ext_present :
245+ outfiles = [os .path .splitext (f )[0 ] + discard_if_ext_present for f in fastfiles ]
246+ nIn = len (fastfiles )
247+ fastfiles = [f for f ,o in zip (fastfiles ,outfiles ) if not os .path .exists (o )]
248+ nMiss = len (fastfiles )
249+ if nIn > nMiss :
250+ print ('[INFO] WriteBatch: discarding simulations, only {}/{} needed' .format (nMiss , nIn ))
251+
252+
210253 def writeb (batchfile , fastfiles ):
211254 with open (batchfile ,'w' ) as f :
255+ if not echo :
256+ if os .name == 'nt' :
257+ f .write ('@echo off\n ' )
212258 for ff in fastfiles :
213259 ff_abs = os .path .abspath (ff )
214260 ff_rel = os .path .relpath (ff_abs , batchdir )
215- l = fastExe_rel + flags + ' ' + ff_rel + flags_after
216- f .write ("{:s}\n " .format (l ))
261+ cmd = fastExe_rel + flags + ' ' + ff_rel + flags_after
262+ if stdOutToFile :
263+ stdout = os .path .splitext (ff_rel )[0 ]+ '.stdout'
264+ cmd += ' > ' + stdout
265+ if run_if_ext_missing is not None :
266+ # TODO might be windows only
267+ ff_out = os .path .splitext (ff_rel )[0 ] + run_if_ext_missing
268+ if os .name == 'nt' :
269+ cmd = 'if not exist {} ({}) else (echo Skipping {})' .format (ff_out , cmd , ff_rel )
270+ else :
271+ cmd = 'if [[ ! -f {} ]] ; then {}; else echo Skipping {} ; fi' .format (ff_out , cmd , ff_rel )
272+ f .write ("{:s}\n " .format (cmd ))
217273 if pause :
218- f .write ("pause\n " ) # windows only..
274+ f .write ("pause\n " ) # might be windows only..
275+
276+
219277
220278 if nBatches == 1 :
221279 writeb (batchfile , fastfiles )
222280 return batchfile
223281 else :
282+
283+ if dispatch :
284+ # TODO this can probably be done with a one liner
285+ fastfiles2 = []
286+ for i in range (nBatches ):
287+ fastfiles2 += fastfiles [i ::nBatches ]
288+ fastfiles = fastfiles2
289+
224290 splits = np .array_split (fastfiles ,nBatches )
225291 base , ext = os .path .splitext (batchfile )
226292 batchfiles = []
0 commit comments