예제 #1
0
def test_concat_results():

    allresult = result.concat_results((res_example, res_example2),
                                      coord=('dim0', [0, 1]))
    print(allresult)
    assert 'dim0' in allresult.data.dims
    assert len(allresult.data['dim0']) == 2
예제 #2
0
def test_concat_results_other_data():

    res = copy.deepcopy(res_example)
    res2 = copy.deepcopy(res_example2)

    res.other_data['other_value'] = xr.DataArray([0.1, 0.2],
                                                 coords=[('layer', [0, 1])])

    res2.other_data['other_value'] = xr.DataArray([0.2, 0.3],
                                                  coords=[('layer', [0, 1])])

    allresult = result.concat_results((res, res2), coord=('dim0', [0, 1]))

    assert allresult.other_data['other_value'].dims == ('dim0', 'layer')
예제 #3
0
def run(sensor, snowpack, ke_option=0, grainsize_option=1, hut_path=None):
    """call HUT for the snowpack and sensor configuration given as argument. Any microstructure model that defines the "radius" parameter
    is valid.

    :param snowpack: describe the snowpack.
    :param sensor: describe the sensor configuration.
    :param ke_option: see HUT snowemis_nlayers.m code
    :param grainsize_option: see HUT snowemis_nlayers.m code
"""

    if hut_path is not None:
        set_hut_path(hut_path)

    if isinstance(snowpack, collections.Sequence):
        result_list = [run(sensor, sp, ke_option=ke_option, grainsize_option=grainsize_option) for sp in snowpack]
        return concat_results(result_list, ('snowpack', range(len(snowpack))))

    if snowpack.substrate is not None:
        Tg = snowpack.substrate.temperature
        roughness_rms = getattr(snowpack.substrate, "roughness_rms", 0)
        soil_eps = snowpack.substrate.permittivity(sensor.frequency, Tg)
    else:
        Tg = 273.0
        roughness_rms = 0
        soil_eps = 1

    snow = []  # snow is a N Layer (snowpack+soil) row and 8 columns. Each colum has a data (see snowemis_nlayer)
    enough_warning = False

    for lay in snowpack.layers:
        density = lay.frac_volume * 917.0
        snow.append((lay.temperature-273.15, lay.thickness*density, 2000*lay.microstructure.radius, density/1000,
                     lay.liquid_water, lay.salinity, 0, 0))
        if lay.salinity and enough_warning:
            print("Warning: salinity in HUT is ppm")
            enough_warning = True
    # ground
    snow.append((Tg-273.15, 0, 0, 0, 0, 0, roughness_rms, soil_eps))

    thetad = np.degrees(sensor.theta)
    TbV = [octave.snowemis_nlayer(otulo, snow,  sensor.frequency/1e9, 0, ke_option, grainsize_option) for otulo in thetad]
    TbH = [octave.snowemis_nlayer(otulo, snow,  sensor.frequency/1e9, 1, ke_option, grainsize_option) for otulo in thetad]

    coords = [('theta', sensor.theta), ('polarization', ['V', 'H'])]

    return Result(np.vstack((TbV, TbH)).T, coords)
예제 #4
0
def run(sensor,
        snowpack,
        scattering_choice=ABORN,
        atmosphere=None,
        memls_path=None,
        memls_driver=None,
        snowpack_dimension=None):
    """ call MEMLS for the snowpack and sensor configuration given as argument. Any microstructure model that defines the "corr_length" parameter
        is valid, but it must be clear that MEMLS only considers exponential autocorrelation.

        :param snowpack: describe the snowpack.
        :param sensor: describe the sensor configuration.
        :param scattering_choice: MEMLS proposes several formulation to compute scattering_function. scattering_choice=ABORN (equals 12) is the default
            here and is recommended choice to compare with IBA. Note that some comments in memlsmain.m suggest to use 
            scattering_choice=MEMLS_RECOMMENDED (equals 11). Note also that the default grain type in memlsmain is graintype=1 
            corresponding to oblate spheroidal calculation of effective permittivity from the empirical representation of depolarization factors. To use a Polder-Van Santen representation of effective permittivity for small spheres, graintype=2 must be set in your local copy of MEMLS.
        :param atmosphere: describe the atmosphere. Only tbdown is used for the Tsky argument of memlsmain.
        :param memls_path: directory path to the memls Matlab scripts
        :param memls_driver: matlab function to call to run memls. memlsmain.m is the default driver in the original MEMLS distribution for the passive case and amemlsmain.m for the active case.
        :param snowpack_dimension: name and values (as a tuple) of the dimension to create for the results when a list of snowpack is provided. E.g. time, point, longitude, latitude. By default the dimension is called 'snowpack' and the values are from 1 to the number of snowpacks.


"""

    if memls_path is not None:
        set_memls_path(memls_path)

    if isinstance(sensor.frequency, Sequence) or isinstance(
            sensor.frequency, np.ndarray):
        raise SMRTError(
            "Sensor must have a single frequency for running memls_legagcy")

    if isinstance(snowpack, SensitivityStudy):
        snowpack_dimension = (snowpack.variable, snowpack.values)
        snowpack = snowpack.snowpacks.tolist()

    if isinstance(snowpack, Sequence):
        result_list = [
            run(sensor,
                sp,
                scattering_choice=scattering_choice,
                atmosphere=atmosphere,
                memls_driver=memls_driver) for sp in snowpack
        ]
        if snowpack_dimension is None:
            snowpack_dimension = 'snowpack', range(len(snowpack))
        return concat_results(result_list, snowpack_dimension)

    Tsky = atmosphere.tbdown(sensor.frequency, np.cos(sensor.theta),
                             1) if atmosphere is not None else 0
    Tgnd = snowpack.substrate.temperature if snowpack.substrate is not None else 273

    if snowpack.substrate is None:
        ground_reflH = itertools.repeat(0)
        ground_reflV = itertools.repeat(0)
    else:
        print(
            "Using MEMLS with substrate has not been tested. Provide feeback if it works (or not)"
        )
        eps_1 = snowpack.layers[-1].permittivity(1, sensor.frequency)
        print(
            "Warning: the permittivity of the ice in the last layer is used instead of the effective permittivity to compute the reflection of the subtrate. This is an approximation that needs to be changed. Please contact developer for any serious simulations with soil..."
        )
        m = snowpack.substrate.specular_reflection_matrix(
            sensor.frequency, eps_1, np.cos(sensor.theta), 2)
        ground_reflH = m.diagonal()[1::2]
        ground_reflV = m.diagonal()[0::2]

    # prepare the input file in a temporary file
    with NamedTemporaryFile("w", delete=False) as f:
        #     layer-number, temp [K], volume fraction of liquid water, density [kg/m3],
        # thickness [cm], Salinity (0 - 0.1) [ppt], expon.corr.length [mm]

        for ilay, lay in enumerate(reversed(snowpack.layers)):
            f.write("%i, %g, %g, %g, %g, %g, %g\n" %
                    (ilay + 1, lay.temperature, lay.liquid_water,
                     lay.frac_volume * DENSITY_OF_ICE, lay.thickness * 100.0,
                     lay.salinity, lay.microstructure.corr_length * 1000.))

    # uncomment these lines if you need to check the input file content.
    #with open(f.name) as ff:
    #    print(ff.readlines())

    if memls_driver is None:
        memls_driver = "memlsmain" if sensor.mode == 'P' else "amemlsmain"

    memlsfct = getattr(octave, memls_driver)

    if sensor.mode == 'P':
        res = [
            memlsfct(sensor.frequency * 1e-9, thetad,
                     float(reflH), float(reflV), f.name, float(Tsky),
                     float(Tgnd), scattering_choice) for thetad, reflH, reflV
            in zip(sensor.theta_deg, ground_reflH, ground_reflV)
        ]
        res = np.vstack(res)
        coords = [('theta', sensor.theta_deg), ('polarization', ['V', 'H'])]

    else:  # active
        mean_slope = 1e3  # a high value to remove this contribution. But in the future should be taken from the substrate model, depending on the model...
        res = [
            memlsfct(sensor.frequency * 1e-9, thetad, float(reflH),
                     float(reflV), float(reflH), float(reflV), f.name,
                     float(Tsky), float(Tgnd), scattering_choice, mean_slope,
                     0)['sigma0'][0, :] for thetad, reflH, reflV in zip(
                         sensor.theta_inc_deg, ground_reflH, ground_reflV)
        ]

        coords = [('polarization', ['V', 'H']),
                  ('polarization_inc', ['V', 'H']),
                  ('theta_inc', sensor.theta_inc_deg),
                  ('theta', sensor.theta_deg)]
        res = np.array(res)
        norm = 4 * np.pi * np.cos(
            sensor.theta)  # convert back backscattering coefficient
        # assemble in the polarizations
        res = [[np.diagflat(res[:, 0] / norm),
                np.diagflat(res[:, 2] / norm)],
               [np.diagflat(res[:, 2] / norm),
                np.diagflat(res[:, 1]) / norm]]

    os.unlink(f.name)

    return Result(res, coords)
예제 #5
0
def run(sensor,
        snowpack,
        dmrt_qms_path=None,
        snowpack_dimension=None,
        full_output=False):
    """call DMRT-QMS for the snowpack and sensor configuration given as argument. The :py:mod:`~smrt.microstructure_model.sticky_hard_spheres` microstructure model 
    must be used.

    :param snowpack: describe the snowpack.
    :param sensor: describe the sensor configuration.
    :param full_output: determine if ks, ka and effective permittivity are return in addition to the result object
"""

    if dmrt_qms_path is not None:
        set_dmrt_qms_path(dmrt_qms_path)

    if isinstance(snowpack, SensitivityStudy):
        snowpack_dimension = (snowpack.variable, snowpack.values)
        snowpack = snowpack.snowpacks.tolist()

    if isinstance(snowpack, Sequence):
        result_list = [run(sensor, sp) for sp in snowpack]
        if snowpack_dimension is None:
            snowpack_dimension = 'snowpack', range(len(snowpack))
        return concat_results(result_list, snowpack_dimension)

    Tg = snowpack.substrate.temperature if snowpack.substrate is not None else 273.0

    rough = Struct()

    if snowpack.substrate is None:
        rough.model = 'QH'
        epsr_ground = complex(1.0, 0.0)
        rough.Q = 0.0
        rough.H = 0.0
    elif hasattr(snowpack.substrate, "Q") and hasattr(snowpack.substrate, "H"):
        rough.model = 'QH'
        epsr_ground = snowpack.substrate.permittivity_model(
            sensor.frequency, Tg)
        rough.Q = snowpack.substrate.Q
        rough.H = snowpack.substrate.H
        if hasattr(snowpack.substrate, "N") and snowpack.substrate.N != 2:
            print(
                "Warning: DMRT QMS with QH model assumes N=2. You should set N=2 to avoid this warning."
            )

    elif hasattr(snowpack.substrate, "roughness_rms"):
        print(
            "Warning: DMRT-QMS does not implement the same version of the Wegmuller & Mazler model"
        )
        rough.model = 'WM'
        epsr_ground = snowpack.substrate.permittivity_model(
            sensor.frequency, Tg)
        rough.s = snowpack.substrate.roughness_rms

    diameter = np.float64(
        [lay.microstructure.radius * 200 for lay in snowpack.layers])
    density = np.float64(
        [lay.frac_volume * DENSITY_OF_ICE / 1000 for lay in snowpack.layers])
    thickness = np.float64([lay.thickness * 100.0 for lay in snowpack.layers])
    stickiness = np.float64([
        min(lay.microstructure.stickiness, 1000.0) for lay in snowpack.layers
    ])
    temperature = np.float64([lay.temperature for lay in snowpack.layers])

    TbV, TbH, deg0, ot, albedo, epsr_snow = octave.DMRT_QMS_passive(
        sensor.frequency * 1e-9,
        diameter,
        density,
        stickiness,
        thickness,
        temperature,
        Tg,
        epsr_ground,
        rough,
        nout=6)

    # squeeze extra dimension
    deg0 = deg0.squeeze()

    # interpolate
    TbV = np.interp(np.degrees(sensor.theta), deg0, TbV.squeeze())
    TbH = np.interp(np.degrees(sensor.theta), deg0, TbH.squeeze())

    coords = [('theta', sensor.theta), ('polarization', ['V', 'H'])]

    if full_output:
        ke = ot / np.array([lay.thickness for lay in snowpack.layers])
        ks = albedo * ke
        ka = (1 - albedo) * ke
        return Result(np.vstack([TbV, TbH]).T, coords), ks, ka, epsr_snow
    else:
        return Result(np.vstack([TbV, TbH]).T, coords)