===================================
TimeshiftFD Component Specification
===================================

.. contents:: Contents
    :local:

Overview
========
**TimeshiftFD component** is a feature descriptor.
This component shifts each attribute's data based on a specified shift amount.

**Example**: When the interval of each _datetime is constant.

* SPD:

  .. code-block:: python
  
      dl1 -> ts1
  
      ---
  
      components:
          dl1:
              component: DataLoader
    
          ts1:
              component: TimeshiftFDComponent
              features: all()
              shift: [["name == 'humidity'", [3, -3]], ["re_match('.*ure', name)", ['-2D']], ["name == 'weather'", [1]]]

* Input of the component:

 +--------+---------------+---------------+------------+-----------+
 |   _sid |   _datetime   |   temperature |   humidity |   weather |
 +========+===============+===============+============+===========+
 | 0      | 2013-06-20    | 22.3          | 88         | sunny     |
 +--------+---------------+---------------+------------+-----------+
 | 1      | 2013-06-21    | 21.8          | 88         | cloudy    |
 +--------+---------------+---------------+------------+-----------+
 | 2      | 2013-06-22    | 22.8          | 75         | sunny     |
 +--------+---------------+---------------+------------+-----------+
 | 3      | 2013-06-23    | 23.4          | 75         | rainy     |
 +--------+---------------+---------------+------------+-----------+
 | 4      | 2013-06-24    | 23.3          | 76         | cloudy    |
 +--------+---------------+---------------+------------+-----------+

* Output of the component:

 +--------+---------------+--------------------+---------------------+-------------------------+-------------------+
 |   _sid |   _datetime   |   ts1(3)_humidity  |   ts1(-3)_humidity  |   ts1(-2D)_temperature  |   ts1(1)_weather  |
 +========+===============+====================+=====================+=========================+===================+
 | 0      | 2013-06-20    | 75                 | NaN                 | NaN                     | cloudy            |
 +--------+---------------+--------------------+---------------------+-------------------------+-------------------+
 | 1      | 2013-06-21    | 76                 | NaN                 | NaN                     | sunny             |
 +--------+---------------+--------------------+---------------------+-------------------------+-------------------+
 | 2      | 2013-06-22    | NaN                | NaN                 | 22.3                    | rainy             |
 +--------+---------------+--------------------+---------------------+-------------------------+-------------------+
 | 3      | 2013-06-23    | NaN                |  88                 | 21.8                    | cloudy            |
 +--------+---------------+--------------------+---------------------+-------------------------+-------------------+
 | 4      | 2013-06-24    | NaN                |  88                 | 22.8                    | NaN               |
 +--------+---------------+--------------------+---------------------+-------------------------+-------------------+

|

**Example**: When the interval of each _datetime is not constant.

* SPD:

  .. code-block:: python

      dl1 -> ts1

      ---

      components:
          dl1:
              component: DataLoader
  
          ts1:
              component: TimeshiftFDComponent
              features: all()
              shift: [["name == 'humidity'", [3]], ["re_match('.*ure', name)", ['-1D']]]

* Input of the component:

 +--------+---------------+----------------+-------------+
 |   _sid |   _datetime   |   temperature  |   humidity  |
 +========+===============+================+=============+
 | 0      | 2013-06-20    | 22.3           |  88         | 
 +--------+---------------+----------------+-------------+
 | 1      | 2013-06-21    | 21.8           |  88         |
 +--------+---------------+----------------+-------------+
 | 2      | 2013-06-23    | 23.4           |  75         |
 +--------+---------------+----------------+-------------+
 | 3      | 2013-06-24    | 23.3           |  76         |
 +--------+---------------+----------------+-------------+
 | 4      | 2013-06-25    | 22.6           |  78         |
 +--------+---------------+----------------+-------------+

* Output of the component:

 +--------+---------------+-------------------------+--------------------+
 |   _sid |   _datetime   |   ts1(-1D)_temperature  |   ts1(3)_humidity  |
 +========+===============+=========================+====================+
 | 0      | 2013-06-20    |  NaN                    |  76                | 
 +--------+---------------+-------------------------+--------------------+
 | 1      | 2013-06-21    | 22.3                    |  78                |
 +--------+---------------+-------------------------+--------------------+
 | 2      | 2013-06-23    |  NaN                    | NaN                |
 +--------+---------------+-------------------------+--------------------+
 | 3      | 2013-06-24    | 23.4                    | NaN                |
 +--------+---------------+-------------------------+--------------------+
 | 4      | 2013-06-25    | 23.3                    | NaN                |
 +--------+---------------+-------------------------+--------------------+

This component has no component-specific external formats.

.. seealso::

    Component-common external format files in :ref:`convert_process`

|

Parameters
==========
Here are the component-specific parameters for the **TimeshiftFD component**.

SPD
---

The following parameter is for "components" section of SPD.

.. list-table::
   :header-rows: 1
   :widths: 1, 25, 1, 1, 25

   * - Parameter Name
     - Format and Type
     - Domain
     - Default Value
     - Description
   * - shift [1]_
     - | [[**feature_expr**, [**shift_value**]]]
     - --
     - --
     - Specifies target features and parameters of shift.

.. [1] Required parameter

Details of shift
----------------

* **feature_expr** follows the format described in *Attribute Selection* of *SPD (SAMPO Process Description) File Specification*::

      're_match(".*Length", name)'

* **shift_value** can be described as integer, digit string, or digit string with time unit as shown below::

      5, '5', '5D', '100H'

  | The following time units are available.


  .. list-table::
     :header-rows: 1
     :widths: 20, 20

     * - Time unit
       - Description
     * - D
       - Day
     * - H
       - Hour
     * - T
       - Minute
     * - S
       - Second
     * - L
       - Millisecond
 
  If the **shift_value** includes a time unit, this component will shift data based on **_datetime** index. If the **shift_value** is integer or digit string, this component will shift data based on input data order.

|

Utilizable Sample Metadata
==========================
There are no component-specific sample metadata available.

|

Output Attributes
=================
**TimeshiftFD component** generates the following attributes:

.. list-table::
  :header-rows: 1
  :widths: 3,1,3

  * - Attribute Name
    - Scale
    - Description
  * - *<component_id>*\ (\ **shift_value**\ )_\ *<original_attribute_name>*
    - Same as the scale of the original attribute.
    - Shifted data based on **shift_value**\ .

These attributes are in the component output data. These can be loaded
in SAMPO API or saved as data.csv after executing :ref:`convert_process`.

.. seealso::

    Obtaining process results via `ProcessResultLoader <../../api/process_result_loader.html>`_.

|

Attribute Metadata
==================
The metadata of the output attributes is created with the following rules.

Context Rule
------------
.. list-table::
  :header-rows: 1
  :widths: 3,1,3

  * - Attribute Name 
    - Context Name
    - Description
  * - *<component_id>*\ (\ **shift_value**\ )_\ *<original_attribute_name>*
    - shift
    - Set the value of **shift_value**

Derivation Rule
---------------
Each new attribute is derived from the corresponding attribute selected by the ``features`` parameter of the component.

Example
-------
.. code-block:: javascript

    {
        "nodes": [
            {"aid": "_sid", "name": "_sid", ... },
            {"aid": "_datetime", "name": "_datetime", ... },
            {"aid": "dl1[0]", "name": "temperature", ... },
            {"aid": "dl1[1]", "name": "humidity", ... },
            {"aid": "ts1[0]", "name": "ts1(3)_humidity", "scale": "integer",
             "is_excluded": false, "cid": "ts1", "cindex": 0, "values": null, 
             "is_kept": false, "context": {"shift": 3}}, 
            {"aid": "ts1[1]", "name": "ts1(-1D)_temperature", "scale": "real",
             "is_excluded": false, "cid": "ts1", "cindex": 1, "values": null, 
             "is_kept": false, "context": {"shift": "-1D"}}
        ], 
        "links": [
            {"source": "dl1[1]", "target": "ts1[0]"}, 
            {"source": "dl1[0]", "target": "ts1[1]"}
        ]
    }

.. seealso::
    
    Attribute metadata file format in :ref:`Attribute Metadata File Specification <attribute-metadata>`

|

Model
=====
The model of this component can be described by its fd_params.

.. list-table::
  :header-rows: 1
  :widths: 3,1,3

  * - fd_params
    - Type
    - Description
  * - source_attr_names
    - list of string
    - A list of attribute names where the output attribute is derived from.
  * - params
    - dict
    - The keys of this dictionary are the same as the context of this component's Attribute Metadata.

When loaded in the SAMPO API, the model is represented as a dict of its fd_params.

.. seealso::

    Obtaining process results via `ProcessResultLoader <../../api/process_result_loader.html>`_.

::

    {'fd_params':
        [{'source_attr_names': ['humidity'], 'params': {'shift': 3}},
         {'source_attr_names': ['temperature'], 'params': {'shift': '-1D'}}]}

Details
=======
* In the learning phase, this component only checks the validity of the shift parameters by using the following conditions:

  * If the ``shift`` parameter includes non list value, raise exception.
  * If a **feature_expr** of a ``shift`` parameter is not string, raise exception.
  * If a **shift_value** of a ``shift`` parameter includes a time unit character and the input dataframe has no **_datetime** index, raise exception.
  * If a **shift_value** format of a ``shift`` parameter is invalid, raise exception.
* In the running phase, this component shifts the input data and returns the transformed data.

  * After shifted, if the index does not exist in the original data, the output data will be NaN. (See example in the overview.)
  * If the input dataframe has non-unique **_datetime** index and a **shift_value** includes a time unit character, this component raises an exception.
