patch-nx tutorial
=================

.. article-info::
    :read-time: 5 min read
    :class-container: sd-p-2 sd-outline-muted sd-rounded-1

the `patch-nx` application is used to patch an existing NXTomo entry in a nexus file.

For now there is two main 'features':

* adding dark series and / or flatfield series to an existing NXTomo entry
* modifying frame type (projection, dark, flatfield, projection, alignment, invalid)

.. note:: You can do both within only one call to the function. In this case we will first update frame type prior to add dark / flatfield series.
          This choice has been made to avoid confusion on frame indices. And to fit the use case users want to modify dark and / or flat.
          But a good practice would be to call twice the command.

Adding dark and / or flatfield serie
------------------------------------

This can be used for example if you want to add some dark of flat series as post processing.

.. warning:: this will modify **inplace** datasets contained in the target entry. If you wan't to save original data then you should
             first copy the file prior to calling this function.

.. warning:: Any dataset you want to insert must be store into a 'permanant' relative position to the file you modify.
             This is needed to insure virtual dataset consistency. This is also why you should provide urls.

.. note:: HDF5 virtual dataset are managed by creating a new data set from original sources and adding a new virtual source pointing to the provided url.


To call this application you can call directly

.. code-block:: bash

   nxtomomill patch-nx [my_file my_entry] [[--darks-at-start url1 --flats-at-dark url2 --darks-at-end url3 --flats-at-end url4]]


.. note:: urls can be provided two ways:

    * `official silx way (recommended) <www.silx.org/doc/silx/latest/modules/io/url.html?highlight=dataurl#silx.io.url.DataUrl>`_
    * tomwer way: data_path@file_path

This is an example on how to add:

* a serie of dark before projections contained in a dataset name 'data2' at the root node of the 'dark.hdf5' file
* a serie of flats between the added dark and the original set of projections contained in the 'flat' dataset inside the my_nxtomo.nx file and only picking slices 1 and 2

.. code-block:: bash

    nxtomomill patch-nx /tmp/tmpzk3v37h_/simple_case/my_nxtomo.nx entry --darks-at-start data2@/tmp/tmpzk3v37h_/dark.hdf5 --flats-at-start silx:///tmp/tmpzk3v37h_/simple_case/simple_case.h5?path=flat&slice=1,2


Modifying frame type
--------------------

From the command line you can define a set of frame for which you would like to change the type.

The API to modify frame type is the following:

.. code-block:: bash

     nxtomomill patch-nx [my_file my_entry] [[--invalid-frames frames1 update-to-projection frames2 --update-to-dark frames3 --update-to-flat frames4 --update-to-alignment frames5]]

Those are some examples of usage:

.. code-block:: bash

    # force frames 26 and 27 to be dark
    nxtomomill patch-nx --update-to-dark 26:28 my_nxtomo.nx entry
    # force all projections to be dark
    nxtomomill patch-nx --update-to-dark projection my_nxtomo.nx entry
    # force frames 10, 13, 16 and 19 to be flatfield
    nxtomomill patch-nx --update-to-flat 10:20:3 my_nxtomo.nx entry
    # force frame 0, 1 and to 4 to be projections
    nxtomomill patch-nx --update-to-proj 0,1,4 my_nxtomo.nx entry
    # force first frame to be alignment projection
    nxtomomill patch-nx --update-to-alignment 0 my_nxtomo.nx entry
    # force all frames to be invalid
    nxtomomill patch-nx --invalid-frames : my_nxtomo.nx entry
    # force all "projection" frame to be invalid
    nxtomomill patch-nx --invalid-frames projection my_nxtomo.nx entry


.. note:: If you try to modify several frame type at the same type you should know that the order of resolution is:
          * modify frame to `alignment` if any
          * modify frame to `projection` if any
          * modify frame to `flatfield` if any
          * modify frame to `dark` type if any
          * modify frame to `invalid` if any


Concrete example of modifying flat field on an .nx file
-------------------------------------------------------

In this example flat field frames at from acquisition A has been mess up.
NXTomo file is name original_acquiA.nx. Entry name is entry000A

And we want to replace them by flat field from acquisition B (master file is acquiB.nx). Entry name is entry000B

This is one way to proceed to replace flat field frames:

1. go to acquisition A folder containing the acquiA.nx file

    .. code-block:: bash

        cd [path_to_acquisitionA_folder]/acquisitionA

2. copy the original .nx file. Modification are in place. This is safer to copy the file.

    .. code-block:: bash

        cp original_acquiA.nx acquiA.nx

3. invalidate the flat field frames made at start. In the case let say that we want to invalid frames from 20 to 40 included:

    .. code-block:: bash

        nxtomomill patch-nx set83_tomo_black_drum_LPJ01_6p5p_20N_0001_0000_patch.nx entry0000 --invalid-frames 20:41

4. check that the invalidation of frames worked properly using silx view for example

5. get the silx url you want to link as the new flat field. Syntax is `silx://[file_path]?path=[data_path]&slice=[slices]`
   for example here we want to link frames 2000 to 2021 from acquiB.nx
   So the url looks like: silx://[folder_to_acquiB]/acquiB.nx?path=/entry000B/instrument/detector/data&slices=2000:2021

6. then patch flat from patch-nx command and the 'flats-at-start' option:

    .. code-block:: bash

        nxtomomill patch-nx acquiA.nx entry000A --flats-at-start "silx://[folder_to_acquiB]/acquiB.nx?path=/entry000B/instrument/detector/data&slices=2000:2021"

    .. warning::
        when you provide the url make sure you use `"` or `'` characters. Otherwise in this case the command will be executed as a background task and slices will be ignored.
        It will also try to link it with the full dataset at `/entry000B/instrument/detector/data`

7. check that your dataset is complete (using silx view for example)
