Repository: radis/radis (language: python)

Issue:
abscoeff2xsection causes crash when using MergeSlabs
### 🐛 Describe the bug

First of all the error traceback for this issue:
```
Traceback (most recent call last):
  File "C:\Users\username\AppData\Local\anaconda3\envs\Radis-Simulator\Lib\threading.py", line 1073, in _bootstrap_inner
    self.run()
  File "C:\Users\username\AppData\Local\anaconda3\envs\Radis-Simulator\Lib\threading.py", line 1010, in run
    self._target(*self._args, **self._kwargs)
  File "D:\_dev\Radis Simulator\src\main.py", line 777, in startSeriesSimulationTask
    gasSpectraDict = Root.combineCalculatedSpectraIntoGasSpectrum(
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\_dev\Radis Simulator\src\main.py", line 1038, in combineCalculatedSpectraIntoGasSpectrum
    hotGasMerge = MergeSlabs(
                  ^^^^^^^^^^^
  File "D:\_dev\Radis Simulator\radis-0.15\radis\los\slabs.py", line 830, in MergeSlabs
    s.update(
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\spectrum.py", line 1626, in update
    return update(
           ^^^^^^^
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\rescale.py", line 614, in update
    _recalculate(
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\rescale.py", line 2163, in _recalculate
    rescaled, rescaled_units = rescale_xsection(
                               ^^^^^^^^^^^^^^^^^
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\rescale.py", line 1816, in rescale_xsection
    xsection = abscoeff2xsection(
               ^^^^^^^^^^^^^^^^^^
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\equations.py", line 62, in abscoeff2xsection
    return abscoeff_cm1 * (k_b * Tgas_K / mole_fraction / pressure_Pa) * 1e6  # cm2
                           ~~~~~~~~~~~~~^~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for /: 'float' and 'str'
```

For context: this was discovered by me when trying to use a SpecDatabase, retrieving certain spectra from it, updating them to get all necessary quantities and combining certain spectra with MergeSlabs, while the spectra have different mole_fraction values.

The problem here is that inside the abscoeff2xsection function, mole_fraction is a string and not a float. Namely here mole_fraction is 'N/A'. This is done inside the MergeSlabs function line 685-687 in slabs.py where all non-intensive parameters are set to N/A. And because I'm merging spectra with different mole_fractions, this will cause that the condition mole_fraction for the merged spectra to be N/A.

And now because I have updated the single spectra retrieved from the database with `.update('all')`, xsection will be present there. Therefore  xsection will be added to the requested quantities to be recomputed (line 752 inside of slabs.py) for the merged spectrum.
This will cause it to be included in the `s.update` in line 830 in slabs.py and cause the call to abscoeff2xsection.

### 💡 Possible solutions

My current workaround it so make sure that xsection is not included in the single spectra that will be merged. 

But a possible solution could be to check if mole_fraction is 'N/A' and then exclude xsection inside the requested quantities to be recomputed. 
Maybe there is also a formula to calculate the crosssection of mixed/merged gases with different mole_fraction amounts which should be applied here - but I'm not deep enough in the theory to answer that.

### 🎲 Radis version

0.15

### 💻 Operating system

Windows


Discussion / hints:
Hello,
Can you provide a **simple** code to reproduce your bug on my computer please? 

Among the several problems raised, and from what I understood, there might be an ambiguity on what is the mole fraction when merging several spectra of different molecules
> Hello, Can you provide a **simple** code to reproduce your bug on my computer please?
> 
> Among the several problems raised, and from what I understood, there might be an ambiguity on what is the mole fraction when merging several spectra of different molecules

```py
import radis

def raisesNoError(firstSpectrum: radis.Spectrum, secondSpectrum: radis.Spectrum):
    quantitiesToUpdate: list[str] = ['transmittance_noslit', 'emissivity_noslit', 'emisscoeff', 'absorbance',
                                     'radiance_noslit', 'abscoeff']

    firstSpectrum.update(quantitiesToUpdate)
    print(firstSpectrum.get_quantities())
    print(f'Is xsection included? {'xsection' in firstSpectrum.get_quantities()}')

    secondSpectrum.update(quantitiesToUpdate)
    print(secondSpectrum.get_quantities())
    print(f'Is xsection included? {'xsection' in secondSpectrum.get_quantities()}')

    print('Calculating MergeSlabs, should not fail:')
    radis.MergeSlabs(
        firstSpectrum,
        secondSpectrum,
        out_of_bounds='transparent',
        resample='full'
    )
    print('Did not fail!')

def raisesError(firstSpectrum: radis.Spectrum, secondSpectrum: radis.Spectrum):
    firstSpectrum.update('all')
    print(firstSpectrum.get_quantities())
    print(f'Is xsection included? {'xsection' in firstSpectrum.get_quantities()}')

    secondSpectrum.update('all')
    print(secondSpectrum.get_quantities())
    print(f'Is xsection included? {'xsection' in secondSpectrum.get_quantities()}')

    print('Calculating MergeSlabs, should fail:')
    radis.MergeSlabs(
        firstSpectrum,
        secondSpectrum,
        out_of_bounds='transparent',
        resample='full'
    )
    print('Did fail! (will not be printed :D)')


if __name__ == '__main__':
    firstSpectrum = radis.calc_spectrum(
        1900, 2300,
        molecule='CO2',
        isotope='all',
        pressure=1.01325,
        Tgas=700,
        mole_fraction=0.1,
        path_length=1,
        databank='hitemp',
    )

    secondSpectrum = radis.calc_spectrum(
        1900, 2300,
        molecule='CO2',
        isotope='all',
        pressure=1.01325,
        Tgas=700,
        mole_fraction=0.2,
        path_length=1,
        databank='hitemp',
    )

    raisesNoError(firstSpectrum.copy(), secondSpectrum.copy())
    raisesError(firstSpectrum.copy(), secondSpectrum.copy())
```

with the output:
```
CO2-hitemp-radisdb-700K-#1552 new quantities added: ['emisscoeff']
['abscoeff', 'absorbance', 'emissivity_noslit', 'transmittance_noslit', 'radiance_noslit', 'emisscoeff']
Is xsection included? False
CO2-hitemp-radisdb-700K-#1104 new quantities added: ['emisscoeff']
['abscoeff', 'absorbance', 'emissivity_noslit', 'transmittance_noslit', 'radiance_noslit', 'emisscoeff']
Is xsection included? False
Calculating MergeSlabs, should not fail:
Did not fail!
CO2-hitemp-radisdb-700K-#1552 new quantities added: ['emisscoeff', 'xsection']
['abscoeff', 'absorbance', 'emissivity_noslit', 'transmittance_noslit', 'radiance_noslit', 'emisscoeff', 'xsection']
Is xsection included? True
CO2-hitemp-radisdb-700K-#0080 new quantities added: ['emisscoeff', 'xsection']
['abscoeff', 'absorbance', 'emissivity_noslit', 'transmittance_noslit', 'radiance_noslit', 'emisscoeff', 'xsection']
Is xsection included? True
Calculating MergeSlabs, should fail:
Traceback (most recent call last):
  File "D:\_dev\Radis Simulator\bugreport_radis.py", line 69, in <module>
    raisesError(firstSpectrum.copy(), secondSpectrum.copy())
  File "D:\_dev\Radis Simulator\bugreport_radis.py", line 36, in raisesError
    radis.MergeSlabs(
  File "D:\_dev\Radis Simulator\radis-0.15\radis\los\slabs.py", line 830, in MergeSlabs
    s.update(
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\spectrum.py", line 1626, in update
    return update(
           ^^^^^^^
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\rescale.py", line 614, in update
    _recalculate(
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\rescale.py", line 2163, in _recalculate
    rescaled, rescaled_units = rescale_xsection(
                               ^^^^^^^^^^^^^^^^^
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\rescale.py", line 1816, in rescale_xsection
    xsection = abscoeff2xsection(
               ^^^^^^^^^^^^^^^^^^
  File "D:\_dev\Radis Simulator\radis-0.15\radis\spectrum\equations.py", line 62, in abscoeff2xsection
    return abscoeff_cm1 * (k_b * Tgas_K / mole_fraction / pressure_Pa) * 1e6  # cm2
                           ~~~~~~~~~~~~~^~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for /: 'float' and 'str'

Process finished with exit code 1
```

Could be considered not the simplest example, but highlights that the only difference between the two scenarios is, that xsection is included or not included, which will raise the TypeError.

Fix patch:
diff --git a/.travis.yml b/.travis.yml
index 070d82de7..19fd5c456 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -138,8 +138,15 @@ jobs:
 
     - stage: deploy
       name: Deploy to PyPI
+      services:
+        - xvfb
       install:
         - sudo apt-get update
+        #Next is to test after deploy
+        - wget -qO- https://micro.mamba.pm/api/micromamba/linux-64/1.5.8 | tar -xvj bin/micromamba
+        - ./bin/micromamba shell init -s bash -p ~/micromamba
+        - source ~/.bashrc
+        - micromamba activate base
       before_script: skip #do NOT run the before_script of "tests" stage
       script:
         - echo "Deploying to PyPI"
@@ -154,3 +161,9 @@ jobs:
         skip_existing: true
         skip_cleanup: true    # to keep wheels (in the ./dist folder?)
         distributions: "sdist bdist_wheel"
+      after_deploy:
+      - VERSION_RADIS=$(cat radis/__version__.txt)
+      - pip install radis==$VERSION_RADIS
+      - pip install pytest
+      - xvfb-run -a pytest -m "fast and not needs_cuda and not download_large_databases and not needs_db_CDSD_HITEMP and not needs_db_CDSD_HITEMP_PCN and not needs_db_CDSD_HITEMP_PC and not needs_db_HITEMP_CO2_DUNHAM and not needs_db_HITEMP_CO_DUNHAM" --durations=10
+
diff --git a/radis/api/exomolapi.py b/radis/api/exomolapi.py
index 7d16cccb9..075a8004b 100644
--- a/radis/api/exomolapi.py
+++ b/radis/api/exomolapi.py
@@ -3,7 +3,7 @@
    * MdbExomol is the MDB for ExoMol
 
 Initial code borrowed from the `Exojax <https://github.com/HajimeKawahara/exojax>`__
-code (which you should also have a look at !), by @HajimeKawahara, under MIT License.
+code (which you should also have a look at!), by @HajimeKawahara, under MIT License.
 
 """
 
@@ -550,27 +550,27 @@ def read_broad(broadf):
     return bdat
 
 
-def check_bdat(bdat):
-    """checking codes in .broad
-    Args:
-       bdat: exomol .broad data given by exomolapi.read_broad
-    Returns:
-       code level: None, a0, a1, other codes unavailable currently,
-    """
+# def check_bdat(bdat):
+#     """checking codes in .broad
+#     Args:
+#        bdat: exomol .broad data given by exomolapi.read_broad
+#     Returns:
+#        code level: None, a0, a1, other codes unavailable currently,
+#     """
 
-    def checkcode(code):
-        cmask = bdat["code"] == code
-        if len(bdat["code"][cmask]) > 0:
-            return True
-        else:
-            return False
+#     def checkcode(code):
+#         cmask = bdat["code"] == code
+#         if len(bdat["code"][cmask]) > 0:
+#             return True
+#         else:
+#             return False
 
-    codelv = None
-    for code in ["a0", "a1"]:
-        if checkcode(code):
-            codelv = code
+#     codelv = None
+#     for code in ["a0", "a1"]:
+#         if checkcode(code):
+#             codelv = code
 
-    return codelv
+#     return codelv
 
 
 def make_j2b(bdat, alpha_ref_default=0.07, n_Texp_default=0.5, jlower_max=None):
@@ -1254,58 +1254,67 @@ def set_broadening_coef(
         if n_Texp_def:
             self.n_Texp_def = n_Texp_def
 
-        if self.broadf:
-            try:
-                bdat = read_broad(self.broad_file)
-                if self.verbose > 1:
-                    print(
-                        "The file `{}` is used.".format(
-                            os.path.basename(self.broad_file)
-                        )
-                    )
-            except FileNotFoundError:
-                warnings.warn(
-                    "Could not load `{}`. The default broadening parameters are used.\n".format(
-                        os.path.basename(self.broad_file)
-                    )
+        if self.broadf and os.path.exists(self.broad_file):
+            bdat = read_broad(self.broad_file)
+            if self.verbose > 1:
+                print(
+                    "The file `{}` is used.".format(os.path.basename(self.broad_file))
                 )
 
+            # codelv = check_bdat(bdat)
+            codelv = np.unique(bdat["code"])
+            if self.verbose:
+                print("Broadening code level:", codelv)
+
+            if len(codelv) > 1:
+                warnings.warn(
+                    f"The broadening file contains more than one broadening code: {codelv}. This feature is NOT implemented yet."
+                )
+            elif codelv == "a0":
+                j2alpha_ref, j2n_Texp = make_j2b(
+                    bdat,
+                    alpha_ref_default=self.alpha_ref_def,
+                    n_Texp_default=self.n_Texp_def,
+                    jlower_max=df["jlower"].max(),
+                )
+                self.alpha_ref = j2alpha_ref[df["jlower"].values]
+                self.n_Texp = j2n_Texp[df["jlower"].values]
+            elif codelv == "a1":
+                j2alpha_ref, j2n_Texp = make_j2b(
+                    bdat,
+                    alpha_ref_default=self.alpha_ref_def,
+                    n_Texp_default=self.n_Texp_def,
+                    jlower_max=df["jlower"].max(),
+                )
+                jj2alpha_ref, jj2n_Texp = make_jj2b(
+                    bdat,
+                    j2alpha_ref_def=j2alpha_ref,
+                    j2n_Texp_def=j2n_Texp,
+                    jupper_max=df["jupper"].max(),
+                )
+                self.alpha_ref = np.array(
+                    jj2alpha_ref[df["jlower"].values, df["jupper"].values]
+                )
+                self.n_Texp = np.array(
+                    jj2n_Texp[df["jlower"].values, df["jupper"].values]
+                )
+            else:
+                warnings.warn(
+                    f"The broadening file contains this broadening code: {codelv}."
+                    + " This broadening code is NOT implemented yet.\n"
+                    + "Using default parameters instead."
+                )
                 self.alpha_ref = np.array(self.alpha_ref_def * np.ones(len(df)))
                 self.n_Texp = np.array(self.n_Texp_def * np.ones(len(df)))
-            else:
-                codelv = check_bdat(bdat)
-                if self.verbose:
-                    print("Broadening code level:", codelv)
-                if codelv == "a0":
-                    j2alpha_ref, j2n_Texp = make_j2b(
-                        bdat,
-                        alpha_ref_default=self.alpha_ref_def,
-                        n_Texp_default=self.n_Texp_def,
-                        jlower_max=df["jlower"].max(),
-                    )
-                    self.alpha_ref = j2alpha_ref[df["jlower"].values]
-                    self.n_Texp = j2n_Texp[df["jlower"].values]
-                elif codelv == "a1":
-                    j2alpha_ref, j2n_Texp = make_j2b(
-                        bdat,
-                        alpha_ref_default=self.alpha_ref_def,
-                        n_Texp_default=self.n_Texp_def,
-                        jlower_max=df["jlower"].max(),
-                    )
-                    jj2alpha_ref, jj2n_Texp = make_jj2b(
-                        bdat,
-                        j2alpha_ref_def=j2alpha_ref,
-                        j2n_Texp_def=j2n_Texp,
-                        jupper_max=df["jupper"].max(),
-                    )
-                    self.alpha_ref = np.array(
-                        jj2alpha_ref[df["jlower"].values, df["jupper"].values]
-                    )
-                    self.n_Texp = np.array(
-                        jj2n_Texp[df["jlower"].values, df["jupper"].values]
-                    )
         else:
+            if not os.path.exists(self.broad_file):
+                warnings.warn(
+                    "Could not load `{}`. The default broadening parameters are used.\n".format(
+                        os.path.basename(self.broad_file)
+                    )
+                )
             print("The default broadening parameters are used.")
+
             self.alpha_ref = np.array(self.alpha_ref_def * np.ones(len(df)))
             self.n_Texp = np.array(self.n_Texp_def * np.ones(len(df)))
 
diff --git a/radis/lbl/loader.py b/radis/lbl/loader.py
index d9373429a..0ace9d3f8 100644
--- a/radis/lbl/loader.py
+++ b/radis/lbl/loader.py
@@ -1172,7 +1172,7 @@ def fetch_databank(
         if [parfuncfmt, source].count("exomol") == 1:
             self.warn(
                 f"Using lines from {source} but partition functions from {parfuncfmt}"
-                + "for consistency we recommend using lines and partition functions from the same database",
+                + " for consistency we recommend using lines and partition functions from the same database",
                 "AccuracyWarning",
             )
         if memory_mapping_engine == "default":
diff --git a/radis/spectrum/rescale.py b/radis/spectrum/rescale.py
index dd409458d..568f2fa93 100644
--- a/radis/spectrum/rescale.py
+++ b/radis/spectrum/rescale.py
@@ -2017,6 +2017,23 @@ def _recalculate(
         recompute.append("abscoeff")
     recompute = set(recompute)  # remove duplicates
 
+    # check the slab is homogeneous to compute the cross-section
+    for key in ["Tgas", "pressure", "mole_fraction"]:
+        if key in spec.conditions:
+            good = isinstance(spec.conditions[key], (int, float)) and not isinstance(
+                spec.conditions[key], bool
+            )
+        else:
+            continue
+        if "xsection" in recompute and not good:
+            recompute.remove("xsection")
+            warn(
+                f"Rescaling the 'xsection' of Spectrum {spec.get_name()} but"
+                + " the spectrum is not homogeneous or not defined:\n"
+                + f"s.conditions[{key}] = 'N/A'\n"
+                + "If you are merging two spectra, make sure cross-sections are not included in the initial spectra, see https://github.com/radis/radis/issues/682."
+            )
+
     # Get units
     rescaled_units = spec.units.copy()
 
@@ -2272,7 +2289,7 @@ def _recalculate(
     for q in wanted:
         if not q in rescaled_list:
             raise AssertionError(
-                "{0} could not be rescaled as wanted. ".format(q)
+                "'{0}' could not be rescaled as wanted. ".format(q)
                 + "The following properties were rescaled: {0}".format(rescaled_list)
             )
     # ... everyone was added in the Spectrum properly
@@ -2280,14 +2297,14 @@ def _recalculate(
     for q in wanted:
         if not q in final_list:
             raise AssertionError(
-                "{0} is not in the final Spectrum. ".format(q)
+                "'{0}' is not in the final Spectrum. ".format(q)
                 + "Rescaled spectrum contains: {0}".format(final_list)
             )
     # ... "everyone was rescaled": check we didnt scale only part of the spectrum
     for q in initial:
         if not q in rescaled_list:
             raise AssertionError(
-                "{0} was initially in the Spectrum but was not ".format(q)
+                "'{0}' was initially in the Spectrum but was not ".format(q)
                 + "rescaled. This can lead to error. Rescaled spectrum "
                 + "contains: {0}".format(rescaled_list)
             )
diff --git a/setup.py b/setup.py
index 80e3f72ef..e9cb06de7 100644
--- a/setup.py
+++ b/setup.py
@@ -37,7 +37,7 @@
 from os.path import abspath, dirname, exists, join
 
 # from setuptools import Extension, find_packages, setup #for cython - unused after v0.15
-from setuptools import find_packages, setup
+from setuptools import setup
 
 # Build description from README (PyPi compatible)
 # -----------------------------------------------
@@ -144,85 +144,86 @@ def show_message(*lines):
     print("=" * 74, file=sys.stderr)
 
 
-def get_ext_modules(with_binaries):
-    """
-    Parameters
-    ----------
-    with_binaries: bool
-        if False, do not try to build Cython extensions
-    """
-    # Based on code from https://github.com/pallets/markupsafe/blob/main/setup.py
-
-    print(sys.version)
-    ext_modules = []
-    cmdclass = {}
-
-    if not with_binaries:
-        # skip building extensions
-        return {"cmdclass": cmdclass, "ext_modules": ext_modules}
-
-    # TO-DO: set language level
-
-    #### Cython is now completely removed - August 2024 - Radis 0.15 ###
-    # try:
-    #     import cython
-    # except (ModuleNotFoundError) as err:
-    #     raise BuildFailed(
-    #         "Cython not found : Skipping all Cython extensions...!"
-    #     ) from err
-
-    # print("Cython " + cython.__version__)
-
-    # from Cython.Distutils import build_ext
-
-    # class build_ext_subclass(build_ext):
-    #     def build_extensions(self):
-    #         c = self.compiler.compiler_type
-    #         copt = {
-    #             "msvc": ["/openmp", "/Ox", "/fp:fast", "/favor:INTEL64"],
-    #             "mingw32": ["-fopenmp", "-O3", "-ffast-math", "-march=native"],
-    #         }
-
-    #         lopt = {"mingw32": ["-fopenmp"]}
-
-    #         print("Compiling with " + c + "...")
-    #         try:
-    #             for e in self.extensions:
-    #                 e.extra_compile_args = copt[c]
-    #         except (KeyError):
-    #             pass
-    #         try:
-    #             for e in self.extensions:
-    #                 e.extra_link_args = lopt[c]
-    #         except (KeyError):
-    #             pass
-    #         try:
-    #             build_ext.build_extensions(self)
-    #         except (CCompilerError, DistutilsExecError, DistutilsPlatformError) as err:
-    #             raise BuildFailed() from err
-
-    # from numpy import get_include
-
-    # ext_modules.append(
-    #     Extension(
-    #         "radis_cython_extensions",
-    #         sources=[
-    #             "./radis/cython/radis_cython_extensions.pyx",
-    #         ],
-    #         include_dirs=[get_include()],
-    #         language="c++",
-    #         extra_link_args=[],
-    #         define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
-    #     )
-    # )
-
-    # cmdclass["build_ext"] = build_ext_subclass
-
-    return {"cmdclass": cmdclass, "ext_modules": ext_modules}
+# Deprecated - See Main install routine for radis<0.15
+# def get_ext_modules(with_binaries):
+#     """
+#     Parameters
+#     ----------
+#     with_binaries: bool
+#         if False, do not try to build Cython extensions
+#     """
+#     # Based on code from https://github.com/pallets/markupsafe/blob/main/setup.py
+
+#     print(sys.version)
+#     ext_modules = []
+#     cmdclass = {}
+
+#     if not with_binaries:
+#         # skip building extensions
+#         return {"cmdclass": cmdclass, "ext_modules": ext_modules}
+
+#     # TO-DO: set language level
+
+#     #### Cython is now completely removed - August 2024 - Radis 0.15 ###
+#     # try:
+#     #     import cython
+#     # except (ModuleNotFoundError) as err:
+#     #     raise BuildFailed(
+#     #         "Cython not found : Skipping all Cython extensions...!"
+#     #     ) from err
+
+#     # print("Cython " + cython.__version__)
+
+#     # from Cython.Distutils import build_ext
+
+#     # class build_ext_subclass(build_ext):
+#     #     def build_extensions(self):
+#     #         c = self.compiler.compiler_type
+#     #         copt = {
+#     #             "msvc": ["/openmp", "/Ox", "/fp:fast", "/favor:INTEL64"],
+#     #             "mingw32": ["-fopenmp", "-O3", "-ffast-math", "-march=native"],
+#     #         }
+
+#     #         lopt = {"mingw32": ["-fopenmp"]}
+
+#     #         print("Compiling with " + c + "...")
+#     #         try:
+#     #             for e in self.extensions:
+#     #                 e.extra_compile_args = copt[c]
+#     #         except (KeyError):
+#     #             pass
+#     #         try:
+#     #             for e in self.extensions:
+#     #                 e.extra_link_args = lopt[c]
+#     #         except (KeyError):
+#     #             pass
+#     #         try:
+#     #             build_ext.build_extensions(self)
+#     #         except (CCompilerError, DistutilsExecError, DistutilsPlatformError) as err:
+#     #             raise BuildFailed() from err
+
+#     # from numpy import get_include
+
+#     # ext_modules.append(
+#     #     Extension(
+#     #         "radis_cython_extensions",
+#     #         sources=[
+#     #             "./radis/cython/radis_cython_extensions.pyx",
+#     #         ],
+#     #         include_dirs=[get_include()],
+#     #         language="c++",
+#     #         extra_link_args=[],
+#     #         define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
+#     #     )
+#     # )
+
+#     # cmdclass["build_ext"] = build_ext_subclass
+
+#     return {"cmdclass": cmdclass, "ext_modules": ext_modules}
 
 
 #%% Main install routine
-def run_setup(with_binary):
+def run_setup():
     setup(
         name="radis",
         version=__version__,
@@ -246,7 +247,7 @@ def run_setup(with_binary):
             "exomol",
             "line-by-line",
         ],
-        packages=find_packages(),
+        # packages=find_packages(), #this misses the gpu folder, see https://github.com/radis/radis/issues/681
         install_requires=[
             # Although it seems like a duplicate of requirements.txt, it is NECESSARY to tell pip what are the dependencies, issue #680.
             # (requirements.txt is only for the user, not for pip, see https://packaging.python.org/discussions/install-requires-vs-requirements/ and https://stackoverflow.com/questions/14399534/reference-requirements-txt-for-the-install-requires-kwarg-in-setuptools-setup-py)
@@ -319,7 +320,7 @@ def run_setup(with_binary):
             "Programming Language :: Python :: 3.12",
             "Operating System :: OS Independent",
         ],
-        **get_ext_modules(with_binary),
+        # **get_ext_modules(with_binary), #see Main install routine for radis<0.15
         include_package_data=True,  # add non .py data files in MANIFEST.in
         # package_data={'radis': ['radis/phys/units.txt']},
         zip_safe=False,  # impossible as long as we have external files read with __file__ syntax
@@ -328,21 +329,23 @@ def run_setup(with_binary):
 
 
 # %% Run Main install routine
-try:
-    run_setup(with_binary=False)  # radis 0.15 - Cython is not implemented anymore
-except BuildFailed:
-    import traceback
-
-    traceback.print_exc()
-    show_message(
-        "WARNING: RADIS C-extension could not be compiled, speedups",
-        " are not enabled.",
-        "Failure information, if any, is above.",
-        "Retrying the build without the C extension now.",
-    )
-    run_setup(with_binary=False)
-    show_message(
-        "WARNING: RADIS C-extension could not be compiled, speedups"
-        " are not enabled.",
-        "Plain-Python build succeeded.",
-    )
+run_setup()
+# %% Run Main install routine for radis<0.15 - Cython is not implemented anymore
+# try:
+#     run_setup(with_binary=False)
+# except BuildFailed:
+#     import traceback
+
+#     traceback.print_exc()
+#     show_message(
+#         "WARNING: RADIS C-extension could not be compiled, speedups",
+#         " are not enabled.",
+#         "Failure information, if any, is above.",
+#         "Retrying the build without the C extension now.",
+#     )
+#     run_setup(with_binary=False)
+#     show_message(
+#         "WARNING: RADIS C-extension could not be compiled, speedups"
+#         " are not enabled.",
+#         "Plain-Python build succeeded.",
+#     )


Test patch:
diff --git a/radis/test/lbl/test_loader.py b/radis/test/lbl/test_loader.py
index 96ac8915e..9e1ca2d6b 100644
--- a/radis/test/lbl/test_loader.py
+++ b/radis/test/lbl/test_loader.py
@@ -22,7 +22,13 @@
 except ImportError:
     vaex = NotInstalled(*not_installed_vaex_args)
 
+pytestmark = pytest.mark.random_order(
+    disabled=True
+)  # to make sure HITEMP-CO2-TEST is downloaded in 1st test and used after
 
+
+@pytest.mark.needs_connection
+@pytest.mark.fast
 def test_retrieve_from_database(
     plot=False, verbose=True, warnings=True, *args, **kwargs
 ):
@@ -229,6 +235,8 @@ def test_custom_abundance(verbose=True, plot=False, *args, **kwargs):
     assert s.compare_with((3 * s3.take("abscoeff")), "abscoeff", rtol=0.5e-2, plot=True)
 
 
+@pytest.mark.needs_connection
+@pytest.mark.download_large_databases
 @pytest.mark.skipif(isinstance(vaex, NotInstalled), reason="Vaex not available")
 def test_vaex_and_pandas_dataframe_fetch_databank():
     """
@@ -250,9 +258,10 @@ def test_vaex_and_pandas_dataframe_fetch_databank():
         1500,
         2000,
         molecule="CO",
-        isotope="1,2,3",
+        isotope="1,2",  # testing only 2 isotopes to save (a bit of) time
         pressure=1.01325,  # bar
         path_length=1,  # cm
+        verbose=3,
     )
 
     def compare_dataframe(df_vaex, df_pandas, columns):
@@ -334,6 +343,7 @@ def compare_dataframe(df_vaex, df_pandas, columns):
     # Comparing the dataframe fetched from GEISA
     assert compare_dataframe(df1, df2, df2.columns)
 
+    # Kurucz
     # Using an atom rather than molecule:
     sf = SpectrumFactory(
         1500,
@@ -434,12 +444,12 @@ def test_vaex_and_pandas_dataframe_load_databank():
 
 def _run_testcases(verbose=True, plot=False):
 
-    test_retrieve_from_database(plot=plot, verbose=verbose)
-    test_ignore_cached_files()
-    test_ignore_irrelevant_files(verbose=verbose)
-    test_custom_abundance()
+    # test_retrieve_from_database(plot=plot, verbose=verbose)
+    # test_ignore_cached_files()
+    # test_ignore_irrelevant_files(verbose=verbose)
+    # test_custom_abundance()
     test_vaex_and_pandas_dataframe_fetch_databank()
-    test_vaex_and_pandas_dataframe_load_databank()
+    # test_vaex_and_pandas_dataframe_load_databank()
 
 
 if __name__ == "__main__":
diff --git a/radis/test/spectrum/test_rescale.py b/radis/test/spectrum/test_rescale.py
index d2278a239..3f30098c6 100644
--- a/radis/test/spectrum/test_rescale.py
+++ b/radis/test/spectrum/test_rescale.py
@@ -551,14 +551,14 @@ def test_astropy_units(verbose=True, warnings=True, *args, **kwargs):
 
 
 def _run_all_tests(verbose=True, warnings=True, *args, **kwargs):
-    test_compression(verbose=verbose, warnings=warnings, *args, **kwargs)
+    # test_compression(verbose=verbose, warnings=warnings, *args, **kwargs)
     test_update_transmittance(verbose=verbose, warnings=warnings, *args, **kwargs)
-    test_get_recompute(verbose=verbose, warnings=warnings, *args, **kwargs)
-    test_rescale_vs_direct_computation(verbose=verbose, *args, **kwargs)
-    test_recompute_equilibrium(verbose=verbose, warnings=warnings, *args, **kwargs)
-    test_rescale_all_quantities(verbose=verbose, *args, **kwargs)
-    test_xsections(*args, **kwargs)
-    test_astropy_units(verbose=True, warnings=True, *args, **kwargs)
+    # test_get_recompute(verbose=verbose, warnings=warnings, *args, **kwargs)
+    # test_rescale_vs_direct_computation(verbose=verbose, *args, **kwargs)
+    # test_recompute_equilibrium(verbose=verbose, warnings=warnings, *args, **kwargs)
+    # test_rescale_all_quantities(verbose=verbose, *args, **kwargs)
+    # test_xsections(*args, **kwargs)
+    # test_astropy_units(verbose=True, warnings=True, *args, **kwargs)
     return True