From 9d3130a6b17b736c0a9368d55c2410a069a86ebb Mon Sep 17 00:00:00 2001 From: Anna Wirbel Date: Tue, 23 Sep 2025 12:28:57 +0200 Subject: [PATCH] allow 0 result raster in aimec - only make plot if relTh variation from shp - update docu --- avaframe/ana3AIMEC/aimecTools.py | 74 ++++-- avaframe/ana4Stats/probAna.py | 5 +- avaframe/out3Plot/outAIMEC.py | 429 ++++++++++++++++++------------ avaframe/out3Plot/outQuickPlot.py | 19 +- docs/moduleAna3AIMEC.rst | 1 + 5 files changed, 335 insertions(+), 193 deletions(-) diff --git a/avaframe/ana3AIMEC/aimecTools.py b/avaframe/ana3AIMEC/aimecTools.py index 4a3e0ef60..b66899e5e 100644 --- a/avaframe/ana3AIMEC/aimecTools.py +++ b/avaframe/ana3AIMEC/aimecTools.py @@ -977,34 +977,55 @@ def computeRunOut(cfgSetup, rasterTransfo, resAnalysisDF, transformedRasters, si if lindex.any(): cUpper = min(lindex) cLower = max(lindex) + runoutFound = True else: log.warning('No max values > threshold found. threshold = %4.2f, too high?' % thresholdValue) cUpper = 0 cLower = 0 + runoutFound = False # search in mean values lindex = np.nonzero(PResCrossMean > thresholdValue)[0] if lindex.any(): cUpperm = min(lindex) cLowerm = max(lindex) + flagMeanFound = True else: log.warning('No average values > threshold found. threshold = %4.2f, too high?' % thresholdValue) cUpperm = 0 cLowerm = 0 - resAnalysisDF.loc[simRowHash, 'sRunout'] = scoord[cLower] - index = np.nanargmax(PResRasters[cLower, :]) - resAnalysisDF.loc[simRowHash, 'lRunout'] = lcoord[index] - resAnalysisDF.loc[simRowHash, 'xRunout'] = gridx[cLower, index] - resAnalysisDF.loc[simRowHash, 'yRunout'] = gridy[cLower, index] + flagMeanFound = False + + if runoutFound: + resAnalysisDF.loc[simRowHash, "sRunout"] = scoord[cLower] + index = np.nanargmax(PResRasters[cLower, :]) + resAnalysisDF.loc[simRowHash, "lRunout"] = lcoord[index] + resAnalysisDF.loc[simRowHash, "xRunout"] = gridx[cLower, index] + resAnalysisDF.loc[simRowHash, "yRunout"] = gridy[cLower, index] + else: + resAnalysisDF.loc[simRowHash, "sRunout"] = np.nan + resAnalysisDF.loc[simRowHash, "lRunout"] = np.nan + resAnalysisDF.loc[simRowHash, "xRunout"] = np.nan + resAnalysisDF.loc[simRowHash, "yRunout"] = np.nan + resAnalysisDF.loc[simRowHash, 'deltaSXY'] = scoord[cLower] - scoord[cUpper] - resAnalysisDF.loc[simRowHash, 'runoutAngle'] = np.rad2deg(np.arctan((zThalweg[cUpper] - zThalweg[cLower]) / - (scoord[cLower] - scoord[cUpper]))) - resAnalysisDF.loc[simRowHash, 'zRelease'] = zThalweg[cUpper] - resAnalysisDF.loc[simRowHash, 'zRunout'] = zThalweg[cLower] - resAnalysisDF.loc[simRowHash, 'sMeanRunout'] = scoord[cLowerm] - resAnalysisDF.loc[simRowHash, 'xMeanRunout'] = x[cLowerm] - resAnalysisDF.loc[simRowHash, 'yMeanRunout'] = y[cLowerm] + resAnalysisDF.loc[simRowHash, "runoutAngle"] = np.rad2deg( + np.arctan((zThalweg[cUpper] - zThalweg[cLower]) / (scoord[cLower] - scoord[cUpper])) + ) + if flagMeanFound: + resAnalysisDF.loc[simRowHash, "zRunout"] = zThalweg[cLower] + resAnalysisDF.loc[simRowHash, "sMeanRunout"] = scoord[cLowerm] + resAnalysisDF.loc[simRowHash, "xMeanRunout"] = x[cLowerm] + resAnalysisDF.loc[simRowHash, "yMeanRunout"] = y[cLowerm] + else: + resAnalysisDF.loc[simRowHash, "zRunout"] = np.nan + resAnalysisDF.loc[simRowHash, "sMeanRunout"] = np.nan + resAnalysisDF.loc[simRowHash, "xMeanRunout"] = np.nan + resAnalysisDF.loc[simRowHash, "yMeanRunout"] = np.nan + + 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 return resAnalysisDF @@ -1268,7 +1289,11 @@ def analyzeArea(rasterTransfo, resAnalysisDF, simRowHash, newRasters, cfg, pathD inputs['simName'] = simName compPlotPath = None - if simRowHash != refSimRowHash and cfgPlots.getboolean('extraPlots'): + if ( + simRowHash != refSimRowHash + and cfgPlots.getboolean("extraPlots") + and resAnalysisDF.loc[simRowHash, "runoutFound"] + ): # only plot comparisons of simulations to reference compPlotPath = outAimec.visuComparison(rasterTransfo, inputs, pathDict) # add contourlines to contourDict @@ -1553,9 +1578,13 @@ def addFieldsToDF(inputsDF): 'sMeanRunout', 'xMeanRunout', 'yMeanRunout', 'elevRel', 'deltaZ', 'refSim_Diff_sRunout', 'refSim_Diff_lRunout', 'dataType', 'runoutLineDiff_line_RMSE', 'runoutLineDiff_poly_RMSE'] - emptyStrFields = ['runoutLineDiff_line_pointsNotFoundInSim', - 'runoutLineDiff_line_pointsNotFoundInRef', 'runoutLineDiff_poly_pointsNotFoundInSim', - 'runoutLineDiff_poly_pointsNotFoundInRef'] + emptyStrFields = [ + "runoutLineDiff_line_pointsNotFoundInSim", + "runoutLineDiff_line_pointsNotFoundInRef", + "runoutLineDiff_poly_pointsNotFoundInSim", + "runoutLineDiff_poly_pointsNotFoundInRef", + "runoutFound", + ] for item in nanFields: inputsDF = pd.concat([inputsDF, pd.DataFrame({item: np.nan}, index=inputsDF.index)], axis=1).copy() @@ -1772,8 +1801,15 @@ def analyzeDiffsRunoutLines(cfgSetup, runoutLine, refDataTransformed, resAnalysi RMSE = np.sqrt(np.sum(diffNoNans**2)/len(diffNoNans)) # plot differences in runout lines - outAimec.plotRunoutLineComparisonToReference(cfgSetup, refLine, runoutLine, pathDict, simName, runoutStr, - refLineStr, RMSE, diffNoNans) + if len(np.where((np.isnan(runoutLine["s"]) == False))[0]) > 0: + outAimec.plotRunoutLineComparisonToReference( + cfgSetup, refLine, runoutLine, pathDict, simName, runoutStr, refLineStr, RMSE, diffNoNans + ) + else: + log.warning( + "No runout line found for simulation: %s, not creating comparison to reference plot" + % simName + ) resAnalysisDF.at[simRowHash, 'runoutLineDiff_%s_pointsNotFoundInSim' % refLine['type']] = runoutStr resAnalysisDF.at[simRowHash, 'runoutLineDiff_%s_pointsNotFoundInRef' % refLine['type']] = refLineStr @@ -1782,4 +1818,4 @@ def analyzeDiffsRunoutLines(cfgSetup, runoutLine, refDataTransformed, resAnalysi else: log.info('For reference data type %s, runout line comparison is not available' % refLine['type']) - return resAnalysisDF \ No newline at end of file + return resAnalysisDF diff --git a/avaframe/ana4Stats/probAna.py b/avaframe/ana4Stats/probAna.py index 2f7f533d7..c9ba2c342 100644 --- a/avaframe/ana4Stats/probAna.py +++ b/avaframe/ana4Stats/probAna.py @@ -99,8 +99,9 @@ def cfgFilesGlobalApproach(avaDir, cfgProb, modName, outDir): plotDir = avaDir / "Outputs" / "ana4Stats" / "plots" if len(paramValuesD["names"]) == 2: sP.plotSample(paramValuesD, plotDir, releaseScenario=releaseScenario) - elif len(paramValuesD["varParNamesInitial"]) == 2: - sP.plotThSampleFromVals(paramValuesD, plotDir) + elif "varParNamesInitial" in paramValuesD.keys(): + if len(paramValuesD["varParNamesInitial"]) == 2: + sP.plotThSampleFromVals(paramValuesD, plotDir) else: log.debug("More or less than two parameters have been varied - no plot of sample available") diff --git a/avaframe/out3Plot/outAIMEC.py b/avaframe/out3Plot/outAIMEC.py index 5755f2f0f..c59dbecf1 100644 --- a/avaframe/out3Plot/outAIMEC.py +++ b/avaframe/out3Plot/outAIMEC.py @@ -261,168 +261,223 @@ def visuRunoutStat(rasterTransfo, inputsDF, resAnalysisDF, newRasters, cfgSetup, pMedian = np.median(pprCrossMax, axis=0) pPercentile = np.percentile(pprCrossMax, [percentile/2, 50, 100-percentile/2], axis=0) maskedArray = np.ma.masked_where(rasterdataPres <= float(thresholdValue), rasterdataPres) - # transpose array for plot - maskedArrayTransposed = np.transpose(maskedArray) - - # get plots limits - indXMin = max(0, indStartOfRunout-5) - xMin = s[indXMin] - xMax = max(runout) + 25 - indYMin = max(0, np.min(np.nonzero(np.any(maskedArray[indStartOfRunout:, :] > 0, axis=0))[0])-5) - yMin = l[indYMin] - indYMax = min(np.max(np.nonzero(np.any(maskedArray[indStartOfRunout:, :] > 0, axis=0))[0])+5, len(l)-1) - yMax = l[indYMax] - - # get colormap for raster plot of peak field - cmap, _, ticks, norm = pU.makeColorMap(pU.colorMaps[runoutResType], np.nanmin( - maskedArrayTransposed[indYMin:indYMax, indXMin:]), np.nanmax(maskedArrayTransposed[indYMin:indYMax, indXMin:]), - continuous=pU.contCmap) - cmap.set_bad('w', 1.) - # Get colors for colorcoding runout points and crossMax values along thalweg for all sims - unitSC = cfgSetup['unit'] - nSamples = np.size(runout) - colorFlag = False - if 'colorParameter' in pathDict: - if pathDict['colorParameter'] is False: + if not np.any(rasterdataPres >= float(thresholdValue)): + log.warning( + "No %s values exceeding threshold of %.2f found to analyze" % (runoutResType, thresholdValue) + ) + outFilePath = "" + else: + # transpose array for plot + maskedArrayTransposed = np.transpose(maskedArray) + + # get plots limits + indXMin = max(0, indStartOfRunout - 5) + xMin = s[indXMin] + xMax = max(runout) + 25 + indYMin = max(0, np.min(np.nonzero(np.any(maskedArray[indStartOfRunout:, :] > 0, axis=0))[0]) - 5) + yMin = l[indYMin] + indYMax = min( + np.max(np.nonzero(np.any(maskedArray[indStartOfRunout:, :] > 0, axis=0))[0]) + 5, len(l) - 1 + ) + yMax = l[indYMax] + + # get colormap for raster plot of peak field + cmap, _, ticks, norm = pU.makeColorMap( + pU.colorMaps[runoutResType], + np.nanmin(maskedArrayTransposed[indYMin:indYMax, indXMin:]), + np.nanmax(maskedArrayTransposed[indYMin:indYMax, indXMin:]), + continuous=pU.contCmap, + ) + cmap.set_bad("w", 1.0) + + # Get colors for colorcoding runout points and crossMax values along thalweg for all sims + unitSC = cfgSetup["unit"] + nSamples = np.size(runout) + colorFlag = False + if "colorParameter" in pathDict: + if pathDict["colorParameter"] is False: + values = None + minVal = 0 + maxVal = 1 + elif isinstance(firstVar, str): + # if str then check for parameter values and create colormap that varies between 0, 1 with number of unique + # values as steps + values = inputsDF[varParList[0]].to_list() + minVal = 0 + maxVal = 1 + colorFlag = True + cmapSCVals = np.linspace(0, 1, nSamples) + else: + values = sorted(inputsDF[varParList[0]].to_list()) + minVal = np.nanmin(values) + maxVal = np.nanmax(values) + cmapSCVals = np.linspace(0, 1, nSamples) + colorFlag = True + else: values = None minVal = 0 maxVal = 1 - elif isinstance(firstVar, str): - # if str then check for parameter values and create colormap that varies between 0, 1 with number of unique - # values as steps - values = inputsDF[varParList[0]].to_list() - minVal = 0 - maxVal = 1 - colorFlag = True - cmapSCVals = np.linspace(0, 1, nSamples) + # create colormap and setup ticks and itemsList + cmapSC, colorSC, ticksSC, normSC, unitSC, itemsList, displayColorBar = pU.getColors4Scatter( + values, nSamples, unitSC + ) + + # if parameter type for colorcoding is str and categorical colormap is chosen + if cfgSetup.getboolean("varParCategorical"): + norm3 = mpl.colors.Normalize(vmin=minVal, vmax=maxVal) + # map string varParList value to 0, 1 colorbar values + if isinstance(firstVar, str): + # fetch amount of different str parameter values + varParStrValues = list(set(resAnalysisDF[varParList[0]].tolist())) + # setup colormap + cmapUsed = cmapCrameri.glasgowS + cmapValues3 = np.linspace(0, 1, len(varParStrValues)) + # create cmap object + cmap3 = mpl.cm.ScalarMappable(norm=norm3, cmap=cmapUsed) + cmap3.set_array([]) + + ############################################ + # Figure: Analysis runout + fig, (ax1, ax3, ax2) = plt.subplots(nrows=3, ncols=1, figsize=(pU.figW * 2, pU.figH * 3.5)) + + ax1.axvline(x=np.max(runout), color="k", linestyle="-.", label="runout max %.0f m" % np.max(runout)) + ax1.axvline( + x=np.average(runout), color="k", linestyle="-", label="runout mean %.0f m" % np.mean(runout) + ) + ax1.axvline(x=np.min(runout), color="k", linestyle=":", label="runout min %.0f m" % np.min(runout)) + + ax1.axvline(x=s[indStartOfRunout], color="k", linestyle="--", label=rasterTransfo["labelRunout"]) + # label=('start of runout area: '+ r'$\beta_{%.1f °}$' % (rasterTransfo['startOfRunoutAreaAngle']))) + ref5, im = pU.NonUnifIm( + ax1, + s, + l, + maskedArrayTransposed, + "$S_{XY}$ (thalweg) [m]", + "$L_{XY}$ (thalweg) [m]", + extent=[xMin, xMax, yMin, yMax], + cmap=cmap, + norm=norm, + ) + + if cfgSetup.getboolean("varParCategorical"): + for simRowHash, resAnalysisRow in resAnalysisDF.iterrows(): + cmapVal1 = cmapValues3[varParStrValues.index(resAnalysisRow[varParList[0]])] + sc = ax1.plot( + resAnalysisRow["sRunout"], + resAnalysisRow["lRunout"], + marker="o", + c=cmap3.to_rgba(cmapVal1), + label=resAnalysisRow[varParList[0]], + ) + # add legend for categorical values and move outside of panel + ax1.legend(loc="center left", bbox_to_anchor=(1.2, 0.5)) else: - values = sorted(inputsDF[varParList[0]].to_list()) - minVal = np.nanmin(values) - maxVal = np.nanmax(values) - cmapSCVals = np.linspace(0, 1, nSamples) - colorFlag = True - else: - values = None - minVal = 0 - maxVal = 1 - # create colormap and setup ticks and itemsList - cmapSC, colorSC, ticksSC, normSC, unitSC, itemsList, displayColorBar = pU.getColors4Scatter(values, nSamples, - unitSC) - - # if parameter type for colorcoding is str and categorical colormap is chosen - if cfgSetup.getboolean('varParCategorical'): - norm3 = mpl.colors.Normalize(vmin=minVal, vmax=maxVal) - # map string varParList value to 0, 1 colorbar values - if isinstance(firstVar, str): - # fetch amount of different str parameter values - varParStrValues = list(set(resAnalysisDF[varParList[0]].tolist())) - # setup colormap - cmapUsed = cmapCrameri.glasgowS - cmapValues3 = np.linspace(0, 1, len(varParStrValues)) - # create cmap object - cmap3 = mpl.cm.ScalarMappable(norm=norm3, cmap=cmapUsed) - cmap3.set_array([]) - - ############################################ - # Figure: Analysis runout - fig, (ax1, ax3, ax2) = plt.subplots(nrows=3, ncols=1, figsize=(pU.figW * 2, pU.figH * 3.5)) - - ax1.axvline(x=np.max(runout), color='k', linestyle='-.', label='runout max %.0f m' % np.max(runout)) - ax1.axvline(x=np.average(runout), color='k', linestyle='-', label='runout mean %.0f m' % np.mean(runout)) - ax1.axvline(x=np.min(runout), color='k', linestyle=':', label='runout min %.0f m' % np.min(runout)) - - ax1.axvline(x=s[indStartOfRunout], color='k', linestyle='--', - label=rasterTransfo['labelRunout']) - #label=('start of runout area: '+ r'$\beta_{%.1f °}$' % (rasterTransfo['startOfRunoutAreaAngle']))) - ref5, im = pU.NonUnifIm(ax1, s, l, maskedArrayTransposed, '$S_{XY}$ (thalweg) [m]', '$L_{XY}$ (thalweg) [m]', - extent=[xMin, xMax, yMin, yMax], - cmap=cmap, norm=norm) - - if cfgSetup.getboolean('varParCategorical'): + sc = ax1.scatter( + resAnalysisDF["sRunout"], + resAnalysisDF["lRunout"], + c=colorSC, + cmap=cmapSC, + norm=normSC, + marker=pU.markers[0], + label=( + "runout points (%s<%.1f%s)" % (runoutResType, cfgSetup.getfloat("thresholdValue"), unit) + ), + ) + if displayColorBar: + pU.addColorBar(sc, ax1, ticksSC, unitSC, title=paraVar, pad=0.08, tickLabelsList=itemsList) + ax1.legend(loc="upper left") + + # set panel axis labels + ax1.set_ylim([yMin, yMax]) + ax1.set_xlim([xMin, xMax]) + ax1.set_title( + "%s field (reference) for (%s>%.1f%s)" + % (name, runoutResType, cfgSetup.getfloat("thresholdValue"), unit) + ) + ax1.set_aspect("equal") + pU.putAvaNameOnPlot(ax1, projectName) + + # add colorbar for peak field + pU.addColorBar(im, ax1, ticks, unit) + + # add third panel for statistical measures of distribution of cross max values + ax2.fill_between( + s, + pPercentile[2], + pPercentile[0], + facecolor=[0.8, 0.8, 0.8], + alpha=0.5, + label=("[%.2f, %.2f]%% interval" % (percentile / 2, 100 - percentile / 2)), + ) + matplotlib.patches.Patch(alpha=0.5, color=[0.8, 0.8, 0.8]) + ax2.plot(s, pMedian, color="r", label="median") + ax2.plot(s, pMean, color="b", label="mean") + + ax2.set_title("%s distribution along thalweg for all sims" % name) + ax2.legend(loc="upper right") + ax2.set_xlabel("$S_{xy}$ (thalweg) [m]") + ax2.set_xlim([s.min(), s.max()]) + ax2.set_ylim(auto=True) + ax2.set_ylabel("$%s_{%s}$ [%s]" % (runoutResType, crossValue, unit)) + + # add middle panel with cross max values along s + # loop over all sims and compute colorbar value and add line plot + countSim = 1 for simRowHash, resAnalysisRow in resAnalysisDF.iterrows(): - cmapVal1 = cmapValues3[varParStrValues.index(resAnalysisRow[varParList[0]])] - sc = ax1.plot(resAnalysisRow['sRunout'], resAnalysisRow['lRunout'], marker='o', c=cmap3.to_rgba(cmapVal1), - label=resAnalysisRow[varParList[0]]) - # add legend for categorical values and move outside of panel - ax1.legend(loc='center left', bbox_to_anchor=(1.2, 0.5)) - else: - sc = ax1.scatter(resAnalysisDF['sRunout'], resAnalysisDF['lRunout'], - c=colorSC, cmap=cmapSC, norm=normSC, marker=pU.markers[0], - label=('runout points (%s<%.1f%s)' % (runoutResType, cfgSetup.getfloat('thresholdValue'), unit))) - if displayColorBar: - pU.addColorBar(sc, ax1, ticksSC, unitSC, title=paraVar, pad=0.08, tickLabelsList=itemsList) - ax1.legend(loc='upper left') - - # set panel axis labels - ax1.set_ylim([yMin, yMax]) - ax1.set_xlim([xMin, xMax]) - ax1.set_title('%s field (reference) for (%s>%.1f%s)' % (name, runoutResType, cfgSetup.getfloat('thresholdValue'), unit)) - ax1.set_aspect('equal') - pU.putAvaNameOnPlot(ax1, projectName) - - # add colorbar for peak field - pU.addColorBar(im, ax1, ticks, unit) - - # add third panel for statistical measures of distribution of cross max values - ax2.fill_between(s, pPercentile[2], pPercentile[0], facecolor=[.8, .8, .8], alpha=0.5, - label=('[%.2f, %.2f]%% interval' % (percentile/2, 100-percentile/2))) - matplotlib.patches.Patch(alpha=0.5, color=[.8, .8, .8]) - ax2.plot(s, pMedian, color='r', label='median') - ax2.plot(s, pMean, color='b', label='mean') - - ax2.set_title('%s distribution along thalweg for all sims' % name) - ax2.legend(loc='upper right') - ax2.set_xlabel('$S_{xy}$ (thalweg) [m]') - ax2.set_xlim([s.min(), s.max()]) - ax2.set_ylim(auto=True) - ax2.set_ylabel('$%s_{%s}$ [%s]' % (runoutResType, crossValue, unit)) - - # add middle panel with cross max values along s - # loop over all sims and compute colorbar value and add line plot - countSim = 1 - for simRowHash, resAnalysisRow in resAnalysisDF.iterrows(): - if colorFlag and (isinstance(firstVar, str) == False): - cmapVal = cmapSCVals[values.index(resAnalysisRow[varParList[0]])] - if np.isnan(cmapVal) and paraVar in ['relTh', 'entTh', 'secondaryRelTh']: - cmapVal = resAnalysisRow[(paraVar+'0')] - elif colorFlag and isinstance(firstVar, str): - cmapVal = cmapSCVals[values.index(resAnalysisRow[varParList[0]])] - else: - cmapVal = countSim / nSamples - if resAnalysisRow['simName'] == pathDict['refSimName']: - ax3.plot(s, resAnalysisRow[runoutResType.lower() + crossValue], c='k', label='reference', zorder=nSamples+1) - else: - if cfgSetup.getboolean('varParCategorical'): - cmapVal = cmapValues3[varParStrValues.index(resAnalysisRow[varParList[0]])] - ax3.plot(s, resAnalysisRow[runoutResType.lower() + crossValue], c=cmap3.to_rgba(cmapVal), - label=resAnalysisRow[varParList[0]]) + if colorFlag and (isinstance(firstVar, str) == False): + cmapVal = cmapSCVals[values.index(resAnalysisRow[varParList[0]])] + if np.isnan(cmapVal) and paraVar in ["relTh", "entTh", "secondaryRelTh"]: + cmapVal = resAnalysisRow[(paraVar + "0")] + elif colorFlag and isinstance(firstVar, str): + cmapVal = cmapSCVals[values.index(resAnalysisRow[varParList[0]])] else: - ax3.plot(s, resAnalysisRow[runoutResType.lower() + crossValue], c=cmapSC(cmapVal)) - countSim = countSim + 1 - - # add colorbar - if colorFlag and (cfgSetup.getboolean('varParCategorical') is False): - cmapSC2 = ScalarMappable(norm=Normalize(minVal, maxVal), cmap=cmapSC) - cbar = ax3.figure.colorbar(cmapSC2, ax=ax3) - cbar.outline.set_visible(False) - if cfgSetup['unit'] != '': - cbar.ax.set_title('[' + cfgSetup['unit'] + ']', pad=10) - cbar.set_label(paraVar) - if isinstance(firstVar, str): - cbar.set_ticks(ticks=np.linspace(0,1,len(itemsList)), labels=itemsList) - # add labels title - ax3.set_title('%s along thalweg for all sims' % name) - ax3.legend(loc='upper right') - ax3.set_xlabel('$S_{xy}$ (thalweg) [m]') - ax3.set_xlim([s.min(), s.max()]) - ax3.set_ylim(auto=True) - ax3.set_ylabel('$%s_{%s}$ [%s]' % (runoutResType, crossValue, unit)) - - outFileName = '_'.join([projectName, runoutResType, str(thresholdValue).replace('.', 'p'), - 'slComparisonStat']) - - outFilePath = pU.saveAndOrPlot(pathDict, outFileName, fig) + cmapVal = countSim / nSamples + if resAnalysisRow["simName"] == pathDict["refSimName"]: + ax3.plot( + s, + resAnalysisRow[runoutResType.lower() + crossValue], + c="k", + label="reference", + zorder=nSamples + 1, + ) + else: + if cfgSetup.getboolean("varParCategorical"): + cmapVal = cmapValues3[varParStrValues.index(resAnalysisRow[varParList[0]])] + ax3.plot( + s, + resAnalysisRow[runoutResType.lower() + crossValue], + c=cmap3.to_rgba(cmapVal), + label=resAnalysisRow[varParList[0]], + ) + else: + ax3.plot(s, resAnalysisRow[runoutResType.lower() + crossValue], c=cmapSC(cmapVal)) + countSim = countSim + 1 + + # add colorbar + if colorFlag and (cfgSetup.getboolean("varParCategorical") is False): + cmapSC2 = ScalarMappable(norm=Normalize(minVal, maxVal), cmap=cmapSC) + cbar = ax3.figure.colorbar(cmapSC2, ax=ax3) + cbar.outline.set_visible(False) + if cfgSetup["unit"] != "": + cbar.ax.set_title("[" + cfgSetup["unit"] + "]", pad=10) + cbar.set_label(paraVar) + if isinstance(firstVar, str): + cbar.set_ticks(ticks=np.linspace(0, 1, len(itemsList)), labels=itemsList) + # add labels title + ax3.set_title("%s along thalweg for all sims" % name) + ax3.legend(loc="upper right") + ax3.set_xlabel("$S_{xy}$ (thalweg) [m]") + ax3.set_xlim([s.min(), s.max()]) + ax3.set_ylim(auto=True) + ax3.set_ylabel("$%s_{%s}$ [%s]" % (runoutResType, crossValue, unit)) + + outFileName = "_".join( + [projectName, runoutResType, str(thresholdValue).replace(".", "p"), "slComparisonStat"] + ) + + outFilePath = pU.saveAndOrPlot(pathDict, outFileName, fig) return outFilePath @@ -1233,13 +1288,60 @@ def plotMaxValuesComp(pathDict, resultsDF, name1, name2, hue=None): valDF = resultsDF[resultsDF['simName'] == pathDict['refSimName']] # define units for available analysis parameters - availableoptions = ['pfvFieldMax', 'pfvFieldMin', 'pfvFieldMean', 'maxpfvCrossMax', - 'pftFieldMax', 'pftFieldMin', 'pftFieldMean', 'maxpftCrossMax', - 'pprFieldMax', 'pprFieldMin', 'pprFieldMean', 'maxpprCrossMax', - 'sRunout', 'deltaSXY', 'zRelease', 'zRunout', 'deltaZ', 'relMass', - 'finalMass', 'entMass', 'runoutAngle'] - units = ['ms-1', 'ms-1', 'ms-1', 'ms-1', 'm', 'm', 'm', 'm', 'kPa', 'kPa', 'kPa', 'kPa', 'm', 'm', 'm', 'm', 'm', - 'kg', 'kg', 'kg', '°'] + availableoptions = [ + "pfvFieldMax", + "pfvFieldMin", + "pfvFieldMean", + "maxpfvCrossMax", + "pftFieldMax", + "pftFieldMin", + "pftFieldMean", + "maxpftCrossMax", + "pfdFieldMax", + "pfdFieldMin", + "pfdFieldMean", + "maxpfdCrossMax", + "pprFieldMax", + "pprFieldMin", + "pprFieldMean", + "maxpprCrossMax", + "sRunout", + "deltaSXY", + "zRelease", + "zRunout", + "deltaZ", + "relMass", + "finalMass", + "entMass", + "runoutAngle", + ] + units = [ + "ms-1", + "ms-1", + "ms-1", + "ms-1", + "m", + "m", + "m", + "m", + "m", + "m", + "m", + "m", + "kPa", + "kPa", + "kPa", + "kPa", + "m", + "m", + "m", + "m", + "m", + "kg", + "kg", + "kg", + "°", + ] if name1 not in availableoptions: message = 'compResType1: %s not in available options' % name1 @@ -1418,7 +1520,6 @@ def plotVelThAlongThalweg(pathDict, rasterTransfo, pftCrossMax, pfvCrossMax, cfg pU.saveAndOrPlot(pathDict, outFileName, fig) - def getIndicesVel(pfvCM, velocityThreshold): """create indices of peak flow velocity cross max vector first above tresholdValue and first below threshold again @@ -1703,4 +1804,4 @@ def boxScalarMeasures(pathDict, resultsDF, name='', orderList=None): plt.show() outFileName = 'distributionAimecScalarValues_%s' % (name) - pU.saveAndOrPlot(pathDict, outFileName, fig) \ No newline at end of file + pU.saveAndOrPlot(pathDict, outFileName, fig) diff --git a/avaframe/out3Plot/outQuickPlot.py b/avaframe/out3Plot/outQuickPlot.py index 5c58d9889..1b2e7aac6 100644 --- a/avaframe/out3Plot/outQuickPlot.py +++ b/avaframe/out3Plot/outQuickPlot.py @@ -582,14 +582,17 @@ def plotContours(contourDict, resType, thresholdValue, pathDict, addLegend=True) # loop over all sims for ind, simName in enumerate(contourDict): - keyLabel = list(contourDict[simName])[0] - for key in contourDict[simName]: - if key == keyLabel and 'line' in key: - ax1.plot(contourDict[simName][key]['x'], contourDict[simName][key]['y'], - c=cmap.to_rgba(ind), label=simName) - elif 'line' in key: - ax1.plot(contourDict[simName][key]['x'], contourDict[simName][key]['y'], - c=cmap.to_rgba(ind)) + if contourDict[simName] == {}: + log.warning('No contour lines found for %s' % simName) + else: + keyLabel = list(contourDict[simName])[0] + for key in contourDict[simName]: + if key == keyLabel and 'line' in key: + ax1.plot(contourDict[simName][key]['x'], contourDict[simName][key]['y'], + c=cmap.to_rgba(ind), label=simName) + elif 'line' in key: + ax1.plot(contourDict[simName][key]['x'], contourDict[simName][key]['y'], + c=cmap.to_rgba(ind)) if addLegend: ax1.legend() diff --git a/docs/moduleAna3AIMEC.rst b/docs/moduleAna3AIMEC.rst index ebc3f2cc3..182582c6a 100644 --- a/docs/moduleAna3AIMEC.rst +++ b/docs/moduleAna3AIMEC.rst @@ -465,6 +465,7 @@ The result variables listed below are partly included in the above described plo - zRunout: altitude of the *sRunout* point - deltaZ: altitude difference between *zRelease* and *zRunout* - runoutAngle: corresponding runout angle based on *deltaSXY* and *deltaZ* +- runoutFound: flag if runout point was found (boolean) If reference data sets are included in analysis, additionally these outputs are provided: