diff --git a/avaframe/com1DFA/particleTools.py b/avaframe/com1DFA/particleTools.py index 3a4e05df3..63ee17c16 100644 --- a/avaframe/com1DFA/particleTools.py +++ b/avaframe/com1DFA/particleTools.py @@ -1011,7 +1011,9 @@ def savePartDictToPickle(partDict, fName): fi.close() -def createAssetsRasterFromParticleLocations(particlesTimeArrays, dem, uniqueAssets, assetsValues): +def createAssetsRasterFromParticleLocations( + particlesTimeArrays, dem, uniqueAssets, assetsValues, noAssetsClass=-1 +): """create a raster indicating particle trajectories colorcoded with assets classes, highest overrides lower classes Parameters @@ -1023,7 +1025,10 @@ def createAssetsRasterFromParticleLocations(particlesTimeArrays, dem, uniqueAsse uniqueAssets: list list of assets class values sorted from low to high assetsValues: dict - dictionary with for each infrastructure class value the affected cell numbers + dictionary with affected cell numbers for each asset class + noAssetsClass: int + optional: value that is set for those parts of particle trajectories that do not affect any assetsValues + default it is set to -1 Returns --------- @@ -1069,7 +1074,7 @@ def createAssetsRasterFromParticleLocations(particlesTimeArrays, dem, uniqueAsse # set all locations where particles were but not affecting assets to class -1.0 testArray = np.full((dem["header"]["nrows"], dem["header"]["ncols"]), np.nan) - testArray[xyIndAllUnique[:, 1], xyIndAllUnique[:, 0]] = -1.0 + testArray[xyIndAllUnique[:, 1], xyIndAllUnique[:, 0]] = noAssetsClass particleAssets = np.where(~np.isnan(particleAssets), particleAssets, testArray) return particleAssets, particlesTimeArrays diff --git a/avaframe/runScripts/runParticlesAssetsInfo.py b/avaframe/runScripts/runParticlesAssetsInfo.py index 163953fc8..43ae64b8f 100644 --- a/avaframe/runScripts/runParticlesAssetsInfo.py +++ b/avaframe/runScripts/runParticlesAssetsInfo.py @@ -16,6 +16,9 @@ from avaframe.in3Utils import logUtils # +++++++++REQUIRED+++++++++++++ +# set the code for parts of particle trajectories that do not affect any assets class +# if not provided, default -1 is used +noAssetsClass = -1 # if particle locations are saved e.g. every second, the resulting assets raster might # show gaps as particles travelled further within this time step, to avoid these gaps # option to perform interpolation - can lead to errors if particle locations too spaced out @@ -26,10 +29,16 @@ cellSizeFactor = 0.5 resizeThreshold = 3 meshCellSizeThreshold = 0.001 -useCompression = True +useCompression = True # only active with .tif outputFileType, no .asc compression remeshInterpMethod = "nearest" # ++++++++++++++++++++++++++++++ +# +++++++++OPTIONAL+++++++++++++ +# choose whether outputFileType = '.tif', '.asc' or 'default' +# 'default' resolves to the file type of the utilized input DEM +outputFileType = '.tif' +# ++++++++++++++++++++++++++++++ + # load avalanche directory cfgMain = cfgUtils.getGeneralConfig() avalancheDir = cfgMain["MAIN"]["avalancheDir"] @@ -93,12 +102,25 @@ # derive info on which particles interacted with infrastructure particleAssets, particleTimeInfo = pT.createAssetsRasterFromParticleLocations( - particleTimeInfo, dem, uniqueAssets, assetsValues + particleTimeInfo, + dem, + uniqueAssets, + assetsValues, + noAssetsClass, ) + + if outputFileType in ['.asc', '.tif']: + _extMap = {".asc": "AAIGrid", ".tif": "GTiff"} + dem["header"]["driver"] = _extMap[outputFileType] + elif outputFileType != 'default': + msg = f"{outputFileType} is not a valid option for 'outputFileType' --> use any of ['default','.asc','.tif']" + raise ValueError(msg) + # export raster rU.writeResultToRaster( dem["header"], particleAssets, (outDir / ("particleAssetsInfo_%s" % simName)), flip=True ) + # create plot plotName = "particleAssetsInfo_%s" % simName diff --git a/avaframe/tests/test_particleTools.py b/avaframe/tests/test_particleTools.py index d4138f043..56dc9e3ef 100644 --- a/avaframe/tests/test_particleTools.py +++ b/avaframe/tests/test_particleTools.py @@ -375,7 +375,11 @@ def test_createAssetsRasterFromParticleLocations(): # call function to be tested particleAssets, particleTimeArrays = particleTools.createAssetsRasterFromParticleLocations( - particlesTimeArrays, dem, uniqueAssets, assetsValues + particlesTimeArrays, + dem, + uniqueAssets, + assetsValues, + -1, ) particleAssetsTest = np.zeros((8, 10)) * np.nan diff --git a/docs/moduleOut3Plot.rst b/docs/moduleOut3Plot.rst index ae12156ca..4ec84dcd6 100644 --- a/docs/moduleOut3Plot.rst +++ b/docs/moduleOut3Plot.rst @@ -248,14 +248,16 @@ To run particle assets information ============================= :py:mod:`out3Plot.particleAnalysisPlots` can also be used to create a plot that shows the cells affected by the particle -trajectories color-coded according to different assets classes (from high to low). This functionality is implemented only -for :py:mod:`com1DFA.com1DFA` and relies on particle dictionaries that are saved for each simulation run. For this, -adding *particles* to the ``resType`` and adjusting the desired saving time step in ``tSteps`` (see Note) in your local copy -of ```com1DFACfg.ini`` is required. To reduce the amount of data that is saved, consider only exporting the required -particle properties by setting ``exportParticlePorperties`` to: *ID|indXDEM|indYDEM|x|y|z|inCellDEM|nPart*. +trajectories color-coded according to different assets classes (from high to low). Cells that are affected by particle +trajectories but not interacting assets are also shown (semi-transparent white), their default value is -1. This +functionality is implemented only for :py:mod:`com1DFA.com1DFA` and relies on particle dictionaries that are saved +for each simulation run. For this, adding *particles* to the ``resType`` and adjusting the desired saving time +step in ``tSteps`` (see Note) in your local copy of ``com1DFACfg.ini`` is required. To reduce the amount of data +that is saved, consider only exporting the required particle properties by setting ``exportParticlePorperties`` +to: *ID|indXDEM|indYDEM|x|y|z|inCellDEM|nPart*. In addition, an assets raster file in ``avalancheDir/Inputs/INFRA`` is required. Classes have to be > 0, negative and zero values are treated as no data values. Preferably, the extent and resolution of the provided -assets raster should match the extent and resolution of the simulation DEM. If extents or resolution do not match, +assets raster should match the extent and resolution of the simulation DEM. If extent and/or resolution do not match, remeshing will be performed. However, this can potentially introduce geometrical artefacts in the assets layer (a corresponding warning will be written to the log-file). In order to avoid introducing new classes as a result of interpolation, the default setting in the corresponding run script (parameter ``remeshInterpMethod``)