diff --git a/avaframe/com1DFA/com1DFA.py b/avaframe/com1DFA/com1DFA.py index bc55e1835..c5f15700a 100644 --- a/avaframe/com1DFA/com1DFA.py +++ b/avaframe/com1DFA/com1DFA.py @@ -3474,13 +3474,6 @@ def prepareVarSimDict(standardCfg, inputSimFiles, variationDict, simNameExisting cfgSim["INPUT"]["tauCFile"] = pathToFric inputSimFiles["entResInfo"]["tauCRemeshed"] = remeshedFric - if inputSimFiles["entResInfo"]["bhd"] == "Yes": - pathToFric, pathToFricFull, remeshedFric = dP.checkExtentAndCellSize( - cfgSim, inputSimFiles["bhdFile"], dem, "bhd" - ) - cfgSim["INPUT"]["bhdFile"] = pathToFric - inputSimFiles["entResInfo"]["bhdRemeshed"] = remeshedFric - # check if physical parameters = variable is chosen that friction fields have correct extent if cfgSim["Physical_parameters"]["Parameters"] == "auto": for fric in ["mu", "k"]: @@ -3491,20 +3484,30 @@ def prepareVarSimDict(standardCfg, inputSimFiles, variationDict, simNameExisting cfgSim["INPUT"]["%sFile" % fric] = pathToFric inputSimFiles["entResInfo"]["%sRemeshed" % fric] = remeshedFric - # check if forest effects = auto is chosen that forest parameter fields have correct extent - if "res" in row._asdict()["simTypeList"] and inputSimFiles["resFile"] is not None: - if ( - cfgSim["FOREST_EFFECTS"]["Forest effects"] == "auto" - and inputSimFiles["entResInfo"]["bhd"] == "Yes" - ): - pathToForest, pathToForestFull, remeshedForest = dP.checkExtentAndCellSize( - cfgSim, inputSimFiles["%sFile" % "bhd"], dem, "bhd" - ) - cfgSim["INPUT"]["%sFile" % "bhd"] = pathToForest - inputSimFiles["entResInfo"]["%sRemeshed" % "bhd"] = remeshedForest + # check if resistance files (resFile (forest density) and bhd file (tree diameter) have correct extent and + # cellsize if forest effects are used and remesh if necessary + if ( + "res" in row._asdict()["simTypeList"] + and cfgSim["FOREST_EFFECTS"]["Forest effects"] == "auto" + and inputSimFiles["entResInfo"]["bhd"] == "Yes" + ): + pathToForest, pathToForestFull, remeshedForest = dP.checkExtentAndCellSize( + cfgSim, inputSimFiles["bhdFile"], dem, "bhd" + ) + cfgSim["INPUT"]["bhdFile"] = pathToForest + inputSimFiles["entResInfo"]["bhdRemeshed"] = remeshedForest + + pathToRes, pathToResFull, remeshedRes = dP.checkExtentAndCellSize( + cfgSim, inputSimFiles["resFile"], dem, "res" + ) + cfgSim["INPUT"]["resFile"] = pathToRes + inputSimFiles["entResInfo"]["resRemeshed"] = remeshedRes + cfgSim["INPUT"]["resistanceScenario"] = str( + pathlib.Path("RES", inputSimFiles["resFile"].name) + ) # add info about entrainment file path to the cfg - if "ent" in row._asdict()["simTypeList"] and inputSimFiles["entFile"] is not None: + if "ent" in row._asdict()["simTypeList"]: if inputSimFiles["entResInfo"]["entThFileType"] != ".shp": pathToEnt, pathToEntFull, remeshedEnt = dP.checkExtentAndCellSize( cfgSim, inputSimFiles["entThFile"], dem, "ent" @@ -3530,7 +3533,10 @@ def prepareVarSimDict(standardCfg, inputSimFiles, variationDict, simNameExisting log.info("Deposition is not entrainable when it's not an ent sim type.") # add info about resistance file path to the cfg - if "res" in row._asdict()["simTypeList"] and inputSimFiles["resFile"] is not None: + if ( + "res" in row._asdict()["simTypeList"] + and (modName not in ["com8MoTPSA", "com9MoTVoellmy"]) + ): if inputSimFiles["entResInfo"]["resFileType"] != ".shp": pathToRes, pathToResFull, remeshedRes = dP.checkExtentAndCellSize( cfgSim, inputSimFiles["resFile"], dem, "res" diff --git a/avaframe/com8MoTPSA/com8MoTPSA.py b/avaframe/com8MoTPSA/com8MoTPSA.py index 91b19e573..e680c6eb2 100644 --- a/avaframe/com8MoTPSA/com8MoTPSA.py +++ b/avaframe/com8MoTPSA/com8MoTPSA.py @@ -381,6 +381,17 @@ def com8MoTPSAPreprocess(simDict, inputSimFiles, cfgMain): log.error(message) raise AssertionError(message) + # if a file in Inputs/RES (forest density) and a _bhd file in Inputs/RASTERS + # (tree diameter) are found - enable forest effects, otherwise disable them + if cfg["FOREST_EFFECTS"]["Forest effects"] == "auto": + cfg = mT.setVariableForestParameters(cfg, inputSimFiles, workInputDir, inputsDir) + else: + message = "Currently only available option is auto for %s" % ( + '["FOREST_EFFECTS"]["Forest effects"]' + ) + log.error(message) + raise AssertionError(message) + rcfFileName = cfgFileDir / (str(key) + ".rcf") currentModule = sys.modules[__name__] cfgUtils.writeCfgFile(avalancheDir, currentModule, cfg, str(key)) diff --git a/avaframe/com8MoTPSA/com8MoTPSACfg.ini b/avaframe/com8MoTPSA/com8MoTPSACfg.ini index e00b5f580..04392f78b 100644 --- a/avaframe/com8MoTPSA/com8MoTPSACfg.ini +++ b/avaframe/com8MoTPSA/com8MoTPSACfg.ini @@ -196,7 +196,7 @@ Speed_L2_Prof_Coeff_1 (-) = 0.13333 Speed_L2_Prof_Coeff_2 (-) = -1.4 [FOREST_EFFECTS] -Forest effects = no +Forest effects = auto Tree drag coefficient (-) = 1.0 Modulus of rupture (MPa) = 50.0 Forest decay coefficient (m s) = 0.15 diff --git a/avaframe/com9MoTVoellmy/com9MoTVoellmy.py b/avaframe/com9MoTVoellmy/com9MoTVoellmy.py index 032fe5cb2..d94859d5d 100644 --- a/avaframe/com9MoTVoellmy/com9MoTVoellmy.py +++ b/avaframe/com9MoTVoellmy/com9MoTVoellmy.py @@ -360,12 +360,6 @@ def com9MoTVoellmyPreprocess(simDict, inputSimFiles, cfgMain): ) log.error(message) raise AssertionError(message) - # elif cfg["FOREST_EFFECTS"]["Forest effects"] == "no": - # cfg["File names"]["Forest density filename"] = "-" - # cfg["File names"]["Tree diameter filename"] = "-" - # else: - # # if forest effects set to yes but files not found - error will be raised by setVariableForestParameters - # cfg = mT.setVariableForestParameters(cfg, inputSimFiles, workInputDir, inputsDir) rcfFileName = cfgFileDir / (str(key) + ".rcf") diff --git a/avaframe/in3Utils/MoTUtils.py b/avaframe/in3Utils/MoTUtils.py index d04d8126d..1736a38d1 100644 --- a/avaframe/in3Utils/MoTUtils.py +++ b/avaframe/in3Utils/MoTUtils.py @@ -288,8 +288,8 @@ def setVariableEntrainmentParameters(cfg, inputSimFiles, workInputDir, inputsDir def setVariableForestParameters(cfg, inputSimFiles, workInputDir, inputsDir): """set file paths in cfg object for forest parameters. - if _nd, _bhd files found in Inputs/RASTERS have to be remeshed, copy remeshed files - to workInputDir with new file name ending _nd, _bhd + if a forest density file in Inputs/RES and a _bhd file in Inputs/RASTERS are + found, set the file paths and enable forest effects, otherwise disable them Parameters ----------- @@ -308,49 +308,19 @@ def setVariableForestParameters(cfg, inputSimFiles, workInputDir, inputsDir): updated configuration info for simulation with file paths to forest parameters """ - if inputSimFiles["entResInfo"]["flagRes"] == "Yes" and inputSimFiles["entResInfo"]["bhd"] == "Yes": + if ( + "res" in cfg["GENERAL"]["simTypeActual"] + and inputSimFiles["entResInfo"]["flagRes"] == "Yes" + and inputSimFiles["entResInfo"]["bhd"] == "Yes" + ): + forestDensityFile = inputsDir / cfg["INPUT"]["resFile"] treeDiamFile = inputsDir / cfg["INPUT"]["bhdFile"] cfg["FOREST_EFFECTS"]["Forest effects"] = "yes" - # TODO Make this remeshed compatible - cfg["File names"]["Forest density filename"] = str(inputSimFiles["resFile"]) + cfg["File names"]["Forest density filename"] = str(forestDensityFile) cfg["File names"]["Tree diameter filename"] = str(treeDiamFile) else: cfg["FOREST_EFFECTS"]["Forest effects"] = "no" cfg["File names"]["Forest density filename"] = "-" cfg["File names"]["Tree diameter filename"] = "-" - # forestParameters = {"nd": "Forest density filename", "bhd": "Tree diameter filename"} - # if inputSimFiles["entResInfo"]["nd"] == "Yes" and inputSimFiles["entResInfo"]["bhd"] == "Yes": - # - # for forestParam in ["nd", "bhd"]: - # forestFile = inputsDir / cfg["INPUT"]["%sFile" % forestParam] - # - # # check first if remeshed files should be used - # if ( - # "_remeshed" in cfg["INPUT"]["%sFile" % forestParam] - # and inputSimFiles["entResInfo"]["%sRemeshed" % forestParam] == "Yes" - # ): - # forestFilePathNew = workInputDir / ( - # forestFile.stem + "_%s" % forestParam + forestFile.suffix - # ) - # shutil.copy2(forestFile, forestFilePathNew) - # cfg["File names"][forestParameters[forestParam]] = str(forestFilePathNew) - # log.info( - # "Remeshed %s file copied to %s and set for %s" - # % (forestParam, str(forestFilePathNew), forestParameters[forestParam]) - # ) - # else: - # cfg["File names"][forestParameters[forestParam]] = str(forestFile) - # - # cfg["FOREST_EFFECTS"]["Forest effects"] = "yes" - # - # else: - # # TODO FSO implement if setting is variable or constant that if variable but file not found then error - # message = "nd and bhd file not found in Inputs/RASTERS - check if file ending is correct (_nd, _bhd) - setting forest effects to no" - # log.warning(message) - # - # cfg["FOREST_EFFECTS"]["Forest effects"] = "no" - # cfg["File names"]["Forest density filename"] = "-" - # cfg["File names"]["Tree diameter filename"] = "-" - return cfg diff --git a/avaframe/tests/test_MoTUtils.py b/avaframe/tests/test_MoTUtils.py index f85a304b6..3e1ac06b7 100644 --- a/avaframe/tests/test_MoTUtils.py +++ b/avaframe/tests/test_MoTUtils.py @@ -502,37 +502,42 @@ def test_setVariableForestParameters_withForest(tmp_path): bhdFile = rastersDir / "test_bhd.asc" bhdFile.write_text("mock bhd data") - # Create mock resistance file - resFile = inputsDir / "RES" / "resistance.shp" - resFile.parent.mkdir(parents=True) - resFile.write_text("mock resistance") + # Create mock remeshed forest density file (path com1DFA writes to cfg["INPUT"]["resFile"]) + resDir = inputsDir / "RES" + resDir.mkdir(parents=True) + resFile = resDir / "forest_density_remeshed.asc" + resFile.write_text("mock forest density") # Setup config cfg = configparser.ConfigParser() cfg["FOREST_EFFECTS"] = { "Forest effects": "auto" } + cfg["GENERAL"] = { + "simTypeActual": "res" + } cfg["File names"] = { "Forest density filename": "", "Tree diameter filename": "" } cfg["INPUT"] = { - "bhdFile": "RASTERS/test_bhd.asc" + "bhdFile": "RASTERS/test_bhd.asc", + "resFile": "RES/forest_density_remeshed.asc", } - # Setup inputSimFiles with forest enabled + # Setup inputSimFiles with forest enabled; resFile is the original raw path inputSimFiles = { "entResInfo": { "flagRes": "Yes", "bhd": "Yes" }, - "resFile": resFile + "resFile": tmp_path / "original_forest_density.asc" } # Call function result = MoTUtils.setVariableForestParameters(cfg, inputSimFiles, workInputDir, inputsDir) - # Verify forest effects enabled + # Verify forest effects enabled and remeshed forest density path used assert result["FOREST_EFFECTS"]["Forest effects"] == "yes" assert str(resFile) in result["File names"]["Forest density filename"] assert str(bhdFile) in result["File names"]["Tree diameter filename"] @@ -552,6 +557,9 @@ def test_setVariableForestParameters_noForest(tmp_path): cfg["FOREST_EFFECTS"] = { "Forest effects": "auto" } + cfg["GENERAL"] = { + "simTypeActual": "res" + } cfg["File names"] = { "Forest density filename": "", "Tree diameter filename": "" @@ -575,6 +583,59 @@ def test_setVariableForestParameters_noForest(tmp_path): assert result["File names"]["Tree diameter filename"] == "-" +def test_setVariableForestParameters_nonResSim(tmp_path): + """Test forest disabled for a non-res sim type even if forest files are present""" + import configparser + + inputsDir = tmp_path / "Inputs" + rastersDir = inputsDir / "RASTERS" + rastersDir.mkdir(parents=True) + workInputDir = tmp_path / "Work" / "Input" + workInputDir.mkdir(parents=True) + + # Create mock bhd file + bhdFile = rastersDir / "test_bhd.asc" + bhdFile.write_text("mock bhd data") + + # Create mock resistance file + resFile = inputsDir / "RES" / "resistance.shp" + resFile.parent.mkdir(parents=True) + resFile.write_text("mock resistance") + + # Setup config + cfg = configparser.ConfigParser() + cfg["FOREST_EFFECTS"] = { + "Forest effects": "auto" + } + cfg["GENERAL"] = { + "simTypeActual": "null" + } + cfg["File names"] = { + "Forest density filename": "", + "Tree diameter filename": "" + } + cfg["INPUT"] = { + "bhdFile": "RASTERS/test_bhd.asc" + } + + # Setup inputSimFiles with forest files present but non-res sim + inputSimFiles = { + "entResInfo": { + "flagRes": "Yes", + "bhd": "Yes" + }, + "resFile": resFile + } + + # Call function + result = MoTUtils.setVariableForestParameters(cfg, inputSimFiles, workInputDir, inputsDir) + + # Verify forest effects disabled for non-res sim + assert result["FOREST_EFFECTS"]["Forest effects"] == "no" + assert result["File names"]["Forest density filename"] == "-" + assert result["File names"]["Tree diameter filename"] == "-" + + def test_RunAndCheckMoT_HighTimeStepCount(): """Test that time step counter logs after 100 steps""" # Create output with 105 lines containing "Step" to trigger printCounter > 100 diff --git a/avaframe/tests/test_com1DFA.py b/avaframe/tests/test_com1DFA.py index 73db01ce3..83b8aadcc 100644 --- a/avaframe/tests/test_com1DFA.py +++ b/avaframe/tests/test_com1DFA.py @@ -3769,3 +3769,76 @@ def test_checkForTif(tmp_path): inputSimFilesTest3 = getInput.getInputDataCom1DFA(avaTestDir3) com1DFA.checkForTif(com8, inputSimFilesTest3) + + +def test_prepareVarSimDict_com8Forest(tmp_path): + """test com8 forest block in prepareVarSimDict remeshes and sets bhd/res paths""" + + testDir = pathlib.Path(__file__).parents[0] + inputDir = testDir / ".." / "data" / "avaAlr" / "Inputs" + avaDir = pathlib.Path(tmp_path, "avaTestNew") + shutil.copytree(inputDir, avaDir / "Inputs") + avaDEM = avaDir / "Inputs" / "avaAlr.tif" + + standardCfg = cfgUtils.getModuleConfig(com8) + standardCfg["GENERAL"]["simTypeList"] = "res" + standardCfg["GENERAL"]["avalancheDir"] = str(avaDir) + standardCfg["GENERAL"]["meshCellSize"] = "5." + standardCfg["GENERAL"]["secRelArea"] = "False" + standardCfg["GENERAL"]["relThFromFile"] = "False" + standardCfg["GENERAL"]["relTh"] = "1.0" + standardCfg["FOREST_EFFECTS"]["Forest effects"] = "auto" + standardCfg["INPUT"]["DEM"] = "avaAlr.tif" + standardCfg["INPUT"]["relThFile"] = "" + + # create bhd and res rasters with same extent and cellsize as the DEM + demHeader = IOf.readRasterHeader(avaDEM) + zeros = np.zeros((demHeader["nrows"], demHeader["ncols"])) + bhdDir = pathlib.Path(avaDir, "Inputs", "RASTERS") + fU.makeADir(bhdDir) + bhdFile = IOf.writeResultToRaster(demHeader, zeros, bhdDir / "avaAlr_bhd", flip=True) + resDir = pathlib.Path(avaDir, "Inputs", "RES") + fU.makeADir(resDir) + resFile = IOf.writeResultToRaster(demHeader, zeros, resDir / "forest", flip=True) + + relPath = pathlib.Path(avaDir, "Inputs", "REL", "relAlr.shp") + inputSimFiles = { + "relFiles": [relPath], + "entResInfo": { + "flagEnt": "No", + "flagRes": "Yes", + "entThFileType": ".shp", + "relThFileType": ".shp", + "resFileType": ".tif", + "secondaryRelThFileType": None, + "tauC": "No", + "mu": "No", + "k": "No", + "xi": "No", + "bhd": "Yes", + }, + "demFile": avaDEM, + "damFile": None, + "secondaryRelFile": None, + "entFile": pathlib.Path(avaDir, "Inputs", "ENT", "entAlr.shp"), + "resFile": resFile, + "bhdFile": bhdFile, + "tauCFile": None, + "muFile": None, + "kFile": None, + "xiFile": None, + "timeDepRelCsv": None, + } + variationDict = {"releaseScenario": ["relAlr"]} + + # call function to be tested + simDict = com1DFA.prepareVarSimDict(standardCfg, inputSimFiles, variationDict, module=com8) + + # one sim expected - forest block sets bhd/res paths in cfg and remeshed flags + assert len(simDict) == 1 + cfgSim = list(simDict.values())[0]["cfgSim"] + assert cfgSim["INPUT"]["bhdFile"] == "RASTERS/avaAlr_bhd.tif" + assert cfgSim["INPUT"]["resFile"] == "RES/forest.tif" + assert cfgSim["INPUT"]["resistanceScenario"] == "RES/forest.tif" + assert inputSimFiles["entResInfo"]["bhdRemeshed"] == "No" + assert inputSimFiles["entResInfo"]["resRemeshed"] == "No" diff --git a/avaframe/tests/test_com8MoTPSA.py b/avaframe/tests/test_com8MoTPSA.py new file mode 100644 index 000000000..80db26c4d --- /dev/null +++ b/avaframe/tests/test_com8MoTPSA.py @@ -0,0 +1,186 @@ +""" + Pytest for com8MoTPSA postprocess layer renaming + + This file is part of Avaframe. +""" + +import configparser +import pathlib +import shutil + +import pytest +from unittest.mock import patch + +import avaframe.com1DFA.com1DFA as com1DFA +from avaframe.com8MoTPSA import com8MoTPSA +from avaframe.in3Utils import cfgUtils + + +RASTER_HEADER = """ncols 10 +nrows 10 +xllcenter 0 +yllcenter 0 +cellsize 5 +NODATA_value -9999 +""" + + +def _createTestRaster(filepath): + """Create a minimal valid raster file for testing""" + with open(filepath, "w") as f: + f.write(RASTER_HEADER) + for _ in range(10): + f.write(" ".join(["0"] * 10) + "\n") + + +def _createMockRawOutputFiles(workDir, simKey, simType): + """Create mock raw MoT-PSA output files matching the expected naming pattern. + + MoT-PSA appends raw suffixes (_p1_max, _p2_max, etc.) to the output root, + which is the simKey itself. The simKey already contains simType_modelType, + so the replace pattern straddles the key/suffix boundary. + """ + simWorkDir = workDir / simKey + simWorkDir.mkdir(parents=True) + + # MoT-PSA appends these suffixes to the key (output root) + rawSuffixes = ["p1_max", "p2_max", "h1_max", "h2_max", "s1_max", "s2_max"] + for suffix in rawSuffixes: + _createTestRaster(simWorkDir / ("%s_%s.asc" % (simKey, suffix))) + + # DataTime.txt needed by postprocess + (simWorkDir / "DataTime.txt").write_text("0.0\n1.0\n") + + +def _createConfigIndicatorDirs(avalancheDir): + """Create configurationFilesDone and configurationFilesLatest dirs. + + In a real run these are created by initialiseRunDirs during project + initialisation; the postprocess function assumes they exist. + """ + for saveDir in ["configurationFilesDone", "configurationFilesLatest"]: + configDir = avalancheDir / "Outputs" / "com8MoTPSA" / "configurationFiles" / saveDir + configDir.mkdir(parents=True) + + +@patch("avaframe.com8MoTPSA.com8MoTPSA.oP.plotAllPeakFields") +@patch("avaframe.com8MoTPSA.com8MoTPSA.rU.readRaster", return_value={"header": {"cellsize": 5}}) +def test_com8MoTPSAPostprocess_layerNaming(mockReadRaster, mockPlot, tmp_path): + """Test that postprocess produces files with L1/L2 layer naming""" + avalancheDir = tmp_path / "testAva" + workDir = avalancheDir / "Work" / "com8MoTPSA" + + simKey = "release1_abc123_com8_C_null_psa" + simType = "null" + + # Create mock raw output files + _createMockRawOutputFiles(workDir, simKey, simType) + _createConfigIndicatorDirs(avalancheDir) + + # Build mock simDict and cfgMain + simDict = { + simKey: { + "simType": simType, + } + } + cfgMain = { + "MAIN": {"avalancheDir": str(avalancheDir)}, + "FLAGS": {"showPlot": "False", "savePlot": "True"}, + } + inputSimFiles = {"demFile": str(tmp_path / "fake_dem.asc")} + + # Run postprocess + com8MoTPSA.com8MoTPSAPostprocess(simDict, cfgMain, inputSimFiles) + + # Check output files in peakFiles directory + peakDir = avalancheDir / "Outputs" / "com8MoTPSA" / "peakFiles" + outputFiles = sorted([f.name for f in peakDir.glob("*.asc")]) + + # Expected: L1/L2 layer naming, modelType stays psa for both layers + expectedFiles = sorted([ + "%s_L1_ppr.asc" % simKey, + "%s_L2_ppr.asc" % simKey, + "%s_L1_pfd.asc" % simKey, + "%s_L2_pfd.asc" % simKey, + "%s_L1_pfv.asc" % simKey, + "%s_L2_pfv.asc" % simKey, + ]) + + assert outputFiles == expectedFiles + + +@patch("avaframe.com8MoTPSA.com8MoTPSA.oP.plotAllPeakFields") +@patch("avaframe.com8MoTPSA.com8MoTPSA.rU.readRaster", return_value={"header": {"cellsize": 5}}) +def test_com8MoTPSAPostprocess_entSimType(mockReadRaster, mockPlot, tmp_path): + """Test layer naming with entrainment simType""" + avalancheDir = tmp_path / "testAva" + workDir = avalancheDir / "Work" / "com8MoTPSA" + + simKey = "release1_abc123_com8_C_ent_psa" + simType = "ent" + + _createMockRawOutputFiles(workDir, simKey, simType) + _createConfigIndicatorDirs(avalancheDir) + + simDict = {simKey: {"simType": simType}} + cfgMain = { + "MAIN": {"avalancheDir": str(avalancheDir)}, + "FLAGS": {"showPlot": "False", "savePlot": "True"}, + } + inputSimFiles = {"demFile": str(tmp_path / "fake_dem.asc")} + + com8MoTPSA.com8MoTPSAPostprocess(simDict, cfgMain, inputSimFiles) + + peakDir = avalancheDir / "Outputs" / "com8MoTPSA" / "peakFiles" + outputFiles = sorted([f.name for f in peakDir.glob("*.asc")]) + + expectedFiles = sorted([ + "%s_L1_ppr.asc" % simKey, + "%s_L2_ppr.asc" % simKey, + "%s_L1_pfd.asc" % simKey, + "%s_L2_pfd.asc" % simKey, + "%s_L1_pfv.asc" % simKey, + "%s_L2_pfv.asc" % simKey, + ]) + + assert outputFiles == expectedFiles + + +def _setupCom8Preprocess(tmp_path, forestEffects): + """Copy avaKot inputs and run com1DFA preprocess for com8 with res simType.""" + testDir = pathlib.Path(__file__).parents[0] + avaSrc = testDir / ".." / "data" / "avaKot" + avaDir = tmp_path / "avaKot" + shutil.copytree(avaSrc / "Inputs", avaDir / "Inputs") + + cfgMain = configparser.ConfigParser() + cfgMain["MAIN"] = {"avalancheDir": str(avaDir), "nCPU": "1"} + cfgMain["FLAGS"] = {"showPlot": "False", "savePlot": "False"} + + cfgCom8 = cfgUtils.getModuleConfig(com8MoTPSA) + cfgCom8["GENERAL"]["simTypeList"] = "res" + cfgCom8["FOREST_EFFECTS"]["Forest effects"] = forestEffects + + simDict, _, inputSimFiles, _ = com1DFA.com1DFAPreprocess(cfgMain, cfgCom8, module=com8MoTPSA) + return simDict, inputSimFiles, cfgMain + + +def test_com8MoTPSAPreprocess_forestEffectsAuto(tmp_path): + """Forest effects auto resolves to no when no bhd raster is present.""" + simDict, inputSimFiles, cfgMain = _setupCom8Preprocess(tmp_path, "auto") + + rcfFiles = com8MoTPSA.com8MoTPSAPreprocess(simDict, inputSimFiles, cfgMain) + + assert len(rcfFiles) == 1 + cfgSim = list(simDict.values())[0]["cfgSim"] + assert cfgSim["FOREST_EFFECTS"]["Forest effects"] == "no" + assert cfgSim["File names"]["Forest density filename"] == "-" + assert cfgSim["File names"]["Tree diameter filename"] == "-" + + +def test_com8MoTPSAPreprocess_forestEffectsNonAuto(tmp_path): + """Forest effects other than auto raises AssertionError.""" + simDict, inputSimFiles, cfgMain = _setupCom8Preprocess(tmp_path, "no") + + with pytest.raises(AssertionError): + com8MoTPSA.com8MoTPSAPreprocess(simDict, inputSimFiles, cfgMain)