diff --git a/mvcm/main.py b/mvcm/main.py
index c0832d67be72e81b711b542bc851d5c0ac1e4ee3..cf59473ba41521b0e2c3ab88e195a1aafec47ccf 100644
--- a/mvcm/main.py
+++ b/mvcm/main.py
@@ -168,19 +168,7 @@ def main(
                 try:
                     vnp02[b]
                 except KeyError:
-                    logger.info(f"Band {b} not found in file. No output will be written.")
-                    with Dataset(file_names["MOD03"]) as f:
-                        attrs = {attr: f.getncattr(attr) for attr in f.ncattrs()}
-                        shape = f["geolocation_data/latitude"][:].shape
-                    save_output(
-                        None,
-                        attrs,
-                        out_file,
-                        compression=5,
-                        debug=debug,
-                        shape=shape,
-                    )
-                    return
+                    logger.info(f"Band {b} not found in file. Fill values will be used instead.")
             logger.info(f"All bands found in file {file_names['MOD02']}. The code will run.")
 
     with Dataset(file_names["MOD03"]) as f:
diff --git a/mvcm/main_prep_only.py b/mvcm/main_prep_only.py
new file mode 100644
index 0000000000000000000000000000000000000000..eb24c3cf174b5ae64a236b0393089666c77149b4
--- /dev/null
+++ b/mvcm/main_prep_only.py
@@ -0,0 +1,295 @@
+"""Main function for MVCM."""
+
+import argparse
+import logging
+import os
+from datetime import datetime as dt
+
+import numpy as np
+import psutil
+import xarray as xr
+from netCDF4 import Dataset  # type: ignore
+from pkg_resources import get_distribution  # type: ignore
+from rich.logging import RichHandler
+from ruamel.yaml import YAML
+
+import mvcm.read_data as rd
+from mvcm.constants import SensorConstants
+from mvcm.write_output import run_mvcm, save_output
+
+_LOG_FORMAT = "%(message)s"
+logging.basicConfig(level="NOTSET", datefmt="[%X]", format=_LOG_FORMAT, handlers=[RichHandler()])
+logger = logging.getLogger(__name__)
+LOG_LEVELS = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
+
+proc = psutil.Process(os.getpid())
+
+
+def main(
+    satellite: str = "snpp",
+    sensor: str = "viirs",
+    data_path: str = "",
+    mod02: str = "",
+    mod03: str = "",
+    img02: str | None = "",
+    img03: str | None = "",
+    threshold_file: str = "",
+    geos_atm_1: str = "",
+    geos_atm_2: str = "",
+    geos_land: str = "",
+    geos_ocean: str = "",
+    geos_constants: str = "",
+    ndvi_file: str = "",
+    sst_file: str = "",
+    eco_file: str = "",
+    out_file: str = "",
+    exe_path: str = "/home/pveglio/mvcm/mvcm",
+    verbose: int = 0,
+    *,
+    debug: bool = False,
+    hires_only: bool = False,
+    mvcm_threshold_file: str | None,
+) -> None:
+    """MVCM main function.
+
+    Parameters
+    ----------
+    satellite: str
+        satellite name, not case-sensitive. Available options: [snpp, ]
+    sensor: str
+        sensor name, not case-sensitive. Available options: [viirs, ]
+    data_path: str
+        path where the data is stored
+    mod02: str
+        VIIRS MOD02 file name
+    mod03: str
+        VIIRS MOD03 file name
+    img02: [optional] str
+        VIIRS IMG02 file name
+    img03: [optional] str
+        VIIRS IMG03 file name
+    threshold_file: str
+        thresholds file name
+    geos_atm_1: str
+        file name of first GEOS5 file for atmospheric parameters
+    goes_atm_2: str
+        file name of second GEOS5 file for atmospheric parameters
+    geos_land: str
+        file name of GEOS5 land parameters
+    geos_ocean: str
+        file name of GEOS5 ocean parameters
+    geos_constants: str
+        file name of GEOS5 constants
+    ndvi_file: str
+        NDVI file name
+    sst_file: str
+        Sea surface temperature file name
+    eco_file: str
+        Ecosystem File
+    out_file: str
+        Output file name
+    verbose: int
+        Verbosity level
+    exe_path: str
+        Path to the MVCM executable
+    debug: bool
+        Debug mode
+    hires_only: bool
+        Only run MVCM with high resolution
+
+    Returns
+    -------
+    None
+    """
+    verbose_level = np.minimum(verbose + 1, 4)
+    logger.setLevel(LOG_LEVELS[verbose_level])
+
+    if img02 is None or img03 is None:
+        use_hires = False
+    else:
+        use_hires = True
+
+    file_names = {
+        "MOD02": f"{mod02}",
+        "MOD03": f"{mod03}",
+        "IMG02": f"{img02}",
+        "IMG03": f"{img03}",
+        "GEOS_atm_1": f"{geos_atm_1}",
+        "GEOS_atm_2": f"{geos_atm_2}",
+        "GEOS_land": f"{geos_land}",
+        "GEOS_ocean": f"{geos_ocean}",
+        "GEOS_constants": f"{geos_constants}",
+        "NDVI": f"{ndvi_file}",
+        "SST": f"{sst_file}",
+        "ECO": f"{eco_file}",
+        "ANC_DIR": f"{data_path}",
+    }
+    logger.info(f"Memory usage #1: {proc.memory_info().rss / 1e6} MB")
+
+    if hires_only is False:
+        logger.info("Running regular MVCM before high resolution")
+        run_mvcm(file_names, mvcm_threshold_file, out_file, exe_path)
+
+    with open(threshold_file) as f:
+        text = f.read()
+    thresholds = YAML(typ="safe").load(text)
+
+    viirs_m_bands = SensorConstants.VIIRS_VIS_BANDS + SensorConstants.VIIRS_IR_BANDS
+
+    with Dataset(file_names["MOD03"]) as f:
+        attrs = {attr: f.getncattr(attr) for attr in f.ncattrs()}
+        lat_shape = f["geolocation_data/latitude"][:].shape
+
+    fmt_in = "%Y-%m-%dT%H:%M:%S.%fZ"
+    fmt_out = "%Y-%m-%dT%H%M"
+
+    # We are not processing night granules
+    if use_hires is True:
+        with xr.open_dataset(file_names["IMG02"], group="observation_data") as vnp02:
+            for b in SensorConstants.VIIRS_IMG_BANDS:
+                try:
+                    vnp02[b]
+                except KeyError:
+                    logger.info(f"Band {b} not found in file. Hires data will be fill values.")
+                    attrs = {"version": _VERSION, "satellite": "VIIRS", "sensor": "VIIRS"}
+                    save_output(None, attrs, out_file, compression=5, debug=debug, shape=lat_shape)
+                    return
+            logger.info(f"All bands found in file {file_names['IMG02']}. The code will run.")
+    else:
+        with xr.open_dataset(file_names["MOD02"], group="observation_data") as vnp02:
+            for b in viirs_m_bands:
+                try:
+                    vnp02[b]
+                except KeyError:
+                    logger.info(f"Band {b} not found in file. Hires data will be fill values.")
+                    attrs = {"version": _VERSION, "satellite": "VIIRS", "sensor": "VIIRS"}
+                    save_output(None, attrs, out_file, compression=5, debug=debug, shape=lat_shape)
+                    return
+            logger.info(f"All bands found in file {file_names['MOD02']}. The code will run.")
+
+    logger.info(f"Memory usage #2: {proc.memory_info().rss / 1e6} MB")
+    # rd.get_data(satellite, sensor, file_names, thresholds, hires=use_hires)
+    viirs_data, pixel_type = rd.get_data(satellite, sensor, file_names, thresholds, hires=use_hires)
+    # viirs_data = rd.get_data(satellite, sensor, file_names, thresholds, hires=use_hires)
+
+    # viirs_data = xr.open_dataset("input_data.nc")
+    logger.info(f"Memory usage #3: {proc.memory_info().rss / 1e6} MB")
+
+    with xr.open_dataset(file_names["MOD02"]) as vnp02:
+        time_str = dt.strftime(dt.strptime(vnp02.time_coverage_start, fmt_in), fmt_out)
+
+    viirs_data.to_netcdf(
+        f"{os.path.dirname(out_file)}/input_data_{time_str}.nc", mode="w", format="NETCDF4"
+    )
+    pixel_type.to_netcdf(
+        f"{os.path.dirname(out_file)}/pixel_type_{time_str}.nc", mode="w", format="NETCDF4"
+    )
+
+    logger.info(f"Memory usage #4: {proc.memory_info().rss / 1e6} MB")
+    ###
+
+
+if __name__ == "__main__":
+    _VERSION = get_distribution("mvcm").version
+    parser = argparse.ArgumentParser(prog="MVCM", description="")
+
+    parser.add_argument(
+        "--satellite",
+        help="satellite name, not case-sensitive. Available options: [snpp, ]",
+        choices=[
+            "snpp",
+        ],
+    )
+    parser.add_argument(
+        "--sensor",
+        help="sensor name, not case-sensitive. Available options: [viirs, ]",
+        choices=[
+            "viirs",
+        ],
+    )
+    parser.add_argument("--path", help="path where the data is stored")
+    parser.add_argument("--l1b", help="level 1b file name")
+    parser.add_argument("--geolocation", help="geolocation file name")
+    parser.add_argument("--hires-l1b", help="VIIRS IMG02 file name")
+    parser.add_argument("--hires-geo", help="VIIRS IMG03 file name")
+    parser.add_argument("-t", "--threshold", help="thresholds file name")
+    parser.add_argument(
+        "--atmos-1",
+        help="file name of the first GEOS-IT file for atmospheric parameters",
+    )
+    parser.add_argument(
+        "--atmos-2",
+        help="file name of the second GEOS-IT file for atmospheric parameters",
+    )
+    parser.add_argument("--land", help="file name of GEOS-IT land parameters")
+    parser.add_argument("--ocean", help="file name of GEOS-IT ocean parameters")
+    parser.add_argument("--constants", help="file name of GEOS-IT constants")
+    parser.add_argument("--ndvi", help="NDVI file name")
+    parser.add_argument("--sst", help="Sea surface temperature file name")
+    parser.add_argument("--eco", help="Ecosystem file")
+    parser.add_argument("-o", "--out", help="output file name")
+    parser.add_argument(
+        "-V",
+        "--version",
+        action="version",
+        version=_VERSION,
+        help="print version and exit",
+    )
+    parser.add_argument(
+        "-v", "--verbose", action="count", default=1, help="print verbose information"
+    )
+    parser.add_argument("-d", "--debug", action="store_true", help="activate debug mode")
+    parser.add_argument("--hires-only", action="store_true", help="run only high resolution code")
+    parser.add_argument("-x", "--mvcm-exe-path", help="path to mvcm executable")
+    parser.add_argument(
+        "--mvcm-thresholds", help="thresholds file name for operational MVCM", default=None
+    )
+
+    args = parser.parse_args()
+
+    satellite = args.satellite or "snpp"
+    sensor = args.sensor or "viirs"
+    data_path = args.path
+    mod02 = args.l1b
+    mod03 = args.geolocation
+    img02 = args.hires_l1b or None
+    img03 = args.hires_geo or None
+    threshold_file = args.threshold
+    geos_atm_1 = args.atmos_1
+    geos_atm_2 = args.atmos_2
+    geos_land = args.land
+    geos_ocean = args.ocean
+    constants = args.constants
+    ndvi_file = args.ndvi
+    sst_file = args.sst
+    eco_file = args.eco
+    out_file = args.out
+    verbose = args.verbose or False
+    debug = args.debug or False
+
+    main(
+        satellite=satellite,
+        sensor=sensor,
+        data_path=data_path,
+        mod02=mod02,
+        mod03=mod03,
+        img02=img02,
+        img03=img03,
+        threshold_file=threshold_file,
+        geos_atm_1=geos_atm_1,
+        geos_atm_2=geos_atm_2,
+        geos_land=geos_land,
+        geos_ocean=geos_ocean,
+        geos_constants=constants,
+        ndvi_file=ndvi_file,
+        sst_file=sst_file,
+        eco_file=eco_file,
+        out_file=out_file,
+        verbose=verbose,
+        debug=debug,
+        exe_path=args.mvcm_exe_path,
+        hires_only=args.hires_only,
+        mvcm_threshold_file=args.mvcm_thresholds,
+    )
+
+# tracemalloc.stop()
diff --git a/mvcm/main_tests_only.py b/mvcm/main_tests_only.py
new file mode 100644
index 0000000000000000000000000000000000000000..f68660e621c97cf4fb062732f9c8bcfbc2a9ab4c
--- /dev/null
+++ b/mvcm/main_tests_only.py
@@ -0,0 +1,612 @@
+"""Main function for MVCM."""
+
+import argparse
+import gc
+import logging
+import os
+
+import numpy as np
+import psutil
+import xarray as xr
+from pkg_resources import get_distribution  # type: ignore
+from rich.logging import RichHandler
+from ruamel.yaml import YAML
+
+import mvcm.spectral_tests as tst
+import mvcm.utility_functions as utils
+from mvcm.constants import SceneConstants, SensorConstants
+from mvcm.restoral import Restoral
+from mvcm.write_output import save_output
+
+# import mvcm.temp_spectral_tests as tst
+
+
+_LOG_FORMAT = "%(message)s"
+logging.basicConfig(level="NOTSET", datefmt="[%X]", format=_LOG_FORMAT, handlers=[RichHandler()])
+logger = logging.getLogger(__name__)
+LOG_LEVELS = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
+
+proc = psutil.Process(os.getpid())
+
+
+def main(
+    threshold_file: str = "",
+    pixel_data: str = "",
+    input_data: str = "",
+    out_file: str = "",
+    verbose: int = 0,
+    *,
+    debug: bool = False,
+    use_hires: bool = False,
+) -> None:
+    """MVCM main function.
+
+    Parameters
+    ----------
+    satellite: str
+        satellite name, not case-sensitive. Available options: [snpp, ]
+    sensor: str
+        sensor name, not case-sensitive. Available options: [viirs, ]
+    data_path: str
+        path where the data is stored
+    mod02: str
+        VIIRS MOD02 file name
+    mod03: str
+        VIIRS MOD03 file name
+    img02: [optional] str
+        VIIRS IMG02 file name
+    img03: [optional] str
+        VIIRS IMG03 file name
+    threshold_file: str
+        thresholds file name
+    geos_atm_1: str
+        file name of first GEOS5 file for atmospheric parameters
+    goes_atm_2: str
+        file name of second GEOS5 file for atmospheric parameters
+    geos_land: str
+        file name of GEOS5 land parameters
+    geos_ocean: str
+        file name of GEOS5 ocean parameters
+    geos_constants: str
+        file name of GEOS5 constants
+    ndvi_file: str
+        NDVI file name
+    sst_file: str
+        Sea surface temperature file name
+    eco_file: str
+        Ecosystem File
+    out_file: str
+        Output file name
+    verbose: int
+        Verbosity level
+    exe_path: str
+        Path to the MVCM executable
+    debug: bool
+        Debug mode
+    hires_only: bool
+        Only run MVCM with high resolution
+
+    Returns
+    -------
+    None
+    """
+    verbose = 4
+    verbose_level = np.minimum(verbose + 1, 4)
+    logger.setLevel(LOG_LEVELS[verbose_level])
+
+    with open(threshold_file) as f:
+        text = f.read()
+    thresholds = YAML(typ="safe").load(text)
+
+    pixel_type = xr.open_dataset(pixel_data, chunks="auto")
+    viirs_data = xr.open_dataset(input_data, chunks="auto")
+
+    # cmin_3d = np.ones((18, viirs_data.M11.shape[0], viirs_data.M11.shape[1]), dtype=np.float32)
+    cmin = np.ones(viirs_data.latitude.shape, dtype=np.float32)
+    # cmin_3d = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+
+    logger.info(f"Memory usage #4: {proc.memory_info().rss / 1e6} MB")
+
+    ##########################################################
+    _bitlist = [
+        "01",
+        "02",
+        "03",
+        "04",
+        "05",
+        "06",
+        "07",
+        "08",
+        "09",
+        "10",
+        "11",
+        "12",
+        "13",
+        "14",
+        "15",
+        "16",
+        "r01",
+        "r02",
+        "r03",
+        "r04",
+        "r05",
+        "r06",
+    ]
+    bits = {}
+
+    for b in _bitlist:
+        bits[b] = {
+            "test": np.zeros(viirs_data.latitude.shape, dtype=np.ubyte),
+            "qa": np.zeros(viirs_data.latitude.shape, dtype=np.ubyte),
+            # "test": xr.zeros_like(viirs_data.latitude, dtype=np.ubyte, chunks="auto"),
+            # "qa": xr.zeros_like(viirs_data.latitude, dtype=np.ubyte, chunks="auto"),
+        }
+    # i = 0
+
+    # bits_xr = xr.Dataset(
+    #     {
+    #         "qa": np.zeros(viirs_data.latitude.shape, dtype=np.ubyte),
+    #         "test": np.zeros(viirs_data.latitude.shape, dtype=np.ubyte),
+    #     },
+    #     # coords={"latitude": viirs_data.latitude, "longitude": viirs_data.longitude},
+    # )
+    viirs_data["locut"] = np.full_like(
+        viirs_data.latitude.shape, fill_value=np.nan, dtype=np.float32
+    )
+    viirs_data["midpt"] = np.full_like(
+        viirs_data.latitude.shape, fill_value=np.nan, dtype=np.float32
+    )
+    viirs_data["hicut"] = np.full_like(
+        viirs_data.latitude.shape, fill_value=np.nan, dtype=np.float32
+    )
+    # logger.info(f"viirs_data: {viirs_data}")
+    logger.info(f"Memory usage #5: {proc.memory_info().rss / 1e6} MB")
+    # scene_types = np.zeros(viirs_data.M11.shape, dtype=np.ubyte)
+    for scene_name in SceneConstants.SCENE_LIST:
+        # for scene_name in ["Land_Day"]:
+        # scene_types[viirs_data[scene_name].values == 1] = i
+
+        logger.info(f"Processing {scene_name}")
+
+        if np.all(viirs_data[scene_name].values == 0):
+            # if viirs_data[scene_name].all() is False:
+            logger.info("Skipping, no pixels in scene.")
+            continue
+
+        logger.debug("initializing CloudTests class")
+        my_scene = tst.CloudTests(
+            data=viirs_data, scene_name=scene_name, thresholds=thresholds, hires=use_hires
+        )
+
+        # Initialize the confidence arrays for the various test groups
+        # cmin_g1 = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+        # cmin_g2 = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+        # cmin_g3 = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+        # cmin_g4 = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+        # cmin_g5 = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+
+        cmin_g1 = np.ones(viirs_data.latitude.shape, dtype=np.float32)
+        cmin_g2 = np.ones(viirs_data.latitude.shape, dtype=np.float32)
+        cmin_g3 = np.ones(viirs_data.latitude.shape, dtype=np.float32)
+        cmin_g4 = np.ones(viirs_data.latitude.shape, dtype=np.float32)
+        cmin_g5 = np.ones(viirs_data.latitude.shape, dtype=np.float32)
+        # cmin_temp = np.ones(viirs_data.M11.shape)
+        # cmin_xr = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+        # cmin_xr2 = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+        # cmin_xr4 = xr.ones_like(viirs_data.latitude, dtype=np.float32, chunks="auto")
+        logger.debug("starting tests")
+
+        if use_hires is True:
+            m15_name = "M15hi"
+        else:
+            m15_name = "M15"
+
+        logger.info(f"Memory usage #6: {proc.memory_info().rss / 1e6} MB")
+        # Group 1
+        cmin_g1, bits["01"] = my_scene.test_11um(m15_name, cmin_g1, bits["01"])
+        # this test needs to be implemented properly,
+        # for now is commented since it's only used for night granules
+        # cmin_g1, bits["02"] = my_scene.surface_temperature_test("", viirs_data, cmin_g1, bits["02"])
+        cmin_g1, bits["03"] = my_scene.sst_test("M15", "M16", cmin_g1, bits["03"])
+
+        # Group 2
+        cmin_g2, bits["04"] = my_scene.bt_diff_86_11um("M14-M15", cmin_g2, bits["04"])
+        cmin_g2, bits["05"] = my_scene.test_11_12um_diff("M15-M16", cmin_g2, bits["05"])
+        # cmin_xr2, bits_xr = my_scene.xr_test_11_12um_diff(cmin_xr2)
+        # cmin_g2 = np.minimum(cmin_g2, cmin_xr2.values)
+        # bits["05"]["qa"] = bits_xr.qa.values
+        # bits["05"]["test"] = bits_xr.test.values
+        cmin_g2, bits["06"] = my_scene.variability_11um_test(m15_name, cmin_g2, bits["06"])
+        cmin_g2, bits["07"] = my_scene.bt_difference_11_4um_test_ocean(
+            "M15-M12", cmin_g2, bits["07"]
+        )
+        # cmin_g2, bits["08"] = my_scene.bt_difference_11_4um_test_land(
+        #     "M15-M16", "M15-M12", cmin_g2, bits["08"]
+        # )
+        cmin_g2, bits["09"] = my_scene.oceanic_stratus_11_4um_test("M15-M12", cmin_g2, bits["09"])
+
+        # Group 3
+        cmin_g3, bits["10"] = my_scene.nir_reflectance_test("M07", cmin_g3, bits["10"])
+        # I need to make sure that this test is performing as intended.
+        # Right now it doesn't seem to have an impact in any way whatsoever
+        cmin_g3, bits["11"] = my_scene.vis_nir_ratio_test("M07-M05ratio", cmin_g3, bits["11"])
+        cmin_g3, bits["12"] = my_scene.test_16_21um_reflectance("M10", cmin_g3, bits["12"])
+        # this test seems to be almost working, but not 100% there yet
+        cmin_g3, bits["13"] = my_scene.visible_reflectance_test("M05", cmin_g3, bits["13"])
+        cmin_g3, bits["11"] = my_scene.gemi_test("GEMI", cmin_g3, bits["11"])
+
+        # Group 4
+        cmin_g4, bits["15"] = my_scene.test_1_38um_high_clouds("M09", cmin_g4, bits["15"])
+        # cmin_xr4, bits_xr = my_scene.xr_test_1_38um_high_clouds(cmin_xr4)
+        # bits["15"]["qa"] = bits_xr.qa.values
+        # bits["15"]["test"] = bits_xr.test.values
+        # cmin_g4 = np.minimum(cmin_g4, cmin_xr4.values)
+
+        # Group 5
+        cmin_g5, bits["16"] = my_scene.thin_cirrus_4_12um_BTD_test("M13-M16", cmin_g5, bits["16"])
+
+        # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+        bit = {}
+        qabit = {}
+        # restoral_bits = {}
+        for b in _bitlist:
+            bit[b] = bits[f"{b}"]["test"]
+            qabit[b] = bits[f"{b}"]["qa"]
+        #     restoral_bits[b] = utils.restoral_flag(bits[f"{b}"])
+        # # if utils.group_count(bit) != 0:
+        # cmin_g4 = cmin_xr.values
+
+        # cmin_temp = np.power(
+        #     cmin_g1 * cmin_g2 * cmin_g3 * cmin_g4 * cmin_g5,
+        #     1 / utils.group_count(qabit),
+        # )
+
+        cmin = np.minimum(
+            np.power(cmin_g1 * cmin_g2 * cmin_g3 * cmin_g4 * cmin_g5, 1 / utils.group_count(qabit)),
+            cmin,
+        )
+        # cmin_3d[i, :, :] = cmin
+        # cmin_3d = np.minimum(cmin_3d, cmin)
+        # cmin = np.minimum(cmin_temp, cmin)
+        # i += 1
+
+        logger.info(f"Memory usage #7: {proc.memory_info().rss / 1e6} MB")
+
+    # cmin = np.min(cmin_3d, axis=0)
+    # cmin = cmin_3d
+    # pixel_type = xr.open_dataset("pixels_data.nc")
+    restore = Restoral(data=viirs_data, thresholds=thresholds, scene_flags=pixel_type)
+    logger.debug("Instance of Restoral class created successfully.")
+    logger.info(f"Memory usage #8: {proc.memory_info().rss / 1e6} MB")
+
+    # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+    # bit = {}
+    restoral_bits = {}
+    for b in _bitlist:
+        # bit[b] = bits[f"{b}"]["test"]
+        restoral_bits[b] = utils.restoral_flag(bits[f"{b}"])
+    # if utils.group_count(bit) != 0:
+
+    # Restoral Tests
+
+    # Spatial Variability
+    idx = np.nonzero(
+        (pixel_type["uniform"].values == 1)
+        & (pixel_type["water"].values == 1)
+        & (pixel_type["ice"].values == 0)
+        & (cmin >= 0.05)
+        & (cmin <= 0.99)
+    )
+    cmin[idx], bits["r01"]["test"][idx] = restore.spatial_variability(cmin, idx, bits["r01"])
+
+    # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+    # Sun Glint
+    sunglint_bits = (
+        restoral_bits["01"] * restoral_bits["03"] * restoral_bits["05"] * restoral_bits["15"]
+    )
+
+    idx = np.nonzero(
+        (pixel_type["day"].values == 1)
+        & (pixel_type["water"].values == 1)
+        & (pixel_type["uniform"].values == 1)
+        & (pixel_type["sunglint"].values == 1)
+        & (cmin <= 0.95)
+        & (sunglint_bits == 1)
+    )
+    cmin[idx], bits["r02"]["test"][idx] = restore.sunglint(cmin, idx, bits["r02"])
+
+    # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+    # Shallow Water
+    # ...
+    sh_water_bits = {
+        "ir": restoral_bits["01"] * restoral_bits["05"],
+        "nir_1": restoral_bits["10"],
+        "nir_2": restoral_bits["15"],
+        "sst": restoral_bits["03"],
+    }
+    idx = np.nonzero(
+        (pixel_type["day"].values == 1)
+        & (pixel_type["water"].values == 1)
+        & (pixel_type["ice"].values == 0)
+    )
+    cmin[idx], bits["r03"]["test"][idx] = restore.shallow_water(
+        sh_water_bits, cmin, idx, bits["r03"]
+    )
+
+    desert_bits = restoral_bits["15"] * restoral_bits["05"]
+    # make sure that the land_bits are calculated properly
+    idx_desert = np.nonzero(pixel_type["desert"].values == 1)
+    # land_bits = np.zeros(desert_bits.shape)
+    temp_bit = restoral_bits["10"] + restoral_bits["13"]
+    temp_bit = np.clip(temp_bit, 0, 1)
+    land_bits = np.zeros(restoral_bits["15"].shape)
+    idx = np.nonzero(
+        (pixel_type["day"].values == 1)
+        & (pixel_type["land"].values == 1)
+        & (pixel_type["desert"].values == 0)
+        & (pixel_type["snow"].values == 0)
+        & (pixel_type["ice"].values == 0)
+        & (cmin <= 0.95)
+    )
+    idx_desert = np.nonzero(
+        (pixel_type["day"].values == 1)
+        & (pixel_type["land"].values == 1)
+        & (pixel_type["desert"].values == 1)
+        & (pixel_type["snow"].values == 0)
+        & (pixel_type["ice"].values == 0)
+        & (cmin <= 0.95)
+    )
+    tmp_bits = (
+        np.clip(restoral_bits["09"] + restoral_bits["13"], 0, 1)
+        * restoral_bits["15"]
+        * restoral_bits["05"]
+        * restoral_bits["11"]
+    )
+    land_bits[idx] = tmp_bits[idx]
+    land_bits[idx_desert] = desert_bits[idx_desert]
+    # make sure that the land_bits are calculated properly
+    idx = np.nonzero(
+        (pixel_type["day"].values == 1)
+        & (pixel_type["land"].values == 1)
+        # & (pixel_type["desert"].values == 0)
+        & (pixel_type["snow"].values == 0)
+        & (pixel_type["ice"].values == 0)
+        & (cmin <= 0.95)
+        & (land_bits == 1)
+    )
+    cmin[idx], bits["r04"]["test"][idx] = restore.land(land_bits, cmin, idx, bits["r04"])
+
+    # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+    # idx = np.nonzero(
+    #     (pixel_type["day"] == 1)
+    #     & (pixel_type["land"] == 1)
+    #     & (pixel_type["desert"] == 1)
+    #     & (pixel_type["snow"] == 0)
+    #     & (pixel_type["ice"] == 0)
+    #     & (cmin <= 0.95)
+    #     & (desert_bits == 1)
+    # )
+    # cmin[idx], bits["r04"]["test"][idx] = restore.land(desert_bits, cmin, idx, bits["r04"])
+
+    coast_bits = restoral_bits["05"]
+    # land_night_bits = restoral_bit["16"]
+
+    # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+    idx = np.nonzero(
+        (pixel_type["day"].values == 1)
+        & (pixel_type["land"].values == 1)
+        & (pixel_type["snow"].values == 0)
+        & (pixel_type["ice"].values == 0)
+        & (pixel_type["coast"].values == 1)
+    )
+    cmin[idx], bits["r05"]["test"][idx] = restore.coast(coast_bits, cmin, idx, bits["r05"])
+
+    # idx = np.nonzero((pixel_type['night'] == 1) & (pixel_type['land'] == 1) &
+    #                  (pixel_type['snow'] == 0) & (pixel_type['ice'] == 0) &
+    #                  (cmin <= 0.95))
+    # cmin[idx], bits['r06']['test'][idx] = restore.land_night(land_night_bits,
+    #                                                          cmin,
+    #                                                          bits['r06'])[idx]
+
+    cmin_final = cmin
+
+    # bits translation MVCM-python -> MVCM-C
+    # 01  13  test_11um
+    # 02  27  surface_temperature_test
+    # 03  27  sst_test
+    # 04  24  bt_diff_86_11um
+    # 05  18  test_11_12um_diff
+    # 07  19  oceanic_stratus_11_4um_test
+    # 10  20  nir_reflectance_test
+    # 11  21  vis_nir_ratio
+    # 12  23  test_16_21um_reflectance
+    # 15  16  test_1_38um_high_clouds
+    # 16  17  thin_cirrus_4_12um_BTD_test
+
+    csc = cmin_final
+    integer_cloud_mask = np.zeros(csc.shape, dtype=np.byte)
+    integer_cloud_mask[csc > 0.99] = 3
+    integer_cloud_mask[(csc <= 0.99) & (csc > 0.95)] = 2
+    integer_cloud_mask[(csc <= 0.95) & (csc > 0.66)] = 1
+    integer_cloud_mask[csc <= 0.66] = 0
+
+    # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+    cloud_mask = np.zeros((6, csc.shape[0], csc.shape[1]), dtype=np.byte)
+    quality_assurance = np.zeros((csc.shape[0], csc.shape[1], 10), dtype=np.ubyte)
+    # scn_id = scn.scene_id(pixel_type)
+
+    output_dict = {
+        "latitude": {"dims": ("x", "y"), "data": viirs_data.latitude.values},
+        "longitude": {"dims": ("x", "y"), "data": viirs_data.longitude.values},
+        "sensor_zenith": {"dims": ("x", "y"), "data": viirs_data.sensor_zenith.values},
+        "sensor_azimuth": {"dims": ("x", "y"), "data": viirs_data.sensor_azimuth.values},
+        "solar_zenith": {"dims": ("x", "y"), "data": viirs_data.solar_zenith.values},
+        "solar_azimuth": {"dims": ("x", "y"), "data": viirs_data.solar_azimuth.values},
+        "confidence": {"dims": ("x", "y"), "data": cmin_final},
+        "cloud_mask": {"dims": ("bits", "x", "y"), "data": cloud_mask},
+        "quality_assurance": {"dims": ("x", "y", "qa"), "data": quality_assurance},
+        "integer_cloud_mask": {"dims": ("x", "y"), "data": integer_cloud_mask},
+    }
+
+    old_debug_data = {
+        "ndvi": {"dims": ("x", "y"), "data": viirs_data.ndvi.values},
+        "sunglint_bits": {"dims": ("x", "y"), "data": sunglint_bits},
+        "eco": {"dims": ("x", "y"), "data": viirs_data.ecosystem.values},
+        "bit1": {"dims": ("x", "y"), "data": bit["01"]},
+        "bit2": {"dims": ("x", "y"), "data": bit["02"]},
+        "bit3": {"dims": ("x", "y"), "data": bit["03"]},
+        "bit4": {"dims": ("x", "y"), "data": bit["04"]},
+        "bit5": {"dims": ("x", "y"), "data": bit["05"]},
+        "bit6": {"dims": ("x", "y"), "data": bit["06"]},
+        "bit7": {"dims": ("x", "y"), "data": bit["07"]},
+        "bit8": {"dims": ("x", "y"), "data": bit["08"]},
+        "bit9": {"dims": ("x", "y"), "data": bit["09"]},
+        "bit10": {"dims": ("x", "y"), "data": bit["10"]},
+        "bit11": {"dims": ("x", "y"), "data": bit["11"]},
+        "bit12": {"dims": ("x", "y"), "data": bit["12"]},
+        "bit13": {"dims": ("x", "y"), "data": bit["13"]},
+        "bit14": {"dims": ("x", "y"), "data": bit["14"]},
+        "bit15": {"dims": ("x", "y"), "data": bit["15"]},
+        "bit16": {"dims": ("x", "y"), "data": bit["16"]},
+        "qabit1": {"dims": ("x", "y"), "data": qabit["01"]},
+        "qabit2": {"dims": ("x", "y"), "data": qabit["02"]},
+        "qabit3": {"dims": ("x", "y"), "data": qabit["03"]},
+        "qabit4": {"dims": ("x", "y"), "data": qabit["04"]},
+        "qabit5": {"dims": ("x", "y"), "data": qabit["05"]},
+        "qabit6": {"dims": ("x", "y"), "data": qabit["06"]},
+        "qabit7": {"dims": ("x", "y"), "data": qabit["07"]},
+        "qabit8": {"dims": ("x", "y"), "data": qabit["08"]},
+        "qabit9": {"dims": ("x", "y"), "data": qabit["09"]},
+        "qabit10": {"dims": ("x", "y"), "data": qabit["10"]},
+        "qabit11": {"dims": ("x", "y"), "data": qabit["11"]},
+        "qabit12": {"dims": ("x", "y"), "data": qabit["12"]},
+        "qabit13": {"dims": ("x", "y"), "data": qabit["13"]},
+        "qabit14": {"dims": ("x", "y"), "data": qabit["14"]},
+        "qabit15": {"dims": ("x", "y"), "data": qabit["15"]},
+        "qabit16": {"dims": ("x", "y"), "data": qabit["16"]},
+        "bit_r1": {"dims": ("x", "y"), "data": bit["r01"]},
+        "bit_r2": {"dims": ("x", "y"), "data": bit["r02"]},
+        "bit_r3": {"dims": ("x", "y"), "data": bit["r03"]},
+        "bit_r4": {"dims": ("x", "y"), "data": bit["r04"]},
+        "bit_r5": {"dims": ("x", "y"), "data": bit["r05"]},
+        "bit_r6": {"dims": ("x", "y"), "data": bit["r06"]},
+        # "M02": {"dims": ("x", "y"), "data": viirs_data.M02.values},
+        # "M03": {"dims": ("x", "y"), "data": viirs_data.M03.values},
+        # "M04": {"dims": ("x", "y"), "data": viirs_data.M04.values},
+        "M05": {"dims": ("x", "y"), "data": viirs_data.M05.values},
+        "M15": {"dims": ("x", "y"), "data": viirs_data.M15.values},
+        # "M15-M12": {"dims": ("x", "y"), "data": viirs_data["M15-M12"].values},
+        # "M15-M16": {"dims": ("x", "y"), "data": viirs_data["M15-M16"].values},
+        "Ocean_Day": {"dims": ("x", "y"), "data": viirs_data.Ocean_Day.values},
+        "Land_Day": {"dims": ("x", "y"), "data": viirs_data.Land_Day.values},
+        "Land_Night": {"dims": ("x", "y"), "data": viirs_data.Land_Night.values},
+        "Land_Day_Desert": {"dims": ("x", "y"), "data": viirs_data.Land_Day_Desert.values},
+        "Land_Day_Desert_Coast": {
+            "dims": ("x", "y"),
+            "data": viirs_data.Land_Day_Desert_Coast.values,
+        },
+        "Day_Snow": {"dims": ("x", "y"), "data": viirs_data.Day_Snow.values},
+        "Polar_Day_Ocean": {"dims": ("x", "y"), "data": viirs_data.Polar_Day_Ocean.values},
+        "Polar_Day_Land": {"dims": ("x", "y"), "data": viirs_data.Polar_Day_Land.values},
+        "Polar_Day_Desert": {"dims": ("x", "y"), "data": viirs_data.Polar_Day_Desert.values},
+        "Polar_Day_Desert_Coast": {
+            "dims": ("x", "y"),
+            "data": viirs_data.Polar_Day_Desert_Coast.values,
+        },
+        "elevation": {"dims": ("x", "y"), "data": viirs_data.height.values},
+        # "scene_type": {"dims": ("x", "y"), "data": scene_types},
+    }
+
+    # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+    if debug:
+        # debug_output.update(old_debug_data)
+        sf = {k: {"dims": ("x", "y"), "data": pixel_type[k]} for k in pixel_type.keys()}
+        old_debug_data = old_debug_data | sf
+
+    # debug_output = xr.Dataset.from_dict(old_debug_data)
+    # debug_output.to_netcdf("/ships19/hercules/pveglio/debug_data.nc", mode="w")
+
+    all_bits = np.zeros((bit["01"].shape[0], bit["01"].shape[1], 22), dtype=np.ubyte)
+    for i in range(len(_bitlist)):
+        all_bits[:, :, i] = bit[_bitlist[i]]
+
+    viirs_m_bands = SensorConstants.VIIRS_VIS_BANDS + SensorConstants.VIIRS_IR_BANDS
+
+    all_bands = np.zeros((viirs_data.M01.shape[0], viirs_data.M01.shape[1], 16), dtype=np.ubyte)
+    for j in range(len(viirs_m_bands)):
+        all_bands[:, :, j] = viirs_data[viirs_m_bands[j]].values
+
+    debug_data = {
+        "bits": {"dims": ("x", "y", "testbits"), "data": all_bits},
+        "bands": {"dims": ("x", "y", "nbands"), "data": all_bands},
+        "ecosystem": {"dims": ("x", "y"), "data": viirs_data.ecosystem.values},
+        "ndvi": {"dims": ("x", "y"), "data": viirs_data.ndvi.values},
+        # "sst": {"dims": ("x", "y"), "data": viirs_data.sst.values},
+        "tpw": {"dims": ("x", "y"), "data": viirs_data.geos_tpw.values},
+        "snow_fraction": {"dims": ("x", "y"), "data": viirs_data.geos_snow_fraction.values},
+        "ice_fraction": {"dims": ("x", "y"), "data": viirs_data.geos_ice_fraction.values},
+        "ocean_fraction": {"dims": ("x", "y"), "data": viirs_data.geos_ocean_fraction.values},
+        "land_ice_fraction": {"dims": ("x", "y"), "data": viirs_data.geos_land_ice_fraction.values},
+        "surface_temperature": {
+            "dims": ("x", "y"),
+            "data": viirs_data.geos_surface_temperature.values,
+        },
+    }
+
+    # logger.debug(f"Memory: {tracemalloc.get_traced_memory()}")
+    if debug:
+        output_dict.update(debug_data)
+
+    output_data = xr.Dataset.from_dict(output_dict)
+    attrs = {"version": _VERSION, "satellite": "VIIRS", "sensor": "VIIRS"}
+    save_output(output_data, attrs, out_file, compression=5, debug=debug)
+
+    # comp = {"zlib": True, "complevel": 5}
+    # if type(ds_out) is xr.Dataset:
+    #     for var in ds_out:
+    #         ds_out[var].encoding.update(comp)
+    # if type(ds_out) is xr.DataArray:
+    #     ds_out.encoding.update(comp)
+    #
+    # for attr in attrs:
+    #     ds_out.attrs[attr] = attrs[attr]
+    #
+    # ds_out.to_netcdf(out_file)
+
+
+if __name__ == "__main__":
+    _VERSION = get_distribution("mvcm").version
+    parser = argparse.ArgumentParser(prog="MVCM", description="")
+
+    parser.add_argument(
+        "--data",
+        help="file name and path containing satellite data and ancillary data interpolated to sensor resolution",
+    )
+    parser.add_argument(
+        "--pixel-type", help="file name and path containing all info on pixel and scene type"
+    )
+    parser.add_argument("-t", "--threshold", help="thresholds file name")
+    parser.add_argument(
+        "-v", "--verbose", action="count", default=1, help="print verbose information"
+    )
+    parser.add_argument("-o", "--out", help="output file name")
+    parser.add_argument("-d", "--debug", action="store_true", help="activate debug mode")
+    parser.add_argument("-H", "--hires", action="store_true", help="run using hires data")
+
+    args = parser.parse_args()
+
+    threshold_file = args.threshold
+    out_file = args.out
+    verbose = args.verbose or False
+    debug = args.debug or False
+    use_hires = args.hires or False
+
+    main(
+        threshold_file=threshold_file,
+        input_data=args.data,
+        pixel_data=args.pixel_type,
+        out_file=out_file,
+        verbose=verbose,
+        debug=debug,
+        use_hires=use_hires,
+    )
diff --git a/pyproject.toml b/pyproject.toml
index 0b148dbde895e3ce918789df6178c73ed59b8a59..519699ac8e535e2516697f2aabf62b5476e2b517 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -23,13 +23,14 @@ dependencies = [
     'wheel',
     'setuptools',
     'numpy==1.26',
-    'xarray',
+    'xarray==2023.6.0',
     'attrs',
     'netCDF4',
     'rich',
     'ruamel.yaml',
     'pre-commit',
     'dask',
+    'psutil',
     ]
 dynamic = ['version']