Repository: paris-saclay-cds/specio

Issue:
Add an argument to read_csv to merge wavelength

Comments:

Patch:
diff --git a/specio/core/functions.py b/specio/core/functions.py
index c47f79d..8185e05 100644
--- a/specio/core/functions.py
+++ b/specio/core/functions.py
@@ -144,7 +144,7 @@ def _validate_filenames(uri):
         return sorted(glob.glob(os.path.expanduser(uri)))
 
 
-def _zip_spectrum(spectrum):
+def _zip_spectrum(spectrum, tol_wavelength):
     """Compress if possible several Spectrum into a single one.
 
     Parameters
@@ -152,6 +152,10 @@ def _zip_spectrum(spectrum):
     spectrum : list of Spectrum
         The list of Spectrum to zip.
 
+    tol_wavelength : float
+        Tolerance to merge spectrum when their wavelength are slightly
+        different.
+
     Returns
     -------
     zipped_spectrum : Spectrum or list of Spectrum
@@ -166,7 +170,8 @@ def _zip_spectrum(spectrum):
         wavelength = spectrum[0].wavelength
         try:
             consistent_wavelength = [np.allclose(sp.wavelength,
-                                                 wavelength)
+                                                 wavelength,
+                                                 atol=tol_wavelength)
                                      for sp in spectrum]
             if not all(consistent_wavelength):
                 return spectrum
@@ -194,7 +199,7 @@ def _zip_spectrum(spectrum):
         return output_spectrum
 
 
-def specread(uri, format=None, **kwargs):
+def specread(uri, format=None, tol_wavelength=1e-5, **kwargs):
     """Read spectra in a given format.
 
     Reads spectrum from the specified file. Returns a list or a
@@ -215,6 +220,10 @@ def specread(uri, format=None, **kwargs):
         The format to use to read the file. By default specio selects
         the appropriate for you based on the filename and its contents.
 
+    tol_wavelength : float, optional
+        Tolerance to merge spectrum when their wavelength are slightly
+        different.
+
     kwargs : dict
         Further keyword arguments are passed to the reader. See :func:`.help`
         to see what arguments are available for a particular format.
@@ -241,7 +250,7 @@ def specread(uri, format=None, **kwargs):
             spectrum = _get_reader_get_data(uri, format, **kwargs)
 
         if isinstance(spectrum, list):
-            spectrum = _zip_spectrum(spectrum)
+            spectrum = _zip_spectrum(spectrum, tol_wavelength)
 
         return spectrum
 


Test patch:
diff --git a/specio/core/tests/test_functions.py b/specio/core/tests/test_functions.py
index 0cfd489..049cdbb 100644
--- a/specio/core/tests/test_functions.py
+++ b/specio/core/tests/test_functions.py
@@ -87,14 +87,25 @@ def _generate_list_spectrum(*args):
             for _ in range(n_spectrum)]
 
 
+def _generate_list_spectrum_close_wavelength(*args):
+    n_wavelength = 5
+    tol = 1e-3
+    wavelength = np.arange(5) + np.random.uniform(low=-tol, high=tol)
+    return Spectrum(np.random.random(n_wavelength),
+                    wavelength,
+                    None)
+
+
 @pytest.mark.parametrize(
-    "side_effect,spectra_type,spectra_shape",
-    [(_generate_spectrum_identical_wavelength, Spectrum, (10, 5)),
-     (_generate_spectrum_different_wavelength_size, list, 10),
-     (_generate_spectrum_different_wavelength, list, 10),
-     (_generate_list_spectrum, list, 30)])
-def test_specread_consitent_wavelength(side_effect, spectra_type,
-                                       spectra_shape, mocker):
+    "side_effect,tol_wavelength,spectra_type,spectra_shape",
+    [(_generate_spectrum_identical_wavelength, 1e-5, Spectrum, (10, 5)),
+     (_generate_spectrum_different_wavelength_size, 1e-5, list, 10),
+     (_generate_spectrum_different_wavelength, 1e-5, list, 10),
+     (_generate_list_spectrum, 1e-5, list, 30),
+     (_generate_list_spectrum_close_wavelength, 1e-2, Spectrum, (10, 5)),
+     (_generate_list_spectrum_close_wavelength, 1e-5, list, 10)])
+def test_specread_consitent_wavelength(side_effect, tol_wavelength,
+                                       spectra_type, spectra_shape, mocker):
     # emulate that we read several file
     mocker.patch('specio.core.functions._validate_filenames',
                  return_value=['filename' for _ in range(10)])
@@ -103,7 +114,7 @@ def test_specread_consitent_wavelength(side_effect, spectra_type,
                  side_effect=side_effect)
 
     # emulate the spectrum reading
-    spectra = specread('')
+    spectra = specread('', tol_wavelength=tol_wavelength)
     assert isinstance(spectra, spectra_type)
     if isinstance(spectra, Spectrum):
         assert spectra.amplitudes.shape == spectra_shape