Skip to content

Data component

mfangaritav edited this page Jan 9, 2024 · 32 revisions

Declaring an object

The first step to run an inversion with VMOD is to declare a Data object. These objects should have as attributes the locations of the stations (attributes xs and ys), an array that contains all the components for the data type (attribute comps) and the uncertainties associated with each observation (attribute err). If the dataset has time-dependent observations the user can store the time information in the attribute ts.

The user can load the locations of data points in meters (add_xs and add_ys) or load the locations in lat/lon coordinates (add_lls) and VMOD will perform a UTM transformation to get the locations in meters, the user also has to load the components for the data type.

GNSS

For example the class that represents the GNSS data type (Gnss) has methods to add the east (add_uxs), north (add_uys), and vertical (add_uzs) components. Here we show an example on how to declare a GNSS object:

from vmod.data import Gnss

#Create Gnss object
obs=Gnss()

#Add the names of the stations
obs.add_names(names)

#Add the x and y coordinates of the stations
obs.add_xs(xs)
obs.add_ys(ys)

#Add deformation dataset in east (uxs), north (uys) and vertical (uzs)
obs.add_ux(uxs)
obs.add_uy(uys)
obs.add_uz(uzs)

#Add uncertainties in east (euxs), north (euys) and vertical (euzs)
obs.add_errx(euxs)
obs.add_erry(euys)
obs.add_errz(euzs)

Alternatively, the user can declare the Gnss object and arrange the GNSS data in a csv file and import the information into the object.

from vmod.data import Gnss

#Create Gnss object
obs=Gnss()

#Import csv into the observation object
obs.importcsv('examples/gps/unimak_gnss_NOAM.txt')

The text file should be arrange in the following way: Station name, longitude, latitude, east velocity, north velocity, vertical velocity, uncertainty in east, uncertainty in north and uncertainty in vertical.

%Name Lon Lat ux uy uz eux euy euz
AB06 -163.42345400042757 54.885322999350095 -0.0031118 -0.0010642  0.0015522 0.0000297 0.0000349 0.0000780
AC10 -164.88672999983683 54.522579999242880 -0.0068234 -0.0007091  0.0041480 0.0000378 0.0000401 0.0001143

InSAR

The InSAR datasets can be import it into Insar objects. It is necessary to load the Line-Of-Sight observations (add_los), the azimuth and incidence angles (add_vecs).

from vmod.data import Insar

#Create Insar object
obs=Insar()

#Add the x and y coordinates of the stations
obs.add_xs(xs)
obs.add_ys(ys)

#Add azimuth and incidence angles.
obs.add_vecs(azs,lks)

#Add deformation dataset
obs.add_los(los)

VMOD has auxiliary libraries to downsample the InSAR datasets using a quadtree algorithm. The function get_quadtree expects a matrix with the LOS observations (los), the azimuth angle(s) (az), the incidence angle(s) (inc), an array that contains the extent of the image (extent), a variance threshold (th) and the name of the file (name) with the quadtree output.

from vmod import util

util.quadtree_var(los,az,inc,extent,th,name)

Similarly, as with the Gnss objects the information for the Insar object can be import it from a text file.

from vmod.data import Insar
csvfile_ref='examples/insar/unimak_des_ref.csv'
obs=Insar()
obs.importcsv(csvfile_ref,ori=[-164.5,54.7])

The first line of the text file should have the header with that has the location of the reference pixel, the dimensions of the interferogram, and the spatial extent. Then the following lines should be arrange as: longitude, latitude for the pixels or data points, azimuth angle, incidence angle, LOS velocity and the uncertainty in the LOS observations. The last two columns are optional to indicate how many pixels each data point represent (after the downsampling).

Reference (Lon,Lat): -164.3750557302111,54.52915370772697, Dimensions: 491,770, Extent: -164.96499666450117,-164.12175031191683,54.38552515474153,54.92376750745494
-164.591 54.726 -11.058264 34.954952 -0.000517 0.000000270     0   245     0   385
-164.922 54.593 -11.243279 33.936565 0.001856 0.000004178   275   306     0    48

This is the output of the auxiliary libraries to downsample the interferogram. Additionally, VMOD has auxiliary functions to read and change the reference pixel of the interferogram. The expected input formats are h5 files from MintPy. You can explore these functions in the notebook for the DVD exercise using the InSAR dataset.

Tilt

The Tilt datasets can be import it into Tilt objects in a similar way as the Gnss objects. It is necessary to load the names of the stations, the locations (longitudes and latitudes, add_lls), the tilt displacements in the east (add_dx), tilt displacements in the north (add_dy) and the uncertainties for the observations (add_err).

from vmod.data import Tilt

names=np.array(['AV36','AV37','AV39'])
lons=np.array([-164.1268,-163.9972,-163.9985])
lats=np.array([54.7718,54.7094,54.8113])

dxs=np.array([0.0000,0.3368*1e-6,0.2976*1e-6])
dys=np.array([0.0000,1.0366*1e-6,-1.0382*1e-6])

errx=np.array([5e-7]*3)
erry=np.array([5e-7]*3)

tilt=Tilt()

tilt.add_names(names)
tilt.add_lls(lons,lats,ori=[-163.970,54.756])
tilt.add_dx(dxs)
tilt.add_dy(dys)
tilt.add_err(errx,erry)

Electronic Distance Meter

The EDM observations can be represented with an Edm object. Here the user has to upload the locations for the origins (add_xorigins, add_yorigins, add_zorigins), the locations for the ends (add_xends, add_yends, add_zends) of the lines and the change in the distances.

from vmod.data import Edm

obs = Edm()

obs.add_xorigins(xorig)
obs.add_yorigins(yorig)
obs.add_zorigins(zorig)

obs.add_xends(xtail)
obs.add_yends(ytail)
obs.add_zends(ztail)

obs.add_deltas(delta)

Levelling

The level measurements can be load into Level objects. In this case the user should add the locations for the data points (add_xs and add_ys) the vertical changes (add_data) and the uncertainties in the observations (add_err).

from vmod.data import Level
 
lvl=Level()

lvl.add_xs(xs)
lvl.add_ys(ys)
lvl.add_ts(ts)

lvl.add_data(delta)

Joint

Multiple dataset can be added to one Data object into a Joint object with the method (add_dataset). The user should defined the relative weights for each of the datasets.

from vmod.data import Joint

#Creating observation object in 
#this case a Joint dataset
obs=Joint()

obs.add_dataset(obsin,wt=1.0)
obs.add_dataset(obsg,wt=3.0)

Create a new data type

Users wishing to include a new datatype should clone the source repository and create a new file in the data folder. This file should contain a new class that inherit from the 'Data' class and that has the functions to initialize the attributes, adding the components belonging to the datatype and a function to derive the components from 3d displacements. For example, in the Insar class we defined the following functions:

class Insar(Data):
    def __init__():
        self.az=None
        self.inc=None
        self.los=None
        super().__init__()

    def add_az(self, los):
        self.assert_size(az,'az')
        self.az=az
    
    def add_inc(self,inc):
        self.assert_size(inc,'inc')
        self.inc=inc

    def add_los(self, los):
        self.add_comp(los,'los')
        self.los=los

    def from_model3d(self, func):
        ux,uy,uz=func(self.xs,self.ys)
        assert isinstance(self.inc,(list,np.ndarray)) and isinstance(self.az,(list,np.ndarray)), 'The look angles have not been defined'
        los=ux*np.sin(self.inc)*np.cos(self.az)-uy*np.sin(self.inc)*np.sin(self.az)-uz*np.cos(self.inc)
        los_ref=self.reference_dataset(los)
        return (-los_ref,)