Skip to content

Commit

Permalink
Model.run now accepts a pandas.Series of snowpacks, the Series index …
Browse files Browse the repository at this point in the history
…is automatically used as a dimension for the results
  • Loading branch information
ghislainp committed Oct 9, 2020
1 parent e02642f commit 87c9b5b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
19 changes: 14 additions & 5 deletions smrt/core/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import copy

import numpy as np
import pandas as pd

from .error import SMRTError
from .result import concat_results
Expand Down Expand Up @@ -194,10 +195,10 @@ def run(self, sensor, snowpack, atmosphere=None, snowpack_dimension=None, progre
# run all the simulations (with atmosphere as long as it is not depreciated), the results is a flat list of results
results = runner(self.run_single_simulation, ((simul, atmosphere) for simul in simulations))

# reshape the results but successive concatenation
for axis, values in reversed(dimensions):
n = len(values)
results = [concat_results(results[i: i + n], (axis, values)) for i in range(0, len(results), n)]
# reshape the results with successive concatenations
for dimension in reversed(dimensions):
n = len(dimension[1]) if isinstance(dimension, tuple) else len(dimension)
results = [concat_results(results[i: i + n], dimension) for i in range(0, len(results), n)]

assert len(results) == 1
return results[0]
Expand All @@ -217,13 +218,21 @@ def prepare_simulations(self, sensor, snowpack, snowpack_dimension):
snowpack_dimension = "snowpack", list(snowpack.keys())
snowpack = list(snowpack.values())

# or is it a pandas Series ?
if isinstance(snowpack, pd.Series):
snowpack_dimension = snowpack.index
snowpack = snowpack.tolist()

# or a sequence ?
if lib.is_sequence(snowpack):
if snowpack_dimension is None:
snowpack_dimension = "snowpack", None
if snowpack_dimension[1] is None:
snowpack_dimension = snowpack_dimension[0], range(len(snowpack))

if isinstance(snowpack_dimension, tuple) and not isinstance(snowpack_dimension[0], str):
raise SMRTError("When the 'snowpack_dimension' argument is a tuple, the first argument must be a string")

# the sensor object is split in its basic sensors (config). How deep the sensor is split depends on the
# radiative transfer solver's broadcast capability.
rt_solver_broadcast_capability = getattr(self.rtsolver, "_broadcast_capability", [])
Expand All @@ -239,7 +248,7 @@ def prepare_recursive(sensor, sensor_configurations):
else: # we're at the end
if lib.is_sequence(snowpack):
for sp in snowpack:
yield (sensor, sp)
yield (sensor, sp)
else:
yield (sensor, snowpack)

Expand Down
17 changes: 12 additions & 5 deletions smrt/core/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ def sigma(self, channel=None, **kwargs):

return _strongsqueeze(self.sel_data(channel=channel, return_backscatter="natural", **kwargs))

def sigma_dB(self, **kwargs):
def sigma_dB(self, channel=None, **kwargs):
"""Return backscattering coefficient. Any parameter can be added to slice the results (e.g. frequency=37e9, polarization_inc='V', polarization='V').
See xarray slicing with sel method (to document)"""

Expand Down Expand Up @@ -411,22 +411,29 @@ def concat_results(result_list, coord):
"""

dim_name, dim_value = coord
if isinstance(coord, tuple):
dim_name, dim_value = coord

ResultClass = type(result_list[0])
index = pd.Index(dim_value, name=dim_name)
elif isinstance(coord, pd.Index):
index = coord
else:
raise SMRTError('unknown type for the coord argument')

ResultClass = type(result_list[0])
if not all([type(result) == ResultClass for result in result_list]):
raise SMRTError("The results are not all of the same type")

# channel_map ?
if any((res.channel_map != result_list[0].channel_map for res in result_list)):
assert isinstance(coord, tuple)
# different channel maps, it means we have different sensors. Merge de sensor maps.
channel_map = {ch: dict(**r.channel_map[ch], **{dim_name: dv}) for r, dv in zip(result_list, dim_value) for ch in r.channel_map}
channel_map = {ch: dict(**r.channel_map[ch], dim_name=dv) for r, dv in zip(result_list, dim_value) for ch in r.channel_map}
else:
# all the channel maps are the same
channel_map = result_list[0].channel_map

return ResultClass(xr.concat([result.data for result in result_list], pd.Index(dim_value, name=dim_name)),
return ResultClass(xr.concat([result.data for result in result_list], index),
channel_map=channel_map)


Expand Down

0 comments on commit 87c9b5b

Please sign in to comment.