Exemplo n.º 1
0
 def setup_method(self):
     """
     This ensures a new Workspace for every test.
     """
     self.dir = os.path.dirname(os.path.realpath(__file__))
     self.ws = Workspace(verbosity=0)
     self.setup_workspace()
Exemplo n.º 2
0
 def test_variable_create(self):
     """
     Test initialization of workspace variables.
     """
     self.ws = Workspace()
     self.ws.IndexCreate("myindex")
     with pytest.raises(Exception):
         print(self.ws.myindex.value)
Exemplo n.º 3
0
def configure_workspace(verbosity=0):
    """Configures the ARTS application.

    Args:
        verbosity: ARTS verbosity level.

    Returns:
        A Workspace object.
    """
    workspace = Workspace(verbosity=0)
    for name in ["general", "continua", "agendas"]:
        workspace.execute_controlfile(join("general", "{}.arts".format(name)))
    workspace.verbositySetScreen(workspace.verbosity, verbosity)
    workspace.jacobianOff()
    workspace.Copy(workspace.abs_xsec_agenda, workspace.abs_xsec_agenda__noCIA)
    workspace.AtmosphereSet1D()
    return workspace
Exemplo n.º 4
0
    def setup(self, verbosity=0):

        self.verbosity  = verbosity
        self._workspace = Workspace(verbosity=verbosity,
                                    agenda_verbosity=verbosity)
        ws = self._workspace
        for include in self.includes:
            ws.execute_controlfile(include)

        ws.Copy(ws.ppath_agenda, ws.ppath_agenda__FollowSensorLosPath)
        ws.Copy(ws.ppath_step_agenda, ws.ppath_step_agenda__GeometricPath)
        ws.Copy(ws.iy_space_agenda, ws.iy_space_agenda__CosmicBackground)
        ws.Copy(ws.iy_surface_agenda, ws.iy_surface_agenda__UseSurfaceRtprop)
        ws.Copy(ws.iy_main_agenda, ws.iy_main_agenda__Emission)

        self.atmosphere.setup(ws, self.sensors)

        for s in self.sensors:
            s.setup(ws, self.atmosphere.scattering)

        self._setup = True
Exemplo n.º 5
0
def test_dimension_broadcast():
    """
    Test propagation of dimension information for ARTS properties
    as well as broadcasting.
    """
    class A(ArtsObject):
        def __init__(self):
            super().__init__()
            pass

        @arts_property("Vector", shape=(dim.P, ), wsv=wsv["p_grid"])
        def p_grid():
            return None

        @arts_property("Tensor3",
                       shape=(dim.P, dim.Lat, dim.Lon),
                       wsv=wsv["t_field"])
        def temperature(self):
            return None

    class TProvider:
        def __init__(self):
            pass

        def get_temperature(self):
            return np.ones((1, 3, 5))

    ws = Workspace()
    a = A()
    dp = TProvider()

    a.p_grid = np.zeros(4)

    a.setup_arts_properties(ws)
    a.get_data_arts_properties(ws, dp)

    assert (ws.t_field.value.shape[0] == 4)
    assert (np.all(ws.p_grid.value == np.zeros(4)))
Exemplo n.º 6
0
from pyarts.workspace import Workspace
from pyarts.classes.EnergyLevelMap import EnergyLevelMap
from pyarts.classes import from_workspace

# Get a workspace
ws = Workspace()
datapath = "../"

elm1 = EnergyLevelMap()
elm1.readxml(datapath +
             "controlfiles/artscomponents/nlte/testdata/nlte_testdata.xml")
ws.ReadXML(
    ws.nlte_field,
    datapath + "controlfiles/artscomponents/nlte/testdata/nlte_testdata.xml")
elm2 = from_workspace(ws.nlte_field)

assert elm1, "Bad read"
assert elm1 == elm2, "Bad read"
assert elm1.data

elm3 = EnergyLevelMap()
elm3.set(elm1)

assert elm3 == elm2

elm4 = EnergyLevelMap()
elm1.savexml("tmp.elm.xml", "binary")
elm4.readxml("tmp.elm.xml")
assert elm4 == elm1
Exemplo n.º 7
0
"""
The surface sub-module provides implementations of the different surface models
that are available in ARTS.
"""
from abc import abstractmethod, abstractproperty
import numpy as np
import os

from artssat.arts_object import ArtsObject, arts_property, Dimension
from pyarts.workspace import Workspace, arts_agenda
from pyarts.workspace.variables import (WorkspaceVariable, workspace_variables)
wsv = workspace_variables

ws = Workspace(verbosity = 0)


class Surface:
    """
    Abstract base class for surfaces.

    This class defines the general interfaces for surface models in artssat.
    """

    @abstractproperty
    def required_data(self):
        pass

    @abstractmethod
    def setup(self, ws):
        """
        Setup the surface model in the given workspace.
Exemplo n.º 8
0
    def __init__(self,
                 ws=None,
                 threads=None,
                 nstreams=4,
                 scale_vmr=True,
                 verbosity=0):
        """Initialize a wrapper for an ARTS workspace.

        Parameters:
            ws (pyarts.workspace.Workspace): An ARTS workspace.
            threads (int): Number of threads to use.
                Default is all available threads.
            nstreams (int): Number of viewing angles to base the radiative
                flux calculation on.
            scale_vmr (bool): Control whether dry volume mixing ratios are
                scaled with the water-vapor concentration (default is `False.`)
            verbosity (int): Control the ARTS verbosity from 0 (quiet) to 2.
        """
        from pyarts.workspace import Workspace, arts_agenda

        self.nstreams = nstreams
        self.scale_vmr = scale_vmr

        if ws is None:
            self.ws = Workspace(verbosity=verbosity)

        self.ws.execute_controlfile("general/general.arts")
        self.ws.execute_controlfile("general/continua.arts")
        self.ws.execute_controlfile("general/agendas.arts")
        self.ws.execute_controlfile("general/planet_earth.arts")

        # Agenda settings
        self.ws.Copy(self.ws.abs_xsec_agenda, self.ws.abs_xsec_agenda__noCIA)
        self.ws.Copy(self.ws.iy_main_agenda, self.ws.iy_main_agenda__Emission)
        self.ws.Copy(self.ws.iy_space_agenda,
                     self.ws.iy_space_agenda__CosmicBackground)
        self.ws.Copy(self.ws.iy_surface_agenda,
                     self.ws.iy_surface_agenda__UseSurfaceRtprop)
        self.ws.Copy(
            self.ws.propmat_clearsky_agenda,
            self.ws.propmat_clearsky_agenda__LookUpTable,
        )
        self.ws.Copy(self.ws.ppath_agenda,
                     self.ws.ppath_agenda__FollowSensorLosPath)
        self.ws.Copy(self.ws.ppath_step_agenda,
                     self.ws.ppath_step_agenda__GeometricPath)

        @arts_agenda
        def p_eq_agenda(workspace):
            workspace.water_p_eq_fieldMK05()

        self.ws.Copy(self.ws.water_p_eq_agenda, p_eq_agenda)

        @arts_agenda
        def cloudbox_agenda(workspace):
            workspace.iyInterpCloudboxField()

        self.ws.Copy(self.ws.iy_cloudbox_agenda, cloudbox_agenda)

        # Number of Stokes components to be computed
        self.ws.IndexSet(self.ws.stokes_dim, 1)

        self.ws.jacobianOff()  # No jacobian calculation
        self.ws.cloudboxOff()  # Clearsky = No scattering

        # Set Absorption Species
        self.ws.abs_speciesSet(species=[
            "O2, O2-CIAfunCKDMT100",
            "H2O, H2O-SelfContCKDMT252, H2O-ForeignContCKDMT252",
            "O3",
            "CO2, CO2-CKDMT252",
            "N2, N2-CIAfunCKDMT252, N2-CIArotCKDMT252",
            "N2O",
            "CH4",
            "CO",
        ])

        # Surface handling
        self.ws.VectorSetConstant(self.ws.surface_scalar_reflectivity, 1, 0.0)
        self.ws.Copy(
            self.ws.surface_rtprop_agenda,
            self.ws.
            surface_rtprop_agenda__Specular_NoPol_ReflFix_SurfTFromt_surface,
        )

        # Read lookup table
        abs_lookup = os.getenv("KONRAD_LOOKUP_TABLE",
                               join(dirname(__file__), "data/abs_lookup.xml"))

        if not isfile(abs_lookup):
            raise FileNotFoundError(
                "Could not find ARTS absorption lookup table.\n"
                "To perform ARTS calculations you have to download the lookup "
                "table at:\n\n    https://doi.org/10.5281/zenodo.3885410\n\n"
                "Afterwards, use the following environment variable to tell "
                "konrad where to find it:\n\n"
                "    $ export KONRAD_LOOKUP_TABLE='/path/to/abs_lookup.xml'")

        self.ws.ReadXML(self.ws.abs_lookup, abs_lookup)
        self.ws.f_gridFromGasAbsLookup()
        self.ws.abs_lookupAdapt()

        # Sensor settings
        self.ws.sensorOff()  # No sensor properties

        # Atmosphere
        self.ws.AtmosphereSet1D()

        # Set number of OMP threads
        if threads is not None:
            self.ws.SetNumberOfThreads(threads)
Exemplo n.º 9
0
 def setup_method(self):
     """
     This ensures a new Workspace for every test.
     """
     self.ws = Workspace(verbosity = 0)
     self.setup_workspace()
Exemplo n.º 10
0
class ActiveSensor(Sensor):
    """
    Specialization of the abstract :code:`Sensor` class that implements
    active sensors (Radar).

    """
    ws = Workspace()
    extinction_scaling = ws.create_variable("Numeric", "extinction_scaling")
    private_wsvs = Sensor.private_wsvs + [
        "range_bins", "instrument_pol_array", "instrument_pol",
        "iy_transmitter_agenda", "extinction_scaling"
    ]

    ############################################################################
    # ARTS properties
    ############################################################################

    @arts_property("Numeric", wsv="extinction_scaling")
    def extinction_scaling(self):
        return 1.0

    @arts_property("Numeric")
    def k2(self):
        return -1.0

    @arts_property("Numeric")
    def y_min(self):
        return -35.0

    @arts_property("Vector", shape=(dim.Joker, ), wsv=wsv["range_bins"])
    def range_bins(self):
        return []

    @arts_property("ArrayOfIndex", wsv=wsv["instrument_pol"])
    def instrument_pol(self):
        return [1]

    @arts_property("ArrayOfArrayOfIndex", wsv=wsv["instrument_pol_array"])
    def instrument_pol_array(self):
        return [[1]]

    @property
    def y_vector_length(self):
        return (self.range_bins.size -
                1) * self.f_grid.size * self.stokes_dimension

    def __init__(self, name, f_grid, stokes_dimension, range_bins=None):
        super().__init__(name, f_grid, stokes_dimension=stokes_dimension)
        self.iy_unit = "dBZe"

        if not range_bins is None:
            self.range_bins = range_bins

    #
    # Agendas
    #

    @property
    def iy_transmitter_agenda(self):
        """
        The :code:`iy_transmitter_agenda` which is required for active
        sensors. Input arguments of :code:`iy_transmitter_agenda` are
        replaced by the private workspace variables of the sensor.

        Returns:

            The iy_transmitter_agenda for the active sensor.

        """
        kwargs = self.get_wsm_kwargs(wsm["iy_transmitterSinglePol"])

        @arts_agenda
        def iy_transmitter_agenda(ws):
            ws.Ignore(ws.rtp_pos)
            ws.Ignore(ws.rtp_los)
            ws.Ignore(ws.f_grid)
            ws.iy_transmitterSinglePol(**kwargs)

        return iy_transmitter_agenda

    def make_iy_main_agenda(self, scattering=False):
        """
        The :code: `iy_main_agenda` for active sensor. Currently uses
        the single scattering radar module, but might be extended
        at some point.
        """

        kwargs = self.get_wsm_kwargs(wsm["iyActiveSingleScat2"])

        @arts_agenda
        def iy_main_agenda(ws):
            ws.Ignore(ws.iy_id)
            ws.Ignore(ws.nlte_field)
            ws.Ignore(ws.rte_pos2)
            ws.Ignore(ws.iy_unit)
            ws.Ignore(ws.iy_aux_vars)
            ws.FlagOff(ws.cloudbox_on)
            ws.ppathCalc()
            ws.FlagOn(ws.cloudbox_on)
            ws.iyActiveSingleScat(
                **kwargs,
                pext_scaling=self._wsvs["extinction_scaling"],
                trans_in_jacobian=1)

        return iy_main_agenda

    #
    # Specialized setters
    #

    def iy_unit_setter(self, u):
        if not u in ["1", "Ze", "dBZe"]:
            raise Exception("Value of iy_unit for an active sensor must"
                            " be one of ['1', 'Ze', 'dBZe']")
        else:
            self._iy_unit.value = u
            self._iy_unit.fixed = True

    def iy_aux_vars_setter(self, v):
        if not type(v) == list:
            v = [v]
        if not all([
                u in [
                    "Radiative background", "Backsacttering", "Optical depth",
                    "Particle extinction"
                ] for u in v
        ]):
            raise Exception("Value of iy_aux_vars for an active sensor must"
                            " be a list consisting of the following strings: "
                            "['RadiativeBackground', 'Backscattering', "
                            "'Optical depth', Particle extinction'].")
        else:
            self._iy_aux_vars.value = v
            self._iy_aux_vars.fixed = False

    #
    # Preparation and y_calc factories.
    #

    def make_preparation_function(self):
        """
        Return the workspace preparation function, which prepares
        a workspace for simulating the signal recorded by the sensor.

        Returns:

            The function to prepare the workspace.

        """
        def preparations(ws):
            ws.IndexSet(ws.stokes_dim, self.stokes_dimension)
            #ws.Copy(ws.iy_transmitter_agenda,
            #        self._wsvs["iy_transmitter_agenda"])
            #ws.Copy(ws.iy_main_agenda,
            #        self._wsvs["_iy_main_agenda"])
            #ws.Copy(ws.instrument_pol, self._wsvs["instrument_pol"])
            #ws.IndexSet(self._wsvs["_stokes_dim"], self.stokes_dimension)
            #ws.IndexSet(ws.stokes_dim, self.stokes_dimension)

        return preparations

    def make_y_calc_function(self, append=False, scattering=False):
        """
        Returns y_calc function, which computes the radar signal
        on an accordingly prepared workspace. This function can
        be converted into an ARTS agenda and thus included in
        the other agendas using the INCLUDE statement.

        Returns:

            The function to compute the radar signal.
        """
        if append:
            raise Exception("ARTS doesn't support appending measurements from"
                            " active sensors.")

        kwargs = self.get_wsm_kwargs(wsm["yActive"])

        if self.y_min:
            y_min = self.y_min
        else:
            y_min = -np.inf

        def y_calc(ws):
            ws.yActive(dbze_min=y_min, k2=self.k2, **kwargs)

        return y_calc

    #
    # Setup
    #

    def setup(self, ws, scattering=True):
        super().setup(ws, scattering)
        self._wsvs["iy_transmitter_agenda"].value = self.iy_transmitter_agenda