-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
update DFA path runscript [ana5; runscripts] #1039
base: master
Are you sure you want to change the base?
Changes from all commits
ef55613
3e29f50
3c5234d
d0fa1b8
dc799fd
c24a916
fe7f05e
fdf3c6b
23a123d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,23 +10,105 @@ | |
import shutil | ||
|
||
# Local imports | ||
from avaframe.in1Data import getInput as gI | ||
import avaframe.in2Trans.shpConversion as shpConv | ||
from avaframe.in3Utils import cfgUtils | ||
from avaframe.in3Utils import fileHandlerUtils as fU | ||
from avaframe.in3Utils import cfgHandling | ||
import avaframe.in3Utils.initializeProject as initProj | ||
import avaframe.in3Utils.geoTrans as gT | ||
import avaframe.com1DFA.particleTools as particleTools | ||
import avaframe.com1DFA.DFAtools as DFAtls | ||
from avaframe.com1DFA import com1DFA | ||
import avaframe.out3Plot.outDebugPlots as debPlot | ||
from avaframe.out3Plot import outCom3Plots | ||
|
||
# create local logger | ||
# change log level in calling module to DEBUG to see log messages | ||
log = logging.getLogger(__name__) | ||
cfgAVA = cfgUtils.getGeneralConfig() | ||
debugPlot = cfgAVA['FLAGS'].getboolean('debugPlot') | ||
|
||
|
||
def generateAveragePath(avalancheDir, pathFromPart, simName, dem, addVelocityInfo=False, flagAvaDir=True, | ||
comModule='com1DFA'): | ||
""" extract path from fileds or particles | ||
def generatePathAndSplitpoint(avalancheDir, cfgDFAPath, cfgMain, runDFAModule): | ||
""" | ||
Parameters: | ||
avalancheDir (str): | ||
path to the avalanche directory | ||
cfgDFAPath (configParser object): | ||
DFAPath configuration | ||
cfgMain (configParser object): | ||
main avaframe configuration | ||
runDFAModule (bool): | ||
whether to run the DFA module (True) or load existing results (False) | ||
Returns | ||
------- | ||
massAvgPath: pathlib | ||
file path to the mass-averaged path result saved as a shapefile | ||
splitPoint: pathlib | ||
file path to the split point result saved as a shapefile | ||
""" | ||
if runDFAModule: # call DFA module to perform simulations with overrides from DFAPath config | ||
# Clean avalanche directory of old work and output files from module | ||
initProj.cleanModuleFiles(avalancheDir, com1DFA, deleteOutput=True) | ||
# create and read the default com1DFA config (no local is read) | ||
com1DFACfg = cfgUtils.getModuleConfig(com1DFA, fileOverride='', modInfo=False, toPrint=False, | ||
onlyDefault=cfgDFAPath['com1DFA_com1DFA_override'].getboolean( | ||
'defaultConfig')) | ||
# and override with settings from DFAPath config | ||
com1DFACfg, cfgDFAPath = cfgHandling.applyCfgOverride(com1DFACfg, cfgDFAPath, com1DFA, | ||
addModValues=False) | ||
outDir = pathlib.Path(avalancheDir, 'Outputs', 'ana5Utils', 'DFAPath') | ||
fU.makeADir(outDir) | ||
# write configuration to file | ||
com1DFACfgFile = outDir / 'com1DFAPathGenerationCfg.ini' | ||
with open(com1DFACfgFile, 'w') as configfile: | ||
com1DFACfg.write(configfile) | ||
# call com1DFA and perform simulations | ||
dem, plotDict, reportDictList, simDF = com1DFA.com1DFAMain(cfgMain, cfgInfo=com1DFACfgFile) | ||
else: # read existing simulation results | ||
# read simulation dem | ||
demOri = gI.readDEM(avalancheDir) | ||
dem = com1DFA.setDEMoriginToZero(demOri) | ||
dem['originalHeader'] = demOri['header'].copy() | ||
# load DFA results (use runCom1DFA to generate these results for example) | ||
# here is an example with com1DFA but another DFA computational module can be used | ||
# as long as it produces some pta, particles or FT, FM and FV results | ||
# create dataFrame of results (read DFA data) | ||
simDF, _ = cfgUtils.readAllConfigurationInfo(avalancheDir) | ||
if simDF is None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar blocks of code found in 2 locations. Consider refactoring. |
||
message = "Did not find any com1DFA simulations in %s/Outputs/com1DFA/" % avalancheDir | ||
log.error(message) | ||
raise FileExistsError(message) | ||
|
||
for simName, simDFrow in simDF.iterrows(): | ||
log.info('Computing avalanche path from simulation: %s', simName) | ||
pathFromPart = cfgDFAPath['PATH'].getboolean('pathFromPart') | ||
resampleDistance = cfgDFAPath['PATH'].getfloat('nCellsResample') * dem['header']['cellsize'] | ||
# get the mass average path | ||
avaProfileMass, particlesIni = generateMassAveragePath(avalancheDir, pathFromPart, simName, dem, | ||
addVelocityInfo=cfgDFAPath['PATH'].getboolean('addVelocityInfo')) | ||
avaProfileMass, _ = gT.prepareLine(dem, avaProfileMass, distance=resampleDistance, Point=None) | ||
avaProfileMass['indStartMassAverage'] = 1 | ||
avaProfileMass['indEndMassAverage'] = np.size(avaProfileMass['x']) | ||
# make the parabolic fit | ||
parabolicFit = getParabolicFit(cfgDFAPath['PATH'], avaProfileMass, dem) | ||
# here the avaProfileMass given in input is overwritten and returns only an x, y, z extended profile | ||
avaProfileMass = extendDFAPath(cfgDFAPath['PATH'], avaProfileMass, dem, particlesIni) | ||
# resample path and keep track of start and end of mass averaged part | ||
avaProfileMass = resamplePath(cfgDFAPath['PATH'], dem, avaProfileMass) | ||
# get split point | ||
splitPoint = getSplitPoint(cfgDFAPath['PATH'], avaProfileMass, parabolicFit) | ||
# make analysis and generate plots | ||
_ = outCom3Plots.generateCom1DFAPathPlot(avalancheDir, cfgDFAPath['PATH'], avaProfileMass, dem, | ||
parabolicFit, splitPoint, simName) | ||
# now save the path and split point as shapefiles | ||
avaPath,splitPoint = saveSplitAndPath(avalancheDir, simDFrow, splitPoint, avaProfileMass, dem) | ||
|
||
return avaPath, splitPoint | ||
|
||
def generateMassAveragePath(avalancheDir, pathFromPart, simName, dem, addVelocityInfo=False, flagAvaDir=True, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function |
||
comModule='com1DFA'): | ||
""" extract path from fields or particles | ||
|
||
Parameters | ||
----------- | ||
|
@@ -63,13 +145,13 @@ def generateAveragePath(avalancheDir, pathFromPart, simName, dem, addVelocityInf | |
particlesIni = particlesList[0] | ||
log.info('Using particles to generate avalanche path profile') | ||
# postprocess to extract path and energy line | ||
avaProfileMass = getDFAPathFromPart(particlesList, addVelocityInfo=addVelocityInfo) | ||
avaProfileMass = getMassAvgPathFromPart(particlesList, addVelocityInfo=addVelocityInfo) | ||
else: | ||
particlesList = '' | ||
# read field | ||
fieldName = ['FT', 'FM'] | ||
if addVelocityInfo: | ||
fieldName.append['FV'] | ||
fieldName.append('FV') | ||
fieldsList, fieldHeader, timeList = com1DFA.readFields(avalancheDir, fieldName, simName=simName, | ||
flagAvaDir=True, comModule='com1DFA') | ||
# get fields header | ||
|
@@ -78,18 +160,18 @@ def generateAveragePath(avalancheDir, pathFromPart, simName, dem, addVelocityInf | |
csz = fieldHeader['cellsize'] | ||
# we want the origin to be in (0, 0) as it is in the avaProfile that comes in | ||
X, Y = gT.makeCoordinateGrid(0, 0, csz, ncols, nrows) | ||
indNonZero = np.where(fieldsList[0]['FD'] > 0) | ||
indNonZero = np.where(fieldsList[0]['FT'] > 0) | ||
# convert this data in a particles style (dict with x, y, z info) | ||
particlesIni = {'x': X[indNonZero], 'y': Y[indNonZero]} | ||
particlesIni, _ = gT.projectOnRaster(dem, particlesIni) | ||
log.info('Using fields to generate avalanche path profile') | ||
# postprocess to extract path and energy line | ||
avaProfileMass = getDFAPathFromField(fieldsList, fieldHeader, dem) | ||
avaProfileMass = getMassAvgPathFromFields(fieldsList, fieldHeader, dem) | ||
|
||
return avaProfileMass, particlesIni | ||
|
||
|
||
def getDFAPathFromPart(particlesList, addVelocityInfo=False): | ||
def getMassAvgPathFromPart(particlesList, addVelocityInfo=False): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function |
||
""" compute mass averaged path from particles | ||
|
||
Also returns the averaged velocity and kinetic energy associated | ||
|
@@ -148,11 +230,11 @@ def getDFAPathFromPart(particlesList, addVelocityInfo=False): | |
return avaProfileMass | ||
|
||
|
||
def getDFAPathFromField(fieldsList, fieldHeader, dem): | ||
def getMassAvgPathFromFields(fieldsList, fieldHeader, dem): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function |
||
""" compute mass averaged path from fields | ||
|
||
Also returns the averaged velocity and kinetic energy associated | ||
The dem and fieldsList (FT, FV and FM) need to have identical dimentions and cell size. | ||
The dem and fieldsList (FT, FM and FV) need to have identical dimensions and cell size. | ||
If FV is not provided, information about velocity and kinetic energy is not computed | ||
|
||
Parameters | ||
|
@@ -530,8 +612,10 @@ def getSplitPoint(cfg, avaProfile, parabolicFit): | |
'z': z[indSplitPoint], 'zPara': zPara[indSplitPoint], 's': sNew[indSplitPoint]} | ||
except IndexError: | ||
noSplitPointFoundMessage = ('Automated split point generation failed as no point where slope is less than %s°' | ||
'was found, provide the split point manually.' % cfg.getfloat('slopeSplitPoint')) | ||
splitPoint = '' | ||
'was found, setting split point at the top. Correct split point manually.' | ||
% cfg.getfloat('slopeSplitPoint')) | ||
splitPoint = {'x': avaProfile['x'][0], 'y': avaProfile['y'][0], | ||
'z': z[0], 'zPara': zPara[0], 's': sNew[0], 'isTopSplitPoint': True} | ||
log.warning(noSplitPointFoundMessage) | ||
if debugPlot: | ||
angleProf, tmpProf, dsProf = gT.prepareAngleProfile(cfg.getfloat('slopeSplitPoint'), avaProfile) | ||
|
@@ -584,7 +668,7 @@ def saveSplitAndPath(avalancheDir, simDFrow, splitPoint, avaProfileMass, dem): | |
avalancheDir: pathlib | ||
avalanche directory pathlib path | ||
simDFrow: pandas series | ||
row of the siulation dataframe coresponding to the current simulation analyzed | ||
row of the simulation dataframe corresponding to the current simulation analyzed | ||
splitPoint: dict | ||
point dictionary | ||
avaProfileMass: dict | ||
|
@@ -593,8 +677,10 @@ def saveSplitAndPath(avalancheDir, simDFrow, splitPoint, avaProfileMass, dem): | |
com1DFA simulation dictionary | ||
Returns | ||
-------- | ||
avaProfile: dict | ||
resampled path profile | ||
pathAB: pathlib | ||
file path to the saved shapefile for the mass-averaged path | ||
splitAB: pathlib | ||
file path to the saved shapefile for the split point | ||
""" | ||
# put path back in original location | ||
if splitPoint != '': | ||
|
@@ -607,7 +693,7 @@ def saveSplitAndPath(avalancheDir, simDFrow, splitPoint, avaProfileMass, dem): | |
relName = simName.split('_')[0] | ||
inProjection = pathlib.Path(avalancheDir, 'Inputs', 'REL', relName + '.prj') | ||
# save profile in Inputs | ||
pathAB = pathlib.Path(avalancheDir, 'Outputs', 'DFAPath', 'massAvgPath_%s_AB_aimec' % simName) | ||
pathAB = pathlib.Path(avalancheDir, 'Outputs', 'ana5Utils', 'DFAPath', 'massAvgPath_%s_AB_aimec' % simName) | ||
name = 'massAvaPath' | ||
shpConv.writeLine2SHPfile(avaProfileMass, name, pathAB) | ||
if inProjection.is_file(): | ||
|
@@ -617,13 +703,13 @@ def saveSplitAndPath(avalancheDir, simDFrow, splitPoint, avaProfileMass, dem): | |
log.warning(message) | ||
log.info('Saved path to: %s', pathAB) | ||
if splitPoint != '': | ||
splitAB = pathlib.Path(avalancheDir, 'Outputs', 'DFAPath', 'splitPointParabolicFit_%s_AB_aimec' % simName) | ||
splitAB = pathlib.Path(avalancheDir, 'Outputs', 'ana5Utils', 'DFAPath', 'splitPointParabolicFit_%s_AB_aimec' % simName) | ||
name = 'parabolaSplitPoint' | ||
shpConv.writePoint2SHPfile(splitPoint, name, splitAB) | ||
if inProjection.is_file(): | ||
shutil.copy(inProjection, splitAB.with_suffix('.prj')) | ||
log.info('Saved split point to: %s', splitAB) | ||
|
||
return pathAB,splitAB | ||
|
||
def weightedAvgAndStd(values, weights): | ||
""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar blocks of code found in 7 locations. Consider refactoring.