Skip to content

[in3,com8,ana3] Add multi-layer result support; breaking change in com8#1236

Open
fso42 wants to merge 7 commits intomasterfrom
multiLayer
Open

[in3,com8,ana3] Add multi-layer result support; breaking change in com8#1236
fso42 wants to merge 7 commits intomasterfrom
multiLayer

Conversation

@fso42
Copy link
Contributor

@fso42 fso42 commented Feb 10, 2026

  • Add layer detection to parseSimName() and layer-aware columns (ppr_l1, ppr_l2) to makeSimFromResDF()
  • Refactor com8MoTPSA postprocess to produce L1/L2 filenames instead of the dfa/psa modelType workaround
  • Add runoutLayer config to AIMEC for explicit layer selection with multi-layer data

Breaking change:

com8MoTPSA output filenames changed. Previously they used the dfa/psa modelType workaround, now they use L1/L2
layer naming. Anyone with existing com8MoTPSA results or scripts that parse the old filenames will be affected.

…t in filename parsing and data handling

- `fileHandlerUtils.makeSimFromResDF`  handle multi-layer result files with layer-suffixed column names.
- Updated `cfgUtils.parseSimName` to recognize and parse layer components (`L1`, `L2`, etc.) in filenames.
…g logic

- Introduced `layers` configuration for specifying simulation output layers (L1: dense flow, L2: powder snow).
- Added `copyRawToLayerPeakFiles` function
- Introduced `runoutLayer` configuration for multi-layer analysis in `ana3AIMECCfg.ini`.
- Updated `checkAIMECinputs` to resolve base resType names to layer-suffixed columns.
- Refactored functions and logic to error out if multi-layer data is detected without a `runoutLayer`.
@fso42 fso42 changed the title [com1,com8,ana3] Add multi-layer result support [in3,com8,ana3] Add multi-layer result support Feb 10, 2026
@fso42 fso42 self-assigned this Feb 10, 2026
@fso42 fso42 added the enhancement New feature or request label Feb 10, 2026
@qltysh
Copy link
Contributor

qltysh bot commented Feb 10, 2026

❌ 2 blocking issues (4 total)

Tool Category Rule Count
black Style Incorrect formatting, autoformat by running qlty fmt. 1
ruff Lint Local variable name is assigned to but never used 1
qlty Structure Function with high complexity (count = 17): mainAIMEC 1
qlty Structure Deeply nested control flow (level = 4) 1

@qltysh one-click actions:

  • Auto-fix formatting (qlty fmt && git push)

@fso42 fso42 added this to the Version 2.0 milestone Feb 10, 2026
@fso42 fso42 changed the title [in3,com8,ana3] Add multi-layer result support [in3,com8,ana3] Add multi-layer result support; breaking change in com8 Feb 10, 2026
@qltysh
Copy link
Contributor

qltysh bot commented Feb 10, 2026

Qlty

Coverage Impact

⬆️ Merging this pull request will increase total coverage on master by 0.16%.

Modified Files with Diff Coverage (6)

RatingFile% DiffUncovered Line #s
Coverage rating: F Coverage rating: F
avaframe/com8MoTPSA/com8MoTPSA.py0.0%74-150
Coverage rating: B Coverage rating: B
avaframe/in3Utils/fileHandlerUtils.py100.0%
Coverage rating: B Coverage rating: B
avaframe/ana3AIMEC/dfa2Aimec.py100.0%
Coverage rating: A Coverage rating: A
avaframe/in3Utils/cfgUtils.py100.0%
Coverage rating: C Coverage rating: C
avaframe/ana3AIMEC/ana3AIMEC.py88.9%218-221
Coverage rating: B Coverage rating: B
avaframe/ana3AIMEC/aimecTools.py93.4%497, 501, 506, 1105
Total87.2%
🤖 Increase coverage with AI coding...

In the `multiLayer` branch, add test coverage for this new code:

- `avaframe/ana3AIMEC/aimecTools.py` -- Lines 497, 501, 506, and 1105
- `avaframe/ana3AIMEC/ana3AIMEC.py` -- Line 218-221
- `avaframe/com8MoTPSA/com8MoTPSA.py` -- Line 74-150

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@fso42 fso42 requested a review from awirb February 10, 2026 12:49
c=cmap3.to_rgba(cmapVal),
label=resAnalysisRow[varParList[0]],
)
else:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deeply nested control flow (level = 4) [qlty:nested-control-flow]

baseRunoutResType = inputs.get('baseRunoutResType', runoutResType)
displayRunoutResType = inputs.get('displayRunoutResType', runoutResType)
unit = pU.cfgPlotUtils['unit' + baseRunoutResType]
name = pU.cfgPlotUtils['name' + baseRunoutResType]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local variable name is assigned to but never used [ruff:F841]

Suggested change
name = pU.cfgPlotUtils['name' + baseRunoutResType]
pU.cfgPlotUtils['name' + baseRunoutResType]

- Added support for resolving base `resType` to layer-suffixed columns in multi-layer simulations using the new `resolveResTypeColumn` function.
- Introduced `computeBaseResTypeList` to validate and compute base `resType` names available for all simulations.
- Updated `checkAIMECinputs` function to handle both single-layer and multi-layer simulations, with input validation and error handling when `runoutLayer` is not configured.
continue
outAimec.plotMaxValuesComp(pathDict, resAnalysisDF, compResType, compResType2,
hue=cfgPlots['scenarioName'])

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function with high complexity (count = 17): mainAIMEC [qlty:function-complexity]

dataframe with for each simulation, the full file path, file name, release area scenario,
simulation type (null, entres, etc.), model type (dfa, ref, etc.), simID,
path to result files (ppr, pft, etc.), simulation name,
cell size and optional name of avalanche, optional time step
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional layer name?

----------
workDir : pathlib.Path
simulation work directory containing raw MoT-PSA output files
simType : str
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the simType here provided, couldn't this be done for all the simTypes as this is part of the raw output file names already no?

Parameters
----------
row : pandas Series
a row from inputsDF or resAnalysisDF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider adding what these dataframes contain - dataFrame organized one row per simulation providing info on the simulation, available result files and optional configuration

if cfgSetup['resTypes'] != '':
# required res types
resTypesWanted = cfgSetup['resTypes'].split('|')
runoutLayer = cfgSetup.get("runoutLayer", "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this used if runoutLayer not exisiting in cfg file - so for backwards compatibility?

# compute base resType names available for all sims
baseResTypeList = computeBaseResTypeList(inputsDF, runoutLayer)

# determine what we want (base names from config)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# determine what we want (base names from config)
# determine base resTypes used for analysis, if not provided in aimec cfg take base res types available for all sims

runoutResType = pathDict.get('runoutResType', cfgSetup['runoutResType'])
resAnalysisDF = aimecTools.computeRunOut(cfgSetup, rasterTransfo, resAnalysisDF, newRasters, simRowHash,
runoutResType=runoutResType)
runoutLine = aimecTools.computeRunoutLine(cfgSetup, rasterTransfo, newRasters, simRowHash, 'simulation', name='',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the runoutRestType a new argument in these functions, in there the same thing happens as in line 396 - if not provided take the one found in cfgSetup - why is it needed to be introduced as arguments in the functions if this check happens outside already?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants