From 76724d97785ac2753b3fe680909e748a804eb30b Mon Sep 17 00:00:00 2001 From: Felix Oesterle <6945681+fso42@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:19:34 +0100 Subject: [PATCH] refactor(runStandardTestsCom1DFA): wrap script execution in `__main__` and improve structure; fixes #1247 - Use `tempfile.TemporaryDirectory` for handling temporary test directories, ensuring automatic cleanup. - Fix division-by-zero issue in statsPlots by validating input values. - Standardize `runoutFound` values as strings in `aimecTools` to ensure consistent conditional checks. --- avaframe/ana3AIMEC/aimecTools.py | 6 +- avaframe/out3Plot/statsPlots.py | 5 +- avaframe/runStandardTestsCom1DFA.py | 286 +++++++++++---------- avaframe/runUpdateBenchmarkTestsCom1DFA.py | 279 ++++++++++---------- 4 files changed, 291 insertions(+), 285 deletions(-) diff --git a/avaframe/ana3AIMEC/aimecTools.py b/avaframe/ana3AIMEC/aimecTools.py index 93520b9be..2b3d9cc35 100644 --- a/avaframe/ana3AIMEC/aimecTools.py +++ b/avaframe/ana3AIMEC/aimecTools.py @@ -1219,7 +1219,7 @@ def computeRunOut( resAnalysisDF.loc[simRowHash, "zRelease"] = zThalweg[cUpper] resAnalysisDF.loc[simRowHash, "elevRel"] = zThalweg[cUpper] resAnalysisDF.loc[simRowHash, "deltaZ"] = zThalweg[cUpper] - zThalweg[cLower] - resAnalysisDF.loc[simRowHash, "runoutFound"] = runoutFound + resAnalysisDF.loc[simRowHash, "runoutFound"] = str(runoutFound) return resAnalysisDF @@ -1520,11 +1520,11 @@ def analyzeArea( if ( simRowHash != refSimRowHash and cfgPlots.getboolean("extraPlots") - and resAnalysisDF.loc[simRowHash, "runoutFound"] + and resAnalysisDF.loc[simRowHash, "runoutFound"].lower() == "true" ): # only plot comparisons of simulations to reference compPlotPath = outAimec.visuComparison(rasterTransfo, inputs, pathDict) - elif not resAnalysisDF.loc[simRowHash, "runoutFound"] and cfgPlots.getboolean("extraPlots"): + elif not resAnalysisDF.loc[simRowHash, "runoutFound"].lower() == "true" and cfgPlots.getboolean("extraPlots"): log.warning( "ContourComparisonToReference plot not generated as only 0 values for comparison simulation: %s" % resAnalysisDF.loc[simRowHash, "simName"] diff --git a/avaframe/out3Plot/statsPlots.py b/avaframe/out3Plot/statsPlots.py index 98fa163bf..87cbf46e6 100644 --- a/avaframe/out3Plot/statsPlots.py +++ b/avaframe/out3Plot/statsPlots.py @@ -232,7 +232,10 @@ def plotHistCDFDiff(dataDiffPlot, ax1, ax2, insert='True', title=['', '']): width = diffMax - diffMin stepsInterval = int(pU.cfg['steps2Centile2']) stepWidth = 2*sortedDiffPlot[ind]/stepsInterval # stepsInterval bins in the [-2sigma,+2sigma] interval - bins = int(width/stepWidth) + if stepWidth > 0 and width > 0: + bins = int(width/stepWidth) + else: + bins = 1 # reduce bins to a sensible size if bins > 1000: diff --git a/avaframe/runStandardTestsCom1DFA.py b/avaframe/runStandardTestsCom1DFA.py index 2d96d9126..c0ec1fd55 100644 --- a/avaframe/runStandardTestsCom1DFA.py +++ b/avaframe/runStandardTestsCom1DFA.py @@ -4,12 +4,14 @@ """ # Load modules +import os import time import pathlib import logging import logging.handlers import multiprocessing import shutil +import tempfile from concurrent.futures import ProcessPoolExecutor, as_completed # Local imports @@ -87,9 +89,7 @@ def runSingleTest( avaName = avaDirOriginal.name # Create unique temp directory for this test to avoid conflicts when multiple tests share same avaDir - import os - - testTempDir = tmpTestsDir / f"{avaName}_{test['NAME']}_{os.getpid()}" + testTempDir = tmpTestsDir / f"{test['NAME']}_{os.getpid()}" testTempDir.mkdir(parents=True, exist_ok=True) # Copy only Inputs directory to temp location (Outputs and Work will be created fresh) @@ -231,144 +231,146 @@ def runSingleTest( return (test["NAME"], reportD, benchDict, avaName, cfgRep) -# +++++++++REQUIRED+++++++++++++ -# Which result types for comparison plots -outputVariable = ["ppr", "pft", "pfv"] -# aimec settings that are not used from default aimecCfg or aimecCfg in benchmark folders -aimecDiffLim = "5" -aimecContourLevels = "1|3|5|10" -aimecFlagMass = "False" -aimecComModules = "benchmarkReference|com1DFA" -# ++++++++++++++++++++++++++++++ - -# log file name; leave empty to use default runLog.log -logName = "runStandardTestsCom1DFA" - -# Load settings from general configuration file -cfgMain = cfgUtils.getGeneralConfig() - -# load all benchmark info as dictionaries from description files -testDictList = tU.readAllBenchmarkDesDicts(info=False) - -# filter benchmarks for tag standardTest -# filterType = "TAGS" -# valuesList = ["resistance"] -filterType = "TAGS" -valuesList = ["standardTest", "standardTestSnowGlide"] -# filterType = "NAME" -# valuesList = ["avaInclinedPlaneEntresTest"] - -testList = tU.filterBenchmarks(testDictList, filterType, valuesList, condition="or") - -# Clean temporary test directory used for parallel execution -tmpTestsDir = pathlib.Path(__file__).parent / "data" / "tmpStdTests" -if tmpTestsDir.exists(): - shutil.rmtree(tmpTestsDir) -tmpTestsDir.mkdir(parents=True, exist_ok=True) - -# Set directory for full standard test report -outDir = pathlib.Path.cwd() / "tests" / "reportsCom1DFA" -fU.makeADir(outDir) - -# Start writing markdown style report for standard tests -reportFile = outDir / "standardTestsReportCom1DFA.md" -with open(reportFile, "w") as pfile: - - # Write header - pfile.write("# Standard Tests Report \n") - pfile.write("## Compare com1DFA simulations to benchmark results \n") - -log = logUtils.initiateLogger(outDir, logName) -log.info("The following benchmark tests will be fetched ") -for test in testList: - log.info("%s" % test["NAME"]) - -# Set up queue-based logging for parallel execution -logQueue = multiprocessing.Manager().Queue() -queueListener = logging.handlers.QueueListener(logQueue, *log.handlers) -queueListener.start() - -# Convert cfgMain to dictionary for pickling -cfgMainDict = {section: dict(cfgMain[section]) for section in cfgMain.sections()} - -# Get number of CPU cores for parallel execution -nCPU = cfgUtils.getNumberOfProcesses(cfgMain, len(testList)) - -# Run tests in parallel using ProcessPoolExecutor -results = [] -failedTests = [] -with ProcessPoolExecutor(max_workers=nCPU) as executor: - # Submit all tests - futures = {} +if __name__ == "__main__": + # +++++++++REQUIRED+++++++++++++ + # Which result types for comparison plots + outputVariable = ["ppr", "pft", "pfv"] + # aimec settings that are not used from default aimecCfg or aimecCfg in benchmark folders + aimecDiffLim = "5" + aimecContourLevels = "1|3|5|10" + aimecFlagMass = "False" + aimecComModules = "benchmarkReference|com1DFA" + # ++++++++++++++++++++++++++++++ + + # log file name; leave empty to use default runLog.log + logName = "runStandardTestsCom1DFA" + + # Load settings from general configuration file + cfgMain = cfgUtils.getGeneralConfig() + + # load all benchmark info as dictionaries from description files + testDictList = tU.readAllBenchmarkDesDicts(info=False) + + # filter benchmarks for tag standardTest + # filterType = "TAGS" + # valuesList = ["resistance"] + filterType = "TAGS" + valuesList = ["standardTest", "standardTestSnowGlide"] + #filterType = "NAME" + #valuesList = ["avaFlatPlaneNullTest"] + + testList = tU.filterBenchmarks(testDictList, filterType, valuesList, condition="or") + + # Create system temporary directory for parallel test execution (auto-cleaned on exit) + tmpTestsDirObj = tempfile.TemporaryDirectory(prefix="avaframe_stdTests_") + tmpTestsDir = pathlib.Path(tmpTestsDirObj.name) + + # Set directory for full standard test report + outDir = pathlib.Path.cwd() / "tests" / "reportsCom1DFA" + fU.makeADir(outDir) + + # Start writing markdown style report for standard tests + reportFile = outDir / "standardTestsReportCom1DFA.md" + with open(reportFile, "w") as pfile: + + # Write header + pfile.write("# Standard Tests Report \n") + pfile.write("## Compare com1DFA simulations to benchmark results \n") + + log = logUtils.initiateLogger(outDir, logName) + log.info("The following benchmark tests will be fetched ") for test in testList: - future = executor.submit( - runSingleTest, - test, - cfgMainDict, - outputVariable, - aimecDiffLim, - aimecContourLevels, - aimecFlagMass, - aimecComModules, - outDir, - tmpTestsDir, - logQueue, - ) - futures[future] = test["NAME"] - - # Collect results as they complete - for future in as_completed(futures): - testName = futures[future] - try: - result = future.result() - results.append(result) - log.info("Completed test: %s" % testName) - except Exception as exc: - log.error("Test %s generated an exception: %s" % (testName, exc)) - failedTests.append({"name": testName, "error": str(exc)}) - -# Stop the queue listener -queueListener.stop() - -# Write reports sequentially in completion order -for testName, reportD, benchDict, avaName, cfgRep in results: - generateCompareReport.writeCompareReport(reportFile, reportD, benchDict, avaName, cfgRep) - -# Collect CPU time data from results -cpuTimeName = [] -cpuTimeBench = [] -cpuTimeSim = [] -for testName, reportD, benchDict, avaName, cfgRep in results: - cpuTimeName.append(testName) - cpuTimeBench.append(benchDict["Simulation Parameters"]["Computation time [s]"]) - cpuTimeSim.append(reportD["Simulation Parameters"]["Computation time [s]"]) - -# Display CPU time in log if we have any successful results -if results: - # Get version info from first successful test - _, reportD, benchDict, _, _ = results[0] - log.info( - "CPU performance comparison between benchmark results (version : %s) and curent branch (version : %s)" - % ( - benchDict["Simulation Parameters"]["Program version"], - reportD["Simulation Parameters"]["Program version"], + log.info("%s" % test["NAME"]) + + # Set up queue-based logging for parallel execution + logQueue = multiprocessing.Manager().Queue() + queueListener = logging.handlers.QueueListener(logQueue, *log.handlers) + queueListener.start() + + # Convert cfgMain to dictionary for pickling + cfgMainDict = {section: dict(cfgMain[section]) for section in cfgMain.sections()} + + # Get number of CPU cores for parallel execution + nCPU = cfgUtils.getNumberOfProcesses(cfgMain, len(testList)) + + # Run tests in parallel using ProcessPoolExecutor + results = [] + failedTests = [] + with ProcessPoolExecutor(max_workers=nCPU) as executor: + # Submit all tests + futures = {} + for test in testList: + future = executor.submit( + runSingleTest, + test, + cfgMainDict, + outputVariable, + aimecDiffLim, + aimecContourLevels, + aimecFlagMass, + aimecComModules, + outDir, + tmpTestsDir, + logQueue, + ) + futures[future] = test["NAME"] + + # Collect results as they complete + for future in as_completed(futures): + testName = futures[future] + try: + result = future.result() + results.append(result) + log.info("Completed test: %s" % testName) + except Exception as exc: + log.error("Test %s generated an exception: %s" % (testName, exc)) + failedTests.append({"name": testName, "error": str(exc)}) + + # Stop the queue listener + queueListener.stop() + + # Write reports sequentially in completion order + for testName, reportD, benchDict, avaName, cfgRep in results: + generateCompareReport.writeCompareReport(reportFile, reportD, benchDict, avaName, cfgRep) + + # Collect CPU time data from results + cpuTimeName = [] + cpuTimeBench = [] + cpuTimeSim = [] + for testName, reportD, benchDict, avaName, cfgRep in results: + cpuTimeName.append(testName) + cpuTimeBench.append(benchDict["Simulation Parameters"]["Computation time [s]"]) + cpuTimeSim.append(reportD["Simulation Parameters"]["Computation time [s]"]) + + # Display CPU time in log if we have any successful results + if results: + # Get version info from first successful test + _, reportD, benchDict, _, _ = results[0] + log.info( + "CPU performance comparison between benchmark results (version : %s) and curent branch (version : %s)" + % ( + benchDict["Simulation Parameters"]["Program version"], + reportD["Simulation Parameters"]["Program version"], + ) ) - ) - log.info(("{:<30}" * 3).format("Test Name", "cpu time Benchmark [s]", "cpu time curent version [s]")) - for name, cpuBench, cpuSim in zip(cpuTimeName, cpuTimeBench, cpuTimeSim): - log.info(("{:<30s}" * 3).format(name, cpuBench, cpuSim)) - -# Display summary of test results -log.info("=" * 80) -log.info("TEST SUMMARY") -log.info("=" * 80) -log.info("Total tests: %d" % len(testList)) -log.info("Successful: %d" % len(results)) -log.info("Failed: %d" % len(failedTests)) - -if failedTests: - log.info("Failed tests:") - for failure in failedTests: - log.info(" - %s: %s" % (failure["name"], failure["error"])) -else: - log.info("All tests completed successfully!") + log.info(("{:<30}" * 3).format("Test Name", "cpu time Benchmark [s]", "cpu time curent version [s]")) + for name, cpuBench, cpuSim in zip(cpuTimeName, cpuTimeBench, cpuTimeSim): + log.info(("{:<30s}" * 3).format(name, cpuBench, cpuSim)) + + # Display summary of test results + log.info("=" * 80) + log.info("TEST SUMMARY") + log.info("=" * 80) + log.info("Total tests: %d" % len(testList)) + log.info("Successful: %d" % len(results)) + log.info("Failed: %d" % len(failedTests)) + + if failedTests: + log.info("Failed tests:") + for failure in failedTests: + log.info(" - %s: %s" % (failure["name"], failure["error"])) + else: + log.info("All tests completed successfully!") + + # Clean up temporary test directory + tmpTestsDirObj.cleanup() diff --git a/avaframe/runUpdateBenchmarkTestsCom1DFA.py b/avaframe/runUpdateBenchmarkTestsCom1DFA.py index 2c1cd9b2c..8967a62ad 100644 --- a/avaframe/runUpdateBenchmarkTestsCom1DFA.py +++ b/avaframe/runUpdateBenchmarkTestsCom1DFA.py @@ -20,149 +20,150 @@ from avaframe.com5SnowSlide import com5SnowSlide -# +++++++++REQUIRED+++++++++++++ -# Which result types do we want to save in the benchmarks -outputVariable = ["ppr", "pft", "pfv"] -# ++++++++++++++++++++++++++++++ - -# log file name; leave empty to use default runLog.log -logName = "runUpdateBenchmarkTestsCom1DFA" - -# Load settings from general configuration file -cfgMain = cfgUtils.getGeneralConfig() - -# load all benchmark info as dictionaries from description files -testDictList = tU.readAllBenchmarkDesDicts(info=False) - -# filter benchmarks to extract only desired ones -type = 'TAGS' -valuesList = ['standardTest', 'standardTestSnowGlide'] -# type = "NAME" -# valuesList = ["avaHofSnowGlideTest"] -testList = tU.filterBenchmarks(testDictList, type, valuesList, condition="or") - -# Set directory for full standard test report -outDir = pathlib.Path("..", "benchmarks") -log = logUtils.initiateLogger(outDir, logName) -fU.makeADir(outDir) - -# version = getVersion() -version = "1.13" - -log.info("The following benchmark tests will be updated ") -for test in testList: - log.info("%s" % test["NAME"]) - -# run Standard Tests sequentially -for test in testList: - - avaDir = test["AVADIR"] - cfgMain["MAIN"]["avalancheDir"] = avaDir - - # Fetch benchmark test info - benchDict = test - simNameRef = test["simNameRef"] - refDir = pathlib.Path("..", "benchmarks", test["NAME"]) - simType = benchDict["simType"] - - rel = benchDict["Simulation Parameters"]["Release Area Scenario"] - - # Clean input directory(ies) of old work and output files - initProj.cleanSingleAvaDir(avaDir) - - # Load input parameters from configuration file for standard tests - avaName = pathlib.Path(avaDir).name - standardCfg = refDir / ("%s_com1DFACfg.ini" % test["AVANAME"]) - modName = "com1DFA" - - # if snowGlide test - if "snowglide" in test["NAME"].lower(): - snowSlideCfgFile = refDir / ("%s_com5SnowGlideCfg.ini" % test["AVANAME"]) - # load snow slide tool config - snowSlideCfg = cfgUtils.getModuleConfig(com5SnowSlide, fileOverride=snowSlideCfgFile) - # ++++++++++ set configurations for com1DFA and override ++++++++++++ - # get comDFA configuration and update with snow slide parameter set - standardCfg = cfgUtils.getModuleConfig( - com1DFA, - avaDir, - toPrint=False, - onlyDefault=snowSlideCfg["com1DFA_com1DFA_override"].getboolean("defaultConfig"), - ) - standardCfg, snowSlideCfg = cfgHandling.applyCfgOverride( - standardCfg, snowSlideCfg, com1DFA, addModValues=False - ) - - # Set timing - startTime = time.time() - - # call com1DFA run - dem, plotDict, reportDictList, simDF = com1DFA.com1DFAMain(cfgMain, cfgInfo=standardCfg) - endTime = time.time() - timeNeeded = endTime - startTime - log.info(("Took %s seconds to calculate." % (timeNeeded))) - - # Update benchmarks - # copy Simulation Parameters to benchmark dict - if simType == "res": - rep = reportDictList[1] # TODO: hacky... need to find a better way to get the right report - else: - rep = reportDictList[0] - - test["simName"] = rep["simName"] - test["Simulation Parameters"] = rep["Simulation Parameters"] - # here we need to reset the version because after updating the first benchmark, - # the version will be marked as dirty... - test["Simulation Parameters"]["Program version"] = version - test["simNameRef"] = rep["simName"]["name"] - # get results file names (.asc) add them to the dictionary and copy the files to benchmark - # first clean the benchmark directory - ascFiles = list(refDir.glob("*.asc")) + list(refDir.glob("*.tif")) + list(refDir.glob("mass*.txt")) - for file in ascFiles: - if file.is_file(): - file.unlink() - partDir = refDir / "particles" - if partDir.is_dir(): - shutil.rmtree(partDir) - # set copy peak results - resDir = pathlib.Path(avaDir, "Outputs", modName, "peakFiles") - simName = rep["simName"]["name"] - files = [] - for suf in outputVariable: - simFileName = simName + "_" + suf + "*" - simFile = list(resDir.glob(simFileName))[0] +if __name__ == "__main__": + # +++++++++REQUIRED+++++++++++++ + # Which result types do we want to save in the benchmarks + outputVariable = ["ppr", "pft", "pfv"] + # ++++++++++++++++++++++++++++++ + + # log file name; leave empty to use default runLog.log + logName = "runUpdateBenchmarkTestsCom1DFA" + + # Load settings from general configuration file + cfgMain = cfgUtils.getGeneralConfig() + + # load all benchmark info as dictionaries from description files + testDictList = tU.readAllBenchmarkDesDicts(info=False) + + # filter benchmarks to extract only desired ones + type = 'TAGS' + valuesList = ['standardTest', 'standardTestSnowGlide'] + # type = "NAME" + # valuesList = ["avaHofSnowGlideTest"] + testList = tU.filterBenchmarks(testDictList, type, valuesList, condition="or") + + # Set directory for full standard test report + outDir = pathlib.Path("..", "benchmarks") + log = logUtils.initiateLogger(outDir, logName) + fU.makeADir(outDir) + + # version = getVersion() + version = "1.13" + + log.info("The following benchmark tests will be updated ") + for test in testList: + log.info("%s" % test["NAME"]) + + # run Standard Tests sequentially + for test in testList: + + avaDir = test["AVADIR"] + cfgMain["MAIN"]["avalancheDir"] = avaDir + + # Fetch benchmark test info + benchDict = test + simNameRef = test["simNameRef"] + refDir = pathlib.Path("..", "benchmarks", test["NAME"]) + simType = benchDict["simType"] + + rel = benchDict["Simulation Parameters"]["Release Area Scenario"] + + # Clean input directory(ies) of old work and output files + initProj.cleanSingleAvaDir(avaDir) + + # Load input parameters from configuration file for standard tests + avaName = pathlib.Path(avaDir).name + standardCfg = refDir / ("%s_com1DFACfg.ini" % test["AVANAME"]) + modName = "com1DFA" + + # if snowGlide test + if "snowglide" in test["NAME"].lower(): + snowSlideCfgFile = refDir / ("%s_com5SnowGlideCfg.ini" % test["AVANAME"]) + # load snow slide tool config + snowSlideCfg = cfgUtils.getModuleConfig(com5SnowSlide, fileOverride=snowSlideCfgFile) + # ++++++++++ set configurations for com1DFA and override ++++++++++++ + # get comDFA configuration and update with snow slide parameter set + standardCfg = cfgUtils.getModuleConfig( + com1DFA, + avaDir, + toPrint=False, + onlyDefault=snowSlideCfg["com1DFA_com1DFA_override"].getboolean("defaultConfig"), + ) + standardCfg, snowSlideCfg = cfgHandling.applyCfgOverride( + standardCfg, snowSlideCfg, com1DFA, addModValues=False + ) + + # Set timing + startTime = time.time() + + # call com1DFA run + dem, plotDict, reportDictList, simDF = com1DFA.com1DFAMain(cfgMain, cfgInfo=standardCfg) + endTime = time.time() + timeNeeded = endTime - startTime + log.info(("Took %s seconds to calculate." % (timeNeeded))) + + # Update benchmarks + # copy Simulation Parameters to benchmark dict + if simType == "res": + rep = reportDictList[1] # TODO: hacky... need to find a better way to get the right report + else: + rep = reportDictList[0] + + test["simName"] = rep["simName"] + test["Simulation Parameters"] = rep["Simulation Parameters"] + # here we need to reset the version because after updating the first benchmark, + # the version will be marked as dirty... + test["Simulation Parameters"]["Program version"] = version + test["simNameRef"] = rep["simName"]["name"] + # get results file names (.asc) add them to the dictionary and copy the files to benchmark + # first clean the benchmark directory + ascFiles = list(refDir.glob("*.asc")) + list(refDir.glob("*.tif")) + list(refDir.glob("mass*.txt")) + for file in ascFiles: + if file.is_file(): + file.unlink() + partDir = refDir / "particles" + if partDir.is_dir(): + shutil.rmtree(partDir) + # set copy peak results + resDir = pathlib.Path(avaDir, "Outputs", modName, "peakFiles") + simName = rep["simName"]["name"] + files = [] + for suf in outputVariable: + simFileName = simName + "_" + suf + "*" + simFile = list(resDir.glob(simFileName))[0] + if simFile.is_file(): + # add file name to dict + files.append(simFile.stem) + destFile = refDir / simFile.name + # copy file to benchmark + shutil.copy2(simFile, destFile) + else: + log.warning("did not find the file %s" % simFile) + # set copy mass result + resDir = pathlib.Path(avaDir, "Outputs", modName) + simFile = resDir / ("mass_" + simName + ".txt") if simFile.is_file(): # add file name to dict files.append(simFile.stem) - destFile = refDir / simFile.name # copy file to benchmark + destFile = refDir / ("mass_" + simName + ".txt") shutil.copy2(simFile, destFile) else: log.warning("did not find the file %s" % simFile) - # set copy mass result - resDir = pathlib.Path(avaDir, "Outputs", modName) - simFile = resDir / ("mass_" + simName + ".txt") - if simFile.is_file(): - # add file name to dict - files.append(simFile.stem) - # copy file to benchmark - destFile = refDir / ("mass_" + simName + ".txt") - shutil.copy2(simFile, destFile) - else: - log.warning("did not find the file %s" % simFile) - test["FILES"] = files - # # set copy particles - # resDir = pathlib.Path(avaDir, 'Outputs', modName, 'particles') - # simFile = sorted(list(resDir.glob('*.p')))[0] - # if simFile.is_file(): - # # copy file to benchmark - # destFile = refDir / 'particles' - # destFile.mkdir() - # simComponents = rep['simName']['name'].split('_') - # destFile = destFile / (simComponents[0] + '_' + simComponents[2]) - # destFile.mkdir() - # destFile = destFile / (simFile.name) - # shutil.copy2(simFile, destFile) - # else: - # log.warning('did not find the file %s' % simFile) - # # write the benchmark dict as JSON - tU.writeDesDicttoJson(test, test["NAME"], refDir) + test["FILES"] = files + # # set copy particles + # resDir = pathlib.Path(avaDir, 'Outputs', modName, 'particles') + # simFile = sorted(list(resDir.glob('*.p')))[0] + # if simFile.is_file(): + # # copy file to benchmark + # destFile = refDir / 'particles' + # destFile.mkdir() + # simComponents = rep['simName']['name'].split('_') + # destFile = destFile / (simComponents[0] + '_' + simComponents[2]) + # destFile.mkdir() + # destFile = destFile / (simFile.name) + # shutil.copy2(simFile, destFile) + # else: + # log.warning('did not find the file %s' % simFile) + # # write the benchmark dict as JSON + tU.writeDesDicttoJson(test, test["NAME"], refDir)