Repository: physiopy/phys2bids

Issue:
Sampling starting time is different in frequency outputs
Right now the sampling starting time is different for outputs with different frequencies when the file is multifreq

## Expected Behavior
sampling starting time is the same in all frequency files

## Actual Behavior
<!--- NECESSARY -->
the sampling time is different in each file. this is due to the fact that BlueprintOutput.init_from_blueprint is assuming that the time channel is always in the blueprint  input object. In multifreq files this is not true due to the way we implement the separation.
```
phys2bids -in Test_belt_pulse_multifreq.txt -chtrig 3 -outdir physio -ntp 60 -tr 1.5
INFO:phys2bids.phys2bids:Currently running phys2bids version v1.3.0-beta+950.gb8ee56c.dirty
INFO:phys2bids.phys2bids:Input file is Test_belt_pulse_multifreq.txt
INFO:phys2bids.utils:File extension is .acq
WARNING:phys2bids.utils:If both acq and txt files exist in the path, acq will be selected.
INFO:phys2bids.phys2bids:Reading the file ./Test_belt_pulse_multifreq.acq
INFO:phys2bids.interfaces.acq:00. Channel RESP - RSP100C: 1336815 samples, 10000.0 samples/sec, loaded: True
INFO:phys2bids.interfaces.acq:01. Channel PULSE - Custom, DA100C: 83550 samples, 625.0 samples/sec, loaded: True
INFO:phys2bids.interfaces.acq:02. Channel MR TRIGGER - Custom, HLT100C - A 5: 1336815 samples, 10000.0 samples/sec, loaded: True
INFO:phys2bids.interfaces.acq:03. Channel PPG100C: 1336815 samples, 10000.0 samples/sec, loaded: True
INFO:phys2bids.interfaces.acq:04. Channel CO2: 1336815 samples, 10000.0 samples/sec, loaded: True
INFO:phys2bids.interfaces.acq:05. Channel O2: 1336815 samples, 10000.0 samples/sec, loaded: True
INFO:phys2bids.phys2bids:Checking that units of measure are BIDS compatible
INFO:phys2bids.phys2bids:Reading infos
INFO:phys2bids.physio_obj:
------------------------------------------------
File Test_belt_pulse_multifreq.acq contains:
01. RESP - RSP100C; sampled at 10000.0 Hz
02. PULSE - Custom, DA100C; sampled at 625.0 Hz
03. MR TRIGGER - Custom, HLT100C - A 5; sampled at 10000.0 Hz
04. PPG100C; sampled at 10000.0 Hz
05. CO2; sampled at 10000.0 Hz
06. O2; sampled at 10000.0 Hz
------------------------------------------------

INFO:phys2bids.viz:saving channel plot to physio/code/conversion/Test_belt_pulse_multifreq.png
INFO:phys2bids.physio_obj:Counting trigger points
INFO:phys2bids.physio_obj:The trigger is in channel 3
INFO:phys2bids.physio_obj:The number of timepoints according to the std_thr method is 60. The computed threshold is 1.5631
INFO:phys2bids.physio_obj:Checking number of timepoints
INFO:phys2bids.physio_obj:Found just the right amount of timepoints!
INFO:phys2bids.viz:Plot trigger
INFO:phys2bids.phys2bids:Found 2 different frequencies in input!
INFO:phys2bids.phys2bids:Preparing 2 output files.
INFO:phys2bids.phys2bids:Exporting files for run 1 freq 10000.0
INFO:phys2bids.phys2bids:
------------------------------------------------
Filename:            Test_belt_pulse_multifreq.acq

Timepoints expected: [60]
Timepoints found:    60
Sampling Frequency:  10000.0 Hz
Sampling started at: 10.4251 s
Tip: Time 0 is the time of first trigger
------------------------------------------------

INFO:phys2bids.phys2bids:Exporting files for run 1 freq 625.0
INFO:phys2bids.phys2bids:
------------------------------------------------
Filename:            Test_belt_pulse_multifreq.acq

Timepoints expected: [60]
Timepoints found:    60
Sampling Frequency:  625.0 Hz
Sampling started at: 0.1288 s
Tip: Time 0 is the time of first trigger
------------------------------------------------
```
## Steps to Reproduce the Problem
<!--- Briefly point out the steps we should take to reproduce the problem -->

   phys2bids -in Test_belt_pulse_multifreq.txt -chtrig 3 -outdir physio -ntp 60 -tr 1.5

## Specifications
<!--- Point out the version of phys2bids you are running and your OS version -->
    - Python version: 3.6.9
    - phys2bids version: phys2bids v1.3.0-beta+950.gb8ee56c
    - Platform: Ubuntu

## Possible solution
<!--- Describe a possible approach to solve the issue -->
    1. Resample time channel to each frequency so the time channel is in all the ``phys_out`` objects
    2. Refractor BlueprintOutput.init_from_blueprint 

Discussion:

Patch:
diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py
index 7f5bbe3..1eac52e 100644
--- a/phys2bids/phys2bids.py
+++ b/phys2bids/phys2bids.py
@@ -373,6 +373,13 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None,
             # Also create a BlueprintOutput object for each unique frequency found.
             # Populate it with the corresponding blueprint input and replace it
             # in the dictionary.
+            # Add time channel in the proper frequency.
+            if uniq_freq != phys_in[run].freq[0]:
+                phys_out[key].ch_name.insert(0, phys_in[run].ch_name[0])
+                phys_out[key].units.insert(0, phys_in[run].units[0])
+                phys_out[key].timeseries.insert(0, np.linspace(phys_in[run].timeseries[0][0],
+                                                phys_in[run].timeseries[0][-1],
+                                                num=phys_out[key].timeseries[0].shape[0]))
             phys_out[key] = BlueprintOutput.init_from_blueprint(phys_out[key])
 
         # Preparing output parameters: name and folder.


Test patch:
diff --git a/phys2bids/tests/test_integration.py b/phys2bids/tests/test_integration.py
index 8b918cc..63cbb22 100644
--- a/phys2bids/tests/test_integration.py
+++ b/phys2bids/tests/test_integration.py
@@ -156,7 +156,7 @@ def test_integration_heuristic(skip_integration, multifreq_lab_file):
     # Check sampling frequency
     assert check_string(log_info, 'Sampling Frequency', '40.0')
     # Check sampling started
-    assert check_string(log_info, 'Sampling started', '-157.8535')
+    assert check_string(log_info, 'Sampling started', '3.6960')
     # Check first trigger
     assert check_string(log_info, 'first trigger', 'Time 0', is_num=False)
 
@@ -167,8 +167,8 @@ def test_integration_heuristic(skip_integration, multifreq_lab_file):
 
     # Compares values in json file with ground truth
     assert math.isclose(json_data['SamplingFrequency'], 40.0,)
-    assert math.isclose(json_data['StartTime'], -157.8535,)
-    assert json_data['Columns'] == ['O2']
+    assert math.isclose(json_data['StartTime'], 3.6960,)
+    assert json_data['Columns'] == ['time', 'O2']
 
     # ##### Checks for 100 Hz files
     # Read log file (note that this file is not the logger file)
@@ -183,7 +183,7 @@ def test_integration_heuristic(skip_integration, multifreq_lab_file):
     # Check sampling frequency
     assert check_string(log_info, 'Sampling Frequency', '100.0')
     # Check sampling started
-    assert check_string(log_info, 'Sampling started', '-0.3057')
+    assert check_string(log_info, 'Sampling started', '3.6960')
     # Check first trigger
     assert check_string(log_info, 'first trigger', 'Time 0', is_num=False)
 
@@ -194,8 +194,8 @@ def test_integration_heuristic(skip_integration, multifreq_lab_file):
 
     # Compares values in json file with ground truth
     assert math.isclose(json_data['SamplingFrequency'], 100.0,)
-    assert math.isclose(json_data['StartTime'], -0.3057,)
-    assert json_data['Columns'] == ['CO2']
+    assert math.isclose(json_data['StartTime'], 3.6960,)
+    assert json_data['Columns'] == ['time', 'CO2']
 
     # Remove generated files
     shutil.rmtree(test_path_output)