Repository: physiopy/phys2bids

Issue:
Adhering to BIDS units standards
<!--- Provide a general summary of the issue in the Title above -->

## Detailed Description
<!--- Provide a detailed description of the change or addition you are proposing -->
[BIDS uses a standard format for units of measure too](https://bids-specification.readthedocs.io/en/stable/99-appendices/05-units.html).
Our files have different ways to report units, but we should treat them with phys2bids!

## Possible Implementation
<!--- Not obligatory, but suggest an idea for implementing addition or change -->
<!--- If you already have worked on the idea, please share a link to the branch in your forked project -->
A possible implementation is adding a dictionary and a function, either in the main script or in a separate file, that gets called toward the end of the `_main()` function - before exporting the `json` file.
The dictionary contains different possible types of homonyms for the units, and the function reads what units our objects contain and changes them accordingly to the dictionary. 

Comments:

Patch:
diff --git a/phys2bids/bids_units.py b/phys2bids/bids_units.py
new file mode 100644
index 0000000..b1eb671
--- /dev/null
+++ b/phys2bids/bids_units.py
@@ -0,0 +1,84 @@
+import logging
+
+LGR = logging.getLogger(__name__)
+
+unit_aliases = {
+                # kelvin: thermodynamic temperature
+                'k': 'K', 'kelvin': 'K', 'kelvins': 'K',
+                # mole: amount of substance
+                'mol': 'mol', 'mole': 'mol',
+                # newton: force, weight
+                'newton': 'N', 'newtons': 'N', 'n': 'N',
+                # pascal: pressure, stress
+                'pascal': 'Pa', 'pascals': 'Pa', 'pa': 'Pa',
+                # volt: voltage (electrical potential), emf
+                'v': 'V', 'volt': 'V', 'volts': 'V',
+                # degree Celsius: temperature relative to 273.15 K
+                '°c': '°C', '°celsius': '°C', 'celsius': '°C',
+                # ampere: electric current
+                'a': 'A', 'ampere': 'A', 'amp': 'A', 'amps': 'A',
+                # second: time and hertzs
+                '1/hz': 's', '1/hertz': 's', 'hz': 'Hz',
+                '1/s': 'Hz', '1/second': 'Hz', '1/seconds': 'Hz',
+                '1/sec': 'Hz', '1/secs': 'Hz', 'hertz': 'Hz',
+                'second': 's', 'seconds': 's', 'sec': 's',
+                'secs': 's', 's': 's',
+}
+
+# Init dictionary of aliases for multipliers. Entries are still lowercase
+prefix_aliases = {
+                    # Multiples - skip "mega" and only up to "tera"
+                    'da': 'da', 'deca': 'da', 'h': 'h', 'hecto': 'h',
+                    'k': 'k', 'kilo': 'k', 'g': 'G', 'giga': 'G', 't': 'T',
+                    'tera': 'T',
+                    # Submultipliers
+                    'd': 'd', 'deci': 'd', 'c': 'c', 'centi': 'c',
+                    'milli': 'm', 'm': 'm', 'µ': 'µ', 'micro': 'µ',
+                    'n': 'n', 'nano': 'n', 'p': 'p', 'pico': 'p',
+                    'f': 'f', 'femto': 'f', 'a': 'a', 'atto': 'a',
+                    'z': 'z', 'zepto': 'z', 'y': 'y', 'yocto': 'y',
+}
+
+
+def bidsify_units(orig_unit):
+    """
+    Read the input unit of measure and use the dictionary of aliases
+    to bidsify its value.
+    It is possible to make simple conversions
+
+    Parameters
+    ----------
+    unit: string
+        Unit of measure, might or might not be BIDS compliant.
+
+    Returns
+    -------
+    new_unit: str
+        BIDSified alias of input unit
+
+    Notes
+    -----
+    This function should implement a double check, one for unit and
+    the other for prefixes (e.g. "milli"). However, that is going to be tricky,
+    unless there is a weird way to multiply two dictionaries together.
+    """
+    # call prefix and unit dicts
+    # for every unit alias in the dict
+    orig_unit = orig_unit.lower()
+    for u_key in unit_aliases.keys():
+        if orig_unit.endswith(u_key):
+            new_unit = unit_aliases[u_key]
+            unit = orig_unit[:-len(u_key)]
+            if unit != '':
+                # for every prefix alias
+                prefix = prefix_aliases.get(unit, '')
+                if prefix == '':
+                    LGR.warning(f'The given unit prefix {unit} does not have aliases, '
+                                f'passing it as is')
+                    prefix = orig_unit[:len(unit)]
+                return prefix + new_unit
+            else:
+                return new_unit
+    LGR.warning(f'The given unit {orig_unit} does not have aliases, '
+                f'passing it as is')
+    return orig_unit
diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py
index e57bcd3..138a512 100644
--- a/phys2bids/phys2bids.py
+++ b/phys2bids/phys2bids.py
@@ -37,6 +37,7 @@ from numpy import savetxt
 from phys2bids import utils, viz, _version
 from phys2bids.cli.run import _get_parser
 from phys2bids.physio_obj import BlueprintOutput
+from phys2bids.bids_units import bidsify_units
 
 LGR = logging.getLogger(__name__)
 
@@ -265,6 +266,8 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None,
 
     LGR.info(f'Reading the file {infile}')
     phys_in = populate_phys_input(infile, chtrig)
+    for index, unit in enumerate(phys_in.units):
+        phys_in.units[index] = bidsify_units(unit)
     LGR.info('Reading infos')
     phys_in.print_info(filename)
     # #!# Here the function viz.plot_channel should be called


Test patch:
diff --git a/phys2bids/tests/test_bids_units.py b/phys2bids/tests/test_bids_units.py
new file mode 100644
index 0000000..4cb58a5
--- /dev/null
+++ b/phys2bids/tests/test_bids_units.py
@@ -0,0 +1,14 @@
+from phys2bids.bids_units import bidsify_units
+from phys2bids.bids_units import unit_aliases
+
+
+def test_bidsify_units():
+    # test unit with standard prefix
+    assert bidsify_units('centik') == 'cK'
+    # test unit with not standard prefix
+    assert bidsify_units('matV') == 'matV'
+    # test unit that's not bids standard
+    assert bidsify_units('mmlie') == 'mmlie'
+    # test there is not problem with every unit in the dict
+    for unit_key in unit_aliases.keys():
+        assert bidsify_units(unit_key) == unit_aliases[unit_key]