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()
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)
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
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
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)))
import os from pyarts.workspace import Workspace from pyarts.classes.SpeciesAuxData import SpeciesAuxData from pyarts.classes import from_workspace # Get a workspace ws = Workspace() datapath = "../../arts-xml-data/" if not os.getenv( "ARTS_XML_DATA_DIR") else os.getenv("ARTS_XML_DATA_DIR") fn = os.path.join(datapath, 'planets/Mars/isotopratio_Mars.xml') sad1 = SpeciesAuxData() sad1.readxml(fn) sad2 = from_workspace(ws.isotopologue_ratios) ws.ReadXML(ws.isotopologue_ratios, fn) sad3 = SpeciesAuxData() sad3.set(sad2) sad4 = SpeciesAuxData() sad1.savexml("tmp.sad.xml", "binary") sad4.readxml("tmp.sad.xml") assert sad1 == sad4 assert sad1 == sad2 assert sad1 == sad3
import os from pyarts.workspace import Workspace from pyarts.classes import from_workspace from pyarts.classes.AbsorptionLines import AbsorptionLines, ArrayOfAbsorptionLines ws = Workspace() datapath = "../../arts-xml-data/" if not os.getenv( "ARTS_XML_DATA_DIR") else os.getenv("ARTS_XML_DATA_DIR") fn1 = os.path.join(datapath, 'spectroscopy/Artscat/') fn2 = os.path.join(datapath, 'spectroscopy/Artscat/O2-66.xml') # Init al = AbsorptionLines() aal = ArrayOfAbsorptionLines() aaal = from_workspace(ws.abs_lines_per_species) # Init is as expected assert al.selfbroadening == False, "Bad init" assert al.bathbroadening == False, "Bad init" assert al.cutoff == "None", "Bad init" assert al.mirroring == "None", "Bad init" assert al.population == "LTE", "Bad init" assert al.normalization == "None", "Bad init" assert al.lineshapetype == "VP", "Bad init" assert al.t0 == 296, "Bad init" assert al.cutofffreq == -1, "Bad init" assert al.linemixinglimit == -1, "Bad init" assert al.quantumidentity.spec_ind == -1, "Bad init" assert al.quantumidentity.type == "None", "Bad init" assert not al.localquantumnumbers, "Bad init" assert not al.broadeningspecies, "Bad init"
def setup_method(self): """ This ensures a new Workspace for every test. """ self.ws = Workspace(verbosity = 0) self.setup_workspace()
class TestVariables: """ Tests the manipulation of workspace variables. """ 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() def setup_workspace(self): ws = self.ws ws.atmosphere_dim = 1 ws.p_grid = np.linspace(1e5, 1e3, 21) ws.Touch(ws.lat_grid) ws.Touch(ws.lon_grid) ws.f_grid = 183.0e9 * np.ones(1) ws.stokes_dim = 1 ws.sensor_los = 180.0 * np.ones((1, 1)) ws.sensor_pos = 830e3 * np.ones((1, 1)) ws.sensorOff() def test_index_transfer(self): """ Create and set Index WSV. """ self.ws.IndexCreate("index_variable") i = np.random.randint(0, 100) self.ws.index_variable = i assert self.ws.index_variable.value == i def test_string_transfer(self): """ Create and set String WSV. """ self.ws.StringCreate("string_variable") s = "some random string." self.ws.string_variable = s assert self.ws.string_variable.value == s def test_array_of_index_transfer(self): """ Create and set ArrayOfIndex WSV. """ self.ws.ArrayOfIndexCreate("array_of_index_variable") i = [np.random.randint(0, 100) for j in range(10)] self.ws.array_of_index_variable = i assert self.ws.array_of_index_variable.value == i self.ws.array_of_index_variable = [] assert self.ws.array_of_index_variable.value == [] def test_array_of_vector_transfer(self): """ Create and set ArrayOfVector WSV. """ self.ws.ArrayOfVectorCreate("array_of_vector_variable") aov = pyarts.xml.load( os.path.join(self.dir, "../xml/reference/arrayofvector.xml")) self.ws.array_of_vector_variable = aov assert self.ws.array_of_vector_variable.value == aov def test_vector_transfer(self): """ Create and set Vector WSV. """ self.ws.VectorCreate("vector_variable") v = np.random.rand(10) self.ws.vector_variable = v assert all(self.ws.vector_variable.value == v) def test_matrix_transfer(self): """ Create and set Matrix WSV. """ self.ws.MatrixCreate("matrix_variable") m = np.random.rand(10, 10) self.ws.matrix_variable = m assert all(self.ws.matrix_variable.value.ravel() == m.ravel()) def test_sparse_transfer(self): """ Create and set Sparse WSV. """ n = 100 d2 = np.ones(n - 2) d1 = np.ones(n - 1) d = np.ones(n) m = sp.sparse.diags(diagonals=[d2, d1, d, d1, d2], offsets=[2, 1, 0, -1, -2]) self.ws.sensor_response = m assert np.all(m.toarray() == self.ws.sensor_response.value.toarray()) def test_tensor_3(self): """ Create and set Tensor3 variable. """ t_0 = np.random.rand(*([3] * 3)) self.ws.Tensor3Create("tensor_3") self.ws.tensor_3 = t_0 assert np.all(t_0 == self.ws.tensor_3.value) def test_tensor_4(self): """ Create and set Tensor4 variable. """ t_0 = np.random.rand(*([3] * 4)) t_1 = self.ws.Tensor4Create("tensor_4") self.ws.tensor_4 = t_0 assert np.all(t_0 == self.ws.tensor_4.value) def test_tensor_5(self): """ Create and set Tensor5 variable. """ t_0 = np.random.rand(*([3] * 5)) t_1 = self.ws.Tensor5Create("tensor_5") self.ws.tensor_5 = t_0 assert np.all(t_0 == self.ws.tensor_5.value) def test_tensor_6(self): """ Create and set Tensor6 variable. """ t_0 = np.random.rand(*([3] * 6)) t_1 = self.ws.Tensor6Create("tensor_6") self.ws.tensor_6 = t_0 assert np.all(t_0 == self.ws.tensor_6.value) def test_tensor_7(self): """ Create and set Tensor7 variable. """ t_0 = np.random.rand(*([3] * 7)) self.ws.Tensor7Create("tensor_7") self.ws.tensor_7 = t_0 assert np.all(t_0 == self.ws.tensor_7.value) def test_time(self): """ Create and set Time variable. """ times = ["2020-01-02 03:04:05", "2021-02-03 04:05:06"] self.ws.ArrayOfTimeCreate("time_1") self.ws.ArrayOfTimeNLinSpace(self.ws.time_1, 2, times[0], times[1]) assert (times[0] == str(self.ws.time_1.value[0])[0:19] and times[1] == str(self.ws.time_1.value[1])[0:19]) def test_creation(self): """ Test creation of WSVs. """ self.ws.ArrayOfIndexCreate("array_of_index") self.ws.ArrayOfIndexCreate("array_of_index") with pytest.raises(Exception): self.ws.VectorCreate("array_of_index") def test_covariance_matrix(self): """ Test manipulation of CorvarianceMatrix objects. """ ws = self.ws ws.jacobianInit() ws.jacobianAddAbsSpecies(species="O3", g1=ws.p_grid, g2=ws.lat_grid, g3=ws.lon_grid) ws.jacobianAddAbsSpecies(species="H2O", g1=ws.p_grid, g2=ws.lat_grid, g3=ws.lon_grid) ws.jacobianClose() ws.covmatDiagonal(out=ws.covmat_block, out_inverse=ws.covmat_block, vars=10.0 * np.ones(ws.p_grid.value.size)) ws.covmat_sxAddBlock(block=ws.covmat_block) ws.covmatDiagonal(out=ws.covmat_block, out_inverse=ws.covmat_block, vars=20.0 * np.ones(ws.p_grid.value.size)) ws.covmat_sxAddBlock(block=ws.covmat_block) def test_variable_creation(self): """ Test creation of named and unnambed WSVs. """ # Unnamed variable wsv = self.ws.create_variable("Matrix", None) self.ws.__setattr__(wsv.name, np.eye(5)) assert np.all( np.isclose(np.eye(5), self.ws.__getattr__(wsv.name).value)) # Named variable wsv = self.ws.create_variable("Matrix", "matrix_wsv") self.ws.matrix_wsv = np.eye(5) assert np.all(np.isclose(np.eye(5), self.ws.matrix_wsv.value)) def test_variable_set_empty(self): """ Test initialization of workspace variables. """ self.ws.f_grid = np.array([94e9]) self.ws.f_grid = [] assert self.ws.f_grid.value.size == 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) def test_convert(self): """ Test automatic conversion of Python types. """ v = WorkspaceVariable.convert("Index", 1.2) assert (v == 1) v = WorkspaceVariable.convert("String", "string") assert (v == "string") v = WorkspaceVariable.convert("Numeric", 1) assert (type(v) == np.float64) v = WorkspaceVariable.convert("Vector", 1.0) assert (v.shape == (1, )) v = WorkspaceVariable.convert("Matrix", 1.0) assert (v.shape == (1, 1)) v = WorkspaceVariable.convert("Tensor3", 1.0) assert (v.shape == (1, 1, 1)) v = WorkspaceVariable.convert("Tensor6", 1.0) assert (v.shape == (1, 1, 1, 1, 1, 1)) v = WorkspaceVariable.convert("ArrayOfArrayOfIndex", 1.0) assert (type(v) == list) assert (type(v[0]) == list) assert (type(v[0][0]) == int) v = WorkspaceVariable.convert("ArrayOfArrayOfIndex", 1) return v
from time import sleep from math import isclose from pyarts.workspace import Workspace from pyarts.classes.Timer import Timer from pyarts.classes import from_workspace ws = Workspace() ws.timerStart() time = 1 sleep(time) ws.timerStop() t = from_workspace(ws.timer) assert isinstance(t, Timer) if t.supported: # Test that we are within 2.5 ticks of the true answer assert isclose((t.realtime_end - t.realtime_start) / t.tick, time, rel_tol=2.5 / t.tick) # t2 = Timer() # t.savexml("tmp.t.xml", "binary") # t2.readxml("tmp.t.xml") # assert t == t2
class TestAgendas: """ Tests the calling of ARTS workspace methods. """ def setup_method(self): """ This ensures a new Workspace for every test. """ self.ws = Workspace(verbosity = 0) self.setup_workspace() def setup_workspace(self): self.ws.execute_controlfile("artscomponents/clearsky/TestClearSky.arts") def test_assignment(self): """ Test assignment of agendas. """ ws = self.ws ws.ppath_agenda = ppath_agenda def test_include(self): ws = self.ws @arts_agenda def ppath_agenda_inc(ws): INCLUDE(ppath_agenda) ws.ppath_agenda = ppath_agenda_inc def test_execution(self): """ Test definition and execution of agendas. """ self.ws.atmosphere_dim = 1 @arts_agenda def add_1(ws): ws.IndexAdd(ws.atmosphere_dim, ws.atmosphere_dim, 1) add_1.execute(self.ws) assert self.ws.atmosphere_dim.value == 2 add_1.append(add_1) add_1.execute(self.ws) assert self.ws.atmosphere_dim.value == 4 args = [self.ws.atmosphere_dim, self.ws.atmosphere_dim, 1] @arts_agenda def add_2(ws): ws.IndexAdd(*args) add_2.execute(self.ws) assert self.ws.atmosphere_dim.value == 5 def test_callback(self): """ Test callbacks by re-implementing iy_space_agenda in Python and comparing results of yCalc. """ z_ppath = [] ws = self.ws ws.yCalc() y_old = np.copy(ws.y.value) import scipy.constants as c @arts_agenda(allow_callbacks=True) def space_agenda(ws): # Since everything happens in Python we need # to tell ARTS that we are using all in and outputs. ws.Ignore(ws.f_grid) ws.Ignore(ws.rtp_pos) ws.Ignore(ws.rtp_los) ws.Touch(ws.iy) # Temperatures and frequency t = 2.735 f = ws.f_grid.value # Compute radiances c1 = 2.0 * c.h / c.c ** 2 c2 = c.h / c.k b = c1 * f ** 3 / (np.exp(c2 * f / t) - 1.0) # Put into iy vector. ws.iy = np.zeros((f.size, ws.stokes_dim.value)) ws.iy.value[:, 0] = b # Copy ppath_agenda into workspace. ws.iy_space_agenda = space_agenda ws.yCalc() y_new = np.copy(ws.y.value) assert(np.allclose(y_new, y_old)) def test_callback_2(self): """ Test a very complicated Python callback. """ @arts_agenda(allow_callbacks=True) def agenda(ws): """ This agenda sets a workspace variable in a very obscure way. """ class Foo: def __init__(self, ws): self.ws = ws def ooo(self): self.ws.IndexSet(ws.stokes_dim, 42) foo = Foo(ws) ws.IndexSet(ws.stokes_dim, 21) foo.ooo() agenda.execute(self.ws) def test_unknown_wsv(self): """ Ensure that an exception is thrown when an unknown WSV is used inside an agenda. This covers https://github.com/atmtools/arts/issues/368 """ with pytest.raises(ValueError): @arts_agenda def my_agenda(ws): ws.UnknownMethod() def test_starred(self): """ Test expansion of starred expression. """ @arts_agenda def agenda(ws): """ This agenda uses a starred expression. """ ws.IndexSet(*[ws.stokes_dim, 42]) self.ws.stokes_dim = 0 agenda.execute(self.ws) assert self.ws.stokes_dim.value == 42 def test_double_starred(self): """ Test expansion of starred expression. """ @arts_agenda def agenda(ws): """ This agenda uses a starred expression. """ ws.IndexSet(**{"out" : ws.stokes_dim, "value" : 42}) self.ws.stokes_dim = 0 agenda.execute(self.ws) assert self.ws.stokes_dim.value == 42 def test_exception(self): """ Ensure that exception is thrown when a agenda variable is set to an invalid value. """ @arts_agenda(allow_callbacks=True) def abs_xsec_agenda(ws): pass self.ws = pyarts.workspace.Workspace() with pytest.raises(Exception): self.ws.abs_xsec_agenda = abs_xsec_agenda
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)
from pyarts.workspace import Workspace from pyarts.classes.Vector import Vector from pyarts.classes.Matrix import Matrix from pyarts.classes.MCAntenna import MCAntenna from pyarts.classes import from_workspace ws = Workspace() mca = MCAntenna() mca.type = 1 mca.type = 2 mca.type = 3 mca.sigma_aa = 4.5 mca.sigma_za = 4.5 mca.aa_grid = Vector([1, 2, 3, 4]) mca.za_grid = Vector([1, 2, 3, 4, 5]) mca.g_lookup = Matrix([[5, 6, 7, 8], [5, 6, 7, 8], [5, 6, 7, 8], [5, 6, 7, 8], [5, 6, 7, 8]]) mca2 = from_workspace(ws.mc_antenna) mca2.set(mca) assert mca2 == mca # mca3 = MCAntenna() # mca.savexml("tmp.mca.xml", "binary") # mca3.readxml("tmp.mca.xml") # assert mca3 == mca
ws.atmgeom_checkedCalc() ws.cloudbox_checkedCalc() ws.sensor_checkedCalc() ws.yCalc() ws.Copy(ws.ybatch_calc_agenda, ybatch_calc_agenda) ws.IndexSet(ws.ybatch_start, 0) ws.IndexSet(ws.ybatch_n, 1) # Amount of atmospheres ws.ybatchCalc() # conduct the forward simulation return ws # test for ybatch def test_ybatch(ws): ybatch_ref = np.array([256.9629541]) assert np.allclose(ws.ybatch.value[0], ybatch_ref) # test for ybatch_jacobians def test_ybatch_jacobians(ws): ybatch_jacobians_ref = np.array([[3.38652849e-6]]) assert np.allclose(ws.ybatch_jacobians.value[0], ybatch_jacobians_ref, atol=1e-12) if __name__ == '__main__': ws = Workspace(verbosity=2) ws = setup_testcase(ws) test_ybatch(ws) test_ybatch_jacobians(ws) print('SurfaceBlackbody tests passed.')
import os from pyarts.workspace import Workspace from pyarts.classes.ScatteringMetaData import ScatteringMetaData from pyarts.classes.SingleScatteringData import SingleScatteringData from pyarts.classes import from_workspace # Get a workspace ws = Workspace() datapath = "../../arts-xml-data/" if not os.getenv("ARTS_XML_DATA_DIR") else os.getenv("ARTS_XML_DATA_DIR") fn1 = os.path.join(datapath, 'scattering/H2O_ice/MieSphere_R1.00000e+00um.meta.xml') fn2 = os.path.join(datapath, 'scattering/H2O_ice/MieSphere_R1.00000e+00um.xml') smd1 = ScatteringMetaData() smd1.readxml(fn1) smd2 = from_workspace(ws.scat_meta_single) ws.ReadXML(ws.scat_meta_single, fn1) smd3 = ScatteringMetaData() smd3.set(smd2) assert smd1 == smd2 assert smd1 == smd3 ssd1 = SingleScatteringData() ssd1.readxml(fn2) ssd2 = from_workspace(ws.scat_data_single) ws.ReadXML(ws.scat_data_single, fn2) ssd3 = SingleScatteringData() ssd3.set(ssd2)
from pyarts.workspace import Workspace from pyarts.classes.QuantumIdentifier import QuantumIdentifier from pyarts.classes.RetrievalQuantity import RetrievalQuantity, ArrayOfRetrievalQuantity from pyarts.classes.SpeciesTag import SpeciesTag from pyarts.classes.Vector import ArrayOfVector from pyarts.classes import from_workspace # Get a workspace ws = Workspace() ws.jacobianInit() ws.atmosphere_dim = 3 p = from_workspace(ws.p_grid) lat = from_workspace(ws.lat_grid) lon = from_workspace(ws.lon_grid) p.data = [3, 2, 1] lat.data = [1, 2, 3, 4] lon.data = [1, 2, 3, 4, 5] ws.jacobianAddTemperature(g1=p.data, g2=lat.data, g3=lon.data) arq = from_workspace(ws.jacobian_quantities) rq = RetrievalQuantity() rq.maintag = "" rq.subtag = "HSE on" rq.subsubtag = "" rq.mode = "" rq.analytical = 1 rq.target.type = "Atm" rq.target.subtype = "Temperature" rq.target.perturbation = 0.1 rq.grids = ArrayOfVector([p, lat, lon])
from math import isclose from pyarts.workspace import Workspace from pyarts.classes.Time import Time from pyarts.classes import from_workspace ws = Workspace() ws.create_variable("Time", "start") ws.create_variable("Time", "end") ws.create_variable("Time", "time") ws.create_variable("Numeric", "dt") start_time = from_workspace(ws.start) end_time = from_workspace(ws.end) cur_time = from_workspace(ws.time) dt = from_workspace(ws.dt) # Test Now and Sleep ws.timeNow(ws.start) ws.Sleep(1) ws.timeNow(ws.end) ws.Duration(ws.dt, ws.start, ws.end) assert dt >= 1, \ f"Slept for one second but duration was less: {float(dt):.3f} s" # Test SleepUntil ws.timeNow(ws.start) end_time.sec = start_time.sec + 1 ws.timeSleep(ws.end) ws.timeNow(ws.time) duration = cur_time.sec - start_time.sec assert duration >= 1, \
class TestMethods: """ Tests the calling of ARTS workspace methods. """ def setup_method(self): """ This ensures a new Workspace for every test. """ self.ws = Workspace(verbosity=0) self.setup_workspace() def setup_workspace(self): self.ws.execute_controlfile( "artscomponents/clearsky/TestClearSky.arts") def test_mixed_arguments(self): """ Check that this raises a syntax error. """ ws = self.ws with pytest.raises(SyntaxError): ws.yCalc(ws.yf, y_f=ws.y_f) def test_unexpected_argument(self): """ Providing a named argument with a name that is not actually an argument of the WSM should raise an error. """ ws = self.ws with pytest.raises(Exception): ws.yCalc(nonsense=ws.y_f) def test_override_output(self): """ Test overriding of output parameters in the two possible ways. """ ws = self.ws y_ref = np.copy(ws.y.value) ws.yf = np.zeros(y_ref.size) ws.yCalc(ws.yf) assert (np.allclose(ws.yf.value, y_ref)) ws.yf = np.zeros(y_ref.size) ws.yCalc(y=ws.yf) assert (np.allclose(ws.yf.value, y_ref)) def test_override_input(self): """ Test overriding of input parameters in the two possible ways. atmgeom_checked WSV is set to zero so that both calculations should fail if input is not overridden. """ ws = self.ws ws.atmgeom_checked = 0 ws.rte_pos = np.array([600e3, 0, 0]) ws.rte_pos2 = np.array([600e3, 0]) ws.rte_los = np.array([180.0, 0]) ws.ppathCalc(ws.ppath, ws.ppath_agenda, ws.ppath_lmax, ws.ppath_lraytrace, 1) ws.ppathCalc(atmgeom_checked=1) def test_generic_input(self): """ Test overriding of generic input in the two possible ways. """ ws = self.ws species = ([ "H2O-SelfContStandardType, H2O-ForeignContStandardType, H2O", "N2-SelfContStandardType", "O3" ]) ws.ArrayOfArrayOfSpeciesTagCreate("abs_species_2") ws.abs_speciesSet(ws.abs_species_2, ws.abs_xsec_agenda_checked, ws.propmat_clearsky_agenda_checked, species) ws.ArrayOfArrayOfSpeciesTagCreate("abs_species_3") ws.abs_speciesSet(abs_species=ws.abs_species_3, species=species) assert (ws.abs_species_2.value == ws.abs_species_3.value) def test_generic_output(self): """ Test overriding of generic input in the two possible ways. """ ws = self.ws tempfile = NamedTemporaryFile() mat = np.ones((2, 2)) ws.sensor_los = np.ones((2, 2)) ws.WriteXML("ascii", ws.sensor_los, tempfile.name) ws.sensor_los = np.zeros((2, 2)) ws.ReadXML(ws.sensor_los, tempfile.name) assert (np.allclose(mat, ws.sensor_los.value)) ws.sensor_los = np.zeros((2, 2)) ws.ReadXML(out=ws.sensor_los, filename=tempfile.name) assert (np.allclose(mat, ws.sensor_los.value)) def test_supergeneric_overload_resolution(self): """ Test resolution of supergeneric methods. """ self.ws.ArrayOfIndexCreate("array_of_index") self.ws.ArrayOfArrayOfIndexCreate("array_of_array_of_index") self.ws.array_of_index = [1, 2, 3] self.ws.Append(self.ws.array_of_array_of_index, self.ws.array_of_index) self.ws.Append(self.ws.array_of_array_of_index, self.ws.array_of_index) def test_supergeneric_overload_failure(self): """ Test expected failure of supergeneric overload resolution. """ with pytest.raises(Exception): self.ws.NumericCreate("numeric_wsv") self.ws.StringCreate("string_wsv") self.ws.Copy(self.ws.string_wsv, self.ws.numeric_wsv) def test_wsm_error(self): """ Test error handling from ARTS WSMs. """ with pytest.raises(Exception): ws.atmgeom_checked = 0 self.ws.yCalc()
from pyarts.workspace import Workspace from pyarts.classes.SpeciesTag import SpeciesTag, ArrayOfArrayOfSpeciesTag from pyarts.classes import from_workspace # Get a workspace ws = Workspace() aast = from_workspace(ws.abs_species) st = SpeciesTag("H2O-161") ws.abs_speciesSet(species=["H2O-161"]) aast.size = 2 aast[1].size = 1 aast[1][0].set(aast[0][0]) assert st == aast[0][0] assert st == aast[1][0] aast.savexml("tmp.aast.xml", "binary") aast2 = ArrayOfArrayOfSpeciesTag() aast2.readxml("tmp.aast.xml") assert aast == aast2
from pyarts.workspace import Workspace ws = Workspace() ws.StringCreate("mystring") ws.StringSet(ws.mystring, "Hello World!") ws.Print(ws.mystring, 0)
class TestWorkspace: def setup_method(self): """This ensures a new Workspace for every test.""" self.dir = os.path.dirname(os.path.realpath(__file__)) self.ws = Workspace() self.setup_workspace() def setup_workspace(self): ws = self.ws ws.atmosphere_dim = 1 ws.p_grid = np.linspace(1e5, 1e3, 21) ws.Touch(ws.lat_grid) ws.Touch(ws.lon_grid) ws.f_grid = 183.0e9 * np.ones(1) ws.stokes_dim = 1 ws.sensor_los = 180.0 * np.ones((1, 1)) ws.sensor_pos = 830e3 * np.ones((1, 1)) ws.sensorOff() def test_execute_controlfile(self): dir = os.path.dirname(os.path.realpath(__file__)) test_dir = os.path.join(dir, "test_files") self.ws.WriteXML("ascii", np.array([1.0]), os.path.join(test_dir, "vector.xml")) os.chdir(test_dir) self.ws.execute_controlfile("controlfile.arts") os.remove(os.path.join(test_dir, "vector.xml")) def test_execute_controlfile(self): dir = os.path.dirname(os.path.realpath(__file__)) test_dir = os.path.join(dir, "test_files") self.ws.WriteXML("ascii", np.array([1.0]), os.path.join(test_dir, "vector.xml")) os.chdir(test_dir) agenda = self.ws.execute_controlfile("controlfile.arts") self.ws.foo = "not bar" @arts_agenda def execute(ws): ws.FlagOff(ws.jacobian_do) ws.StringSet(ws.foo, "still not bar") INCLUDE("controlfile.arts") INCLUDE(agenda) self.ws.execute_agenda(execute) assert self.ws.foo.value == "bar" os.remove(os.path.join(test_dir, "vector.xml")) def test_wsv_setattr(self): wsv = self.ws.atmosphere_dim wsv.value = 12 assert self.ws.atmosphere_dim.value == 12 def test_callbacks(self): @arts_agenda def agenda(ws): """ This agenda sets a workspace variable in a very obscure way. """ class Foo: def __init__(self, ws): self.ws = ws def ooo(self): self.ws.IndexSet(ws.stokes_dim, 42) foo = Foo(ws) ws.IndexSet(ws.stokes_dim, 21) foo.ooo() agenda.execute(self.ws) assert self.ws.stokes_dim.value == 42 def test_contiguous_arrays(self): x = np.linspace(0, 1, 256) xf = np.asarray(x, order='F') self.ws.f_grid = xf assert np.array_equal(self.ws.f_grid.value, xf) self.ws.f_grid = x[::2] assert np.array_equal(self.ws.f_grid.value, x[::2]) self.ws.f_grid = np.ascontiguousarray(x[::2]) assert np.array_equal(self.ws.f_grid.value, x[::2]) def test_name_collision(self): self.ws.VectorSetConstant(self.ws.f_grid, 10, 1.) self.ws.VectorCreate("np") f_grid = self.ws.f_grid.value assert np.all(np.isclose(f_grid, np.ones(10)))
from pyarts.workspace import Workspace from pyarts.classes.Ppath import Ppath from pyarts.classes import from_workspace # Get a workspace ws = Workspace() ws.atmosphere_dim = 1 ws.cloudbox_on = 0 ws.ppath_inside_cloudbox_do = 0 cloudbox_limits = from_workspace(ws.cloudbox_limits) z_field = from_workspace(ws.z_field) z_field.data = [0, 1, 2, 3] z_field.data = z_field.data.reshape(4, 1, 1) z_surface = from_workspace(ws.z_surface) z_surface.data = [0] rte_pos = from_workspace(ws.rte_pos) rte_pos.data = [4] rte_los = from_workspace(ws.rte_los) rte_los.data = [91] ws.ppath_lmax = 0.1 ws.ppathPlaneParallel() # Get the path path = from_workspace(ws.ppath) path2 = Ppath() path2.set(path) assert isinstance(path, Ppath), "Bad read" assert path, "Bad read" assert path2 == path
class _ARTS: 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) def calc_lookup_table(self, filename=None, fnum=2**15, wavenumber=None): """Calculate an absorption lookup table. The lookup table is constructed to cover surface temperatures between 200 and 400 K, and water vapor mixing ratio up to 40%. The frequency grid covers the whole outgoing longwave spectrum from 10 to 3,250 cm^-1. References: An absorption lookup table can be found at https://doi.org/10.5281/zenodo.3885410 Parameters: filename (str): (Optional) path to an ARTS XML file to store the lookup table. fnum (int): Number of frequencies in frequency grid. Ignored if `wavenumber` is set. wavenumber (ndarray): Wavenumber grid [m-1]. """ # Create a frequency grid if wavenumber is None: wavenumber = np.linspace(10e2, 3_250e2, fnum) self.ws.f_grid = ty.physics.wavenumber2frequency(wavenumber) # Read line catagloge and create absorption lines. self.ws.ReadSplitARTSCAT( abs_lines=self.ws.abs_lines, abs_species=self.ws.abs_species, basename="hitran_split_artscat5/", fmin=0.0, fmax=1e99, globalquantumnumbers="", localquantumnumbers="", ignore_missing=0, ) # Set line shape and cut off. self.ws.abs_linesSetLineShapeType(self.ws.abs_lines, "VP") self.ws.abs_linesSetNormalization(self.ws.abs_lines, "VVH") self.ws.abs_linesSetCutoff(self.ws.abs_lines, "ByLine", 750e9) self.ws.abs_lines_per_speciesCreateFromLines() self.ws.abs_lines_per_speciesCompact() # Create a standard atmosphere p_grid = get_quadratic_pgrid(1_200e2, 0.5, 80) atmosphere = Atmosphere(p_grid) atmosphere["T"][ -1, :] = 300.0 + 5.0 * np.log(atmosphere["plev"] / 1000e2) atmosphere.tracegases_rcemip() atmosphere["O2"][:] = 0.2095 atmosphere["CO2"][:] = 1.5 * 348e-6 h2o = 0.01 * (p_grid / 1000e2)**0.2 atmosphere["H2O"][:] = h2o[:-1] # Convert the konrad atmosphere into an ARTS atm_fields_compact. atm_fields_compact = atmosphere.to_atm_fields_compact() self.ws.atm_fields_compact = atm_fields_compact self.ws.atm_fields_compactAddConstant( atm_fields_compact=self.ws.atm_fields_compact, name="abs_species-N2", value=0.7808, condensibles=["abs_species-H2O"], ) # Setup the lookup table calculation self.ws.AtmFieldsAndParticleBulkPropFieldFromCompact() self.ws.vmr_field.value = self.ws.vmr_field.value.clip(min=0.0) self.ws.atmfields_checkedCalc() self.ws.abs_lookupSetup(p_step=1.0) # Do not refine p_grid self.ws.abs_t_pert = np.arange(-160, 61, 20) nls_idx = [ i for i, tag in enumerate(self.ws.abs_species.value) if "H2O" in tag[0] ] self.ws.abs_speciesSet( abs_species=self.ws.abs_nls, species=[", ".join(self.ws.abs_species.value[nls_idx[0]])], ) self.ws.abs_nls_pert = np.array( [10**x for x in [-9, -7, -5, -3, -1, 0, 0.5, 1, 1.5, 2]]) # Run checks self.ws.abs_xsec_agenda_checkedCalc() self.ws.lbl_checkedCalc() # Calculate actual lookup table. self.ws.abs_lookupCalc() if filename is not None: self.ws.WriteXML("binary", self.ws.abs_lookup, filename) def set_atmospheric_state(self, atmosphere, t_surface): """Set and check the atmospheric fields.""" import pyarts atm_fields_compact = atmosphere.to_atm_fields_compact() # Scale dry-air VMRs with H2O and CO2 content. if self.scale_vmr: variable_vmrs = (atm_fields_compact.get("abs_species-H2O")[0] + atm_fields_compact.get("abs_species-CO2")[0]) else: t3_shape = atm_fields_compact.get("abs_species-H2O")[0].shape variable_vmrs = np.zeros(t3_shape) for species in atm_fields_compact.grids[0]: if (species.startswith("abs_species-") and "H2O" not in species and "CO2" not in species): atm_fields_compact.scale(species, 1 - variable_vmrs) # Compute the N2 VMR as a residual of the full atmosphere composition. n2 = pyarts.types.GriddedField3( grids=atm_fields_compact.grids[1:], data=0.7808 * (1 - variable_vmrs), ) self.ws.atm_fields_compact = atm_fields_compact self.ws.atm_fields_compactAddSpecies( atm_fields_compact=self.ws.atm_fields_compact, name="abs_species-N2", value=n2, ) self.ws.AtmFieldsAndParticleBulkPropFieldFromCompact() self.ws.vmr_field = self.ws.vmr_field.value.clip(min=0) # Surface & TOA # Add pressure layers to the surface and top-of-the-atmosphere to # ensure consistent atmosphere boundaries between ARTS and RRTMG. self.ws.t_surface = np.array([[t_surface]]) self.ws.z_surface = np.array([[0.0]]) self.ws.z_field.value[0, 0, 0] = 0.0 # Perform configuration and atmosphere checks self.ws.atmfields_checkedCalc() self.ws.propmat_clearsky_agenda_checkedCalc() self.ws.atmgeom_checkedCalc() self.ws.cloudbox_checkedCalc() def calc_spectral_irradiance_field(self, atmosphere, t_surface): """Calculate the spectral irradiance field.""" self.set_atmospheric_state(atmosphere, t_surface) # get the zenith angle grid and the integrations weights self.ws.AngularGridsSetFluxCalc(N_za_grid=self.nstreams, N_aa_grid=1, za_grid_type="double_gauss") # calculate intensity field self.ws.Tensor3Create("trans_field") self.ws.spectral_radiance_fieldClearskyPlaneParallel( trans_field=self.ws.trans_field, use_parallel_za=0, ) self.ws.spectral_irradiance_fieldFromSpectralRadianceField() return ( self.ws.f_grid.value.copy(), self.ws.p_grid.value.copy(), self.ws.spectral_irradiance_field.value.copy(), self.ws.trans_field.value[:, 1:, 0].copy().prod(axis=1), ) def calc_optical_thickness(self, atmosphere, t_surface): """Calculate the spectral irradiance field.""" self.set_atmospheric_state(atmosphere, t_surface) self.ws.propmat_clearsky_fieldCalc() tau = np.trapz( y=self.ws.propmat_clearsky_field.value[:, :, 0, 0, :, 0, 0], x=self.ws.z_field.value[:, 0, 0], axis=-1, ) return self.ws.f_grid.value.copy(), tau @staticmethod def integrate_spectral_irradiance(frequency, irradiance): """Integrate the spectral irradiance field over the frequency. Parameters: frequency (ndarray): Frequency [Hz]. irradiance (ndarray): Spectral irradiance [W m^-2 / Hz]. Returns: ndarray, ndarray: Downward flux, upward, flux [W m^-2] """ F = np.trapz(irradiance, frequency, axis=0)[:, 0, 0, :] # Fluxes lw_down = -F[:, 0] lw_up = F[:, 1] return lw_down, lw_up def calc_spectral_olr(self, atmosphere, surface): """Calculate the outgoing longwave radiation as function of wavenumber. Parameters: atmosphere (konrad.atmosphere.Atmosphere): Atmosphere model. surface (konrad.surface.Surface): Surface model. Returns: ndarray: Outgoing longwave radiation [W m^-2 / cm^-1] """ f, _, irradiance_field, _ = self.calc_spectral_irradiance_field( atmosphere=atmosphere, t_surface=surface["temperature"][0]) return f, irradiance_field[:, -1, 0, 0, 1]
""" Surface ======= """ import numpy as np from pyarts.workspace import Workspace, arts_agenda ws = Workspace() ws.NumericCreate("surface_temperature") ws.NumericCreate("surface_salinity") ws.NumericCreate("surface_windspeed") from artssat.atmosphere.surface.surface import Tessem, Telsem, CombinedSurface
""" 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.
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
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
import os from pyarts.workspace import Workspace from pyarts.classes.CIARecord import CIARecord, ArrayOfCIARecord from pyarts.classes import from_workspace # Get a workspace ws = Workspace() datapath = "../../arts-xml-data/" if not os.getenv( "ARTS_XML_DATA_DIR") else os.getenv("ARTS_XML_DATA_DIR") fn = os.path.join(datapath, "spectroscopy/cia/borysow/Borysow_CIA_JUICE_SWI.xml") acr1 = ArrayOfCIARecord() assert not acr1, "Bad init" acr1.readxml(fn) ws.ReadXML(ws.abs_cia_data, fn) acr2 = from_workspace(ws.abs_cia_data) assert acr1, "Bad read" assert acr1 == acr2, "Bad read" assert isinstance(acr1[0], CIARecord), "Bad type" acr3 = ArrayOfCIARecord() acr3.set(acr1) assert acr1 == acr3, "Bad read" acr1.savexml("tmp.acr.xml", "binary") acr3 = ArrayOfCIARecord() acr3.readxml("tmp.acr.xml")