=====
Usage
=====

To use LIDAR Suit in a project::

    import lidarwind as lst



--------------------------
Generating the config file
--------------------------


After installing lidarwind, it is recommended to generate the configuration file (config.json). The global attributes from the NetCDF files generated by lidarwind are defined in this file. To create the config.json, the user needs to use the lst.configuration class. Below you can find an example of how this file is generated.

.. code-block:: python

    >>> config = lst.Configurations(lst=lst)
    >>> config = config.load_institution('institution name')
    >>> config = config.load_instrument('instrument name')
    >>> config = config.load_site('site name')
    >>> config = config.load_contact('contact person')
    >>> config = config.load_email('contact email')
    >>> config = config.load_comments('additional information')
    >>> config.generate_conf()

The configuration file can also be created using the default values.

.. code-block:: python

    >>> lst.configurations(lst=lst).generate_conf()

Whenever the class lst.RetriveWindFFT() is used to retrieve wind, lidarwind will try to load the global attributes from the config.json. If this file does not exist, lidarwind will create it using the default values and displays the following message.

.. code-block:: python

    'You do not have a config file yet'
    'a temporary config file was generated'
    'See the documentation for generating it'



-------------------
Data pre-processing
-------------------


The NetCDF files produced by the WindCube operating system while following the 6-beam or the DBS can differ from each other. The methods for retrieving wind also differ from each other. For those reasons, the lidarwind has different pre-processing classes to handle those files and create the requirements for deriving wind.



6-beam data pre-processing
--------------------------


The 6-beam data is pre-processed by the DataOperations class. It merges all data, grouping the observations into zenith pointing and slanted. To use this class, the user only needs to pass a list of file paths. The merged data set can be accessed using the merged_data attribute. After pre-processing the data, one can also save the pre-processed data as NetCDF and continue with the wind retrieval or turbulence estimation afterwards.

.. code-block:: python

    >>> merged_ds = lidarwind.DataOperations(file_list).merged_data
    >>> merged_ds.to_netcdf(output_file_path)


DBS data pre-processing
--------------------------

The pre-processing of the DBS data is handled by the DbsOperations class. This class needs a list of file paths and a list of variables that will be merged. While executing, it adds a mean time variable to identify all observations from a complete DBS scan. After using this class, the user can access the merged data by calling the merged_ds attribute, which can also be saved as a NetCDF file to continue with the wind retrieval afterwards.


.. code-block:: python

    >>> var_list = ['azimuth', 'elevation', 'radial_wind_speed',
    >>>             'radial_wind_speed_status', 'measurement_height', 'cnr']
    >>> merged_ds = lst.DbsOperations(file_list, var_list).merged_ds
    >>> merged_ds.to_netcdf(output_file_path)


---------------
Retrieving wind
---------------

lidarwind is able to retrieve wind from the 6-beam data and also from the DBS data.

6-beam data wind retrieval
--------------------------

To retrieve the wind speed and direction from the 6-beam data, the user needs to prepare the dataset for it. It is made by using the GetRestructuredData class. This class groups the slanted data by their azimuth and creates an azimuth dimension to store it. Once it is done, the output object from GetRestructuredData class contains all the information needed for retrieving wind profiles using the RetriveWindFFT class.

The RetriveWindFFT class applies the fast Fourier transform (FFT) along the azimuthal dimension of the dataset for each complete scanning cycle and derives the wind speed and direction from that. A short description of the FFT-based wind retrieval can be found in the :any:`6-beam <six-beam>` section. Below you can see how to retrieve winds from the 6-data. The wind_obj has an attribute wind_prop (a xarray dataset) where the wind profiles are stored.


.. code-block:: python

    >>> restruct_data = lst.GetRestructuredData(merged_ds)
    >>> wind_obj = lst.RetriveWindFFT(restruct_data)


A notebook example combining all steps for retrieving wind can be found in the list of `notebooks examples <examples/merging_6beam_rendered.html>`_.  You can run the same example online by clicking on the binder badge listed in the package :any:`introduction <intro>`.


DBS data wind retrieval
-----------------------

The retrieval of the wind from the DBS observations is made by the GetWindProperties5Beam class, and it uses the merged dataset generated by the DbsOperations class to do it. The GetWindProperties5Beam class applies the methodology described in the :ref:`DBS overview section <DBS>` to retrieve wind speed and direction profiles. The wind speed and direction are available as attributes of the returned object.


.. code-block:: python

    >>> wind_obj = lst.GetWindProperties5Beam(merged_ds)
    >>> hor_wind_speed = wind_obj.hor_wind_speed
    >>> ver_wind_speed = wind_obj.ver_wind_speed
    >>> hor_wind_dir = wnd_obj.hor_wind_dir

A notebook example combining all steps for retrieving wind can be found in the list of `notebooks examples <examples/dbs_scans_rendered.html>`_.  You can run the same example online by clicking on the binder badge listed in the package :any:`introduction <intro>`.


---------------------
Turbulence estimation
---------------------

The lidarwind package also contains an implementation of the :any:`6-beam <six-beam>` method for estimating the Reynolds stress tensor components. This estimation is made by the SixBeamMethod class using the returned object from GetRestructuredData class. As introduced in the overview, the 6-beam method requires variances as input. The user needs to indicate the window size to calculate the variance in time. However, SixBeamMethod class requires a window defined in terms of the number of profiles that fit within the desired time window. Below you can find an example of how to relate a time window to its equivalent number of profiles.


.. code-block:: python

    >>> # desired time windown in minutes
    >>> time_window = 5

    >>> # duration of one minute in seconds
    >>> minute_lenght = 60

    >>> # vertical observations time resolution in seconds
    >>> time_resolution = restruct_data.data_transf_90.time.diff(dim='time').values * 1e-9
    >>> time_resolution = int(time_resolution[0])

    >>> # frequency convertion from minutes to profile number
    >>> freq = (minute_lenght/time_resolution)*time_window
    >>> freq = int(freq)


As soon as the time window is converted to its number of profiles equivalent, the SixBeamMethod class can be applied to the returned object from GetRestructuredData class. The variance and co-variance profiles are available in the attribute var_comp_ds (a xarray dataset)


.. code-block:: python

    >>> restruct_data = lst.GetRestructuredData(merged_ds)
    >>> turb_data = lst.SixBeamMethod(restruct_data, freq=freq, freq90=freq)
    >>> turb_data.var_comp_ds
