diff --git a/pyproject.toml b/pyproject.toml index 670d60c0c4c..624c112ee38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,10 +79,13 @@ dependencies = [ "resfo-utilities>=0.5.0", "natsort>=8.4.0", "shapely>=2.1.2", + "probabilit>=0.4.2", + "openpyxl>=3.1.5", ] [project.scripts] ert = "ert.__main__:main" +fmudesign = "ert.config.fmudesign.fmudesignrunner:main" "fm_dispatch.py" = "_ert.forward_model_runner.fm_dispatch:main" everest = "everest.bin.main:start_everest" everserver = "everest.detached.everserver:main" diff --git a/src/ert/config/fmudesign/__init__.py b/src/ert/config/fmudesign/__init__.py new file mode 100644 index 00000000000..cea45b146e1 --- /dev/null +++ b/src/ert/config/fmudesign/__init__.py @@ -0,0 +1,10 @@ +from ._designsummary import summarize_design +from ._excel_to_dict import excel_to_dict, inputdict_to_yaml +from .create_design import DesignMatrix + +__all__ = [ + "DesignMatrix", + "excel_to_dict", + "inputdict_to_yaml", + "summarize_design", +] diff --git a/src/ert/config/fmudesign/_designsummary.py b/src/ert/config/fmudesign/_designsummary.py new file mode 100644 index 00000000000..4cbe754325b --- /dev/null +++ b/src/ert/config/fmudesign/_designsummary.py @@ -0,0 +1,116 @@ +"""Module for summarizing design set up for one by one sensitivities""" + +import pandas as pd + + +def _get_sensitivity_type(senscase: str) -> str: + """Determine sensitivity type based on the case name""" + sensitivity_types = {"p10_p90": "mc", "ref": "ref"} + return sensitivity_types.get(senscase.lower(), "scalar") + + +def summarize_design(filename: str, sheetname: str = "DesignSheet01") -> pd.DataFrame: + """ + Summarizes the design set up for one by one sensitivities + specified in a design matrix on standard fmu format. + + Args: + filename (str): Name of excel or csv file containing designmatrix + for one by one sensitivities on standard FMU format. + sheetname (str): Name of sheet in excel workbook which + contains the designmatrix (only for excel input). Defaults to + 'DesignSheet01'. + + Returns: + pd.DataFrame: Summary of sensitivities, + corresponding realisation numbers, + senstype('mc' or 'scalar') + and senscase (name of high and low cases). + Each row represents one sensitivity + with 1-2 cases (low/high). + Column names are ['sensno', 'sensname', + 'senstype', 'casename1', 'startreal1', 'endreal1', + 'casename2', 'startreal2', 'endreal2'] + + Example: + >> from semeio.fmudesign import summarize_design + >> designname = 'design_filename.xlsx' + >> designsheet = 'DesignSheet01' + >> designtable = summarize_design(designname, designsheet) + + """ + + # Read design matrix + if str(filename).endswith(".xlsx"): + # Drop empty rows or columns that have been read in + # due to having background colour/formatting + dgn = ( + pd.read_excel(filename, sheetname, engine="openpyxl") + .dropna(axis=0, how="all") + .loc[:, lambda df: ~df.columns.str.contains("^Unnamed")] + ) + elif str(filename).endswith(".csv"): + dgn = pd.read_csv(filename) + else: + raise ValueError( + "Design matrix must be on Excel or csv format" + " and filename must end with .xlsx or .csv" + ) + + # Initialize results DataFrame with same columns + designsummary = pd.DataFrame( + columns=[ + "sensno", + "sensname", + "senstype", + "casename1", + "startreal1", + "endreal1", + "casename2", + "startreal2", + "endreal2", + ] + ) + + # Get unique sensitivity names in order of appearance + sensnames = dgn["SENSNAME"].unique() + + for sensno, sensname in enumerate(sensnames): + sens_group = dgn[dgn["SENSNAME"] == sensname].copy() + # Get cases in order of appearance + cases = ( + sens_group.drop_duplicates("SENSCASE")[["SENSCASE"]].to_numpy().flatten() + ) + + # First case + case1_data = sens_group[sens_group["SENSCASE"] == cases[0]] + casename1 = cases[0] + startreal1 = case1_data["REAL"].min() + endreal1 = case1_data["REAL"].max() + + # Handle second case if it exists + if len(cases) > 1: + case2_data = sens_group[sens_group["SENSCASE"] == cases[1]] + casename2 = cases[1] + startreal2 = case2_data["REAL"].min() + endreal2 = case2_data["REAL"].max() + else: + casename2 = None + startreal2 = None + endreal2 = None + + senstype = _get_sensitivity_type(cases[0]) + # Add row to results + designsummary.loc[sensno] = [ + sensno, + sensname, + senstype, + casename1, + startreal1, + endreal1, + casename2, + startreal2, + endreal2, + ] + + return designsummary diff --git a/src/ert/config/fmudesign/_excel_to_dict.py b/src/ert/config/fmudesign/_excel_to_dict.py new file mode 100644 index 00000000000..e713201bb9a --- /dev/null +++ b/src/ert/config/fmudesign/_excel_to_dict.py @@ -0,0 +1,771 @@ +"""This module contains functions for reading Excel config files. +These are converted to a dict-of-dicts representation, then they are used +by the DesignMatrix class to generate design matrices. +""" + +import collections +import contextlib +import math +from collections import Counter +from collections.abc import Hashable, Sequence +from pathlib import Path +from typing import Any, cast + +import numpy as np +import openpyxl # type: ignore[import-untyped] +import pandas as pd +import yaml + +from .design_distributions import read_correlations +from .utils import seeds_from_extern + + +def excel_to_dict( + input_filename: str, + *, + gen_input_sheet: str = "general_input", + design_input_sheet: str = "designinput", + default_val_sheet: str = "defaultvalues", +) -> dict[str, Any]: + """Read excel file with input to design setup + + Args: + input_filename (str): Name of excel input file + gen_input_sheet (str): Sheet name for general input + design_input_sheet (str): Sheet name for design input + default_val_sheet (str): Sheet name for default input + + Returns: + dict on format for DesignMatrix.generate + """ + # To be backwards compatible, we do not change the input arg names + general_input_sheet = gen_input_sheet + default_values_sheet = default_val_sheet + + # Find sheets + _assert_no_merged_cells(input_filename) + xlsx = openpyxl.load_workbook(input_filename, read_only=True, keep_links=False) + general_input_sheet = find_sheet(general_input_sheet, names=xlsx.sheetnames) + design_input_sheet = find_sheet(design_input_sheet, names=xlsx.sheetnames) + default_values_sheet = find_sheet(default_values_sheet, names=xlsx.sheetnames) + + generalinput = ( + pd.read_excel( + input_filename, + general_input_sheet, + header=None, + index_col=0, + engine="openpyxl", + ) + .dropna(axis=0, how="all") + .dropna(axis=1, how="all") + .loc[:, 1] + .to_dict() + ) + + if (design_type := generalinput.get("designtype")) != "onebyone": + raise ValueError( + "Generation of DesignMatrix only implemented " + f"for type 'onebyone', not {design_type}" + ) + + return _excel_to_dict_onebyone( + input_filename=input_filename, + general_input_sheet=general_input_sheet, + design_input_sheet=design_input_sheet, + default_values_sheet=default_values_sheet, + ) + + +def inputdict_to_yaml(inputdict: dict[str, Any], filename: str) -> None: + """Write inputdict to yaml format + + Args: + inputdict (dict) + filename (str): name of output file + """ + with Path(filename).open("w", encoding="utf-8") as stream: + yaml.dump(inputdict, stream) + + +def find_sheet(name: str, names: list[str]) -> str: + """Search for Excel sheets with a soft matching. Raises ValueError if zero + or more than one match is found. + + Examples: + >>> find_sheet('general_input', ['generalinput', 'designinput', 'defaultinput']) + 'generalinput' + >>> find_sheet('variable_input', ['generalinput', 'designinput', 'defaultinput']) + Traceback (most recent call last): + ... + ValueError: No match for variable_input: ['generalinput', 'designinput', 'defaultinput'] + """ # ruff: ignore[line-too-long] + + def sanitize(inputstring: str) -> str: + return inputstring.lower().strip().replace("_", "") + + found = [name_i for name_i in names if sanitize(name) == sanitize(name_i)] + if len(found) > 1: + raise ValueError(f"More than one match for {name}: {found}") + if len(found) == 0: + raise ValueError(f"No match for {name}: {names}") + return found[0] + + +def _check_designinput(dsgn_input: pd.DataFrame) -> None: + """Checks for valid input in designinput sheet""" + # Filter out rows where sensname has no value + valid_sensnames = dsgn_input["sensname"].dropna() + duplicated_mask = valid_sensnames.duplicated() + + if duplicated_mask.any(): + # Find the first duplicate to include in error message + duplicate_name = valid_sensnames[duplicated_mask].iloc[0] + raise ValueError( + f"sensname '{duplicate_name}' was found on more than one row in " + "designinput sheet. Two sensitivities can not share the same sensname. " + "Please correct this and rerun" + ) + + # Check for duplicate parameter names within each sensname + for sensname, df_sensname in dsgn_input.ffill().groupby("sensname"): + param_names = list(df_sensname["param_name"]) + try: + _raise_if_duplicates(param_names) + except ValueError as e: + raise ValueError(f"Duplicate param names in {sensname}\n{e}") from e + + +def _check_for_mixed_sensitivities(sens_name: str, sens_group: pd.DataFrame) -> None: + """Checks for valid input in designinput sheet. A sensitivity cannot contain + two different sensitivity types + """ + + unique_types = sens_group["type"].dropna().unique() + if len(unique_types) > 1: + raise ValueError( + f"The sensitivity with sensname '{sens_name}' in designinput sheet " + "contains more than one sensitivity type. For each sensname all parameters " + "must be specified using the same type (seed, scenario, dist, ref, " + "background, extern)" + ) + + +def resolve_path(input_filename: str, reference: str | None) -> str | None: + """The path `input_filename` is an Excel sheet, and `reference` is a cell + value that *might* be a reference to another file. Resolve the path to + `reference` and return. If no such file exists, return `reference`. + """ + # The reference is None, so just return it back + if reference is None: + return reference + + # It's a string but not a reference to another file + if not str(reference).endswith(("xlsx", "csv")): + return reference + + # If the reference is e.g. 'C:/Users/USER/files/doe1.xlsx' + reference_path = Path(reference) + if reference_path.is_absolute() and reference_path.exists(): + return str(reference_path.resolve()) + + # If the reference is e.g. 'doe1.xlsx' + full_path = Path(input_filename).parent / reference_path + if full_path.exists(): + return str(full_path.resolve()) + + if reference_path.exists(): + return str(reference_path.resolve()) + + raise ValueError(f"Failed to resolve path for file: {reference}") + + +def _excel_to_dict_onebyone( + input_filename: str, + *, + general_input_sheet: str, + design_input_sheet: str, + default_values_sheet: str, +) -> dict[str, Any]: + """Reads configuration from Excel file for a onebyone design matrix. + + Args: + input_filename (str): Name of excel workbook + general_input_sheet (str): name of general input sheet + design_input_sheet (str): name of design input sheet + default_values_sheet (str): name of default value sheet + + Returns: + dict on format for DesignMatrix.generate + """ + output: dict[str, Any] = { + "input_file": input_filename + } # This is the config that we read and return + + # Read the general input sheet to a dictionary + generalinput = ( + pd.read_excel( + input_filename, + general_input_sheet, + header=None, + engine="openpyxl", + ) + .dropna(axis=0, how="all") + .dropna(axis=1, how="all") + .set_index(0) + .loc[:, 1] + .to_dict() + ) + + def parse_value(value: object) -> object: + if pd.isna(value): + return None + if isinstance(value, str): + return value.strip() + return value + + # Convert NaN values to None and strip other values + generalinput = { + str(key).strip(): parse_value(value) for (key, value) in generalinput.items() + } + + # Check that there are no wrong keys or typos, e.g. 'repets' + ALLOWED_KEYS = { + "designtype", + "repeats", + "correlation_iterations", + "distribution_seed", + "rms_seeds", + "background", + } + extra_keys = set(generalinput.keys()) - set(ALLOWED_KEYS) + if extra_keys: + msg = ( + "In the general input sheet, the following parameter(s) are not" + f"recognized and cannot be parsed:\n{extra_keys!r}\n" + f"Allowed keys:{ALLOWED_KEYS!r}" + ) + raise LookupError(msg) + + # Copy keys over if they exist + keys = ["designtype", "repeats", "correlation_iterations", "distribution_seed"] + for key in keys: + if key not in generalinput: + continue + output[key] = generalinput[key] + + # Copy the 'rms_seeds' key over. It is called 'seeds' further down in + # the code for historical reasons. + key = "seeds" + with contextlib.suppress(KeyError): + output[key] = generalinput["rms_seeds"] + + # If 'seeds' / 'rms_seed' is a file, then read it + if key in output: + maybe_path = resolve_path(input_filename, output[key]) + if isinstance(maybe_path, str) and Path(maybe_path).exists(): + output[key] = seeds_from_extern(maybe_path) + + # If 'background' is a file, then read it + key = "background" + output[key] = {} + try: + value = str(generalinput[key]) + if value.endswith(("csv", "xlsx")): + output[key]["extern"] = resolve_path(input_filename, value) + else: + output[key] = _read_background(input_filename, value) + except KeyError: + output[key] = None + except ValueError: + output[key] = generalinput[key] + + output["defaultvalues"] = _read_defaultvalues(input_filename, default_values_sheet) + + output["sensitivities"] = {} + designinput = ( + pd.read_excel(input_filename, design_input_sheet, engine="openpyxl") + .dropna(axis=0, how="all") + .loc[:, lambda df: ~df.columns.astype(str).str.contains("^Unnamed")] + ) + + # Strip strings in column 'sensname' while preserving NaN values + designinput = designinput.assign(sensname=lambda df: df["sensname"].str.strip()) + + _check_designinput(designinput) + + designinput["sensname"] = designinput["sensname"].ffill() + + if "decimals" in designinput: + # Convert to numeric, then filter for integers + numeric_decimals = pd.to_numeric(designinput["decimals"], errors="coerce") + mask = numeric_decimals.notna() & (numeric_decimals % 1 == 0) + + valid_decimals = designinput[mask] + output["decimals"] = { + row.param_name: int(cast("float", row.decimals)) + for row in valid_decimals.itertuples() + } + + grouped = designinput.groupby("sensname", sort=False) + + # Read each sensitivity + for sensname, group in grouped: + _check_for_mixed_sensitivities( + str(sensname), + group, + ) + + sensdict: dict[str, Any] = {} + + sens_type = group["type"].iloc[0] + if sens_type in {"ref", "background"}: + sensdict["senstype"] = sens_type + + elif sens_type == "seed": + sensdict["seedname"] = "RMS_SEED" + sensdict["senstype"] = sens_type + if _has_value(group["param_name"].iloc[0]): + sensdict["parameters"] = _read_constants(group) + else: + sensdict["parameters"] = None + + elif sens_type == "scenario": + sensdict = _read_scenario_sensitivity(group) + sensdict["senstype"] = sens_type + + elif sens_type == "dist": + sensdict["senstype"] = sens_type + sensdict["parameters"] = _read_dist_sensitivity(group) + sensdict["correlations"] = None + if "corr_sheet" in group: + sensdict["correlations"] = _read_correlations(group, input_filename) + + elif sens_type == "extern": + sensdict["extern_file"] = resolve_path( + input_filename, str(group["extern_file"].iloc[0]) + ) + sensdict["senstype"] = sens_type + sensdict["parameters"] = list(group["param_name"]) + + else: + raise ValueError( + f"Sensitivity {sensname} does not have a valid sensitivity type" + ) + + if "numreal" in group and _has_value(group["numreal"].iloc[0]): + # Using default number of realisations: + # 'repeats' from general_input sheet + sensdict["numreal"] = int(group["numreal"].iloc[0]) + + # If this sensitivity has dependencies, then get them from sheet + sensdict["dependencies"] = {} + if "dependencies" in group: + # Get all dependencies in this sensitivity + valid_deps = group[group["dependencies"].notna()] + dependencies_dict = {} + + # For each dependency, get the mapping + for row in valid_deps.itertuples(): + dependencies_dict[row.param_name] = _read_dependencies( + filename=input_filename, + sheetname=str(row.dependencies), + from_parameter=str(row.param_name), + ) + sensdict["dependencies"] = dependencies_dict + + # Add this sensitivity to the sensitivities + output["sensitivities"][str(sensname)] = sensdict + + return output + + +def _read_defaultvalues(filename: str, sheetname: str) -> dict[str, Any]: + """Reads defaultvalues, also used as values for + reference/base case + + Args: + filename (str): Name of excel file + sheetname (string): name of defaultsheet + + Returns: + dict with defaultvalues (parameter, value) + """ + default_df = ( + pd.read_excel(filename, sheetname, header=0, index_col=0, engine="openpyxl") + .dropna(axis=0, how="all") + # Drop all unnamed columns from the df + .loc[:, lambda df: ~df.columns.astype(str).str.contains("^Unnamed")] + ) + + if default_df.empty: + return {} + + # Strip leading/trailing spaces from parameter names such that + # for example " PARAM" and "PARAM" are treated as duplicates. + default_df.index = default_df.index.str.strip() + + # Check for duplicates and raise error if found + duplicates = default_df.index.duplicated(keep=False) + if duplicates.any(): + duplicate_names = default_df.index[duplicates].unique() + raise ValueError( + f"Duplicate parameter names found in sheet '{sheetname}': " + f"{', '.join(duplicate_names)}. All parameter names must be unique." + ) + + return {str(k): v for k, v in default_df.iloc[:, 0].to_dict().items()} + + +def _read_dependencies( + *, filename: str, sheetname: str, from_parameter: str +) -> dict[str, Any]: + """Reads parameters that are set from other parameters + + Args: + filename(str): name of excel file + sheetname (string): name of dependency sheet + from_parameter (string): parameter name to map from + + Returns: + dict with design parameter, dependent parameters + and values + """ + depend_dict: dict[str, Any] = {} + depend_df = ( + pd.read_excel(filename, sheetname, dtype=str, na_values="", engine="openpyxl") + .dropna(axis=0, how="all") + .loc[:, lambda df: ~df.columns.astype(str).str.contains("^Unnamed")] + ) + + if from_parameter in depend_df: + depend_dict["from_values"] = depend_df[from_parameter].tolist() + depend_dict["to_params"] = {} + for key in depend_df: + if key != from_parameter: + depend_dict["to_params"][key] = depend_df[key].tolist() + else: + raise ValueError( + f"Parameter {from_parameter} specified to have derived parameters, " + f"but the sheet specifying the dependencies {sheetname} does " + "not contain the input parameter. " + ) + return depend_dict + + +def _read_background(inp_filename: str, bck_sheet: str) -> dict[str, Any]: + """Reads excel sheet with background parameters and distributions + + Args: + inp_filename (str): name of Excel workbook + bck_sheet (str): name of sheet with background parameters + + Returns: + dict with parameter names and distributions + """ + backdict: dict[str, Any] = {} + paramdict: dict[str, Any] = {} + bck_input = ( + pd.read_excel(inp_filename, bck_sheet, engine="openpyxl") + .dropna(axis=0, how="all") + .loc[:, lambda df: ~df.columns.astype(str).str.contains("^Unnamed")] + ) + + backdict["correlations"] = None + if "corr_sheet" in bck_input: + backdict["correlations"] = _read_correlations(bck_input, inp_filename) + + if "dist_param1" not in bck_input.columns.to_numpy(): + bck_input["dist_param1"] = float("NaN") + if "dist_param2" not in bck_input.columns.to_numpy(): + bck_input["dist_param2"] = float("NaN") + if "dist_param3" not in bck_input.columns.to_numpy(): + bck_input["dist_param3"] = float("NaN") + if "dist_param4" not in bck_input.columns.to_numpy(): + bck_input["dist_param4"] = float("NaN") + + for row in bck_input.itertuples(): + if not _has_value(row.param_name): + raise ValueError( + "Background parameters specified " + "where one line has empty parameter " + "name " + ) + if not _has_value(row.dist_param1): + raise ValueError( + f"Parameter {row.param_name} has been input " + "in background sheet but with empty " + "first distribution parameter " + ) + if not _has_value(row.dist_param2) and _has_value(row.dist_param3): + raise ValueError( + f"Parameter {row.param_name} has been input in " + "background sheet with " + 'value for "dist_param3" while ' + '"dist_param2" is empty. This is not ' + "allowed" + ) + if not _has_value(row.dist_param3) and _has_value(row.dist_param4): + raise ValueError( + f"Parameter {row.param_name} has been input in " + "background sheet with " + 'value for "dist_param4" while ' + '"dist_param3" is empty. This is not ' + "allowed" + ) + distparams = [ + item + for item in [ + row.dist_param1, + row.dist_param2, + row.dist_param3, + row.dist_param4, + ] + if _has_value(item) + ] + if "corr_sheet" in bck_input: + corrsheet = None if not _has_value(row.corr_sheet) else row.corr_sheet + else: + corrsheet = None + paramdict[str(row.param_name)] = [str(row.dist_name), distparams, corrsheet] + backdict["parameters"] = paramdict + + if "decimals" in bck_input: + decimals: dict[str, Any] = {} + for row in bck_input.itertuples(): + if _has_value(row.decimals) and _is_int(row.decimals): + decimals[row.param_name] = int(row.decimals) + backdict["decimals"] = decimals + + return backdict + + +def _read_scenario_sensitivity(sensgroup: pd.DataFrame) -> dict[str, Any]: + """Reads parameters and values + for scenario sensitivities + """ + sdict: dict[str, Any] = {} + sdict["cases"] = {} + casedict1: dict[str, Any] = {} + casedict2: dict[str, Any] = {} + + if not _has_value(sensgroup["senscase1"].iloc[0]): + raise ValueError( + "Sensitivity {} has been input " + "as a scenario sensitivity, but " + "without a name in senscase1 column.".format(sensgroup["sensname"].iloc[0]) + ) + + for row in sensgroup.itertuples(): + if not _has_value(row.param_name): + raise ValueError( + f"Scenario sensitivity {row.sensname} specified " + "where one line has empty parameter " + "name " + ) + if not _has_value(row.value1): + raise ValueError( + f"Parameter {row.param_name} has been input " + 'as type "scenario" but with empty ' + "value in value1 column " + ) + casedict1[str(row.param_name)] = row.value1 + + if _has_value(sensgroup["senscase2"].iloc[0]): + for row in sensgroup.itertuples(): + if not _has_value(row.value2): + raise ValueError( + "Sensitivity {} has been input " + "with a name in senscase2 column " + "but without a value for parameter {} " + "in value2 column.".format( + sensgroup["sensname"].iloc[0], row.param_name + ) + ) + casedict2[str(row.param_name)] = row.value2 + sdict["cases"][str(sensgroup["senscase1"].iloc[0])] = casedict1 + sdict["cases"][str(sensgroup["senscase2"].iloc[0])] = casedict2 + else: + for row in sensgroup.itertuples(): + if _has_value(row.value2): + raise ValueError( + "Sensitivity {} has been input " + "with a value for parameter {} " + "in value2 column " + "but without a name for the scenario " + "in senscase2 column.".format( + sensgroup["sensname"].iloc[0], row.param_name + ) + ) + sdict["cases"][str(sensgroup["senscase1"].iloc[0])] = casedict1 + return sdict + + +def _read_constants(sensgroup: pd.DataFrame) -> dict[str, Any]: + """Reads constants to be used together with + seed sensitivity + """ + if "dist_param1" not in sensgroup.columns.to_numpy(): + sensgroup["dist_param1"] = float("NaN") + paramdict: dict[str, Any] = {} + for row in sensgroup.itertuples(): + if not _has_value(row.dist_param1): + raise ValueError( + f"Parameter name {row.param_name} has been input " + 'in a sensitivity of type "seed". \n' + f"If {row.param_name} was meant to be the name of " + "the seed parameter, this is " + "unfortunately not allowed. " + "The seed parameter name is standardised " + "to RMS_SEED and should not be specified.\n " + "If you instead meant to specify a constant " + "value for another parameter in the seed " + 'sensitivity, please remember "const" in ' + 'dist_name and a value in "dist_param1". ' + ) + distparams = row.dist_param1 + paramdict[str(row.param_name)] = [str(row.dist_name), distparams] + return paramdict + + +def _read_dist_sensitivity(sensgroup: pd.DataFrame) -> dict[str, Any]: + """Reads parameters and distributions + for monte carlo sensitivities + """ + if "dist_param1" not in sensgroup.columns.to_numpy(): + sensgroup["dist_param1"] = float("NaN") + if "dist_param2" not in sensgroup.columns.to_numpy(): + sensgroup["dist_param2"] = float("NaN") + if "dist_param3" not in sensgroup.columns.to_numpy(): + sensgroup["dist_param3"] = float("NaN") + if "dist_param4" not in sensgroup.columns.to_numpy(): + sensgroup["dist_param4"] = float("NaN") + paramdict: dict[str, Any] = {} + for row in sensgroup.itertuples(): + if not _has_value(row.param_name): + raise ValueError( + f"Dist sensitivity {row.sensname} specified " + "where one line has empty parameter " + "name " + ) + if not _has_value(row.dist_param1): + raise ValueError( + f"Parameter {row.param_name} has been input " + 'as type "dist" but with empty ' + "first distribution parameter " + ) + if not _has_value(row.dist_param2) and _has_value(row.dist_param3): + raise ValueError( + f"Parameter {row.param_name} has been input with " + 'value for "dist_param3" while ' + '"dist_param2" is empty. This is not ' + "allowed" + ) + if not _has_value(row.dist_param3) and _has_value(row.dist_param4): + raise ValueError( + f"Parameter {row.param_name} has been input with " + 'value for "dist_param4" while ' + '"dist_param3" is empty. This is not ' + "allowed" + ) + distparams = [ + item + for item in [ + row.dist_param1, + row.dist_param2, + row.dist_param3, + row.dist_param4, + ] + if _has_value(item) + ] + if "corr_sheet" in sensgroup: + corrsheet = None if not _has_value(row.corr_sheet) else row.corr_sheet + else: + corrsheet = None + paramdict[str(row.param_name)] = [str(row.dist_name), distparams, corrsheet] + + return paramdict + + +def _read_correlations( + sensgroup: pd.DataFrame, inputfile: str +) -> dict[str, Any] | None: + """Parse correlation information from a sensitivity group.""" + + # No correlation sheet column exists + if "corr_sheet" not in sensgroup.columns: + return None + + # The column exists, but it is all blank + if sensgroup["corr_sheet"].dropna().empty: + return None + + correlations: dict[str, Any] = {"inputfile": inputfile} + + # Create a mapping 'corr_to_params' like: + # {'corr1': ['var_A', 'var_B', ...], ...} + corr_to_params = collections.defaultdict(list) + for _, row in sensgroup.iterrows(): + if not _has_value(row["corr_sheet"]): + continue + corr_to_params[row["corr_sheet"]].append(row["param_name"]) + + # Open the correlation sheet and peek at it + # We want to verify that if variables ['A', 'B'] point to the corr sheet, + # then exactly those variables are also defined in the sheet + for corr_sheet, parameters in corr_to_params.items(): + df_corr = read_correlations(excel_filename=inputfile, corr_sheet=corr_sheet) + if set(df_corr.columns) != set(parameters): + sensname = sensgroup["sensname"].iloc[0] + msg = f"Mismatch between parameters in sensitivity group {sensname!r} " + msg += f"pointing to\ncorrelation sheet {corr_sheet!r} and " + msg += "parameters specified in that correlation sheet.\n" + msg += f"Parameters in sensitivity group: {sorted(set(parameters))}\n" + msg += f"Parameters in correlation sheet: {sorted(set(df_corr.columns))}\n" + msg += "These parameters must be specified one-to-one." + raise ValueError(msg) + + correlations["sheetnames"] = list(set(corr_to_params.keys())) + + return correlations + + +def _has_value(value: Any) -> bool: + """Returns False only if the argument is np.nan""" + try: + return not np.isnan(value) + except TypeError: + return True + + +def _is_int(teststring: str) -> bool: + """Test if string is a finite integer""" + try: + if not np.isnan(int(teststring)): + return math.isclose((float(teststring) % 1), 0, abs_tol=1e-14) + except ValueError: + return False + else: + return False # It was a "number", but it was NaN. + + +def _raise_if_duplicates(container: Sequence[Hashable]) -> None: + """Raises a descriptive error if there are duplicates in the container.""" + duplicates = {k: v for (k, v) in Counter(container).items() if v > 1} + if duplicates: + raise ValueError(f"Duplicates with counts: {duplicates}") + + +def _assert_no_merged_cells(input_filename: str) -> None: + """Raises an exception if any merged cells exist, else returns None.""" + + workbook = openpyxl.load_workbook(input_filename) + for sheet_name in workbook.sheetnames: + worksheet = workbook[sheet_name] + merged_ranges = list(worksheet.merged_cells.ranges) + if merged_ranges: + raise Exception( + "Merged cells are not allowed. Found merged cell in " + f"{input_filename} at sheet '{sheet_name}'.\n" + f"Found {len(merged_ranges)} merged cell range(s): {merged_ranges}" + ) diff --git a/src/ert/config/fmudesign/config_validation.py b/src/ert/config/fmudesign/config_validation.py new file mode 100644 index 00000000000..db218bb9ab3 --- /dev/null +++ b/src/ert/config/fmudesign/config_validation.py @@ -0,0 +1,84 @@ +"""Module for validation of config (typically read from Excel).""" + +import copy +import numbers +from typing import Any + + +def validate_configuration( + config: dict[str, Any], verbosity: int = 0 +) -> dict[str, Any]: + """Main function for config validation. + + This function is responsible for: + - Checking that required keys exist + - Checking that values are set to valid types + - Setting default values if keys are not set + + """ + config = copy.deepcopy(config) + + if config["designtype"] != "onebyone": + raise ValueError( + "Generation of DesignMatrix only implemented for type 'onebyone', " + f"not {config['designtype']}" + ) + + if "repeats" not in config: + raise LookupError('"repeats" must be specified in general input sheet') + + key = "correlation_iterations" + if key not in config: + if verbosity > 0: + print(f"{key!r} not set in general input sheet. Setting to default 0.") + print(" - When set to 0, Iman Conover is used to induce correlations.") + print( + " - When set to a positive integer N, Iman Conover is followed by N iterations\n" # ruff: ignore[line-too-long] + " of random permutations (swaps). This leads to results that are never worse, and often better.\n" # ruff: ignore[line-too-long] + " It is especially useful for skewed distributions like lognormal and high dimensional problems." # ruff: ignore[line-too-long] + ) + print( + f" If desired correlation does not match observed, try setting {key!r}=999 or higher." # ruff: ignore[line-too-long] + ) + config[key] = 0 + else: + try: + config[key] = int(config[key]) + except (ValueError, TypeError) as err: + raise ValueError( + f"{key!r} must be a non-negative integer, got: {config[key]}" + ) from err + + key = "distribution_seed" + if key not in config: + raise ValueError( + "You did not specify a value for 'distribution_seed', which is used to " + "seed the random number generator that draws from distributions in Monte " + "Carlo sensitivities.\n" + "- Specify a number (e.g. a 6 digit integer) to seed the random number " + "generator and obtain reproducible results.\n" + "- Specify None if you do not want to seed the random number generator. " + "Your analysis will not be reproducible." + ) + if not (isinstance(config[key], numbers.Integral) or (config[key] is None)): + raise ValueError( + f"{key!r} must be a non-negative integer or None, got: {config[key]}" + ) + + # 'seeds' here is 'rms_seeds' in the input. It can be either: + # - 'default' => gives seed numbers 1000, 1001, 1002, ... + # - 'None' => seed number not added + # - a path to a file + key = "seeds" + if key not in config: + msg = '"rms_seeds" must be specified in general input sheet\n' + msg += ' - Set to "None", "default" or path to a file.' + raise LookupError(msg) + is_default = config[key] == "default" + is_none = config[key] is None + is_list = isinstance(config[key], list) and config[key] + if not any([is_default, is_none, is_list]): + msg = f"'rms_seeds' must be 'None', 'default' or a list, got: {config[key]}" + raise ValueError(msg) + + return config diff --git a/src/ert/config/fmudesign/create_design.py b/src/ert/config/fmudesign/create_design.py new file mode 100644 index 00000000000..44db4f63fae --- /dev/null +++ b/src/ert/config/fmudesign/create_design.py @@ -0,0 +1,991 @@ +"""Module for generating design matrices that can be run by DESIGN2PARAMS +and DESIGN_KW in FMU/ERT. + + +A DesignMatrix is a "God-object" that contains information about all info +used to generate design matrices, including one or several Sensitivities. + + +""" + +from __future__ import annotations + +import copy +from datetime import datetime +from pathlib import Path +from typing import TYPE_CHECKING, Any, cast + +import numpy as np +import pandas as pd +import probabilit # type: ignore[import-untyped] + +from . import design_distributions as design_dist +from ._excel_to_dict import _raise_if_duplicates +from .config_validation import validate_configuration +from .quality_report import QualityReporter, print_corrmat +from .utils import ( + find_max_realisations, + map_dependencies, + parameters_from_extern, + printwarning, + to_numeric_safe, +) + +if TYPE_CHECKING: + from collections.abc import Hashable, Sequence + + +class DesignMatrix: + """Class for design matrix in FMU. Can contain a onebyone design + or a full montecarlo design. + + Attributes: + designvalues (pd.DataFrame): design matrix on standard fmu format + contains columns 'REAL' (realization number), and if a onebyone + design, also columns 'SENSNAME' and 'SENSCASE' + defaultvalues (dict): default values for design + backgroundvalues (pd.DataFrame): Used when background parameters are + not constant. Either a set is sampled from specified distributions + or they are read from a file. + """ + + def __init__(self, verbosity: int = 0, output_dir: Path | None = None) -> None: + """ + Placeholders for: + designvalues: dataframe with parameters that varies + defaultvalues: dictionary of default/base case values + backgroundvalues: dataframe with background parameters + seedvalues: list of seed values + verbosity: how much information to print + output_dir: where to write debugging output and QC plots + + """ + self.designvalues: pd.DataFrame + self.defaultvalues: dict[Hashable, Any] = {} + self.backgroundvalues: pd.DataFrame | None = None + self.seedvalues: list[int] | None = None + self.verbosity: int = verbosity + self.output_dir: Path | None = output_dir + + def reset(self) -> None: + """Resets DesignMatrix to empty. Necessary iin case method generate + is used several times for same instance of DesignMatrix + """ + self.designvalues = pd.DataFrame() + self.defaultvalues = {} + self.backgroundvalues = None + self.seedvalues = None + + def generate(self, inputdict: dict[str, Any]) -> None: + """Generating design matrix from input dictionary in specific + format. Adding default values and background values if existing. + Looping through sensitivities and adding them to designvalues. + + Args: + inputdict (dict): input parameters for design + """ + inputdict = validate_configuration(inputdict, verbosity=self.verbosity) + + self.reset() # Emptying if regenerating matrix + self.rng = np.random.default_rng(seed=inputdict.get("distribution_seed")) + self.defaultvalues = inputdict["defaultvalues"] + + # Reading or generating rms seed values + max_reals = find_max_realisations(inputdict) + self.seedvalues = DesignMatrix.create_rms_seeds(inputdict["seeds"], max_reals) + + # If background values used - read or generate + if "background" in inputdict: + self.add_background( + back_dict=inputdict["background"], + max_values=max_reals, + correlation_iterations=inputdict.get("correlation_iterations", 0), + ) + + sensitivity: Sensitivity + + self.designvalues["SENSNAME"] = None + self.designvalues["SENSCASE"] = None + + for key in inputdict["sensitivities"]: + sens = inputdict["sensitivities"][key] + + # Numer of realization (rows) to use for each sensitivity + size = sens["numreal"] if "numreal" in sens else inputdict["repeats"] + + print(f" Generating sensitivity : {key}") + + if sens["senstype"] == "ref": + sensitivity = SingleRealisationReference(key, verbosity=self.verbosity) + sensitivity.generate(size=size) + sensitivity.map_dependencies(sens.get("dependencies", {})) + self._add_sensitivity(sensitivity) + elif sens["senstype"] == "background": + sensitivity = BackgroundSensitivity(key, verbosity=self.verbosity) + sensitivity.generate(size=size) + sensitivity.map_dependencies(sens.get("dependencies", {})) + self._add_sensitivity(sensitivity) + elif sens["senstype"] == "seed": + sensitivity = SeedSensitivity(key, verbosity=self.verbosity) + sensitivity.generate( + size=size, + seedname=sens["seedname"], + seedvalues=self.seedvalues, + parameters=sens["parameters"], + ) + sensitivity.map_dependencies(sens.get("dependencies", {})) + + self._add_sensitivity(sensitivity) + elif sens["senstype"] == "scenario": + sensitivity = ScenarioSensitivity(key, verbosity=self.verbosity) + for casekey in sens["cases"]: + case = sens["cases"][casekey] + temp_case = ScenarioSensitivityCase(casekey) + temp_case.generate( + size=size, + parameters=case, + seedvalues=self.seedvalues, + ) + sensitivity.add_case(temp_case) + sensitivity.map_dependencies(sens.get("dependencies", {})) + + self._add_sensitivity(sensitivity) + elif sens["senstype"] == "dist": + sensitivity = MonteCarloSensitivity(key, verbosity=self.verbosity) + sensitivity.generate( + size=size, + parameters=sens["parameters"], + seedvalues=self.seedvalues, + corrdict=sens["correlations"], + rng=self.rng, + correlation_iterations=inputdict.get("correlation_iterations", 0), + ) + sensitivity.map_dependencies(sens.get("dependencies", {})) + + self._add_sensitivity(sensitivity) + + elif sens["senstype"] == "extern": + sensitivity = ExternSensitivity(key, verbosity=self.verbosity) + sensitivity.generate( + size=size, + filename=sens["extern_file"], + parameters=sens["parameters"], + seedvalues=self.seedvalues, + ) + sensitivity.map_dependencies(sens.get("dependencies", {})) + + self._add_sensitivity(sensitivity) + + else: + raise ValueError(f"Unknown sensitivity type: {sens['senstype']!r}") + + # MonteCarloSensitivity is special - it can produce debugging outputs + is_montecarlo = isinstance(sensitivity, MonteCarloSensitivity) + if is_montecarlo and self.verbosity > 0: + sensitivity = cast("MonteCarloSensitivity", sensitivity) + quality_reporter = QualityReporter( + df=sensitivity.sensvalues, variables=sens["parameters"] + ) + + # Print to terminal + quality_reporter.print_numeric() + quality_reporter.print_discrete() + for corr_name, df_corr in sensitivity.correlation_dfs_.items(): + quality_reporter.print_correlation(corr_name, df_corr) + + if is_montecarlo and self.verbosity > 1 and self.output_dir is not None: + sensitivity = cast("MonteCarloSensitivity", sensitivity) + output_dir = self.output_dir / key + quality_reporter.plot_columns(output_dir=output_dir) + + # Correlations + for corr_name, df_corr in sensitivity.correlation_dfs_.items(): + # Always plot heatmaps + quality_reporter.plot_correlation_heatmap( + corr_name, df_corr, output_dir=output_dir, show=False + ) + + # Only plot pairgrid for small correlations + if len(df_corr) <= 6: + quality_reporter.plot_correlation( + corr_name, df_corr, output_dir=output_dir, show=False + ) + + # Once all sensitivities have been added, complete the work + if "background" in inputdict: + self._fill_with_background_values() + self._fill_with_defaultvalues() + + # Round columns in `self.designvalues` to desired precision + self._set_decimals(inputdict) + + # Create REAL column (realization number) + self.designvalues = self.designvalues.assign(REAL=lambda df: np.arange(len(df))) + + # Re-order columns + start_cols = ["REAL", "SENSNAME", "SENSCASE", "RMS_SEED"] + self.designvalues = self.designvalues[ + [col for col in start_cols if col in self.designvalues] + + [col for col in self.designvalues if col not in start_cols] + ] + + # Make all values numerical if possible + self.designvalues = self.designvalues.map(to_numeric_safe) + + def to_xlsx( + self, + filename: str, + designsheet: str = "DesignSheet01", + defaultsheet: str = "DefaultValues", + ) -> None: + """Writing design matrix to excel workfbook on standard fmu format + to be used in FMU/ERT by DESIGN2PARAMS and DESIGN_KW + + Args: + filename (str): output filename (extension .xlsx) + designsheet (str): name of excel sheet containing design matrix + (optional, defaults to 'DesignSheet01') + defaultsheet (str): name of excel sheet containing default + values (optional, defaults to 'DefaultValues') + """ + # Create folder for output file + Path(filename).parent.mkdir(exist_ok=True, parents=True) + + if not filename.endswith(".xlsx"): + filename += ".xlsx" + print(f"Warning: Missing .xlsx suffix. Changed to: {filename}") + + with pd.ExcelWriter(filename, engine="openpyxl") as writer: + self.designvalues.to_excel( + writer, sheet_name=designsheet, index=False, header=True + ) + # Default values + defaults = pd.DataFrame( + data=list(self.defaultvalues.items()), + columns=["defaultparameters", "defaultvalue"], + ) + defaults.to_excel( + writer, sheet_name=defaultsheet, index=False, header=False + ) + + version_info = pd.DataFrame( + { + "Description": ["Created using semeio version:", "Created on:"], + "Value": [ + "semeio.__version__", + datetime.now() + .astimezone() + .isoformat(sep=" ", timespec="seconds"), + ], + } + ) + version_info.to_excel(writer, sheet_name="Metadata", index=False) + + print( + f"Design matrix of shape {self.designvalues.shape} written to: {filename!r}" + ) + + @staticmethod + def create_rms_seeds( + seeds: list[int] | str | None, max_reals: int + ) -> list[int] | None: + """Create RMS seems from 'seeds' argument. + + Args: + seeds: Seed configuration. Can be: + - None: returns None + - "default": Generates sequential seeds 1001, 1002, 1003, ... + - list of seeds, e.g. [1, 2, 3] + max_reals: Maximum number of seed values to generate or load + """ + if seeds is None: + return None + + if seeds == "default": + return [item + 1000 for item in range(max_reals)] + + if isinstance(seeds, list): + if max_reals > len(seeds): + print( + f"Provided number of seed values ({len(seeds)}) in external file " + f"is lower than the maximum number of realisations ({max_reals}).\n" + "Seeds will be repeated, e.g. [1, 2, 3] => [1, 2, 3, 1, 2, ...]" + ) + + return [int(seeds[item % len(seeds)]) for item in range(max_reals)] + + # Raise if none of the cases above apply. We do this because if we did not we + # would return None, which is a valid case in itself. + raise ValueError(f"Must be None, 'default' or list: {seeds=}") + + def add_background( + self, + back_dict: dict[str, Any] | None, + max_values: int, + correlation_iterations: int = 0, + ) -> None: + """Adding background as specified in dictionary. + Either from external file or from distributions in background + dictionary + + Args: + back_dict (dict): how to generate background values + max_values (int): number of background values to generate + correlation_iterations (int): Number of permutations performed + on samples after Iman-Conover in an attempt to match observed + correlation to desired correlation as well as possible. + """ + if back_dict is None: + self.backgroundvalues = None + elif "extern" in back_dict: + print(f"Reading background values from: {back_dict['extern']}") + self.backgroundvalues = parameters_from_extern(back_dict["extern"]) + elif "parameters" in back_dict: + print("Generating background values from distributions.") + self._add_dist_background( + back_dict=back_dict, + size=max_values, + correlation_iterations=correlation_iterations, + ) + + def background_to_excel( + self, filename: str, backgroundsheet: str = "Background" + ) -> None: + """Writing background values to an Excel spreadsheet + + Args: + filename (str): output filename (extension .xlsx) + backgroundsheet (str): name of excel sheet + """ + if self.backgroundvalues is None: + raise ValueError("No background values available to write to Excel") + + xlsxwriter = pd.ExcelWriter(filename, engine="openpyxl") + self.backgroundvalues.to_excel( + xlsxwriter, sheet_name=backgroundsheet, index=False, header=True + ) + xlsxwriter.close() + print(f"Backgroundvalues written to {filename}") + + def _add_sensitivity( + self, + sensitivity: Sensitivity, + ) -> None: + """Adding a sensitivity to the design + + Args: + sensitivity of class Scenario, MonteCarlo or Extern + """ + existing_values = self.designvalues + new_values = sensitivity.sensvalues + self.designvalues = pd.concat([existing_values, new_values]) + + def _fill_with_background_values(self) -> None: + """Substituting NaNs with background values if existing. + background values not in design are added as separate columns + """ + if self.backgroundvalues is None: + return + + grouped = self.designvalues.groupby(["SENSNAME", "SENSCASE"], sort=False) + result_values = pd.DataFrame() + for sensname, case_ in grouped: + temp_df = case_.reset_index() + temp_df = temp_df.fillna(self.backgroundvalues) + for key in self.backgroundvalues.columns: + if key not in case_: + temp_df[key] = self.backgroundvalues[key] + if len(temp_df) > len(self.backgroundvalues): + raise ValueError( + "Provided number of background values " + f"{len(self.backgroundvalues)} is smaller than number" + f" of realisations for sensitivity {sensname}" + ) + elif len(temp_df) > len(self.backgroundvalues): + print( + "Provided number of background values " + f"({len(self.backgroundvalues)}) is smaller than number" + f" of realisations for sensitivity {sensname}" + f" and parameter {key}. " + "Will be filled with default values." + ) + existing_values = result_values.copy() + result_values = pd.concat([existing_values, temp_df]) + + result_values = result_values.drop(["index"], axis=1) + self.designvalues = result_values + + def _fill_with_defaultvalues(self) -> None: + """Filling NaNs with default values""" + for key in self.designvalues.columns: + if key in self.defaultvalues: + self.designvalues[key] = self.designvalues[key].fillna( + self.defaultvalues[key] + ) + elif key not in {"REAL", "SENSNAME", "SENSCASE", "RMS_SEED"}: + raise LookupError(f"No defaultvalues given for parameter {key} ") + + def _add_dist_background( + self, + back_dict: dict[str, Any], + size: int, + correlation_iterations: int, + ) -> None: + """Drawing background values from distributions + specified in dictionary + + Args: + back_dict (dict): parameters and distributions + size (int): Number of samples to generate + correlation_iterations (int): Number of permutations performed + on samples after Iman-Conover in an attempt to match observed + correlation to desired correlation as well as possible. + """ + + mc_background = MonteCarloSensitivity("background") + mc_background.generate( + size=size, + parameters=back_dict["parameters"], + seedvalues=None, + corrdict=back_dict["correlations"], + rng=self.rng, + correlation_iterations=correlation_iterations, + ) + mc_backgroundvalues = mc_background.sensvalues.copy() + quality_reporter = QualityReporter( + df=mc_backgroundvalues, variables=back_dict["parameters"] + ) + + # Print info to terminal + if self.verbosity > 0: + quality_reporter.print_numeric() + quality_reporter.print_discrete() + for corr_name, df_corr in mc_background.correlation_dfs_.items(): + quality_reporter.print_correlation(corr_name, df_corr) + + # Write plots to disk + if self.verbosity > 0 and self.output_dir is not None: + output_dir = self.output_dir / mc_background.sensname + quality_reporter.plot_columns(output_dir=output_dir) + + # Correlations + for corr_name, df_corr in mc_background.correlation_dfs_.items(): + quality_reporter.plot_correlation( + corr_name, df_corr, output_dir=output_dir, show=False + ) + + # Rounding of background values as specified + if "decimals" in back_dict: + for key in back_dict["decimals"]: + if design_dist.is_number(mc_backgroundvalues[key].iloc[0]): + mc_backgroundvalues[key] = ( + mc_backgroundvalues[key] + .astype(float) + .round(int(back_dict["decimals"][key])) + ) + else: + raise ValueError("Cannot round a string parameter") + self.backgroundvalues = mc_backgroundvalues.copy() + + def _set_decimals(self, inputdict: dict[str, Any]) -> None: + """Round to specified number of decimals. + + Args: + inputdict (dictionary): input diction that might have a sub-dict + with key "decimals". This sub-dict has + (key, value)s are (param, decimals) + """ + inputdict = copy.deepcopy(inputdict) + + # No decimal information => Nothing to do. + if not inputdict.get("decimals", {}): + return + + # If there are dependencies (derived params) that are copies, + # like TO := copy(FROM), then the new TO column must be rounded too. + for sensdict in inputdict["sensitivities"].values(): + if not sensdict["dependencies"]: + continue + for from_param, from_dict in sensdict["dependencies"].items(): + for to_param in from_dict["to_params"]: + if not inputdict["decimals"].get(from_param, None): + continue + inputdict["decimals"][to_param] = inputdict["decimals"].get( + from_param, "" + ) + + # Round each column + dict_decimals = inputdict["decimals"] + for key in self.designvalues.columns: + if key in dict_decimals: + if design_dist.is_number(self.designvalues[key].iloc[0]): + self.designvalues[key] = ( + self.designvalues[key] + .astype(float) + .round(int(dict_decimals[key])) + ) + else: + raise ValueError(f"Cannot round a string parameter {key}") + + +class Sensitivity: + sensvalues: pd.DataFrame + + def __init__(self, sensname: str, verbosity: int = 0) -> None: + """ + Args: + sensname (str): Name of sensitivity. Defines SENSNAME in design matrix. + verbosity (int): How much information to print. Non-negative integer. + """ + self.sensname: str = sensname + self.verbosity: int = verbosity + + def map_dependencies(self, dependencies: dict[str, Any]) -> Sensitivity: + """Map the dependencies, mutating the dataframe `self.sensvalues`.""" + verbose = self.verbosity > 0 # Because the function takes a boolean + self.sensvalues: pd.DataFrame = map_dependencies( + self.sensvalues, dependencies=dependencies, verbose=verbose + ) + return self + + +class SeedSensitivity(Sensitivity): + """ + A seed sensitivity is normally the reference for one by one sensitivities, + which all other sensitivities are compared to. All parameters will be at + their default values. Only the RMS_SEED will be varying. + + It contains a list of seeds to be repeated for each sensitivity + The parameter name is hardcoded to RMS_SEED + It will be assigned the sensname 'p10_p90' which will be written to + the SENSCASE column in the output. + + Attributes: + sensname (str): name of sensitivity + sensvalues (pd.DataFrame): design values for the sensitivity + + """ + + def generate( + self, + size: int, + seedname: str, + seedvalues: Sequence[int] | None, + parameters: dict[str, Any] | None, + ) -> None: + """Generates parameter values for a seed sensitivity + + Args: + size (int): number of rows to generate + seedname (str): name of seed parameter to add + seedvalues (list): list of integer seedvalues + parameters (dict): parameter names and + distributions or values. + """ + if seedvalues is None: + msg = ( + "Seed values must be set when running sensitivity type 'seed'. " + f"Got seed: {seedvalues}" + ) + raise ValueError(msg) + + self.sensvalues = pd.DataFrame(index=range(size)) + self.sensvalues[seedname] = seedvalues[0:size] + + if parameters is not None: + for key in parameters: + dist_name = parameters[key][0].lower() + constant = parameters[key][1] + if dist_name != "const": + raise ValueError( + 'A sensitivity of type "seed" can only have ' + "additional parameters where dist_name is " + f'"const". Check sensitivity {self.sensname}"' + ) + self.sensvalues[key] = constant + + self.sensvalues["SENSNAME"] = self.sensname + self.sensvalues["SENSCASE"] = "p10_p90" + + +class SingleRealisationReference(Sensitivity): + """ + The class is used in set-ups where one wants a single realisation + containing only default values as a reference, but the realisation + itself is not included in a sensitivity. + Typically used when RMS_SEED is not a parameter. + SENSCASE will be set to 'ref' in design matrix, to flag that it should be + excluded as a sensitivity in the plot. + + Attributes: + sensname (str): name of sensitivity + sensvalues (pd.DataFrame): design values for the sensitivity + + """ + + def generate( + self, + size: int, + ) -> None: + """Generates realisation number only + + Args: + realnums (list): list of integers with realization numbers + """ + self.sensvalues = pd.DataFrame(index=range(size)) + self.sensvalues["SENSNAME"] = self.sensname + self.sensvalues["SENSCASE"] = "ref" + + +class BackgroundSensitivity(Sensitivity): + """ + The class is used in set-ups where one sensitivities + are run on top of varying background parameters. + Typically used when RMS_SEED is not a parameter, so the reference + for tornadoplots will be the realisations with all parameters + at their default values except the background parameters. + SENSCASE will be set to 'p10_p90' in design matrix. + + Attributes: + sensname (str): name of sensitivity + sensvalues (pd.DataFrame): design values for the sensitivity + + """ + + def generate(self, size: int) -> None: + """Generates realisation number only + + Args: + size (int): number of rows to generate + """ + self.sensvalues = pd.DataFrame(index=range(size)) + self.sensvalues["SENSNAME"] = self.sensname + self.sensvalues["SENSCASE"] = "p10_p90" + + +class ScenarioSensitivity(Sensitivity): + """Each design can contain one or several single sensitivities of type + Seed, MonteCarlo or Scenario. + Each ScenarioSensitivity can contain 1-2 ScenarioSensitivityCases. + + The ScenarioSensitivity class is used for sensitivities where all + realizatons in a ScenarioSensitivityCase have identical values + but one or more parameter has a different values from the other + ScenarioSensitivityCase. + + Exception is the seed value and the special case where + varying background parameters are specified. Then these are varying + within the case. + + Attributes: + case1 (ScenarioSensitivityCase): first case, e.g. 'low case' + case2 (ScenarioSensitivityCase): second case, e.g. 'high case' + sensvalues (pd.DataFrame): design values for the sensitivity, containing + 1-2 cases + """ + + case1: ScenarioSensitivityCase | None = None + case2: ScenarioSensitivityCase | None = None + + def add_case(self, senscase: ScenarioSensitivityCase) -> None: + """ + Adds a ScenarioSensitivityCase instance + to a ScenarioSensitivity object. + + Args: + senscase (ScenarioSensitivityCase): + Equals SENSCASE in design matrix. + """ + if self.case1 is not None: # Case 1 has been read, this is case2 + if senscase.sensvalues is not None and "SENSCASE" in senscase.sensvalues: + self.case2 = senscase + senscase.sensvalues["SENSNAME"] = self.sensname + self.sensvalues = pd.concat( + [self.sensvalues, senscase.sensvalues], sort=True + ) + elif senscase.sensvalues is not None and "SENSCASE" in senscase.sensvalues: + self.case1 = senscase + self.sensvalues = senscase.sensvalues.copy() + self.sensvalues["SENSNAME"] = self.sensname + + +class ScenarioSensitivityCase(Sensitivity): + """Each ScenarioSensitivity can contain one or + two ScenarioSensitivityCases. + + The 1-2 cases are typically 'low' and 'high' cases for one or + a set of parameters, where all realisatons in + the case have identical values except the seed value + and in special cases specified background values which may + vary within the case. + + One or two ScenarioSensitivityCase instances can be added to each + ScenarioSensitivity object. + + Attributes: + sensname (str): name of the sensitivity case, + equals SENSCASE in design matrix. + sensvalues (pd.DataFrame): parameters and values + for the sensitivity with realisation numbers as index. + + """ + + def generate( + self, + size: int, + parameters: dict[str, Any], + seedvalues: Sequence[int] | None, + ) -> None: + """Generate sensvalues for the ScenarioSensitivityCase + + Args: + size (int): number of rows to generate + parameters (dict): + dictionary with parameter names and values + seeds (str): default or None + """ + + self.sensvalues = pd.DataFrame( + columns=list(parameters.keys()), index=range(size) + ) + for key, value in parameters.items(): + self.sensvalues[key] = value + self.sensvalues["SENSCASE"] = self.sensname + + if seedvalues: + self.sensvalues["RMS_SEED"] = seedvalues[:size] + + +class MonteCarloSensitivity(Sensitivity): + """ + For a MonteCarloSensitivity one or several parameters + are drawn from specified distributions with or without correlations. + A MonteCarloSensitivity can only contain + one case, where the name SENSCASE is automatically set to 'p10_p90' in the + design matrix to flag that p10_p90 should be calculated in TornadoPlot. + + Attributes: + sensname (str): name for the sensitivity. + Equals SENSNAME in design matrix. + sensvalues (pd.DataFrame): parameters and values for the sensitivity + with realisation numbers as index. + """ + + def generate( + self, + *, + size: int, + parameters: dict[str, Any], + seedvalues: Sequence[int] | None, + corrdict: dict[str, Any] | None, + rng: np.random.Generator, + correlation_iterations: int = 0, + ) -> None: + """Generates parameter values by drawing from defined distributions. + + Args: + size (int): number of rows to generate + parameters (dict): dictionary of parameters and distributions + values (list): a list of seed values or None + corrdict (dict): Configuration for correlated parameters. Contains: + - 'inputfile': Name of Excel file with correlation matrices + - 'sheetnames': List of sheet names, where each sheet contains a + correlation matrix. If None, parameters are treated as uncorrelated. + rng (numpy.random.Generator): Random number generator instance + correlation_iterations (int): Number of permutations performed + on samples after Iman-Conover in an attempt to match observed + correlation to desired correlation as well as possible. + """ + self.sensvalues = pd.DataFrame( + columns=list(parameters.keys()), index=range(size) + ) + self.correlation_dfs_ = {} # Store correlation matrices (dataframes) + + if size < 0: + raise ValueError(f"Got < 0 samples ({size=})") + + distr_by_name = {} + for param_name, (dist_name, dist_params, _) in parameters.items(): + # Convert to a probabilit Distribution object + distr = design_dist.to_probabilit( + distname=dist_name, dist_parameters=dist_params + ) + distr_by_name[param_name] = distr + + # Create a dummy NoOp node for sampling each parent distribution + expression = probabilit.modeling.NoOp(*distr_by_name.values()) + + if corrdict: + # Create an iterator over correlation groups from the main sheet + df_params = ( + pd.DataFrame.from_dict( + parameters, + orient="index", + columns=["dist_name", "dist_params", "corr_sheet"], + ) + .reset_index() + .rename(columns={"index": "param_name"}) + .assign(corr_sheet=lambda df: df.corr_sheet.fillna("nocorr")) + ) + + corr_groups = dict(iter(df_params.groupby("corr_sheet"))) + corr_groups.pop("nocorr", None) + + for corr_group_name, corr_group in corr_groups.items(): + corr_group_name = cast("str", corr_group_name) + + # Skip nocorr + if corr_group_name == "nocorr": + continue + + # A single correlation - print warning and skip it + if len(corr_group) == 1: + printwarning(corr_group_name) + continue + + # Read correlation matrix and convert it to a proper matrix + df_correlations = design_dist.read_correlations( + excel_filename=corrdict["inputfile"], corr_sheet=corr_group_name + ) + multivariate_parameters = df_correlations.index.tolist() + correlations = df_correlations.to_numpy() + + if self.verbosity == 0: + print( + f"Sampling {len(multivariate_parameters)} parameters", + f"in correlation group {corr_group_name!r}", + ) + else: + print( + f"Sampling {len(multivariate_parameters)} parameters", + f"in correlation group {corr_group_name!r}: " + f"{multivariate_parameters}", + ) + + # Get the nearest correlation matrix + nearest = probabilit.correlation.nearest_correlation_matrix( + correlations, weights=None, eps=1e-6, verbose=False + ) + if not np.allclose(correlations, nearest): + print( + f"\nWarning: Correlation matrix {corr_group_name!r} " + "is inconsistent" + ) + print("Requirements:") + print(" - All diagonal elements must be 1") + print(" - All elements must be between -1 and 1") + print(" - The matrix must be positive semi-definite") + print("\nInput correlation matrix:") + print_corrmat(df_correlations) + df_correlations = pd.DataFrame( + nearest, + index=df_correlations.index, + columns=df_correlations.columns, + ) + print("\nAdjusted to nearest consistent correlation matrix:") + print_corrmat(df_correlations) + + corrvars = [distr_by_name[name] for name in multivariate_parameters] + expression.correlate(*corrvars, corr_mat=df_correlations.to_numpy()) + self.correlation_dfs_[corr_group_name] = df_correlations + + # Either do ImanConover followed by Permutation, or simply ImanConover + if correlation_iterations > 0: + correlator = probabilit.correlation.Composite( + iterations=correlation_iterations, + correlation_type="pearson", + random_state=rng, + verbose=False, + ) + else: + correlator = probabilit.correlation.ImanConover() + + # Sample the dummy node - this samples every parent and populates "samples_" + expression.sample( + size=size, random_state=rng, method="lhs", correlator=correlator + ) + + for distr_name, distr_obj in distr_by_name.items(): + samples = distr_obj.samples_ + is_numeric = issubclass(samples.dtype.type, np.number) + if is_numeric and not np.all(np.isfinite(distr_obj.samples_)): + raise ValueError( + f"Sampling produced non-finite values in {distr_name}={distr_obj}\n" + "Please review the parameters in the distribution." + ) + + # Discrete distributions are handled in a special way. We map them + # to Uniform distributions, sample in [0, 1), then map those samples + # back to the categorical values AFTER sampling. This is so that we + # can "induce correlations" between categorical values. + if hasattr(distr_obj, "_values"): + probabilities = getattr(distr_obj, "_probabilities", None) + samples = design_dist.quantiles_to_values( + quantiles=samples, + values=distr_obj._values, + probabilities=probabilities, + ) + + self.sensvalues = self.sensvalues.assign(**{distr_name: samples}) + + if self.sensname != "background": + self.sensvalues["SENSNAME"] = self.sensname + self.sensvalues["SENSCASE"] = "p10_p90" + if "RMS_SEED" not in self.sensvalues and seedvalues: + self.sensvalues["RMS_SEED"] = seedvalues[:size] + + null_columns = self.sensvalues.isna().any(axis=0) + if null_columns.any(): + cols_w_null = list(null_columns.loc[lambda ser: ser].index) + raise ValueError(f"Found NaN values in columns: {cols_w_null}") + + +class ExternSensitivity(Sensitivity): + """ + Used when reading parameter values from a file + Assumed to be used with monte carlo type sensitivities and + will hence write 'p10_p90' as SENSCASE in output designmatrix + + Attributes: + sensname (str): Name of sensitivity. + Defines SENSNAME in design matrix + sensvalues (pd.DataFrame): design values for the sensitivity + + """ + + def generate( + self, + size: int, + filename: str, + parameters: list[str], + seedvalues: Sequence[int] | None, + ) -> None: + """Reads parameter values for a monte carlo sensitivity + from file + + Args: + size (int): number of samples to generate + filename (str): file to read values from + parameters (list): list with parameter names + seeds (str): default or None + """ + _raise_if_duplicates(parameters) + self.sensvalues = pd.DataFrame(columns=parameters, index=range(size)) + extern_values = parameters_from_extern(filename) + if size > len(extern_values): + raise ValueError( + f"Number of realisations {size} specified for " + f"sensitivity {self.sensname} is larger than rows in " + f"file {filename}" + ) + for param in parameters: + if param in extern_values: + self.sensvalues[param] = list(extern_values[param][:size]) + else: + raise ValueError(f"Parameter {param} not in external file") + + self.sensvalues["SENSNAME"] = self.sensname + self.sensvalues["SENSCASE"] = "p10_p90" + + if seedvalues: + self.sensvalues["RMS_SEED"] = seedvalues[:size] diff --git a/src/ert/config/fmudesign/design_distributions.py b/src/ert/config/fmudesign/design_distributions.py new file mode 100644 index 00000000000..0c6f32051f8 --- /dev/null +++ b/src/ert/config/fmudesign/design_distributions.py @@ -0,0 +1,387 @@ +"""Module for random sampling of parameter values from distributions.""" + +from collections.abc import Sequence +from typing import Any + +import numpy as np +import numpy.typing as npt +import pandas as pd +import probabilit # type: ignore[import-untyped] +from scipy import stats + + +def validate_params(distname: str, parameters: list[str]) -> list[float]: + """Common parameter validation for all distributions. + + Example: + >>> validate_params('normal', ['0', '-3.14', '1e10']) + [0.0, -3.14, 10000000000.0] + >>> validate_params('normal', ['inf']) + Traceback (most recent call last): + ... + ValueError: Parameter 1 in distribution normal is not finite: inf + """ + new_parameters: list[float] = [] + + for i, parameter in enumerate(parameters): + try: + new_parameters.append(float(parameter)) + except (ValueError, TypeError) as e: + raise ValueError( + f"Parameter {i + 1} in distribution {distname} not " + f"convertible to number: {parameter}" + ) from e + + if not np.isfinite(new_parameters[i]): + raise ValueError( + f"Parameter {i + 1} in distribution {distname} " + f"is not finite: {parameter}" + ) + + return new_parameters + + +def quantiles_to_values( + *, + quantiles: npt.NDArray[Any], + values: npt.NDArray[Any], + probabilities: npt.NDArray[Any] | None = None, +) -> npt.NDArray[Any]: + """Maps quantiles to values (which can be categorical or not). + + Assume values = [A, B, C], then probabilities = [1, 1, 1] = [1/3, 1/3, 1/3], + first we bin the interval [0, 1) into segments matching the probabilities: + - A: [0, 1/3) + - B: [1/3, 2/3) + - C: [2/3, 1) + Then we map the quantiles into the ranges back onto the original values. + + Examples + -------- + >>> values = np.array(["A", "B", "C"]) + >>> quantiles = np.array([0, 1/3, 0.5, 0.8]) + >>> quantiles_to_values(quantiles=quantiles, values=values) + array(['A', 'B', 'B', 'C'], dtype='>> probabilities = np.array([0.2, 0.3, 0.5]) + >>> quantiles = (np.arange(1, 10)) / 10 + >>> quantiles_to_values(quantiles=quantiles, values=values, + ... probabilities=probabilities) # [0.1, 0.2, ...] + array(['A', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C'], dtype='= 0) + + # Create bin edges + edges = np.cumsum([0, *list(probabilities)]) + # Map to bin indices, then back onto the original values + bin_indices = np.digitize(quantiles, edges, right=False) - 1 + return values[bin_indices] + + +def to_probabilit( + distname: str, + dist_parameters: Sequence[str], +) -> probabilit.modeling.AbstractDistribution: + """ + Prepare scipy distributions with parameters + Args: + distname (str): distribution name 'normal', 'lognormal', 'triang', + 'uniform', 'logunif', 'discrete', 'pert', 'beta' + dist_parameters (list): list with parameters for distribution + Returns: + array with sampled values + """ + + distname = distname.lower().strip() + + # A discrete variable is a distribution over categoricals, e.g. ('A', 'B', 'C') + # with weights (0.5, 0.3, 0.2). The way we deal with them is that we sample uniform + # values, then assign the interval [0, 0.5) to A, [0.5, 0.8) to B and [0.8, 1) to C. + # This means that we can "correlate" these variables, in the sense that if their + # underlying Uniforms are correlated, then the categorical values will often match + # too. To accomplish all of this we assign _values and _probabilities to the + # distribution instances below. This "correlation" only exists in a narrow specific + # sense of course. + + if distname.startswith("disc"): + if len(dist_parameters) == 1: + values_str = str(dist_parameters[0]) + values = [v.strip() for v in values_str.split(",")] + distr = probabilit.Distribution("uniform") + distr._values = np.array(values) + return distr + values_str, probabilities_str = map(str, dist_parameters) + values = [v.strip() for v in values_str.split(",")] + probabilities = [float(v.strip()) for v in probabilities_str.split(",")] + if len(values) != len(probabilities): + raise ValueError( + "Length mismatch for discrete distribution, " + f"dist_param1 has length {len(values)}, " + f"but dist_param2 has length {len(probabilities)}. " + "dist_param1 and dist_param2 must have the same numer of " + "entries for discrete distributions." + ) + distr = probabilit.Distribution("uniform") + distr._values = np.array(values) + distr._probabilities = np.array(probabilities) + return distr + + # Special case for constant + if distname.startswith("const"): + return probabilit.Constant(dist_parameters[0]) + + # Convert parameters + parameters: list[float] = validate_params( + distname=distname, parameters=list(dist_parameters) + ) + + match (distname, parameters): + # ================== NORMAL ================== + + case [_, (p10, p90)] if distname.startswith("normal_p10_p90"): + # We use the equations + # p10 = mu - z*sigma and p90 = mu + z*sigma + # to find mu and sigma + z_score = stats.norm.ppf(0.9) + mean = (p10 + p90) / 2 + std = (p90 - p10) / (2 * z_score) + return probabilit.distributions.Normal(mean=mean, std=std) + + case [_, (p10, p90, low, high)] if distname.startswith("normal_p10_p90"): + z_score = stats.norm.ppf(0.9) + mean = (p10 + p90) / 2 + std = (p90 - p10) / (2 * z_score) + return probabilit.distributions.TruncatedNormal( + mean=mean, std=std, low=low, high=high + ) + + case [_, (mean, std)] if distname.startswith("norm"): + return probabilit.distributions.Normal(mean=mean, std=std) + + case [_, (mean, std, low, high)] if distname.startswith("norm"): + return probabilit.distributions.TruncatedNormal( + mean=mean, std=std, low=low, high=high + ) + + case [_, parameters] if distname.startswith("norm"): + raise ValueError( + f"Normal must have 2 or 4 parameters, got: " + f"{len(parameters)} ({parameters})" + ) + + # ================== LOGNORMAL ================== + + case [_, (mu, sigma)] if distname.startswith("logn"): + return probabilit.distributions.Lognormal.from_log_params( + mu=mu, sigma=sigma + ) + + case [_, (mu, sigma, low, high)] if distname.startswith("logn"): + # (mu, sigma) are defined in log-space, but (low, high) + # are defined on exp-space + return probabilit.modeling.Exp( + probabilit.distributions.TruncatedNormal( + mu, sigma, low=np.log(low), high=np.log(high) + ) + ) + + case [_, parameters] if distname.startswith("logn"): + raise ValueError( + f"Lognormal must have 2 or 4 parameters, got: " + f"{len(parameters)} ({parameters})" + ) + + # ================== UNIFORM ================== + + case [_, (p10, p90)] if distname.startswith("uniform_p10_p90"): + length = (p90 - p10) / 0.8 + minimum = p10 - 0.1 * length + maximum = p90 + 0.1 * length + return probabilit.distributions.Uniform(minimum=minimum, maximum=maximum) + + case [_, (minimum, maximum)] if distname.startswith("unif"): + return probabilit.distributions.Uniform(minimum=minimum, maximum=maximum) + + case [_, parameters] if distname.startswith("unif"): + raise ValueError( + f"Uniform must have 2 parameters, got: {len(parameters)} ({parameters})" + ) + + # ================== TRIANGULAR ================== + + case [_, (low, mode, high)] if distname.startswith("triangular_p10_p90"): + return probabilit.distributions.Triangular( + low=low, mode=mode, high=high, low_perc=0.1, high_perc=0.9 + ) + + case [_, (minimum, mode, maximum)] if distname.startswith("triang"): + return probabilit.distributions.Triangular( + low=minimum, mode=mode, high=maximum, low_perc=0.0, high_perc=1.0 + ) + + case [_, parameters] if distname.startswith("triang"): + raise ValueError( + f"Triangular must have 3 parameters, got: " + f"{len(parameters)} ({parameters})" + ) + + # ================== BETA ================== + + case [_, (a, b)] if distname.startswith("beta"): + # Defaults to probabilit.Distribution("beta", a=a, b=b, loc=0, scale=1) + return probabilit.Distribution("beta", a=a, b=b) + + case [_, (a, b, low, high)] if distname.startswith("beta"): + loc = low + scale = high - low + return probabilit.Distribution("beta", a=a, b=b, loc=loc, scale=scale) + + case [_, parameters] if distname.startswith("beta"): + raise ValueError( + f"Beta must have 2 or 4 parameters, got: " + f"{len(parameters)} ({parameters})" + ) + + # ================== PERT ================== + + case [_, (low, mode, high)] if distname.startswith("pert_p10_p90"): + return probabilit.distributions.PERT( + low=low, mode=mode, high=high, low_perc=0.1, high_perc=0.9 + ) + + case [_, (low, mode, high, scale)] if distname.startswith("pert_p10_p90"): + return probabilit.distributions.PERT( + low=low, mode=mode, high=high, low_perc=0.1, high_perc=0.9, gamma=scale + ) + + case [_, (minimum, mode, maximum)] if distname.startswith("pert"): + return probabilit.distributions.PERT( + low=minimum, mode=mode, high=maximum, low_perc=0.0, high_perc=1.0 + ) + + case [_, (minimum, mode, maximum, scale)] if distname.startswith("pert"): + return probabilit.distributions.PERT( + low=minimum, + mode=mode, + high=maximum, + low_perc=0.0, + high_perc=1.0, + gamma=scale, + ) + + case [_, parameters] if distname.startswith("pert"): + raise ValueError( + f"PERT must have 3 or 4 parameters, got: " + f"{len(parameters)} ({parameters})" + ) + + # ================== LOGUNIFORM ================== + + case [_, (low, high)] if distname.startswith("logunif"): + return probabilit.Distribution("loguniform", low, high) + + case [_, parameters] if distname.startswith("logunif"): + raise ValueError( + f"Loguniform must have 2 parameters, got: " + f"{len(parameters)} ({parameters})" + ) + + case [distname, parameters]: + raise ValueError(f"Invalid combination of {distname=} and {parameters=}.") + + +def is_number(teststring: str) -> bool: + """Test if a string can be parsed as a float""" + try: + return not np.isnan(float(teststring)) + except ValueError: + return False + + +def read_correlations(excel_filename: str, corr_sheet: str) -> pd.DataFrame: + """Read a correlation matrix from an Excel sheet. + + The sheet must have rows/columns with variable names. They must match. + The upper-triangular part must be empty strings. The lower triangular part + must be specified. + + Args: + excel_filename (str): name of Excel file containing correlation matrix + corr_sheet (str): name of sheet containing correlation matrix + + Returns: + pd.DataFrame: Dataframe with correlations, parameter names + as column and index + """ + if not str(excel_filename).endswith(".xlsx"): + raise ValueError( + "Correlation matrix filename should be on Excel format and end with .xlsx" + ) + + correlations = ( + pd.read_excel( + excel_filename, + sheet_name=corr_sheet, + index_col=0, + # A user reported failures when a single space ' ' was present + # in the upper triangular part. Therefore we add spaces as NaN too. + na_values=[" " * i for i in range(10)], + engine="openpyxl", + ) + .dropna(axis=0, how="all") + # Remove any 'Unnamed' columns that Excel/pandas may have automatically added. + .loc[:, lambda df: ~df.columns.str.contains("^Unnamed")] + # Remove whitespace + .rename(columns=str.strip) + .rename(index=str.strip) + ) + + if list(correlations.index) != list(correlations.columns): + msg = ( + "Mismatch between column and index in correlation " + f"matrix sheet: {corr_sheet!r}\n" + f"Column: {correlations.columns.tolist()}\n" + f"Index : {correlations.index.tolist()}\n" + "These values must match exactly. Please fix sheet " + f"{corr_sheet!r} in file {excel_filename!r}." + ) + raise ValueError(msg) + + arr = correlations.to_numpy(copy=True) + upper_idx = np.triu_indices_from(arr, k=1) + lower_idx = np.tril_indices_from(arr, k=0) # Include diag + lower_entries = arr[lower_idx] + + if not np.all(np.isnan(arr[upper_idx])): + raise ValueError( + "All upper-triangular elements in matrix in " + f"corr sheet {corr_sheet} must be blank." + ) + + if not np.all(np.isfinite(lower_entries)): + raise ValueError( + "All lower-triangular elements in matrix in " + f"corr sheet {corr_sheet} must be specified." + ) + + if np.any((lower_entries < -1) | (lower_entries > 1)): + raise ValueError( + "All lower-triangular elements in matrix in " + f"corr sheet {corr_sheet} must be between -1 and 1." + ) + + # Build symmetric matrix from lower triangle + np.nan_to_num(arr, copy=False, nan=0.0) + mat = arr + arr.T + np.fill_diagonal(mat, 1.0) + return pd.DataFrame(mat, index=correlations.index, columns=correlations.columns) diff --git a/src/ert/config/fmudesign/examples/ex1_onebyone_rms_repeat.xlsx b/src/ert/config/fmudesign/examples/ex1_onebyone_rms_repeat.xlsx new file mode 100644 index 00000000000..3d2c57813d3 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex1_onebyone_rms_repeat.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex2_correlations.xlsx b/src/ert/config/fmudesign/examples/ex2_correlations.xlsx new file mode 100644 index 00000000000..2dd52e6b214 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex2_correlations.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex2_doe1.xlsx b/src/ert/config/fmudesign/examples/ex2_doe1.xlsx new file mode 100644 index 00000000000..f89741402f1 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex2_doe1.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex3_velocities.xlsx b/src/ert/config/fmudesign/examples/ex3_velocities.xlsx new file mode 100644 index 00000000000..d7db0fd09f8 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex3_velocities.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex4_background_parameters.xlsx b/src/ert/config/fmudesign/examples/ex4_background_parameters.xlsx new file mode 100644 index 00000000000..89a93e47c5e Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex4_background_parameters.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex4_doe1.xlsx b/src/ert/config/fmudesign/examples/ex4_doe1.xlsx new file mode 100644 index 00000000000..f89741402f1 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex4_doe1.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex5_single_reference.xlsx b/src/ert/config/fmudesign/examples/ex5_single_reference.xlsx new file mode 100644 index 00000000000..fa7cfe29d35 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex5_single_reference.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex6_singlereference_and_seed.xlsx b/src/ert/config/fmudesign/examples/ex6_singlereference_and_seed.xlsx new file mode 100644 index 00000000000..b48d6ee1b25 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex6_singlereference_and_seed.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex7_background_no_seed.xlsx b/src/ert/config/fmudesign/examples/ex7_background_no_seed.xlsx new file mode 100644 index 00000000000..52a5b629760 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex7_background_no_seed.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex7_doe1.xlsx b/src/ert/config/fmudesign/examples/ex7_doe1.xlsx new file mode 100644 index 00000000000..f89741402f1 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex7_doe1.xlsx differ diff --git a/src/ert/config/fmudesign/examples/ex8_mc_with_correls.xlsx b/src/ert/config/fmudesign/examples/ex8_mc_with_correls.xlsx new file mode 100644 index 00000000000..3ee600a5ff2 Binary files /dev/null and b/src/ert/config/fmudesign/examples/ex8_mc_with_correls.xlsx differ diff --git a/src/ert/config/fmudesign/examples/fmudesign_ex_montecarlo.xlsx b/src/ert/config/fmudesign/examples/fmudesign_ex_montecarlo.xlsx new file mode 100644 index 00000000000..5b19a475982 Binary files /dev/null and b/src/ert/config/fmudesign/examples/fmudesign_ex_montecarlo.xlsx differ diff --git a/src/ert/config/fmudesign/examples/fmudesign_ex_onebyone.xlsx b/src/ert/config/fmudesign/examples/fmudesign_ex_onebyone.xlsx new file mode 100644 index 00000000000..24b085c684d Binary files /dev/null and b/src/ert/config/fmudesign/examples/fmudesign_ex_onebyone.xlsx differ diff --git a/src/ert/config/fmudesign/fmudesignrunner.py b/src/ert/config/fmudesign/fmudesignrunner.py new file mode 100644 index 00000000000..f30eb0ec245 --- /dev/null +++ b/src/ert/config/fmudesign/fmudesignrunner.py @@ -0,0 +1,341 @@ +""" +This module is responsible for running the 'fmudesign' CLI tool. + +It contains argumenting parsing logic, some argument validation and high-level +functions that delegate to lower-level functions for creating design matrices. + +There are two main sub-commands: + $ fmudesign init => Create example/demo configuration file for the user + $ fmudesign run => Run a configuration file and produce design matrix + +Without arguments (init / run), the CLI will execute 'run' to be backwards +compatible. For more information, look at the code or execute + + $ fmudesign --help + +""" + +import argparse +import dataclasses +import functools +import shutil +import sys +import traceback +import warnings +from argparse import ArgumentParser, Namespace, _SubParsersAction +from importlib.resources import as_file, files +from pathlib import Path + +from ._excel_to_dict import excel_to_dict +from .create_design import DesignMatrix + + +@dataclasses.dataclass +class Example: + # Examples used in the 'fmudesign init' subcommand + + filename: str + description: str + # Auxiliary files that the main file depend on (external params, seeds, etc.) + other_files: list[str] = dataclasses.field(default_factory=list) + + +EXAMPLES = [ + Example( + "fmudesign_ex_montecarlo.xlsx", + description=( + "Shows all statistical parameter distributions, " + "how to correlate samples, etc." + ), + ), + Example( + "fmudesign_ex_onebyone.xlsx", + description="The example file used in fmu-coursedocs. Extensively documented.", + ), + Example( + "ex1_onebyone_rms_repeat.xlsx", + description="One by one sensitivities with repeating RMS seeds", + ), + Example( + "ex2_correlations.xlsx", + description=( + "Sensitivities with group of (correlated) parameters " + "sampled from distributions" + ), + other_files=["ex2_doe1.xlsx"], + ), + Example( + "ex3_velocities.xlsx", + description="Testing different velocity models with uncertainty", + ), + Example( + "ex4_background_parameters.xlsx", + description="Sensitivities with background parameters", + other_files=["ex4_doe1.xlsx"], + ), + Example( + "ex5_single_reference.xlsx", + description="Sensitivities with a single reference realisation", + ), + Example( + "ex6_singlereference_and_seed.xlsx", + description=( + "Sensitivities with a single reference realisation and seed sensitivity" + ), + ), + Example( + "ex7_background_no_seed.xlsx", + description="Sensitivities with background but without RMS seed", + other_files=["ex7_doe1.xlsx"], + ), + Example("ex8_mc_with_correls.xlsx", description="Full Monte Carlo sensitivity"), +] + + +def get_parser() -> tuple[ArgumentParser, _SubParsersAction]: # type: ignore[type-arg] + """Create argument parser and return (parser, subparsers).""" + + # =============== MAIN PARSER =============== + parser = argparse.ArgumentParser( + description="Generates design matrices to be used with ERT", + epilog=( + f""" +example usage: + $ fmudesign --help + $ fmudesign init --help + $ fmudesign run --help + $ fmudesign init {next(iter(EXAMPLES)).filename} + $ fmudesign run {next(iter(EXAMPLES)).filename} output_example.xlsx + +getting help: + - Documentation: https://equinor.github.io/fmu-tools/fmudesign.html + - Issue tracker: https://github.com/equinor/semeio/issues""" + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + add_help=False, + ) + + parser.add_argument( + "-h", "--help", action="help", help="Show this help message and exit" + ) + subparsers = parser.add_subparsers(dest="command", help="Available subcommands") + + # =============== SUBCOMMAND: run =============== + description = "Generate a design matrix from a config file." + epilog = """example usage: + $ fmudesign --help + $ fmudesign run input_config_example.xlsx + $ fmudesign run input_config_example.xlsx output_example.xlsx """ + + parser_run = subparsers.add_parser( + "run", + help=description, + formatter_class=argparse.RawDescriptionHelpFormatter, + add_help=False, + epilog=epilog, + description=description, + ) + + parser_run.add_argument( + "-h", "--help", action="help", help="Show this help message and exit" + ) + parser_run.add_argument( + "config", + type=str, + help="Input design matrix filename in Excel format", + ) + parser_run.add_argument( + "destination", + type=str, + nargs="?", + help=( + "Destination filename for design matrix " + "(default: generateddesignmatrix.xlsx)" + ), + default="generateddesignmatrix.xlsx", + ) + parser_run.add_argument( + "--designinput", + type=str, + help=( + "Alternative sheetname for the worksheet designinput (default: designinput)" + ), + default="designinput", + ) + parser_run.add_argument( + "--defaultvalues", + type=str, + help=( + "Alternative sheetname for worksheet defaultvalues (default: defaultvalues)" + ), + default="defaultvalues", + ) + parser_run.add_argument( + "--general_input", + type=str, + help=( + "Alternative sheetname for the worksheet general_input" + "(default: general_input)" + ), + default="general_input", + ) + parser_run.add_argument( + "-v", + "--verbose", + action="count", + help=( + "Verbosity of terminal output and plotting, " + "run with increased verbosity level -v -v to include more information" + ), + default=0, + ) + func = functools.partial(subcommand_run, parser=parser_run) + parser_run.set_defaults(func=func) + + # =============== SUBCOMMAND: init =============== + description = "Initialize a demo file to get started with fmudesign." + epilog = "available demo files:\n" + ljust = max(len(f.filename) for f in EXAMPLES) + for example in EXAMPLES: + epilog += f" - {example.filename.ljust(ljust)} : {example.description}\n" + + ex_filename = next(iter(EXAMPLES)).filename + epilog += "\nexample usage:\n" + epilog += f" $ fmudesign init {ex_filename}\n" + epilog += f" $ fmudesign run {ex_filename}" + + parser_init = subparsers.add_parser( + "init", + help=description, + formatter_class=argparse.RawDescriptionHelpFormatter, + add_help=False, + epilog=epilog, + description=description, + ) + parser_init.add_argument( + "-h", "--help", action="help", help="Show this help message and exit" + ) + parser_init.add_argument( + "file", type=str, nargs="?", help="Name of demo file to create." + ) + + func = functools.partial(subcommand_init, parser=parser_init) + parser_init.set_defaults(func=func) + + return parser, subparsers + + +def subcommand_run(args: Namespace, parser: ArgumentParser) -> None: + """Handles the 'run' subcommand.""" + + # Check if defaults were changed + for sheet in ["designinput", "defaultvalues", "general_input"]: + default = parser.get_default(sheet) + custom = getattr(args, sheet) + if default != custom: + print(f"Worksheet changed from default: {default!r} -> {custom!r}") + + # Check existence of config file + if not Path(args.config).is_file(): + raise OSError(f"Input file {args.config} does not exist") + + # Check if destination exists + if Path(args.config).resolve() == Path(args.destination).resolve(): + raise OSError( + f'Identical name "{args.config}" have been provided for the input' + "file and the output file" + ) + + # Parse Excel config file to dict-of-dict configuration + print(f"Reading file: {args.config!r}") + config = excel_to_dict( + args.config, + gen_input_sheet=args.general_input, + design_input_sheet=args.designinput, + default_val_sheet=args.defaultvalues, + ) + + # If destination is 'analysis/generateddesignmatrix.xlsx', then plots + # will be saved to 'analysis/generateddesignmatrix//.png' + output_dir = Path(args.destination).parent / Path(args.destination).stem + design = DesignMatrix(verbosity=args.verbose, output_dir=output_dir) + + design.generate(config) + design.to_xlsx(args.destination) + + +def subcommand_init(args: Namespace, parser: ArgumentParser) -> None: + """Handles the 'init' subcommand.""" + EXAMPLES_DIR = files("ert.config.fmudesign.examples") + + # Verify that all examples in EXAMPLES_DIR exist on disk + for example in EXAMPLES: + assert (EXAMPLES_DIR / example.filename).is_file() + + # No files were provided + if not args.file: + parser.print_help() + sys.exit(0) + + filename = args.file.strip() + valid_names = {ex.filename for ex in EXAMPLES} + if filename not in valid_names: + print(f"Error on {filename!r}. Not found among: {valid_names}") + sys.exit(1) + + if Path(filename).exists(): + print(f"Error on {filename!r}. Already exists.") + sys.exit(1) + + with as_file(EXAMPLES_DIR / filename) as source_path: + shutil.copy(source_path, filename) + print(f"Created file {filename!r}.") + + examples_by_filename = {example.filename: example for example in EXAMPLES} + for other_file in examples_by_filename[filename].other_files: + with as_file(EXAMPLES_DIR / other_file) as source_path: + shutil.copy(source_path, other_file) + print(f" Created auxiliary file {other_file!r}.") + + sys.exit(0) + + +def main() -> None: + """semeio.fmudesign is a command line utility for generating design matrices + + Wrapper for the the semeio.fmudesign module + """ + warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings("ignore", category=FutureWarning) + + parser, _subparsers = get_parser() + + # Backwards compatibility. If not a known command, assume "run" + valid_cmds = ("run", "init", "-h", "--help", "-v") + if len(sys.argv) > 1 and sys.argv[1] not in valid_cmds: + sys.argv.insert(1, "run") + + args = parser.parse_args() + + # No subcommand was provided + if not hasattr(args, "func"): + parser.print_help() + sys.exit(0) + + try: + args.func(args) + except Exception: + traceback.print_exc() + print( + "\n \n", + "fmudesign failed. Read the error message above and fix the input file.\n", + " - Documentation: https://equinor.github.io/fmu-tools/fmudesign.html\n", + " - Course docs: https://fmu-docs.equinor.com/docs/fmu-coursedocs/fmu-howto/sensitivities/index.html \n", # ruff: ignore[line-too-long] + " - Issues/feature requests: https://github.com/equinor/semeio/issues\n", + "If you believe this error is a bug or are unable to fix it, create an issue or contact the scout team \n", # ruff: ignore[line-too-long] + ) + sys.exit(1) # Exit with a non-zero status code (required for smoke tests!) + + +if __name__ == "__main__": + main() diff --git a/src/ert/config/fmudesign/quality_report.py b/src/ert/config/fmudesign/quality_report.py new file mode 100644 index 00000000000..343aa9890a6 --- /dev/null +++ b/src/ert/config/fmudesign/quality_report.py @@ -0,0 +1,629 @@ +import copy +import math +from pathlib import Path +from typing import TYPE_CHECKING, Any, cast + +import matplotlib.pyplot as plt +import numpy as np +import numpy.typing as npt +import pandas as pd +import scipy as sp +import seaborn as sns +from probabilit.correlation import ( # type: ignore[import-untyped] + nearest_correlation_matrix, +) + +from .design_distributions import to_probabilit + +if TYPE_CHECKING: + from matplotlib.patches import Rectangle + +COLORS = list(plt.rcParams["axes.prop_cycle"].by_key()["color"]) + + +class QualityReporter: + """This class is responsible for quality reporting a dataframe with samples. + It has methods to print statistical outputs and save figures to disk. + + Examples + >>> import pandas as pd + >>> df = pd.DataFrame({"a": [2, 4, 2, 3, 4, 3, 2, 3, 4, 5], + ... "b": [2, 4, 2, 4, 2, 4, 2, 3, 2, 3], + ... "c": list("asdfsdfsdf")}) + >>> variables = {"a": ["Normal",[0, 1]], "b": ["Expon",[1]], "c":["Discrete"]} + >>> quality_reporter = QualityReporter(df, variables=variables) + >>> quality_reporter.print_numeric() + ================ CONTINUOUS PARAMETERS ================ + mean std min 10% 50% 90% max + a 3.2 1.032796 2.0 2.0 3.0 4.1 5.0 + b 2.8 0.918937 2.0 2.0 2.5 4.0 4.0 + >>> quality_reporter.print_discrete() + ================ DISCRETE PARAMETERS ================ + | c | proportion | + |:----|-------------:| + | s | 0.3 | + | d | 0.3 | + | f | 0.3 | + | a | 0.1 | + """ + + def __init__(self, df: pd.DataFrame, variables: dict[str, list[Any]]) -> None: + """Initialize QualityReporter with dataframe and variable descriptions. + + Args: + df: DataFrame containing the samples + variables: Dictionary mapping variable names to their + distribution descriptions + e.g., {"COST": ["normal", [0.0, 1.0]]} + """ + self.df: pd.DataFrame = df.loc[:, list(variables.keys())] + self.variables: dict[str, list[Any]] = copy.deepcopy(variables) + assert not self.df.empty + + def print_numeric(self) -> None: + """Print statistics for all numerical columns.""" + df_numeric = self.df.select_dtypes(include="number") + if df_numeric.empty: + return + + print("=" * 16, "CONTINUOUS PARAMETERS", "=" * 16) + + with pd.option_context( + "display.max_rows", None, "display.max_columns", None, "display.width", None + ): + print( + df_numeric.describe(percentiles=[0.1, 0.5, 0.9]).T.drop( + columns=["count"] + ) + ) + + def print_discrete(self) -> None: + """Print statistics for all discrete (non-numerical) columns.""" + df_non_numeric = self.df.select_dtypes(exclude="number") + if df_non_numeric.empty: + return + + print("=" * 16, "DISCRETE PARAMETERS", "=" * 16) + + for column in df_non_numeric.columns: + print(self.df[column].value_counts(normalize=True).round(3).to_markdown()) + + @staticmethod + def _create_output_dir(output_dir: Path | None) -> Path | None: + if output_dir is not None: + output_dir = Path(output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + return output_dir + return None + + def plot_columns(self, output_dir: Path | None = None) -> None: + """Loop through all columns and plot them, saving to disk if + `output_dir` is given and exists. + + Args: + output_dir: Optional directory path to save plots. If None, plots + are not saved to disk. + """ + df_numeric = self.df.select_dtypes(include="number") + df_non_numeric = self.df.select_dtypes(exclude="number") + + print("=" * 16, "GENERATING VARIABLE PLOTS", "=" * 16) + + # Create output directory if specified + output_path = self._create_output_dir(output_dir) + + # Plot numeric columns + for column in df_numeric.columns: + # We do not plot constant distributions + if self.variables[column][0].lower().startswith("const"): + continue + + fig, _ax = self.plot_numeric( + series=self.df[column], + var_name=column, + var_description=self.variables[column], + ) + + if output_path is not None: + filename = output_path / f"{column}.png" + fig.savefig(filename, dpi=200) + print(f" - Saved variable: {filename}") + + plt.close(fig) + + # Plot discrete columns + for column in df_non_numeric.columns: + fig, _ax = self.plot_discrete( + series=self.df[column], + var_name=column, + var_description=self.variables[column], + ) + + if output_path is not None: + filename = output_path / f"{column}.png" + fig.savefig(filename, dpi=200) + print(f" - Saved file: {filename}") + + plt.close(fig) + + @staticmethod + def plot_numeric( + series: pd.Series, var_name: str, var_description: list[Any] + ) -> tuple[plt.Figure, plt.Axes]: + """Create a plot for a single numeric column, returning (fig, ax). + + Args: + series: Pandas series containing the numeric data + var_name: Name of the variable + var_description: Description of the variable distribution + + Returns: + Tuple of (matplotlib Figure, matplotlib Axes) + """ + fig, ax = plt.subplots(figsize=(6, 4)) + bins = max(int(math.sqrt(len(series))), 10) + sns.histplot(data=series, stat="density", bins=bins, ax=ax) + sns.kdeplot(series, ax=ax, color="blue", label="KDE") + + # Create string to describe distiribution + var_string = ( + f"{var_description[0]}~(" + + ", ".join( + f"dist_param{i + 1}={v}" for i, v in enumerate(var_description[1]) + ) + + ")" + ) + + ax.set_title(f"{var_name}\n{var_string}", fontsize=7) + + # Add plot of expected PDF + dist_name, dist_parameters = var_description[:2] + + try: + dist = to_probabilit(dist_name, dist_parameters) + x = np.linspace(series.min(), series.max(), 1000) + pdf = dist.to_scipy().pdf(x) + ax.plot(x, pdf, color="red", lw=2, ls="--", label="expected PDF") + except AttributeError: + print(f" - Plot warning: PDF not plotted for {var_name}") + + # Add rugplot + ax.scatter( + series.to_numpy(), + np.zeros(len(series)), + marker="|", + color=COLORS[1], + alpha=0.8, + ) + + # Add average and quantiles to the plot + mean = series.mean() + ax.axvline( + x=mean, + color="black", + ls="-", + alpha=0.8, + label=f"mean={mean:.2e}", + ) + + quantiles = [0.1, 0.5, 0.9] + for q in quantiles: + quantile_value = series.quantile(q=q) + P_label = f"{q * 100:.0f}".zfill(2) # e.g. 0.05 => '05' + ax.axvline( + x=quantile_value, + color="black", + ls="--", + alpha=0.8, + label=f"P{P_label}={quantile_value:.2e}", + ) + + ax.grid(visible=True, ls="--", alpha=0.5) + ax.legend(loc="upper left", bbox_to_anchor=(1.05, 1), fontsize=7) + fig.tight_layout() + + return fig, ax + + @staticmethod + def plot_discrete( + series: pd.Series, var_name: str, var_description: list[Any] + ) -> tuple[plt.Figure, plt.Axes]: + """Create a plot for a single discrete column, returning (fig, ax). + + Args: + series: Pandas series containing the discrete data + var_name: Name of the variable + var_description: Description of the variable distribution + + Returns: + Tuple of (matplotlib Figure, matplotlib Axes) + """ + fig, ax = plt.subplots(figsize=(6, 4)) + + # Calculate normalized proportions + proportions = series.value_counts(normalize=True) + value_counts = series.value_counts(normalize=False) + + # Create DataFrame for seaborn + plot_data = pd.DataFrame( + {var_name: proportions.index, "proportion": proportions.to_numpy()} + ).sort_values(by=var_name) + + # Use seaborn barplot with normalized values + sns.barplot(data=plot_data, x=var_name, y="proportion", ax=ax) + + # Create string to describe distiribution + var_string = ( + f"{var_description[0]}~(" + + ", ".join( + f"dist_param{i + 1}={v}" for i, v in enumerate(var_description[1]) + ) + + ")" + ) + + ax.set_title(f"{var_name}\n{var_string}", fontsize=7) + ax.set_ylabel("Proportion") + + # Add percentage labels on bars + for _proportion, count, p in zip( + proportions, value_counts, ax.patches, strict=False + ): + rect = cast("Rectangle", p) + # assert math.isclose(_proportion, rect.get_height()) + percentage = f"{rect.get_height():.1%} (n={count:.0f})" + ax.annotate( + percentage, + (rect.get_x() + rect.get_width() / 2.0, rect.get_height()), + ha="center", + va="bottom", + fontsize=9, + ) + + ax.grid(visible=True, ls="--", alpha=0.5, axis="y") + ax.tick_params(axis="x", rotation=0) + fig.tight_layout() + + return fig, ax + + def print_correlation(self, corr_name: str, df_corr: pd.DataFrame) -> None: + """Print information about desired and achieved correlation matrices. + + Args: + corr_name: Name of the correlation group + df_corr: DataFrame containing the desired correlation matrix + """ + corr_arr = df_corr.to_numpy() + assert np.allclose(corr_arr, corr_arr.T) + assert df_corr.shape[0] == df_corr.shape[1] + + # Get lower triangular indices + idx_low_triang = np.tril_indices_from(corr_arr, k=-1) + corr = self.df[df_corr.columns].select_dtypes(include="number").corr() + # Do not print if only a single variable remains + if corr.shape[1] == 1: + return + + print( + "=" * 16, + f"CORRELATION_GROUP {corr_name!r} (num variables: {len(df_corr.columns)})", + "=" * 16, + ) + + if len(df_corr) <= 12: + print("Desired correlation:") + print_corrmat(df_corr) + else: + print("Skipping printing desired correlation. Matrix too large.") + + nearest_corr = nearest_correlation_matrix( + corr_arr, weights=None, eps=1e-6, verbose=False + ) + diffs = nearest_corr[idx_low_triang] - corr_arr[idx_low_triang] + corr_rmse = np.sqrt(np.mean(diffs**2)) + + if corr_rmse > 1e-2: + print(f"The desired correlation matrix is not valid => {corr_rmse=:.2f}") + print("Closest valid correlation matrix (used as target):") + df_nearest_corr = pd.DataFrame( + nearest_corr, columns=df_corr.columns, index=df_corr.index + ) + print_corrmat(df_nearest_corr) + else: + print("The desired correlation matrix is valid") + + # No correlation in samples (e.g. discrete variables) + if corr.empty: + return + + if len(corr) <= 12: + print("Observed (Pearson) correlation in samples:") + print_corrmat(corr) + else: + print("Skipping printing observed (Pearson) correlation. Matrix too large.") + + # Difference between achieved corr in samples and target + diffs = corr.to_numpy()[idx_low_triang] - nearest_corr[idx_low_triang] + corr_rmse = np.sqrt(np.mean(diffs**2)) + print( + "Distance metrics between target correlation matrix " + "and empirical correlation matrix" + ) + print(f" - Root Mean Squared Error (RMSE): {corr_rmse:.6f}") + + if corr_rmse > 0.05: + print( + "Target correlation matrix and empirical correlation achieved", + " in data does not match well\n" + "This is natural with few samples, or very high/low desired correlations, " # ruff: ignore[line-too-long] + "or distributions that are far from\nnormal (e.g. lognormal)." + " Setting 'correlation_iterations' to 999 in the general input sheet might help.", # ruff: ignore[line-too-long] + ) + + def plot_correlation( + self, + corr_name: str, + df_corr: pd.DataFrame, + *, + output_dir: Path | None = None, + show: bool, + ) -> None: + """Plot correlation group of variables. + + Args: + corr_name: Name of the correlation group + df_corr: DataFrame containing the correlation structure to plot + output_dir: Optional directory path to save plots + show: Whether or not to show the matplotlib figure + """ + # Short circuit this case, as there is nothing to do + if (not show) and (output_dir is None): + return + + def corrfunc( + x: npt.NDArray[np.float64], + y: npt.NDArray[np.float64], + **kwargs: Any, + ) -> None: + # Add correlations and grid to plots + r, _ = sp.stats.pearsonr(x, y) + ax = plt.gca() + ax.annotate( + r"$\rho=$" + f"{r:.2f}", + xy=(0.05, 0.95), + xycoords=ax.transAxes, + ) + ax.grid(visible=True, ls="--", alpha=0.5) + + def add_grid(*args: Any, **kwargs: Any) -> None: + ax = plt.gca() + ax.grid(visible=True, ls="--", alpha=0.5) + + df = self.df[df_corr.columns].select_dtypes(include="number") + + # Only plot if two or more variables remain + if df.shape[1] <= 1: + return + + pairgrid = sns.PairGrid(df) + + pairgrid.map_upper(sns.kdeplot) + pairgrid.map_upper(add_grid) + bins = max(int(math.sqrt(len(df))), 30) + pairgrid.map_diag(sns.histplot, bins=bins, kde=True) + + pairgrid.map_lower(sns.scatterplot, s=10, alpha=0.6) + pairgrid.map_lower(corrfunc) + + # Add rugplots to diagonal plots + for i, var in enumerate(df.columns): + pairgrid.diag_axes[i].scatter( + df[var].to_numpy(), + np.zeros(len(df)), + marker="|", + color="black", + alpha=0.5, + ) + + output_path = self._create_output_dir(output_dir) + if output_path is not None: + filename = output_path / f"{corr_name}.png" + pairgrid.savefig(filename, dpi=200) + print(f" - Saved correlation: {filename}") + + if show: + plt.show() + + plt.close(pairgrid.fig) + + def plot_correlation_heatmap( + self, + corr_name: str, + df_corr: pd.DataFrame, + *, + output_dir: Path | None = None, + show: bool, + ) -> None: + """Plot correlation heapmap of group of variables. + + Args: + corr_name: Name of the correlation group + df_corr: DataFrame containing the correlation structure to plot + output_dir: Optional directory path to save plots + show: Whether or not to show the matplotlib figure + """ + # Short circuit this case, as there is nothing to do + if (not show) and (output_dir is None): + return + + df = self.df[df_corr.columns].select_dtypes(include="number") + + # Only plot if two or more variables remain + if df.shape[1] <= 1: + return + + correlation_matrix = df.corr() + n_vars = len(correlation_matrix) + + # Roughly try to create a figure of a good size + size = 3 + n_vars * 0.15 + fig, ax = plt.subplots(1, 1, figsize=(size, size)) + + # Custom annotation + arr = correlation_matrix.to_numpy() + annot_arr = np.empty_like(arr, dtype=object) + for (i, j), value in np.ndenumerate(arr): + annot_arr[i, j] = "1" if i == j else f"{value:.2f}".replace("0.", ".") + annot_matrix = pd.DataFrame( + annot_arr, + index=correlation_matrix.index, + columns=correlation_matrix.columns, + ) + + # Based on a linear regression + annot_fontsize = max(8 - 0.115 * n_vars, 2) + sns.heatmap( + correlation_matrix, + annot=annot_matrix, + fmt="", + cmap="coolwarm", + center=0, + square=True, + linewidths=0.5, + cbar_kws={"shrink": 0.75}, + vmin=-1, + vmax=1, + ax=ax, + annot_kws={"size": annot_fontsize}, + ) + ax.set_title(f"Observed correlation: {corr_name}", fontsize=11) + + # Rotate labels + ax.set_xticklabels(ax.get_xticklabels(), rotation=90, ha="center", va="top") + ax.set_yticklabels(ax.get_yticklabels(), rotation=0) + ax.tick_params(axis="both", which="major", labelsize=6) + plt.subplots_adjust(bottom=0.15) + + fig.tight_layout() + + output_path = self._create_output_dir(output_dir) + if output_path is not None: + filename = output_path / f"{corr_name}_heatmap.png" + fig.savefig(filename, dpi=200) + print(f" - Saved correlation heatmap: {filename}") + + if show: + plt.show() + + plt.close(fig) + + +def print_corrmat(df_corrmat: pd.DataFrame) -> None: + """Print a correlation matrix. + + Example: + >>> values = np.array([[ 1, -0, 0.9], + ... [ -0, 1, 0], + ... [0.9, 0, 1]]) + >>> vars_ = ['OWC1', 'OWC2', 'OWC3'] + >>> df_corrmat = pd.DataFrame(values, index=vars_, columns=vars_) + >>> print_corrmat(df_corrmat) + | | (1) | (2) | (3) | + |:---------|------:|------:|------:| + | (1) OWC1 | 1.00 | | | + | (2) OWC2 | 0.00 | 1.00 | | + | (3) OWC3 | 0.90 | 0.00 | 1.00 | + """ + values = df_corrmat.to_numpy(copy=True) + assert np.allclose(values, values.T) + # Make slightly negative values positive + mask = np.isclose(values, 0) + values[mask] = np.abs(values[mask]) + df_corrmat = pd.DataFrame( + values, index=df_corrmat.index, columns=df_corrmat.columns + ) + + # Compress columns into integers so we can show more on the screen + assert list(df_corrmat.columns) == list(df_corrmat.index) + varnames = list(df_corrmat.columns) + df_corrmat = df_corrmat.set_axis( + [f"({i})" for i, _ in enumerate(varnames, 1)], axis=1 + ) + df_corrmat = df_corrmat.set_axis( + [f"({i}) {varname}" for i, varname in enumerate(varnames, 1)], axis=0 + ) + + # Remove upper triangular part for prettier printing + def formatter(x: float) -> str: + return np.format_float_positional(x, precision=2, unique=True, min_digits=2) + + mask = np.triu(np.ones_like(df_corrmat, dtype=bool), k=1) + df_display = df_corrmat.astype(float).map(formatter) + df_display[mask] = "" + print( + df_display.to_markdown( + floatfmt=".2f", + disable_numparse=True, + numalign="right", + stralign="right", + colalign=("left",), + ) + ) + + +if __name__ == "__main__": + # Testing an experimenting with this class is easier with an example, + # rather than trying to formally test the design of output plots + # using units tests and the like. Therefore an example is included. + + # Create sample data + rng = np.random.default_rng(42) + n_samples = 500 + + # Generate correlated data + mean = [0, 0] + cov = [[1, 0.7], [0.7, 1]] + correlated_data = rng.multivariate_normal(mean, cov, n_samples) + + df = pd.DataFrame( + { + "COST": correlated_data[:, 0] * 100 + 1000, + "EFFICIENCY": correlated_data[:, 1] * 0.1 + 0.8, + "MATERIAL": rng.choice( + ["Steel", "Aluminum", "Titanium"], n_samples, p=[0.5, 0.3, 0.2] + ), + } + ) + + variables: dict[str, list[Any]] = { + "COST": ["Normal", [1000, 100]], + "EFFICIENCY": ["Normal", [0.8, 0.1]], + "MATERIAL": ["Discrete", ["Steel", "Aluminum", "Titanium"]], + } + + # Create QualityReporter + quality_reporter = QualityReporter(df, variables) + + # 1. Plot all columns + quality_reporter.plot_columns() + + # 2. Plot individual numeric variable + fig, ax = quality_reporter.plot_numeric(df["COST"], "COST", variables["COST"]) + plt.show() + plt.close(fig) + + # 3. Plot individual discrete variable + fig, ax = quality_reporter.plot_discrete( + df["MATERIAL"], "MATERIAL", variables["MATERIAL"] + ) + plt.show() + plt.close(fig) + + # 4. Correlation analysis and plotting + correlation_matrix = pd.DataFrame( + [[1.0, 0.7], [0.7, 1.0]], + index=["COST", "EFFICIENCY"], + columns=["COST", "EFFICIENCY"], + ) + + quality_reporter.print_correlation("corr1", correlation_matrix) + quality_reporter.plot_correlation("corr1", correlation_matrix, show=True) diff --git a/src/ert/config/fmudesign/utils.py b/src/ert/config/fmudesign/utils.py new file mode 100644 index 00000000000..c8fc41e4302 --- /dev/null +++ b/src/ert/config/fmudesign/utils.py @@ -0,0 +1,214 @@ +"""Module for utility functions that do not belong elsewhere.""" + +from typing import Any + +import pandas as pd + + +def parameters_from_extern(filename: str) -> pd.DataFrame: + """Read parameter values or background values + from specified file. Format either Excel ('xlsx') + or csv. + + Args: + filename (str): name of file + """ + if str(filename).endswith(".xlsx"): + return ( + pd.read_excel(filename, engine="openpyxl") + .dropna(axis=0, how="all") + .loc[:, lambda df: ~df.columns.str.contains("^Unnamed")] + ) + + if str(filename).endswith(".csv"): + return pd.read_csv(filename) + + raise ValueError( + "External file with parameter values should " + "be on Excel or csv format " + "and end with .xlsx or .csv" + ) + + +def seeds_from_extern(filename: str) -> list[int]: + """Read parameter values or background values + from specified file. Format either Excel ('xlsx') + or csv. + + Args: + filename (str): name of file + """ + if str(filename).endswith(".xlsx"): + df_seeds = ( + pd.read_excel(filename, header=None, engine="openpyxl") + .dropna(axis=0, how="all") + .dropna(axis=1, how="all") + ) + return df_seeds.iloc[:, 0].tolist() + + if str(filename).endswith(".csv") or str(filename).endswith(".txt"): + df_seeds = pd.read_csv(filename, header=None) + return df_seeds.iloc[:, 0].tolist() + + raise ValueError( + "External file with seed values should " + "be on Excel or csv format " + "and end with .xlsx .csv or .txt" + ) + + +def find_max_realisations(config: dict[str, Any]) -> int: + """Finds the maximum number of realisations over all sensitivity cases.""" + max_reals = config.get("repeats", 0) + for sens_info in config["sensitivities"].values(): + max_reals = max(sens_info.get("numreal", 0), max_reals) + assert max_reals > 0 + return max_reals + + +def printwarning(corr_group_name: str) -> None: + print( + "#######################################################\n" + "semeio.fmudesign Warning: \n" + "Using designinput sheets where " + "corr_sheet is only specified for one parameter " + "will cause non-correlated parameters .\n" + f"ONLY ONE PARAMETER WAS SPECIFIED TO USE CORR_SHEET {corr_group_name}\n" + "\n" + "Note change in how correlated parameters are specified \n" + "from fmudeisgn version 1.0.1 in August 2019 :\n" + "Name of correlation sheet must be specified for each " + "parameter in correlation matrix. \n" + "This to enable use of several correlation sheets. " + "This also means non-correlated parameters do not " + "have to be included in correlation matrix. \n " + "See documentation: \n" + "https://equinor.github.io/fmu-tools/" + "fmudesign.html#create-design-matrix-for-" + "one-by-one-sensitivities\n" + "\n" + "####################################################\n" + ) + + +def to_numeric_safe(val: float | str) -> int | float | str: + """Convert all values that CAN be converted to numeric. Retain the rest. + This used to be pd.to_numeric(..., errors='ignore'), but was deprecated. + + Examples + -------- + >>> df = pd.DataFrame({'a': ['cat', '3.5', '-1', 0, 'dog']}) + >>> df.map(to_numeric_safe).a.values + array(['cat', np.float64(3.5), np.int64(-1), 0, 'dog'], dtype=object) + + >>> [to_numeric_safe(e) for e in [5, '3', 'dog']] + [5, np.int64(3), 'dog'] + + """ + assert not isinstance(val, pd.Series | pd.DataFrame | list) + try: + return pd.to_numeric(val) # noq + except (ValueError, TypeError): + return val + + +def map_dependencies( + df: pd.DataFrame, *, dependencies: dict[str, Any], verbose: bool = False +) -> pd.DataFrame: + """Return a new copy of `df` with dependencies mapped. + + Examples + -------- + >>> df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': ['A', 'B', 'C', 'D']}) + >>> dependencies = {'a': {'from_values': [1, 2, 3, 4], + ... 'to_params':{'c': [1, 4, 9, 16]}}} + >>> map_dependencies(df, dependencies=dependencies) + a b c + 0 1 A 1 + 1 2 B 4 + 2 3 C 9 + 3 4 D 16 + + A messy mix of numbers and strings: + + >>> df = pd.DataFrame({'a': ['1', '2', 3, 4], 'b': ['A', 'B', 'C', 'D']}) + >>> dependencies = {'a': {'from_values': ['1', 2, '3', 4], + ... 'to_params':{'c': [1, 4, 9, '16']}}} + >>> map_dependencies(df, dependencies=dependencies) + a b c + 0 1 A 1 + 1 2 B 4 + 2 3 C 9 + 3 4 D 16 + + If no `to_params` are given, then the `from` column is copied: + + >>> dependencies = {'a': {'from_values': ['1', 2, '3', 4], + ... 'to_params':{'c': [1, 4, 9, '16'], + ... 'd': []}}} + >>> map_dependencies(df, dependencies=dependencies) + a b c d + 0 1 A 1 1 + 1 2 B 4 2 + 2 3 C 9 3 + 3 4 D 16 4 + """ + + df = df.copy() + for from_param, from_dict in dependencies.items(): + # No column to map from + if from_param not in df.columns: + continue + + from_values = from_dict["from_values"] + from_values = [to_numeric_safe(value) for value in from_values] + + for to_param, to_values_ in from_dict["to_params"].items(): + to_values = [to_numeric_safe(value) for value in to_values_] + + # No values to map to => to_param = copy(from_param) + if not to_values: + df = df.assign(**{to_param: df[from_param].map(to_numeric_safe)}) + if verbose: + print(f"Copied {from_param!r} to {to_param!r}") + continue + + if len(from_values) != len(to_values): + msg = ( + f"Mapping dependencies {from_param!r} to {to_param!r} failed.\n" + f"Length mismatch.\nMapping from values: {from_values!r}" + f"\nMapping to values: {to_values!r}" + ) + raise ValueError(msg) + + # At this point we have a mapping 'from_param' - > 'to_param' + # defined elementwise by values of 'from_values' -> 'to_values' + mapping = dict(zip(from_values, to_values, strict=False)) + + # Check that every value will be mapped + not_mapped = set(df[from_param].map(to_numeric_safe)) - set(from_values) + if not_mapped: + msg = ( + f"Mapping dependencies {from_param!r} to {to_param!r} using " + f"mapping:\n{mapping!r}\n failed. The following values could " + f"not be mapped:\n{not_mapped!r}" + ) + raise ValueError(msg) + + df = df.assign( + **{ + # Bind loop variables as default args to the lambda + to_param: lambda df, from_param=from_param, mapping=mapping: ( + df[from_param].map(to_numeric_safe).map(mapping) + ) + } + ) + if verbose: + print( + f"Mapping dependency. From {from_param!r} " + f"to {to_param!r} using map:" + ) + for from_, to_ in mapping.items(): + print(f" {from_} => {to_}") + + return df diff --git a/tests/ert/ui_tests/fmudesign/__init__.py b/tests/ert/ui_tests/fmudesign/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/ert/ui_tests/fmudesign/design_input/__init__.py b/tests/ert/ui_tests/fmudesign/design_input/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/ert/ui_tests/fmudesign/design_input/design_input.py b/tests/ert/ui_tests/fmudesign/design_input/design_input.py new file mode 100644 index 00000000000..a4fc7e768b3 --- /dev/null +++ b/tests/ert/ui_tests/fmudesign/design_input/design_input.py @@ -0,0 +1,31 @@ +from abc import ABC, abstractmethod +from io import BytesIO + +import xlsxwriter + + +class DesignInput(ABC): + """Baseclass for creating test data mimicking Excel workbooks containing the 3 + sheets required by fmudesign in the form of a bytestream which can be passed + to fmudesign.excel_to_dict(). + """ + + GENERAL_SHEET: str = "general_input" + DESIGN_SHEET: str = "designinput" + DEFAULT_SHEET: str = "defaultvalues" + + @abstractmethod + def excel_byte_stream(self) -> BytesIO: + pass + + @abstractmethod + def _write_general_input(self, wb: xlsxwriter.Workbook) -> None: + pass + + @abstractmethod + def _write_design_input(self, wb: xlsxwriter.Workbook) -> None: + pass + + @abstractmethod + def _write_default_values(self, wb: xlsxwriter.Workbook) -> None: + pass diff --git a/tests/ert/ui_tests/fmudesign/design_input/fmudesign_ex_onebyone.py b/tests/ert/ui_tests/fmudesign/design_input/fmudesign_ex_onebyone.py new file mode 100644 index 00000000000..9097305f33a --- /dev/null +++ b/tests/ert/ui_tests/fmudesign/design_input/fmudesign_ex_onebyone.py @@ -0,0 +1,146 @@ +from io import BytesIO + +import xlsxwriter + +from tests.ert.ui_tests.fmudesign.design_input.design_input import DesignInput + + +class FmudesignOneByOne(DesignInput): + def excel_byte_stream(self) -> BytesIO: + byte_stream = BytesIO() + with xlsxwriter.Workbook(byte_stream) as wb: + self._write_general_input(wb) + self._write_design_input(wb) + self._write_default_values(wb) + byte_stream.seek(0) + return byte_stream + + def _write_general_input(self, wb: xlsxwriter.Workbook) -> None: + ws = wb.add_worksheet(self.GENERAL_SHEET) + rows = [ + ["designtype", "onebyone"], + ["repeats", 10], + ["rms_seeds", "default"], + ["background", None], + ["distribution_seed", None], + ] + for row_idx, row in enumerate(rows): + ws.write_row(row_idx, 0, row) + + def _write_design_input(self, wb: xlsxwriter.Workbook) -> None: + ws = wb.add_worksheet(self.DESIGN_SHEET) + header = [ + "sensname", + "numreal", + "type", + "param_name", + "senscase1", + "value1", + "senscase2", + "value2", + "dist_name", + "dist_param1", + "dist_param2", + "dist_param3", + "dist_param4", + "decimals", + "corr_sheet", + "extern_file", + ] + rows = [ + [ + "rms_seed", + None, + "seed", + ] + + [None] * 13, + [ + "faults", + None, + "scenario", + "FAULT_POSITION", + "east", + -1, + "west", + 1, + ] + + [None] * 8, + [ + "velmodel", + None, + "scenario", + "DC_MODEL", + "alternative", + "hum2", + ] + + [None] * 10, + [ + "contacts", + None, + "scenario", + "OWC1", + "shallow", + 2600, + "deep", + 2700, + ] + + [None] * 8, + [ + None, + None, + None, + "OWC2", + None, + 2700, + None, + 2800, + ] + + [None] * 8, + [ + None, + None, + None, + "OWC3", + None, + 2800, + None, + 2900, + ] + + [None] * 8, + [ + "multz", + 20, + "dist", + "MULTZ_ILE", + None, + None, + None, + None, + "logunif", + 0.0001, + 1, + ] + + [None] * 5, + ] + ws.write_row(0, 0, header) + for row_idx, row in enumerate(rows, start=1): + ws.write_row(row_idx, 0, row) + + def _write_default_values(self, wb: xlsxwriter.Workbook) -> None: + ws = wb.add_worksheet(self.DEFAULT_SHEET) + header = ["param_name", "default_values"] + rows = [ + ["RMS_SEED", 1000], + ["FAULT_POSITION", 0], + ["DC_MODEL", "base"], + ["OWC1", 2650], + ["OWC2", 2750], + ["OWC3", 2850], + ["MULTZ_ILE", 0.1], + ["PARAM1", 100], + ["PARAM2", 200], + ["PARAM3", 0.5], + ] + ws.write_row(0, 0, header) + for row_idx, row in enumerate(rows, start=1): + ws.write_row(row_idx, 0, row) diff --git a/tests/ert/ui_tests/fmudesign/test_one_by_one_sensitivity.py b/tests/ert/ui_tests/fmudesign/test_one_by_one_sensitivity.py new file mode 100644 index 00000000000..e4c168b6e83 --- /dev/null +++ b/tests/ert/ui_tests/fmudesign/test_one_by_one_sensitivity.py @@ -0,0 +1,26 @@ +from importlib.resources import files + +from ert.config.fmudesign import excel_to_dict +from tests.ert.ui_tests.fmudesign.design_input.fmudesign_ex_onebyone import ( + FmudesignOneByOne, +) + +EXAMPLES_DIR = files("ert.config.fmudesign.examples") + + +def test_that_one_by_one_byte_stream_gives_same_dict_result_as_file(): + xlsx_byte_stream = FmudesignOneByOne().excel_byte_stream() + + stream_result = excel_to_dict(xlsx_byte_stream) + + one_by_one_example_filename = str(EXAMPLES_DIR / "fmudesign_ex_onebyone.xlsx") + + xlsx_result = excel_to_dict(one_by_one_example_filename) + + assert stream_result.keys() == xlsx_result.keys() + assert all( + stream_result[key] == xlsx_result[key] + for key in xlsx_result + # The inputfile will differ as one is a byte steam while the other a string + if key != "input_file" + ) diff --git a/tests/ert/ui_tests/test_fmu_design.py b/tests/ert/ui_tests/test_fmu_design.py new file mode 100644 index 00000000000..0427f6bf63f --- /dev/null +++ b/tests/ert/ui_tests/test_fmu_design.py @@ -0,0 +1,6 @@ +from io import BytesIO +import polars as pl + +def _df_to_excel_stream(df: pl.DataFrame) -> BytesIO: + byte_stream = BytesIO() + diff --git a/tests/ert/unit_tests/config/fmudesign/__init__.py b/tests/ert/unit_tests/config/fmudesign/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/ert/unit_tests/config/fmudesign/data/README.md b/tests/ert/unit_tests/config/fmudesign/data/README.md new file mode 100644 index 00000000000..ed51a76fcf1 --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/data/README.md @@ -0,0 +1,4 @@ +Testdata for tornadoplots from one by one sensitivities (design matrix) +distributions: contains design matrix on fmu standard format in excel and .csv format +results: contains in place volumes exported from RMS in fmu standard csv format +config: contains yaml config files for add_webviz_tornado_onebyone.py diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/correlations.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/correlations.xlsx new file mode 100644 index 00000000000..6504ee445b3 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/correlations.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background.xlsx new file mode 100755 index 00000000000..10fc5654238 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background_extseeds.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background_extseeds.xlsx new file mode 100644 index 00000000000..39d6dba4113 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background_extseeds.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background_no_seed.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background_no_seed.xlsx new file mode 100644 index 00000000000..f6ad5dea20b Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_background_no_seed.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_corr_discrete.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_corr_discrete.xlsx new file mode 100644 index 00000000000..353c69d5c03 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_corr_discrete.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_default_no_seed.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_default_no_seed.xlsx new file mode 100644 index 00000000000..0882adea074 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_default_no_seed.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example1.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example1.xlsx new file mode 100644 index 00000000000..b1ac0ec298f Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example1.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example2.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example2.xlsx new file mode 100644 index 00000000000..0baea63141a Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example2.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example_velocities.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example_velocities.xlsx new file mode 100644 index 00000000000..358d846623c Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_example_velocities.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_many_correlations.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_many_correlations.xlsx new file mode 100644 index 00000000000..1056b4c0c3d Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_many_correlations.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_mc_with_correls.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_mc_with_correls.xlsx new file mode 100755 index 00000000000..7b895070b66 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_mc_with_correls.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_multiple_dependencies.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_multiple_dependencies.xlsx new file mode 100644 index 00000000000..4c1d13de8a6 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_multiple_dependencies.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_onebyone.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_onebyone.xlsx new file mode 100644 index 00000000000..7331fc219dd Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_onebyone.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_singlereference.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_singlereference.xlsx new file mode 100644 index 00000000000..f7015fa6579 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_singlereference.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/design_input_singlereference_and_seed.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_singlereference_and_seed.xlsx new file mode 100644 index 00000000000..569616f8056 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/design_input_singlereference_and_seed.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/doe1.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/doe1.xlsx new file mode 100644 index 00000000000..f89741402f1 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/doe1.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/generateddesignmatrix.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/generateddesignmatrix.xlsx new file mode 100644 index 00000000000..8c010535949 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/generateddesignmatrix.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/seeds.csv b/tests/ert/unit_tests/config/fmudesign/data/config/seeds.csv new file mode 100644 index 00000000000..3248aef51fa --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/data/config/seeds.csv @@ -0,0 +1,100 @@ +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/seeds.txt b/tests/ert/unit_tests/config/fmudesign/data/config/seeds.txt new file mode 100644 index 00000000000..42c8e73d5a1 --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/data/config/seeds.txt @@ -0,0 +1,5 @@ +2000 +2001 +2002 +2003 +2004 diff --git a/tests/ert/unit_tests/config/fmudesign/data/config/seeds.xlsx b/tests/ert/unit_tests/config/fmudesign/data/config/seeds.xlsx new file mode 100644 index 00000000000..f948116f4a4 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/config/seeds.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/distributions/design.csv b/tests/ert/unit_tests/config/fmudesign/data/distributions/design.csv new file mode 100644 index 00000000000..ce2afa4d9b9 --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/data/distributions/design.csv @@ -0,0 +1,111 @@ +REAL,SENSNAME,SENSCASE,RMS_SEED,COHIBA_MODE,RAND_VEL_MODEL,OWCAEAST,GP2FILL,FAULTSEAL,RELP_GO +0,rms_seed,P10_P90,1000,PREDICTION,0,2603,0.5,0.5,0.5 +1,rms_seed,P10_P90,1001,PREDICTION,0,2603,0.5,0.5,0.5 +2,rms_seed,P10_P90,1002,PREDICTION,0,2603,0.5,0.5,0.5 +3,rms_seed,P10_P90,1003,PREDICTION,0,2603,0.5,0.5,0.5 +4,rms_seed,P10_P90,1004,PREDICTION,0,2603,0.5,0.5,0.5 +5,rms_seed,P10_P90,1005,PREDICTION,0,2603,0.5,0.5,0.5 +6,rms_seed,P10_P90,1006,PREDICTION,0,2603,0.5,0.5,0.5 +7,rms_seed,P10_P90,1007,PREDICTION,0,2603,0.5,0.5,0.5 +8,rms_seed,P10_P90,1008,PREDICTION,0,2603,0.5,0.5,0.5 +9,rms_seed,P10_P90,1009,PREDICTION,0,2603,0.5,0.5,0.5 +10,hum_seed,P10_P90,1000,SIMULATION,0,2603,0.5,0.5,0.5 +11,hum_seed,P10_P90,1001,SIMULATION,0,2603,0.5,0.5,0.5 +12,hum_seed,P10_P90,1002,SIMULATION,0,2603,0.5,0.5,0.5 +13,hum_seed,P10_P90,1003,SIMULATION,0,2603,0.5,0.5,0.5 +14,hum_seed,P10_P90,1004,SIMULATION,0,2603,0.5,0.5,0.5 +15,hum_seed,P10_P90,1005,SIMULATION,0,2603,0.5,0.5,0.5 +16,hum_seed,P10_P90,1006,SIMULATION,0,2603,0.5,0.5,0.5 +17,hum_seed,P10_P90,1007,SIMULATION,0,2603,0.5,0.5,0.5 +18,hum_seed,P10_P90,1008,SIMULATION,0,2603,0.5,0.5,0.5 +19,hum_seed,P10_P90,1009,SIMULATION,0,2603,0.5,0.5,0.5 +20,velmodel,alternative,1000,PREDICTION,1,2603,0.5,0.5,0.5 +21,velmodel,alternative,1001,PREDICTION,1,2603,0.5,0.5,0.5 +22,velmodel,alternative,1002,PREDICTION,1,2603,0.5,0.5,0.5 +23,velmodel,alternative,1003,PREDICTION,1,2603,0.5,0.5,0.5 +24,velmodel,alternative,1004,PREDICTION,1,2603,0.5,0.5,0.5 +25,velmodel,alternative,1005,PREDICTION,1,2603,0.5,0.5,0.5 +26,velmodel,alternative,1006,PREDICTION,1,2603,0.5,0.5,0.5 +27,velmodel,alternative,1007,PREDICTION,1,2603,0.5,0.5,0.5 +28,velmodel,alternative,1008,PREDICTION,1,2603,0.5,0.5,0.5 +29,velmodel,alternative,1009,PREDICTION,1,2603,0.5,0.5,0.5 +30,owc_aeast,shallow,1000,PREDICTION,0,2596,0.5,0.5,0.5 +31,owc_aeast,shallow,1001,PREDICTION,0,2596,0.5,0.5,0.5 +32,owc_aeast,shallow,1002,PREDICTION,0,2596,0.5,0.5,0.5 +33,owc_aeast,shallow,1003,PREDICTION,0,2596,0.5,0.5,0.5 +34,owc_aeast,shallow,1004,PREDICTION,0,2596,0.5,0.5,0.5 +35,owc_aeast,shallow,1005,PREDICTION,0,2596,0.5,0.5,0.5 +36,owc_aeast,shallow,1006,PREDICTION,0,2596,0.5,0.5,0.5 +37,owc_aeast,shallow,1007,PREDICTION,0,2596,0.5,0.5,0.5 +38,owc_aeast,shallow,1008,PREDICTION,0,2596,0.5,0.5,0.5 +39,owc_aeast,shallow,1009,PREDICTION,0,2596,0.5,0.5,0.5 +40,owc_aeast,deep,1000,PREDICTION,0,2610,0.5,0.5,0.5 +41,owc_aeast,deep,1001,PREDICTION,0,2610,0.5,0.5,0.5 +42,owc_aeast,deep,1002,PREDICTION,0,2610,0.5,0.5,0.5 +43,owc_aeast,deep,1003,PREDICTION,0,2610,0.5,0.5,0.5 +44,owc_aeast,deep,1004,PREDICTION,0,2610,0.5,0.5,0.5 +45,owc_aeast,deep,1005,PREDICTION,0,2610,0.5,0.5,0.5 +46,owc_aeast,deep,1006,PREDICTION,0,2610,0.5,0.5,0.5 +47,owc_aeast,deep,1007,PREDICTION,0,2610,0.5,0.5,0.5 +48,owc_aeast,deep,1008,PREDICTION,0,2610,0.5,0.5,0.5 +49,owc_aeast,deep,1009,PREDICTION,0,2610,0.5,0.5,0.5 +50,gas_fraction,no_fill,1000,PREDICTION,0,2603,0,0.5,0.5 +51,gas_fraction,no_fill,1001,PREDICTION,0,2603,0,0.5,0.5 +52,gas_fraction,no_fill,1002,PREDICTION,0,2603,0,0.5,0.5 +53,gas_fraction,no_fill,1003,PREDICTION,0,2603,0,0.5,0.5 +54,gas_fraction,no_fill,1004,PREDICTION,0,2603,0,0.5,0.5 +55,gas_fraction,no_fill,1005,PREDICTION,0,2603,0,0.5,0.5 +56,gas_fraction,no_fill,1006,PREDICTION,0,2603,0,0.5,0.5 +57,gas_fraction,no_fill,1007,PREDICTION,0,2603,0,0.5,0.5 +58,gas_fraction,no_fill,1008,PREDICTION,0,2603,0,0.5,0.5 +59,gas_fraction,no_fill,1009,PREDICTION,0,2603,0,0.5,0.5 +60,gas_fraction,filled,1000,PREDICTION,0,2603,1,0.5,0.5 +61,gas_fraction,filled,1001,PREDICTION,0,2603,1,0.5,0.5 +62,gas_fraction,filled,1002,PREDICTION,0,2603,1,0.5,0.5 +63,gas_fraction,filled,1003,PREDICTION,0,2603,1,0.5,0.5 +64,gas_fraction,filled,1004,PREDICTION,0,2603,1,0.5,0.5 +65,gas_fraction,filled,1005,PREDICTION,0,2603,1,0.5,0.5 +66,gas_fraction,filled,1006,PREDICTION,0,2603,1,0.5,0.5 +67,gas_fraction,filled,1007,PREDICTION,0,2603,1,0.5,0.5 +68,gas_fraction,filled,1008,PREDICTION,0,2603,1,0.5,0.5 +69,gas_fraction,filled,1009,PREDICTION,0,2603,1,0.5,0.5 +70,fault_seal,open,1000,PREDICTION,0,2603,0.5,0,0.5 +71,fault_seal,open,1001,PREDICTION,0,2603,0.5,0,0.5 +72,fault_seal,open,1002,PREDICTION,0,2603,0.5,0,0.5 +73,fault_seal,open,1003,PREDICTION,0,2603,0.5,0,0.5 +74,fault_seal,open,1004,PREDICTION,0,2603,0.5,0,0.5 +75,fault_seal,open,1005,PREDICTION,0,2603,0.5,0,0.5 +76,fault_seal,open,1006,PREDICTION,0,2603,0.5,0,0.5 +77,fault_seal,open,1007,PREDICTION,0,2603,0.5,0,0.5 +78,fault_seal,open,1008,PREDICTION,0,2603,0.5,0,0.5 +79,fault_seal,open,1009,PREDICTION,0,2603,0.5,0,0.5 +80,fault_seal,tight,1000,PREDICTION,0,2603,0.5,1,0.5 +81,fault_seal,tight,1001,PREDICTION,0,2603,0.5,1,0.5 +82,fault_seal,tight,1002,PREDICTION,0,2603,0.5,1,0.5 +83,fault_seal,tight,1003,PREDICTION,0,2603,0.5,1,0.5 +84,fault_seal,tight,1004,PREDICTION,0,2603,0.5,1,0.5 +85,fault_seal,tight,1005,PREDICTION,0,2603,0.5,1,0.5 +86,fault_seal,tight,1006,PREDICTION,0,2603,0.5,1,0.5 +87,fault_seal,tight,1007,PREDICTION,0,2603,0.5,1,0.5 +88,fault_seal,tight,1008,PREDICTION,0,2603,0.5,1,0.5 +89,fault_seal,tight,1009,PREDICTION,0,2603,0.5,1,0.5 +90,relp_go,lc,1000,PREDICTION,0,2603,0.5,0.5,0 +91,relp_go,lc,1001,PREDICTION,0,2603,0.5,0.5,0 +92,relp_go,lc,1002,PREDICTION,0,2603,0.5,0.5,0 +93,relp_go,lc,1003,PREDICTION,0,2603,0.5,0.5,0 +94,relp_go,lc,1004,PREDICTION,0,2603,0.5,0.5,0 +95,relp_go,lc,1005,PREDICTION,0,2603,0.5,0.5,0 +96,relp_go,lc,1006,PREDICTION,0,2603,0.5,0.5,0 +97,relp_go,lc,1007,PREDICTION,0,2603,0.5,0.5,0 +98,relp_go,lc,1008,PREDICTION,0,2603,0.5,0.5,0 +99,relp_go,lc,1009,PREDICTION,0,2603,0.5,0.5,0 +100,relp_go,hc,1000,PREDICTION,0,2603,0.5,0.5,1 +101,relp_go,hc,1001,PREDICTION,0,2603,0.5,0.5,1 +102,relp_go,hc,1002,PREDICTION,0,2603,0.5,0.5,1 +103,relp_go,hc,1003,PREDICTION,0,2603,0.5,0.5,1 +104,relp_go,hc,1004,PREDICTION,0,2603,0.5,0.5,1 +105,relp_go,hc,1005,PREDICTION,0,2603,0.5,0.5,1 +106,relp_go,hc,1006,PREDICTION,0,2603,0.5,0.5,1 +107,relp_go,hc,1007,PREDICTION,0,2603,0.5,0.5,1 +108,relp_go,hc,1008,PREDICTION,0,2603,0.5,0.5,1 +109,relp_go,hc,1009,PREDICTION,0,2603,0.5,0.5,1 diff --git a/tests/ert/unit_tests/config/fmudesign/data/distributions/design.xlsx b/tests/ert/unit_tests/config/fmudesign/data/distributions/design.xlsx new file mode 100755 index 00000000000..cf3cba87331 Binary files /dev/null and b/tests/ert/unit_tests/config/fmudesign/data/distributions/design.xlsx differ diff --git a/tests/ert/unit_tests/config/fmudesign/data/distributions/designsummary.csv b/tests/ert/unit_tests/config/fmudesign/data/distributions/designsummary.csv new file mode 100644 index 00000000000..abab7bae7b1 --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/data/distributions/designsummary.csv @@ -0,0 +1,8 @@ +sensno,sensname,senstype,casename1,startreal1,endreal1,casename2,startreal2,endreal2 +0,rms_seed,mc,P10_P90,0,9,nan,nan,nan +1,hum_seed,mc,P10_P90,10,19,nan,nan,nan +2,velmodel,scalar,alternative,20,29,nan,nan,nan +3,owc_aeast,scalar,shallow,30,39,deep,40,49 +4,gas_fraction,scalar,no_fill,50,59,filled,60,69 +5,fault_seal,scalar,open,70,79,tight,80,89 +6,relp_go,scalar,lc,90,99,hc,100,109 diff --git a/tests/ert/unit_tests/config/fmudesign/snapshots/test_create_design/test_generate_full_mc_snapshot/design_output_mc_with_correls.json b/tests/ert/unit_tests/config/fmudesign/snapshots/test_create_design/test_generate_full_mc_snapshot/design_output_mc_with_correls.json new file mode 100644 index 00000000000..793926d21db --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/snapshots/test_create_design/test_generate_full_mc_snapshot/design_output_mc_with_correls.json @@ -0,0 +1,9023 @@ +{ + "defaultvalues": { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 1, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.01, + "HUM_METHOD": "SIMPLE", + "HUM_MODE": "PREDICTION", + "INJ_UNC": 0, + "NTG1": 0.25, + "NTG2": 0.45, + "NTG6": 0.8, + "OWC1": 0.001, + "OWC2": 0.1, + "OWC3": 0.07, + "PARAM1": 0.035, + "PARAM2": 0.05, + "PARAM3": 0.02, + "RMS_SEED": 1000 + }, + "designvalues": [ + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.007, + "NTG1": 0.95, + "NTG2": 0.61, + "OWC1": 2547.0, + "OWC2": 2466.3, + "OWC3": 2427.0, + "PARAM1": 0.031, + "PARAM2": -0.96, + "PARAM3": 0.0, + "REAL": 0.0, + "RMS_SEED": 1000.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.84, + "NTG2": 0.64, + "OWC1": 2527.1, + "OWC2": 2463.9, + "OWC3": 2472.4, + "PARAM1": 0.036, + "PARAM2": 0.02, + "PARAM3": 0.0, + "REAL": 1.0, + "RMS_SEED": 1001.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.033, + "NTG1": 0.81, + "NTG2": 0.61, + "OWC1": 2511.9, + "OWC2": 2461.0, + "OWC3": 2480.7, + "PARAM1": 0.036, + "PARAM2": -0.62, + "PARAM3": 7036570000.0, + "REAL": 2.0, + "RMS_SEED": 1002.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.496, + "NTG1": 0.8, + "NTG2": 0.59, + "OWC1": 2502.9, + "OWC2": 2453.1, + "OWC3": 2483.3, + "PARAM1": 0.037, + "PARAM2": -0.22, + "PARAM3": 0.009, + "REAL": 3.0, + "RMS_SEED": 1003.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.026, + "NTG1": 0.95, + "NTG2": 0.57, + "OWC1": 2510.1, + "OWC2": 2458.8, + "OWC3": 2462.8, + "PARAM1": 0.031, + "PARAM2": 0.69, + "PARAM3": 0.0, + "REAL": 4.0, + "RMS_SEED": 1004.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.017, + "NTG1": 0.86, + "NTG2": 0.55, + "OWC1": 2530.9, + "OWC2": 2468.4, + "OWC3": 2453.7, + "PARAM1": 0.038, + "PARAM2": 0.04, + "PARAM3": 0.0, + "REAL": 5.0, + "RMS_SEED": 1005.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.176, + "NTG1": 0.84, + "NTG2": 0.56, + "OWC1": 2546.5, + "OWC2": 2475.4, + "OWC3": 2411.0, + "PARAM1": 0.028, + "PARAM2": -0.9, + "PARAM3": 3901990000.0, + "REAL": 6.0, + "RMS_SEED": 1006.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.013, + "NTG1": 0.82, + "NTG2": 0.62, + "OWC1": 2504.0, + "OWC2": 2474.1, + "OWC3": 2457.9, + "PARAM1": 0.038, + "PARAM2": 0.81, + "PARAM3": 0.023, + "REAL": 7.0, + "RMS_SEED": 1007.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.127, + "NTG1": 0.81, + "NTG2": 0.55, + "OWC1": 2514.0, + "OWC2": 2470.0, + "OWC3": 2448.4, + "PARAM1": 0.031, + "PARAM2": 0.82, + "PARAM3": 0.0, + "REAL": 8.0, + "RMS_SEED": 1008.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.082, + "NTG1": 0.92, + "NTG2": 0.64, + "OWC1": 2525.3, + "OWC2": 2478.2, + "OWC3": 2458.1, + "PARAM1": 0.039, + "PARAM2": 0.63, + "PARAM3": 110548.0, + "REAL": 9.0, + "RMS_SEED": 1009.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.081, + "NTG1": 0.79, + "NTG2": 0.58, + "OWC1": 2528.6, + "OWC2": 2472.0, + "OWC3": 2458.7, + "PARAM1": 0.034, + "PARAM2": -0.09, + "PARAM3": 51.206, + "REAL": 10.0, + "RMS_SEED": 1010.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.825, + "NTG1": 0.81, + "NTG2": 0.63, + "OWC1": 2523.3, + "OWC2": 2473.8, + "OWC3": 2439.5, + "PARAM1": 0.039, + "PARAM2": 0.63, + "PARAM3": 2731.64, + "REAL": 11.0, + "RMS_SEED": 1011.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.405, + "NTG1": 0.9, + "NTG2": 0.61, + "OWC1": 2519.4, + "OWC2": 2464.8, + "OWC3": 2438.9, + "PARAM1": 0.032, + "PARAM2": 0.6, + "PARAM3": 0.002, + "REAL": 12.0, + "RMS_SEED": 1012.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.559, + "NTG1": 0.84, + "NTG2": 0.6, + "OWC1": 2545.6, + "OWC2": 2491.1, + "OWC3": 2413.0, + "PARAM1": 0.04, + "PARAM2": -0.27, + "PARAM3": 1.991, + "REAL": 13.0, + "RMS_SEED": 1013.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.611, + "NTG1": 0.89, + "NTG2": 0.59, + "OWC1": 2539.7, + "OWC2": 2475.1, + "OWC3": 2445.4, + "PARAM1": 0.031, + "PARAM2": 0.31, + "PARAM3": 0.0, + "REAL": 14.0, + "RMS_SEED": 1014.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.005, + "NTG1": 0.85, + "NTG2": 0.63, + "OWC1": 2536.5, + "OWC2": 2466.9, + "OWC3": 2434.4, + "PARAM1": 0.041, + "PARAM2": 0.39, + "PARAM3": 71.14, + "REAL": 15.0, + "RMS_SEED": 1015.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.116, + "NTG1": 0.8, + "NTG2": 0.55, + "OWC1": 2524.0, + "OWC2": 2468.2, + "OWC3": 2437.4, + "PARAM1": 0.037, + "PARAM2": -0.47, + "PARAM3": 0.0, + "REAL": 16.0, + "RMS_SEED": 1016.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.92, + "NTG2": 0.58, + "OWC1": 2512.3, + "OWC2": 2480.0, + "OWC3": 2462.6, + "PARAM1": 0.032, + "PARAM2": 0.63, + "PARAM3": 0.0, + "REAL": 17.0, + "RMS_SEED": 1017.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.77, + "NTG2": 0.62, + "OWC1": 2531.4, + "OWC2": 2489.3, + "OWC3": 2413.6, + "PARAM1": 0.035, + "PARAM2": -0.35, + "PARAM3": 84.753, + "REAL": 18.0, + "RMS_SEED": 1018.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.038, + "NTG1": 0.82, + "NTG2": 0.61, + "OWC1": 2510.9, + "OWC2": 2458.1, + "OWC3": 2475.5, + "PARAM1": 0.036, + "PARAM2": -0.38, + "PARAM3": 0.013, + "REAL": 19.0, + "RMS_SEED": 1019.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.94, + "NTG2": 0.62, + "OWC1": 2547.3, + "OWC2": 2468.8, + "OWC3": 2444.3, + "PARAM1": 0.033, + "PARAM2": -0.76, + "PARAM3": 0.136, + "REAL": 20.0, + "RMS_SEED": 1020.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.784, + "NTG1": 0.78, + "NTG2": 0.62, + "OWC1": 2539.6, + "OWC2": 2492.5, + "OWC3": 2443.2, + "PARAM1": 0.038, + "PARAM2": 0.26, + "PARAM3": 0.105, + "REAL": 21.0, + "RMS_SEED": 1021.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.064, + "NTG1": 0.82, + "NTG2": 0.6, + "OWC1": 2541.9, + "OWC2": 2474.9, + "OWC3": 2427.5, + "PARAM1": 0.035, + "PARAM2": 0.85, + "PARAM3": 0.008, + "REAL": 22.0, + "RMS_SEED": 1022.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.089, + "NTG1": 0.93, + "NTG2": 0.58, + "OWC1": 2502.3, + "OWC2": 2446.7, + "OWC3": 2478.0, + "PARAM1": 0.04, + "PARAM2": 0.21, + "PARAM3": 0.0, + "REAL": 23.0, + "RMS_SEED": 1023.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.84, + "NTG2": 0.62, + "OWC1": 2525.4, + "OWC2": 2464.0, + "OWC3": 2475.6, + "PARAM1": 0.029, + "PARAM2": -0.97, + "PARAM3": 1.689, + "REAL": 24.0, + "RMS_SEED": 1024.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.9, + "NTG2": 0.55, + "OWC1": 2528.0, + "OWC2": 2462.4, + "OWC3": 2449.9, + "PARAM1": 0.036, + "PARAM2": 0.52, + "PARAM3": 27.378, + "REAL": 25.0, + "RMS_SEED": 1025.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.336, + "NTG1": 0.81, + "NTG2": 0.57, + "OWC1": 2522.5, + "OWC2": 2458.9, + "OWC3": 2460.4, + "PARAM1": 0.036, + "PARAM2": -0.83, + "PARAM3": 0.561, + "REAL": 26.0, + "RMS_SEED": 1026.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.076, + "NTG1": 0.79, + "NTG2": 0.56, + "OWC1": 2526.3, + "OWC2": 2481.0, + "OWC3": 2449.3, + "PARAM1": 0.036, + "PARAM2": -0.78, + "PARAM3": 1264310.0, + "REAL": 27.0, + "RMS_SEED": 1027.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.88, + "NTG2": 0.56, + "OWC1": 2507.8, + "OWC2": 2463.7, + "OWC3": 2436.8, + "PARAM1": 0.027, + "PARAM2": 0.08, + "PARAM3": 145.245, + "REAL": 28.0, + "RMS_SEED": 1028.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.92, + "NTG2": 0.57, + "OWC1": 2547.0, + "OWC2": 2484.2, + "OWC3": 2415.8, + "PARAM1": 0.038, + "PARAM2": 0.42, + "PARAM3": 73619800.0, + "REAL": 29.0, + "RMS_SEED": 1029.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.318, + "NTG1": 0.78, + "NTG2": 0.62, + "OWC1": 2503.0, + "OWC2": 2458.3, + "OWC3": 2488.3, + "PARAM1": 0.04, + "PARAM2": -0.92, + "PARAM3": 58244500.0, + "REAL": 30.0, + "RMS_SEED": 1030.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.003, + "NTG1": 0.93, + "NTG2": 0.56, + "OWC1": 2549.5, + "OWC2": 2490.2, + "OWC3": 2407.4, + "PARAM1": 0.035, + "PARAM2": -0.22, + "PARAM3": 61.275, + "REAL": 31.0, + "RMS_SEED": 1031.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.006, + "NTG1": 0.79, + "NTG2": 0.6, + "OWC1": 2506.5, + "OWC2": 2453.8, + "OWC3": 2463.5, + "PARAM1": 0.029, + "PARAM2": 0.62, + "PARAM3": 0.007, + "REAL": 32.0, + "RMS_SEED": 1032.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.007, + "NTG1": 0.86, + "NTG2": 0.57, + "OWC1": 2520.4, + "OWC2": 2467.2, + "OWC3": 2454.8, + "PARAM1": 0.038, + "PARAM2": 0.34, + "PARAM3": 0.0, + "REAL": 33.0, + "RMS_SEED": 1033.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.004, + "NTG1": 0.81, + "NTG2": 0.6, + "OWC1": 2516.3, + "OWC2": 2460.6, + "OWC3": 2459.7, + "PARAM1": 0.035, + "PARAM2": 0.72, + "PARAM3": 0.007, + "REAL": 34.0, + "RMS_SEED": 1034.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.017, + "NTG1": 0.79, + "NTG2": 0.62, + "OWC1": 2515.8, + "OWC2": 2454.0, + "OWC3": 2471.5, + "PARAM1": 0.035, + "PARAM2": 0.5, + "PARAM3": 0.0, + "REAL": 35.0, + "RMS_SEED": 1035.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.017, + "NTG1": 0.84, + "NTG2": 0.57, + "OWC1": 2547.7, + "OWC2": 2482.1, + "OWC3": 2415.4, + "PARAM1": 0.041, + "PARAM2": 0.11, + "PARAM3": 0.062, + "REAL": 36.0, + "RMS_SEED": 1036.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.715, + "NTG1": 0.82, + "NTG2": 0.61, + "OWC1": 2526.8, + "OWC2": 2442.1, + "OWC3": 2460.0, + "PARAM1": 0.044, + "PARAM2": 0.61, + "PARAM3": 1336400000.0, + "REAL": 37.0, + "RMS_SEED": 1037.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.011, + "NTG1": 0.89, + "NTG2": 0.6, + "OWC1": 2514.2, + "OWC2": 2454.1, + "OWC3": 2461.7, + "PARAM1": 0.038, + "PARAM2": -0.3, + "PARAM3": 0.0, + "REAL": 38.0, + "RMS_SEED": 1038.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.77, + "NTG2": 0.57, + "OWC1": 2508.4, + "OWC2": 2472.0, + "OWC3": 2448.0, + "PARAM1": 0.038, + "PARAM2": 0.68, + "PARAM3": 15.074, + "REAL": 39.0, + "RMS_SEED": 1039.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.011, + "NTG1": 0.77, + "NTG2": 0.58, + "OWC1": 2543.0, + "OWC2": 2470.1, + "OWC3": 2448.1, + "PARAM1": 0.042, + "PARAM2": -0.04, + "PARAM3": 763730000.0, + "REAL": 40.0, + "RMS_SEED": 1040.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.527, + "NTG1": 0.86, + "NTG2": 0.54, + "OWC1": 2520.7, + "OWC2": 2477.9, + "OWC3": 2435.6, + "PARAM1": 0.037, + "PARAM2": 0.15, + "PARAM3": 359967000.0, + "REAL": 41.0, + "RMS_SEED": 1041.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.006, + "NTG1": 0.85, + "NTG2": 0.6, + "OWC1": 2544.9, + "OWC2": 2483.9, + "OWC3": 2426.5, + "PARAM1": 0.036, + "PARAM2": -0.14, + "PARAM3": 49044.1, + "REAL": 42.0, + "RMS_SEED": 1042.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.134, + "NTG1": 0.98, + "NTG2": 0.63, + "OWC1": 2531.3, + "OWC2": 2473.4, + "OWC3": 2454.2, + "PARAM1": 0.039, + "PARAM2": 0.3, + "PARAM3": 1353.63, + "REAL": 43.0, + "RMS_SEED": 1043.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.96, + "NTG2": 0.56, + "OWC1": 2519.7, + "OWC2": 2471.7, + "OWC3": 2444.5, + "PARAM1": 0.031, + "PARAM2": -0.94, + "PARAM3": 5180.77, + "REAL": 44.0, + "RMS_SEED": 1044.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.275, + "NTG1": 0.98, + "NTG2": 0.59, + "OWC1": 2527.9, + "OWC2": 2481.3, + "OWC3": 2421.0, + "PARAM1": 0.035, + "PARAM2": -0.29, + "PARAM3": 0.001, + "REAL": 45.0, + "RMS_SEED": 1045.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.9, + "NTG1": 0.92, + "NTG2": 0.58, + "OWC1": 2548.4, + "OWC2": 2482.7, + "OWC3": 2417.4, + "PARAM1": 0.033, + "PARAM2": -0.46, + "PARAM3": 0.0, + "REAL": 46.0, + "RMS_SEED": 1046.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.121, + "NTG1": 0.85, + "NTG2": 0.54, + "OWC1": 2546.9, + "OWC2": 2495.1, + "OWC3": 2413.9, + "PARAM1": 0.04, + "PARAM2": 0.41, + "PARAM3": 0.427, + "REAL": 47.0, + "RMS_SEED": 1047.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.015, + "NTG1": 0.79, + "NTG2": 0.62, + "OWC1": 2537.4, + "OWC2": 2470.7, + "OWC3": 2434.3, + "PARAM1": 0.037, + "PARAM2": 0.09, + "PARAM3": 7.828, + "REAL": 48.0, + "RMS_SEED": 1048.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.013, + "NTG1": 0.81, + "NTG2": 0.55, + "OWC1": 2535.8, + "OWC2": 2474.4, + "OWC3": 2416.4, + "PARAM1": 0.038, + "PARAM2": -0.94, + "PARAM3": 0.272, + "REAL": 49.0, + "RMS_SEED": 1049.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.005, + "NTG1": 0.91, + "NTG2": 0.62, + "OWC1": 2520.9, + "OWC2": 2457.2, + "OWC3": 2429.0, + "PARAM1": 0.043, + "PARAM2": -0.07, + "PARAM3": 970939.0, + "REAL": 50.0, + "RMS_SEED": 1050.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.103, + "NTG1": 0.8, + "NTG2": 0.61, + "OWC1": 2540.0, + "OWC2": 2476.5, + "OWC3": 2426.7, + "PARAM1": 0.03, + "PARAM2": -0.05, + "PARAM3": 0.0, + "REAL": 51.0, + "RMS_SEED": 1051.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.283, + "NTG1": 0.82, + "NTG2": 0.58, + "OWC1": 2533.0, + "OWC2": 2457.5, + "OWC3": 2428.8, + "PARAM1": 0.039, + "PARAM2": 0.18, + "PARAM3": 9911890000.0, + "REAL": 52.0, + "RMS_SEED": 1052.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.169, + "NTG1": 0.87, + "NTG2": 0.56, + "OWC1": 2538.8, + "OWC2": 2437.1, + "OWC3": 2450.6, + "PARAM1": 0.04, + "PARAM2": -0.19, + "PARAM3": 0.003, + "REAL": 53.0, + "RMS_SEED": 1053.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.914, + "NTG1": 0.8, + "NTG2": 0.58, + "OWC1": 2507.0, + "OWC2": 2451.8, + "OWC3": 2481.5, + "PARAM1": 0.034, + "PARAM2": -0.25, + "PARAM3": 1145.09, + "REAL": 54.0, + "RMS_SEED": 1054.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.053, + "NTG1": 0.91, + "NTG2": 0.59, + "OWC1": 2539.4, + "OWC2": 2483.5, + "OWC3": 2420.3, + "PARAM1": 0.041, + "PARAM2": 0.15, + "PARAM3": 0.731, + "REAL": 55.0, + "RMS_SEED": 1055.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.332, + "NTG1": 0.88, + "NTG2": 0.6, + "OWC1": 2501.3, + "OWC2": 2460.2, + "OWC3": 2455.5, + "PARAM1": 0.03, + "PARAM2": 0.48, + "PARAM3": 0.0, + "REAL": 56.0, + "RMS_SEED": 1056.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.13, + "NTG1": 0.85, + "NTG2": 0.62, + "OWC1": 2539.0, + "OWC2": 2463.7, + "OWC3": 2443.5, + "PARAM1": 0.035, + "PARAM2": 0.45, + "PARAM3": 22762.8, + "REAL": 57.0, + "RMS_SEED": 1057.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.641, + "NTG1": 0.81, + "NTG2": 0.59, + "OWC1": 2518.4, + "OWC2": 2474.0, + "OWC3": 2429.4, + "PARAM1": 0.044, + "PARAM2": 0.81, + "PARAM3": 1423.78, + "REAL": 58.0, + "RMS_SEED": 1058.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.237, + "NTG1": 0.82, + "NTG2": 0.62, + "OWC1": 2502.7, + "OWC2": 2437.8, + "OWC3": 2493.9, + "PARAM1": 0.035, + "PARAM2": -0.37, + "PARAM3": 3.774, + "REAL": 59.0, + "RMS_SEED": 1059.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.316, + "NTG1": 0.78, + "NTG2": 0.61, + "OWC1": 2527.6, + "OWC2": 2493.2, + "OWC3": 2423.6, + "PARAM1": 0.032, + "PARAM2": -0.86, + "PARAM3": 1.259, + "REAL": 60.0, + "RMS_SEED": 1060.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.754, + "NTG1": 0.94, + "NTG2": 0.6, + "OWC1": 2500.6, + "OWC2": 2458.4, + "OWC3": 2465.4, + "PARAM1": 0.038, + "PARAM2": -0.02, + "PARAM3": 0.656, + "REAL": 61.0, + "RMS_SEED": 1061.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.015, + "NTG1": 0.78, + "NTG2": 0.61, + "OWC1": 2510.2, + "OWC2": 2477.9, + "OWC3": 2462.3, + "PARAM1": 0.034, + "PARAM2": 0.89, + "PARAM3": 0.374, + "REAL": 62.0, + "RMS_SEED": 1062.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.028, + "NTG1": 0.84, + "NTG2": 0.55, + "OWC1": 2534.1, + "OWC2": 2457.7, + "OWC3": 2447.9, + "PARAM1": 0.033, + "PARAM2": -0.3, + "PARAM3": 0.0, + "REAL": 63.0, + "RMS_SEED": 1063.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.91, + "NTG2": 0.61, + "OWC1": 2526.4, + "OWC2": 2458.2, + "OWC3": 2469.1, + "PARAM1": 0.033, + "PARAM2": 0.37, + "PARAM3": 7441.01, + "REAL": 64.0, + "RMS_SEED": 1064.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.031, + "NTG1": 0.9, + "NTG2": 0.62, + "OWC1": 2540.9, + "OWC2": 2443.1, + "OWC3": 2460.8, + "PARAM1": 0.036, + "PARAM2": -0.39, + "PARAM3": 889491.0, + "REAL": 65.0, + "RMS_SEED": 1065.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.064, + "NTG1": 0.89, + "NTG2": 0.6, + "OWC1": 2516.9, + "OWC2": 2447.6, + "OWC3": 2470.5, + "PARAM1": 0.03, + "PARAM2": -0.75, + "PARAM3": 0.0, + "REAL": 66.0, + "RMS_SEED": 1066.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.89, + "NTG2": 0.51, + "OWC1": 2516.0, + "OWC2": 2458.6, + "OWC3": 2448.6, + "PARAM1": 0.038, + "PARAM2": -0.16, + "PARAM3": 12.693, + "REAL": 67.0, + "RMS_SEED": 1067.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.15, + "NTG1": 0.83, + "NTG2": 0.56, + "OWC1": 2537.0, + "OWC2": 2483.0, + "OWC3": 2430.2, + "PARAM1": 0.031, + "PARAM2": -0.84, + "PARAM3": 6016.1, + "REAL": 68.0, + "RMS_SEED": 1068.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.033, + "NTG1": 0.8, + "NTG2": 0.59, + "OWC1": 2542.2, + "OWC2": 2461.9, + "OWC3": 2433.9, + "PARAM1": 0.034, + "PARAM2": 0.87, + "PARAM3": 3105.41, + "REAL": 69.0, + "RMS_SEED": 1069.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.029, + "NTG1": 0.85, + "NTG2": 0.54, + "OWC1": 2526.5, + "OWC2": 2467.2, + "OWC3": 2451.0, + "PARAM1": 0.03, + "PARAM2": 0.88, + "PARAM3": 0.058, + "REAL": 70.0, + "RMS_SEED": 1070.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.016, + "NTG1": 0.92, + "NTG2": 0.59, + "OWC1": 2538.9, + "OWC2": 2486.8, + "OWC3": 2434.7, + "PARAM1": 0.033, + "PARAM2": -0.74, + "PARAM3": 10.392, + "REAL": 71.0, + "RMS_SEED": 1071.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.9, + "NTG2": 0.62, + "OWC1": 2502.5, + "OWC2": 2454.9, + "OWC3": 2482.6, + "PARAM1": 0.036, + "PARAM2": -0.73, + "PARAM3": 28.252, + "REAL": 72.0, + "RMS_SEED": 1072.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.041, + "NTG1": 0.88, + "NTG2": 0.62, + "OWC1": 2532.9, + "OWC2": 2484.9, + "OWC3": 2434.0, + "PARAM1": 0.036, + "PARAM2": 0.38, + "PARAM3": 672094.0, + "REAL": 73.0, + "RMS_SEED": 1073.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.03, + "NTG1": 0.83, + "NTG2": 0.59, + "OWC1": 2502.2, + "OWC2": 2451.2, + "OWC3": 2485.9, + "PARAM1": 0.029, + "PARAM2": 0.88, + "PARAM3": 0.005, + "REAL": 74.0, + "RMS_SEED": 1074.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.88, + "NTG2": 0.61, + "OWC1": 2529.9, + "OWC2": 2455.6, + "OWC3": 2430.2, + "PARAM1": 0.039, + "PARAM2": 0.22, + "PARAM3": 113742.0, + "REAL": 75.0, + "RMS_SEED": 1075.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.76, + "NTG2": 0.58, + "OWC1": 2504.4, + "OWC2": 2444.0, + "OWC3": 2481.2, + "PARAM1": 0.038, + "PARAM2": -0.03, + "PARAM3": 22.731, + "REAL": 76.0, + "RMS_SEED": 1076.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.439, + "NTG1": 0.82, + "NTG2": 0.59, + "OWC1": 2537.8, + "OWC2": 2490.0, + "OWC3": 2441.3, + "PARAM1": 0.035, + "PARAM2": 0.18, + "PARAM3": 24794.9, + "REAL": 77.0, + "RMS_SEED": 1077.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.66, + "NTG1": 0.78, + "NTG2": 0.62, + "OWC1": 2536.8, + "OWC2": 2473.3, + "OWC3": 2432.9, + "PARAM1": 0.04, + "PARAM2": -0.06, + "PARAM3": 0.074, + "REAL": 78.0, + "RMS_SEED": 1078.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.009, + "NTG1": 0.76, + "NTG2": 0.57, + "OWC1": 2543.3, + "OWC2": 2484.5, + "OWC3": 2426.1, + "PARAM1": 0.032, + "PARAM2": 0.27, + "PARAM3": 2907.06, + "REAL": 79.0, + "RMS_SEED": 1079.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.05, + "NTG1": 0.78, + "NTG2": 0.57, + "OWC1": 2510.7, + "OWC2": 2466.5, + "OWC3": 2447.6, + "PARAM1": 0.04, + "PARAM2": 0.86, + "PARAM3": 0.036, + "REAL": 80.0, + "RMS_SEED": 1080.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.93, + "NTG2": 0.57, + "OWC1": 2506.3, + "OWC2": 2488.1, + "OWC3": 2459.0, + "PARAM1": 0.035, + "PARAM2": -0.08, + "PARAM3": 158.625, + "REAL": 81.0, + "RMS_SEED": 1081.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.8, + "NTG2": 0.59, + "OWC1": 2501.6, + "OWC2": 2436.3, + "OWC3": 2497.4, + "PARAM1": 0.028, + "PARAM2": -0.45, + "PARAM3": 0.0, + "REAL": 82.0, + "RMS_SEED": 1082.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.003, + "NTG1": 0.93, + "NTG2": 0.59, + "OWC1": 2543.4, + "OWC2": 2488.4, + "OWC3": 2420.0, + "PARAM1": 0.04, + "PARAM2": -0.49, + "PARAM3": 0.0, + "REAL": 83.0, + "RMS_SEED": 1083.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.099, + "NTG1": 0.98, + "NTG2": 0.59, + "OWC1": 2544.4, + "OWC2": 2492.0, + "OWC3": 2423.4, + "PARAM1": 0.035, + "PARAM2": -0.31, + "PARAM3": 665545000.0, + "REAL": 84.0, + "RMS_SEED": 1084.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.225, + "NTG1": 0.84, + "NTG2": 0.59, + "OWC1": 2520.5, + "OWC2": 2470.5, + "OWC3": 2465.5, + "PARAM1": 0.04, + "PARAM2": -0.79, + "PARAM3": 0.224, + "REAL": 85.0, + "RMS_SEED": 1085.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.042, + "NTG1": 0.77, + "NTG2": 0.53, + "OWC1": 2520.1, + "OWC2": 2482.8, + "OWC3": 2468.4, + "PARAM1": 0.038, + "PARAM2": -0.73, + "PARAM3": 0.001, + "REAL": 86.0, + "RMS_SEED": 1086.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.84, + "NTG2": 0.61, + "OWC1": 2506.1, + "OWC2": 2450.2, + "OWC3": 2466.2, + "PARAM1": 0.036, + "PARAM2": 0.47, + "PARAM3": 0.07, + "REAL": 87.0, + "RMS_SEED": 1087.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.583, + "NTG1": 0.86, + "NTG2": 0.6, + "OWC1": 2543.6, + "OWC2": 2484.3, + "OWC3": 2419.5, + "PARAM1": 0.035, + "PARAM2": 0.42, + "PARAM3": 107.93, + "REAL": 88.0, + "RMS_SEED": 1088.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.79, + "NTG2": 0.57, + "OWC1": 2545.9, + "OWC2": 2486.9, + "OWC3": 2420.6, + "PARAM1": 0.036, + "PARAM2": 0.71, + "PARAM3": 0.004, + "REAL": 89.0, + "RMS_SEED": 1089.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.014, + "NTG1": 0.86, + "NTG2": 0.55, + "OWC1": 2503.3, + "OWC2": 2460.0, + "OWC3": 2477.2, + "PARAM1": 0.032, + "PARAM2": 0.13, + "PARAM3": 14.614, + "REAL": 90.0, + "RMS_SEED": 1090.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.414, + "NTG1": 0.9, + "NTG2": 0.6, + "OWC1": 2521.5, + "OWC2": 2456.2, + "OWC3": 2466.0, + "PARAM1": 0.037, + "PARAM2": 0.01, + "PARAM3": 99926.9, + "REAL": 91.0, + "RMS_SEED": 1091.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.8, + "NTG2": 0.57, + "OWC1": 2548.2, + "OWC2": 2492.3, + "OWC3": 2417.2, + "PARAM1": 0.034, + "PARAM2": 0.29, + "PARAM3": 38056100.0, + "REAL": 92.0, + "RMS_SEED": 1092.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.056, + "NTG1": 0.89, + "NTG2": 0.59, + "OWC1": 2511.0, + "OWC2": 2445.3, + "OWC3": 2458.2, + "PARAM1": 0.036, + "PARAM2": -0.77, + "PARAM3": 0.001, + "REAL": 93.0, + "RMS_SEED": 1093.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.044, + "NTG1": 0.94, + "NTG2": 0.63, + "OWC1": 2501.0, + "OWC2": 2463.0, + "OWC3": 2469.8, + "PARAM1": 0.036, + "PARAM2": -0.33, + "PARAM3": 0.0, + "REAL": 94.0, + "RMS_SEED": 1094.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.366, + "NTG1": 0.76, + "NTG2": 0.63, + "OWC1": 2523.5, + "OWC2": 2442.0, + "OWC3": 2489.4, + "PARAM1": 0.035, + "PARAM2": -0.61, + "PARAM3": 64.825, + "REAL": 95.0, + "RMS_SEED": 1095.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.005, + "NTG1": 0.86, + "NTG2": 0.63, + "OWC1": 2526.0, + "OWC2": 2457.8, + "OWC3": 2458.9, + "PARAM1": 0.04, + "PARAM2": -0.15, + "PARAM3": 0.128, + "REAL": 96.0, + "RMS_SEED": 1096.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.791, + "NTG1": 0.8, + "NTG2": 0.61, + "OWC1": 2521.4, + "OWC2": 2472.7, + "OWC3": 2424.0, + "PARAM1": 0.037, + "PARAM2": -0.89, + "PARAM3": 586.68, + "REAL": 97.0, + "RMS_SEED": 1097.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.079, + "NTG1": 0.78, + "NTG2": 0.61, + "OWC1": 2534.4, + "OWC2": 2470.9, + "OWC3": 2445.7, + "PARAM1": 0.041, + "PARAM2": -0.46, + "PARAM3": 40421500000.0, + "REAL": 98.0, + "RMS_SEED": 1098.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.031, + "NTG1": 0.79, + "NTG2": 0.59, + "OWC1": 2507.6, + "OWC2": 2464.6, + "OWC3": 2470.9, + "PARAM1": 0.036, + "PARAM2": 0.67, + "PARAM3": 80.48, + "REAL": 99.0, + "RMS_SEED": 1099.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.067, + "NTG1": 0.81, + "NTG2": 0.59, + "OWC1": 2523.9, + "OWC2": 2468.6, + "OWC3": 2423.2, + "PARAM1": 0.03, + "PARAM2": -0.38, + "PARAM3": 0.0, + "REAL": 100.0, + "RMS_SEED": 1100.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.78, + "NTG2": 0.61, + "OWC1": 2508.6, + "OWC2": 2453.2, + "OWC3": 2452.8, + "PARAM1": 0.028, + "PARAM2": 0.03, + "PARAM3": 0.021, + "REAL": 101.0, + "RMS_SEED": 1101.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.007, + "NTG1": 0.82, + "NTG2": 0.63, + "OWC1": 2540.2, + "OWC2": 2479.6, + "OWC3": 2425.2, + "PARAM1": 0.036, + "PARAM2": 0.4, + "PARAM3": 0.001, + "REAL": 102.0, + "RMS_SEED": 1102.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.032, + "NTG1": 0.84, + "NTG2": 0.63, + "OWC1": 2538.0, + "OWC2": 2468.1, + "OWC3": 2455.8, + "PARAM1": 0.04, + "PARAM2": 0.64, + "PARAM3": 612431.0, + "REAL": 103.0, + "RMS_SEED": 1103.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.008, + "NTG1": 0.92, + "NTG2": 0.58, + "OWC1": 2504.6, + "OWC2": 2480.8, + "OWC3": 2438.8, + "PARAM1": 0.034, + "PARAM2": 0.06, + "PARAM3": 3261110.0, + "REAL": 104.0, + "RMS_SEED": 1104.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.083, + "NTG1": 0.83, + "NTG2": 0.6, + "OWC1": 2545.5, + "OWC2": 2476.1, + "OWC3": 2425.0, + "PARAM1": 0.03, + "PARAM2": 0.49, + "PARAM3": 0.006, + "REAL": 105.0, + "RMS_SEED": 1105.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.472, + "NTG1": 0.81, + "NTG2": 0.61, + "OWC1": 2546.8, + "OWC2": 2456.0, + "OWC3": 2436.5, + "PARAM1": 0.034, + "PARAM2": -0.11, + "PARAM3": 450.839, + "REAL": 106.0, + "RMS_SEED": 1106.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.269, + "NTG1": 0.77, + "NTG2": 0.62, + "OWC1": 2505.6, + "OWC2": 2450.9, + "OWC3": 2454.9, + "PARAM1": 0.042, + "PARAM2": 0.26, + "PARAM3": 885.285, + "REAL": 107.0, + "RMS_SEED": 1107.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.684, + "NTG1": 0.79, + "NTG2": 0.58, + "OWC1": 2512.5, + "OWC2": 2451.8, + "OWC3": 2470.3, + "PARAM1": 0.032, + "PARAM2": 0.78, + "PARAM3": 265.675, + "REAL": 108.0, + "RMS_SEED": 1108.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.84, + "NTG2": 0.62, + "OWC1": 2541.5, + "OWC2": 2487.6, + "OWC3": 2411.7, + "PARAM1": 0.037, + "PARAM2": 0.0, + "PARAM3": 3.055, + "REAL": 109.0, + "RMS_SEED": 1109.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.032, + "NTG1": 0.88, + "NTG2": 0.64, + "OWC1": 2518.1, + "OWC2": 2469.9, + "OWC3": 2439.9, + "PARAM1": 0.03, + "PARAM2": 0.34, + "PARAM3": 2.023, + "REAL": 110.0, + "RMS_SEED": 1110.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.006, + "NTG1": 0.87, + "NTG2": 0.6, + "OWC1": 2530.4, + "OWC2": 2475.8, + "OWC3": 2452.8, + "PARAM1": 0.031, + "PARAM2": 0.66, + "PARAM3": 0.076, + "REAL": 111.0, + "RMS_SEED": 1111.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.033, + "NTG1": 0.78, + "NTG2": 0.58, + "OWC1": 2526.0, + "OWC2": 2435.4, + "OWC3": 2465.9, + "PARAM1": 0.031, + "PARAM2": -0.07, + "PARAM3": 0.0, + "REAL": 112.0, + "RMS_SEED": 1112.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.189, + "NTG1": 0.79, + "NTG2": 0.6, + "OWC1": 2537.7, + "OWC2": 2470.4, + "OWC3": 2464.7, + "PARAM1": 0.036, + "PARAM2": -0.59, + "PARAM3": 3.581, + "REAL": 113.0, + "RMS_SEED": 1113.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.001, + "NTG1": 0.95, + "NTG2": 0.53, + "OWC1": 2507.5, + "OWC2": 2465.2, + "OWC3": 2469.0, + "PARAM1": 0.037, + "PARAM2": 0.14, + "PARAM3": 163179000000.0, + "REAL": 114.0, + "RMS_SEED": 1114.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.014, + "NTG1": 0.79, + "NTG2": 0.56, + "OWC1": 2532.1, + "OWC2": 2446.5, + "OWC3": 2468.6, + "PARAM1": 0.028, + "PARAM2": -0.31, + "PARAM3": 1227.5, + "REAL": 115.0, + "RMS_SEED": 1115.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.678, + "NTG1": 0.86, + "NTG2": 0.52, + "OWC1": 2530.1, + "OWC2": 2440.6, + "OWC3": 2450.1, + "PARAM1": 0.043, + "PARAM2": -0.01, + "PARAM3": 2.641, + "REAL": 116.0, + "RMS_SEED": 1116.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.533, + "NTG1": 0.87, + "NTG2": 0.59, + "OWC1": 2535.9, + "OWC2": 2470.0, + "OWC3": 2427.3, + "PARAM1": 0.033, + "PARAM2": -0.42, + "PARAM3": 0.0, + "REAL": 117.0, + "RMS_SEED": 1117.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.071, + "NTG1": 0.83, + "NTG2": 0.56, + "OWC1": 2517.6, + "OWC2": 2469.2, + "OWC3": 2447.3, + "PARAM1": 0.041, + "PARAM2": 0.95, + "PARAM3": 570.996, + "REAL": 118.0, + "RMS_SEED": 1118.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.021, + "NTG1": 0.78, + "NTG2": 0.56, + "OWC1": 2514.0, + "OWC2": 2469.6, + "OWC3": 2442.0, + "PARAM1": 0.033, + "PARAM2": 0.46, + "PARAM3": 138549.0, + "REAL": 119.0, + "RMS_SEED": 1119.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.003, + "NTG1": 0.84, + "NTG2": 0.54, + "OWC1": 2512.9, + "OWC2": 2461.4, + "OWC3": 2450.3, + "PARAM1": 0.043, + "PARAM2": 0.06, + "PARAM3": 0.004, + "REAL": 120.0, + "RMS_SEED": 1120.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.264, + "NTG1": 0.86, + "NTG2": 0.59, + "OWC1": 2528.2, + "OWC2": 2448.3, + "OWC3": 2472.1, + "PARAM1": 0.028, + "PARAM2": -0.24, + "PARAM3": 0.002, + "REAL": 121.0, + "RMS_SEED": 1121.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.005, + "NTG1": 0.89, + "NTG2": 0.59, + "OWC1": 2515.3, + "OWC2": 2485.0, + "OWC3": 2420.2, + "PARAM1": 0.041, + "PARAM2": -0.58, + "PARAM3": 0.003, + "REAL": 122.0, + "RMS_SEED": 1122.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.84, + "NTG2": 0.59, + "OWC1": 2510.5, + "OWC2": 2477.8, + "OWC3": 2445.9, + "PARAM1": 0.036, + "PARAM2": -0.19, + "PARAM3": 0.004, + "REAL": 123.0, + "RMS_SEED": 1123.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.067, + "NTG1": 0.89, + "NTG2": 0.62, + "OWC1": 2503.5, + "OWC2": 2443.7, + "OWC3": 2475.9, + "PARAM1": 0.038, + "PARAM2": -0.63, + "PARAM3": 0.0, + "REAL": 124.0, + "RMS_SEED": 1124.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.152, + "NTG1": 0.83, + "NTG2": 0.59, + "OWC1": 2541.5, + "OWC2": 2470.8, + "OWC3": 2449.0, + "PARAM1": 0.031, + "PARAM2": -0.53, + "PARAM3": 0.0, + "REAL": 125.0, + "RMS_SEED": 1125.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.068, + "NTG1": 0.85, + "NTG2": 0.55, + "OWC1": 2508.5, + "OWC2": 2451.7, + "OWC3": 2477.0, + "PARAM1": 0.034, + "PARAM2": 0.36, + "PARAM3": 13327.7, + "REAL": 126.0, + "RMS_SEED": 1126.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.118, + "NTG1": 0.89, + "NTG2": 0.58, + "OWC1": 2540.8, + "OWC2": 2457.8, + "OWC3": 2458.6, + "PARAM1": 0.033, + "PARAM2": 0.35, + "PARAM3": 296.314, + "REAL": 127.0, + "RMS_SEED": 1127.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.008, + "NTG1": 0.88, + "NTG2": 0.6, + "OWC1": 2518.7, + "OWC2": 2467.7, + "OWC3": 2461.1, + "PARAM1": 0.029, + "PARAM2": -0.26, + "PARAM3": 3.431, + "REAL": 128.0, + "RMS_SEED": 1128.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.015, + "NTG1": 0.81, + "NTG2": 0.61, + "OWC1": 2516.6, + "OWC2": 2476.9, + "OWC3": 2438.7, + "PARAM1": 0.032, + "PARAM2": 0.61, + "PARAM3": 6.329, + "REAL": 129.0, + "RMS_SEED": 1129.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.011, + "NTG1": 0.82, + "NTG2": 0.59, + "OWC1": 2534.9, + "OWC2": 2475.2, + "OWC3": 2428.2, + "PARAM1": 0.032, + "PARAM2": 0.09, + "PARAM3": 1.005, + "REAL": 130.0, + "RMS_SEED": 1130.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.023, + "NTG1": 0.9, + "NTG2": 0.57, + "OWC1": 2523.6, + "OWC2": 2485.5, + "OWC3": 2453.4, + "PARAM1": 0.035, + "PARAM2": -0.25, + "PARAM3": 124010.0, + "REAL": 131.0, + "RMS_SEED": 1131.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.207, + "NTG1": 0.85, + "NTG2": 0.59, + "OWC1": 2533.3, + "OWC2": 2478.3, + "OWC3": 2436.1, + "PARAM1": 0.041, + "PARAM2": 0.3, + "PARAM3": 93.759, + "REAL": 132.0, + "RMS_SEED": 1132.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.136, + "NTG1": 0.83, + "NTG2": 0.59, + "OWC1": 2536.7, + "OWC2": 2468.1, + "OWC3": 2463.7, + "PARAM1": 0.032, + "PARAM2": 0.59, + "PARAM3": 201034.0, + "REAL": 133.0, + "RMS_SEED": 1133.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.005, + "NTG1": 0.76, + "NTG2": 0.63, + "OWC1": 2538.3, + "OWC2": 2459.5, + "OWC3": 2442.3, + "PARAM1": 0.032, + "PARAM2": 0.32, + "PARAM3": 1017650.0, + "REAL": 134.0, + "RMS_SEED": 1134.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.004, + "NTG1": 0.77, + "NTG2": 0.6, + "OWC1": 2505.9, + "OWC2": 2470.3, + "OWC3": 2457.7, + "PARAM1": 0.035, + "PARAM2": 0.69, + "PARAM3": 1977.15, + "REAL": 135.0, + "RMS_SEED": 1135.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.006, + "NTG1": 0.88, + "NTG2": 0.64, + "OWC1": 2536.2, + "OWC2": 2490.5, + "OWC3": 2421.5, + "PARAM1": 0.034, + "PARAM2": 0.54, + "PARAM3": 462826.0, + "REAL": 136.0, + "RMS_SEED": 1136.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.051, + "NTG1": 0.83, + "NTG2": 0.6, + "OWC1": 2525.6, + "OWC2": 2484.8, + "OWC3": 2412.1, + "PARAM1": 0.032, + "PARAM2": -0.56, + "PARAM3": 0.0, + "REAL": 137.0, + "RMS_SEED": 1137.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.06, + "NTG1": 0.78, + "NTG2": 0.58, + "OWC1": 2532.8, + "OWC2": 2448.0, + "OWC3": 2437.3, + "PARAM1": 0.035, + "PARAM2": -0.52, + "PARAM3": 98.115, + "REAL": 138.0, + "RMS_SEED": 1138.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.016, + "NTG1": 0.83, + "NTG2": 0.6, + "OWC1": 2503.4, + "OWC2": 2440.4, + "OWC3": 2479.0, + "PARAM1": 0.032, + "PARAM2": 0.48, + "PARAM3": 0.0, + "REAL": 139.0, + "RMS_SEED": 1139.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.013, + "NTG1": 0.86, + "NTG2": 0.53, + "OWC1": 2520.5, + "OWC2": 2467.6, + "OWC3": 2446.9, + "PARAM1": 0.035, + "PARAM2": -0.66, + "PARAM3": 0.001, + "REAL": 140.0, + "RMS_SEED": 1140.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.272, + "NTG1": 0.82, + "NTG2": 0.61, + "OWC1": 2533.3, + "OWC2": 2462.6, + "OWC3": 2448.8, + "PARAM1": 0.037, + "PARAM2": 0.78, + "PARAM3": 1.838, + "REAL": 141.0, + "RMS_SEED": 1141.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.382, + "NTG1": 0.87, + "NTG2": 0.61, + "OWC1": 2502.7, + "OWC2": 2455.9, + "OWC3": 2481.6, + "PARAM1": 0.04, + "PARAM2": 0.56, + "PARAM3": 0.0, + "REAL": 142.0, + "RMS_SEED": 1142.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.001, + "NTG1": 0.86, + "NTG2": 0.61, + "OWC1": 2506.0, + "OWC2": 2459.8, + "OWC3": 2466.4, + "PARAM1": 0.038, + "PARAM2": -0.11, + "PARAM3": 16735.2, + "REAL": 143.0, + "RMS_SEED": 1143.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.012, + "NTG1": 0.77, + "NTG2": 0.61, + "OWC1": 2549.6, + "OWC2": 2465.5, + "OWC3": 2429.9, + "PARAM1": 0.039, + "PARAM2": -0.54, + "PARAM3": 0.407, + "REAL": 144.0, + "RMS_SEED": 1144.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.009, + "NTG1": 0.94, + "NTG2": 0.6, + "OWC1": 2504.2, + "OWC2": 2461.9, + "OWC3": 2470.0, + "PARAM1": 0.039, + "PARAM2": 0.05, + "PARAM3": 0.001, + "REAL": 145.0, + "RMS_SEED": 1145.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.544, + "NTG1": 0.79, + "NTG2": 0.62, + "OWC1": 2513.2, + "OWC2": 2440.0, + "OWC3": 2484.4, + "PARAM1": 0.037, + "PARAM2": -0.0, + "PARAM3": 11440.5, + "REAL": 146.0, + "RMS_SEED": 1146.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.964, + "NTG1": 0.81, + "NTG2": 0.56, + "OWC1": 2525.6, + "OWC2": 2458.0, + "OWC3": 2451.1, + "PARAM1": 0.037, + "PARAM2": -0.11, + "PARAM3": 248270.0, + "REAL": 147.0, + "RMS_SEED": 1147.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.009, + "NTG1": 0.76, + "NTG2": 0.61, + "OWC1": 2549.1, + "OWC2": 2494.5, + "OWC3": 2430.6, + "PARAM1": 0.035, + "PARAM2": 0.99, + "PARAM3": 0.0, + "REAL": 148.0, + "RMS_SEED": 1148.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.294, + "NTG1": 0.85, + "NTG2": 0.64, + "OWC1": 2534.9, + "OWC2": 2478.8, + "OWC3": 2418.2, + "PARAM1": 0.031, + "PARAM2": -0.25, + "PARAM3": 0.332, + "REAL": 149.0, + "RMS_SEED": 1149.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.93, + "NTG2": 0.62, + "OWC1": 2512.5, + "OWC2": 2463.3, + "OWC3": 2474.6, + "PARAM1": 0.028, + "PARAM2": -0.1, + "PARAM3": 0.0, + "REAL": 150.0, + "RMS_SEED": 1150.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.935, + "NTG1": 0.81, + "NTG2": 0.58, + "OWC1": 2507.2, + "OWC2": 2479.3, + "OWC3": 2464.9, + "PARAM1": 0.039, + "PARAM2": -0.6, + "PARAM3": 5426.66, + "REAL": 151.0, + "RMS_SEED": 1151.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.82, + "NTG2": 0.55, + "OWC1": 2540.6, + "OWC2": 2467.1, + "OWC3": 2449.1, + "PARAM1": 0.035, + "PARAM2": -0.69, + "PARAM3": 0.0, + "REAL": 152.0, + "RMS_SEED": 1152.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.048, + "NTG1": 0.83, + "NTG2": 0.58, + "OWC1": 2511.8, + "OWC2": 2466.5, + "OWC3": 2454.3, + "PARAM1": 0.037, + "PARAM2": 0.2, + "PARAM3": 131.092, + "REAL": 153.0, + "RMS_SEED": 1153.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.479, + "NTG1": 0.79, + "NTG2": 0.6, + "OWC1": 2543.8, + "OWC2": 2468.9, + "OWC3": 2440.7, + "PARAM1": 0.029, + "PARAM2": 0.12, + "PARAM3": 1.136, + "REAL": 154.0, + "RMS_SEED": 1154.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.81, + "NTG2": 0.6, + "OWC1": 2538.4, + "OWC2": 2458.7, + "OWC3": 2430.3, + "PARAM1": 0.037, + "PARAM2": 0.65, + "PARAM3": 0.0, + "REAL": 155.0, + "RMS_SEED": 1155.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.165, + "NTG1": 0.94, + "NTG2": 0.64, + "OWC1": 2533.1, + "OWC2": 2479.0, + "OWC3": 2433.2, + "PARAM1": 0.032, + "PARAM2": -0.78, + "PARAM3": 0.0, + "REAL": 156.0, + "RMS_SEED": 1156.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.123, + "NTG1": 0.87, + "NTG2": 0.61, + "OWC1": 2541.2, + "OWC2": 2481.9, + "OWC3": 2419.2, + "PARAM1": 0.036, + "PARAM2": 0.1, + "PARAM3": 0.0, + "REAL": 157.0, + "RMS_SEED": 1157.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.004, + "NTG1": 0.88, + "NTG2": 0.58, + "OWC1": 2540.2, + "OWC2": 2454.5, + "OWC3": 2453.2, + "PARAM1": 0.034, + "PARAM2": 0.93, + "PARAM3": 1.569, + "REAL": 158.0, + "RMS_SEED": 1158.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.024, + "NTG1": 0.83, + "NTG2": 0.59, + "OWC1": 2546.2, + "OWC2": 2485.7, + "OWC3": 2410.5, + "PARAM1": 0.027, + "PARAM2": -0.65, + "PARAM3": 406.363, + "REAL": 159.0, + "RMS_SEED": 1159.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.301, + "NTG1": 0.77, + "NTG2": 0.63, + "OWC1": 2540.7, + "OWC2": 2452.5, + "OWC3": 2438.5, + "PARAM1": 0.04, + "PARAM2": 0.41, + "PARAM3": 34583000.0, + "REAL": 160.0, + "RMS_SEED": 1160.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.063, + "NTG1": 0.85, + "NTG2": 0.63, + "OWC1": 2531.0, + "OWC2": 2451.0, + "OWC3": 2442.2, + "PARAM1": 0.034, + "PARAM2": -0.39, + "PARAM3": 2011750.0, + "REAL": 161.0, + "RMS_SEED": 1161.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.738, + "NTG1": 0.83, + "NTG2": 0.59, + "OWC1": 2503.9, + "OWC2": 2462.3, + "OWC3": 2466.3, + "PARAM1": 0.032, + "PARAM2": 0.44, + "PARAM3": 0.101, + "REAL": 162.0, + "RMS_SEED": 1162.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.006, + "NTG1": 0.83, + "NTG2": 0.56, + "OWC1": 2539.2, + "OWC2": 2475.0, + "OWC3": 2429.5, + "PARAM1": 0.039, + "PARAM2": 0.25, + "PARAM3": 0.055, + "REAL": 163.0, + "RMS_SEED": 1163.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.183, + "NTG1": 0.8, + "NTG2": 0.61, + "OWC1": 2509.8, + "OWC2": 2454.8, + "OWC3": 2474.5, + "PARAM1": 0.034, + "PARAM2": -0.21, + "PARAM3": 0.203, + "REAL": 164.0, + "RMS_SEED": 1164.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.037, + "NTG1": 0.81, + "NTG2": 0.61, + "OWC1": 2517.6, + "OWC2": 2461.4, + "OWC3": 2456.8, + "PARAM1": 0.036, + "PARAM2": 0.28, + "PARAM3": 75876.2, + "REAL": 165.0, + "RMS_SEED": 1165.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.009, + "NTG1": 0.8, + "NTG2": 0.63, + "OWC1": 2519.1, + "OWC2": 2443.3, + "OWC3": 2457.4, + "PARAM1": 0.033, + "PARAM2": 0.34, + "PARAM3": 8263.11, + "REAL": 166.0, + "RMS_SEED": 1166.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.035, + "NTG1": 0.8, + "NTG2": 0.6, + "OWC1": 2508.1, + "OWC2": 2457.2, + "OWC3": 2456.9, + "PARAM1": 0.03, + "PARAM2": -0.08, + "PARAM3": 0.033, + "REAL": 167.0, + "RMS_SEED": 1167.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.241, + "NTG1": 0.94, + "NTG2": 0.59, + "OWC1": 2519.9, + "OWC2": 2466.1, + "OWC3": 2456.0, + "PARAM1": 0.035, + "PARAM2": 0.66, + "PARAM3": 0.0, + "REAL": 168.0, + "RMS_SEED": 1168.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.005, + "NTG1": 0.88, + "NTG2": 0.62, + "OWC1": 2522.7, + "OWC2": 2453.7, + "OWC3": 2469.9, + "PARAM1": 0.032, + "PARAM2": -0.77, + "PARAM3": 176.632, + "REAL": 169.0, + "RMS_SEED": 1169.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.01, + "NTG1": 0.81, + "NTG2": 0.54, + "OWC1": 2511.8, + "OWC2": 2459.9, + "OWC3": 2477.3, + "PARAM1": 0.039, + "PARAM2": -0.37, + "PARAM3": 2.276, + "REAL": 170.0, + "RMS_SEED": 1170.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.667, + "NTG1": 0.82, + "NTG2": 0.63, + "OWC1": 2503.7, + "OWC2": 2437.1, + "OWC3": 2452.1, + "PARAM1": 0.027, + "PARAM2": 0.15, + "PARAM3": 0.0, + "REAL": 171.0, + "RMS_SEED": 1171.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.777, + "NTG1": 0.81, + "NTG2": 0.63, + "OWC1": 2511.3, + "OWC2": 2482.3, + "OWC3": 2448.9, + "PARAM1": 0.031, + "PARAM2": 0.9, + "PARAM3": 33.415, + "REAL": 172.0, + "RMS_SEED": 1172.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.004, + "NTG1": 0.9, + "NTG2": 0.57, + "OWC1": 2548.9, + "OWC2": 2494.0, + "OWC3": 2430.7, + "PARAM1": 0.039, + "PARAM2": -0.82, + "PARAM3": 0.613, + "REAL": 173.0, + "RMS_SEED": 1173.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.342, + "NTG1": 0.89, + "NTG2": 0.58, + "OWC1": 2523.1, + "OWC2": 2489.6, + "OWC3": 2435.5, + "PARAM1": 0.03, + "PARAM2": -0.43, + "PARAM3": 0.124, + "REAL": 174.0, + "RMS_SEED": 1174.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.448, + "NTG1": 0.81, + "NTG2": 0.6, + "OWC1": 2539.7, + "OWC2": 2459.0, + "OWC3": 2437.1, + "PARAM1": 0.034, + "PARAM2": -0.7, + "PARAM3": 542.855, + "REAL": 175.0, + "RMS_SEED": 1175.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.072, + "NTG1": 0.84, + "NTG2": 0.58, + "OWC1": 2536.8, + "OWC2": 2486.7, + "OWC3": 2415.9, + "PARAM1": 0.033, + "PARAM2": 0.73, + "PARAM3": 8.4, + "REAL": 176.0, + "RMS_SEED": 1176.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.003, + "NTG1": 0.77, + "NTG2": 0.64, + "OWC1": 2506.4, + "OWC2": 2453.6, + "OWC3": 2467.8, + "PARAM1": 0.025, + "PARAM2": -0.64, + "PARAM3": 0.0, + "REAL": 177.0, + "RMS_SEED": 1177.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.041, + "NTG1": 0.83, + "NTG2": 0.6, + "OWC1": 2530.6, + "OWC2": 2486.3, + "OWC3": 2414.9, + "PARAM1": 0.033, + "PARAM2": -0.33, + "PARAM3": 0.008, + "REAL": 178.0, + "RMS_SEED": 1178.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.025, + "NTG1": 0.96, + "NTG2": 0.6, + "OWC1": 2532.4, + "OWC2": 2467.7, + "OWC3": 2444.9, + "PARAM1": 0.038, + "PARAM2": -0.17, + "PARAM3": 0.0, + "REAL": 179.0, + "RMS_SEED": 1179.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.01, + "NTG1": 0.91, + "NTG2": 0.56, + "OWC1": 2500.2, + "OWC2": 2439.6, + "OWC3": 2494.9, + "PARAM1": 0.033, + "PARAM2": 0.24, + "PARAM3": 0.193, + "REAL": 180.0, + "RMS_SEED": 1180.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.258, + "NTG1": 0.75, + "NTG2": 0.54, + "OWC1": 2531.2, + "OWC2": 2486.6, + "OWC3": 2439.2, + "PARAM1": 0.039, + "PARAM2": -0.67, + "PARAM3": 4215710.0, + "REAL": 181.0, + "RMS_SEED": 1181.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.052, + "NTG1": 0.9, + "NTG2": 0.55, + "OWC1": 2506.5, + "OWC2": 2471.2, + "OWC3": 2435.8, + "PARAM1": 0.039, + "PARAM2": -0.02, + "PARAM3": 0.0, + "REAL": 182.0, + "RMS_SEED": 1182.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.362, + "NTG1": 0.87, + "NTG2": 0.64, + "OWC1": 2549.9, + "OWC2": 2483.7, + "OWC3": 2406.7, + "PARAM1": 0.032, + "PARAM2": -0.89, + "PARAM3": 0.941, + "REAL": 183.0, + "RMS_SEED": 1183.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.85, + "NTG2": 0.58, + "OWC1": 2513.4, + "OWC2": 2439.1, + "OWC3": 2486.6, + "PARAM1": 0.037, + "PARAM2": 0.21, + "PARAM3": 2.886, + "REAL": 184.0, + "RMS_SEED": 1184.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.93, + "NTG2": 0.6, + "OWC1": 2529.1, + "OWC2": 2445.1, + "OWC3": 2463.8, + "PARAM1": 0.033, + "PARAM2": -0.54, + "PARAM3": 0.0, + "REAL": 185.0, + "RMS_SEED": 1185.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.837, + "NTG1": 0.95, + "NTG2": 0.54, + "OWC1": 2511.2, + "OWC2": 2456.1, + "OWC3": 2471.4, + "PARAM1": 0.027, + "PARAM2": 0.2, + "PARAM3": 0.002, + "REAL": 186.0, + "RMS_SEED": 1186.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.391, + "NTG1": 0.87, + "NTG2": 0.61, + "OWC1": 2518.5, + "OWC2": 2471.5, + "OWC3": 2423.7, + "PARAM1": 0.027, + "PARAM2": -0.88, + "PARAM3": 0.0, + "REAL": 187.0, + "RMS_SEED": 1187.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.643, + "NTG1": 0.79, + "NTG2": 0.61, + "OWC1": 2544.7, + "OWC2": 2469.1, + "OWC3": 2421.0, + "PARAM1": 0.042, + "PARAM2": -1.0, + "PARAM3": 0.006, + "REAL": 188.0, + "RMS_SEED": 1188.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.003, + "NTG1": 0.79, + "NTG2": 0.58, + "OWC1": 2542.3, + "OWC2": 2476.7, + "OWC3": 2433.2, + "PARAM1": 0.036, + "PARAM2": 0.29, + "PARAM3": 13.842, + "REAL": 189.0, + "RMS_SEED": 1189.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.069, + "NTG1": 0.8, + "NTG2": 0.6, + "OWC1": 2525.8, + "OWC2": 2473.0, + "OWC3": 2462.9, + "PARAM1": 0.031, + "PARAM2": 0.52, + "PARAM3": 7588.49, + "REAL": 190.0, + "RMS_SEED": 1190.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.96, + "NTG2": 0.56, + "OWC1": 2501.6, + "OWC2": 2464.4, + "OWC3": 2472.9, + "PARAM1": 0.037, + "PARAM2": 0.45, + "PARAM3": 1.054, + "REAL": 191.0, + "RMS_SEED": 1191.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.018, + "NTG1": 0.79, + "NTG2": 0.53, + "OWC1": 2524.9, + "OWC2": 2459.2, + "OWC3": 2471.9, + "PARAM1": 0.033, + "PARAM2": -0.41, + "PARAM3": 0.0, + "REAL": 192.0, + "RMS_SEED": 1192.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.019, + "NTG1": 0.9, + "NTG2": 0.63, + "OWC1": 2529.2, + "OWC2": 2457.1, + "OWC3": 2456.4, + "PARAM1": 0.039, + "PARAM2": -0.31, + "PARAM3": 0.004, + "REAL": 193.0, + "RMS_SEED": 1193.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.012, + "NTG1": 0.85, + "NTG2": 0.59, + "OWC1": 2545.0, + "OWC2": 2480.1, + "OWC3": 2441.4, + "PARAM1": 0.041, + "PARAM2": -0.43, + "PARAM3": 0.264, + "REAL": 194.0, + "RMS_SEED": 1194.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.8, + "NTG2": 0.6, + "OWC1": 2524.5, + "OWC2": 2465.1, + "OWC3": 2468.7, + "PARAM1": 0.033, + "PARAM2": -0.24, + "PARAM3": 0.016, + "REAL": 195.0, + "RMS_SEED": 1195.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.731, + "NTG1": 0.79, + "NTG2": 0.63, + "OWC1": 2531.4, + "OWC2": 2479.1, + "OWC3": 2447.5, + "PARAM1": 0.035, + "PARAM2": -0.8, + "PARAM3": 71.745, + "REAL": 196.0, + "RMS_SEED": 1196.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.016, + "NTG1": 0.9, + "NTG2": 0.58, + "OWC1": 2517.7, + "OWC2": 2446.0, + "OWC3": 2464.5, + "PARAM1": 0.042, + "PARAM2": -0.12, + "PARAM3": 0.36, + "REAL": 197.0, + "RMS_SEED": 1197.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.013, + "NTG1": 0.97, + "NTG2": 0.63, + "OWC1": 2505.3, + "OWC2": 2469.8, + "OWC3": 2480.8, + "PARAM1": 0.033, + "PARAM2": 0.75, + "PARAM3": 0.0, + "REAL": 198.0, + "RMS_SEED": 1198.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.035, + "NTG1": 0.88, + "NTG2": 0.54, + "OWC1": 2547.6, + "OWC2": 2487.1, + "OWC3": 2418.0, + "PARAM1": 0.042, + "PARAM2": 0.38, + "PARAM3": 0.091, + "REAL": 199.0, + "RMS_SEED": 1199.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.604, + "NTG1": 0.97, + "NTG2": 0.54, + "OWC1": 2528.3, + "OWC2": 2449.2, + "OWC3": 2462.1, + "PARAM1": 0.034, + "PARAM2": 0.1, + "PARAM3": 1432730.0, + "REAL": 200.0, + "RMS_SEED": 1200.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.046, + "NTG1": 0.86, + "NTG2": 0.6, + "OWC1": 2514.6, + "OWC2": 2477.6, + "OWC3": 2434.2, + "PARAM1": 0.033, + "PARAM2": 0.01, + "PARAM3": 0.0, + "REAL": 201.0, + "RMS_SEED": 1201.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.077, + "NTG1": 0.82, + "NTG2": 0.62, + "OWC1": 2509.3, + "OWC2": 2447.0, + "OWC3": 2482.1, + "PARAM1": 0.035, + "PARAM2": -0.06, + "PARAM3": 2915850.0, + "REAL": 202.0, + "RMS_SEED": 1202.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.929, + "NTG1": 0.77, + "NTG2": 0.57, + "OWC1": 2518.1, + "OWC2": 2468.3, + "OWC3": 2436.0, + "PARAM1": 0.027, + "PARAM2": 0.65, + "PARAM3": 0.318, + "REAL": 203.0, + "RMS_SEED": 1203.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.8, + "NTG2": 0.64, + "OWC1": 2543.2, + "OWC2": 2477.3, + "OWC3": 2425.9, + "PARAM1": 0.036, + "PARAM2": 0.64, + "PARAM3": 112.948, + "REAL": 204.0, + "RMS_SEED": 1204.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.01, + "NTG1": 0.83, + "NTG2": 0.61, + "OWC1": 2539.9, + "OWC2": 2479.1, + "OWC3": 2442.8, + "PARAM1": 0.033, + "PARAM2": 0.01, + "PARAM3": 0.003, + "REAL": 205.0, + "RMS_SEED": 1205.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.023, + "NTG1": 0.9, + "NTG2": 0.59, + "OWC1": 2510.2, + "OWC2": 2450.8, + "OWC3": 2476.4, + "PARAM1": 0.035, + "PARAM2": 0.5, + "PARAM3": 0.031, + "REAL": 206.0, + "RMS_SEED": 1206.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.85, + "NTG2": 0.61, + "OWC1": 2537.3, + "OWC2": 2454.7, + "OWC3": 2449.8, + "PARAM1": 0.041, + "PARAM2": 0.31, + "PARAM3": 971.421, + "REAL": 207.0, + "RMS_SEED": 1207.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.9, + "NTG2": 0.58, + "OWC1": 2520.9, + "OWC2": 2460.9, + "OWC3": 2458.9, + "PARAM1": 0.035, + "PARAM2": 0.9, + "PARAM3": 39.432, + "REAL": 208.0, + "RMS_SEED": 1208.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.056, + "NTG1": 0.83, + "NTG2": 0.57, + "OWC1": 2506.8, + "OWC2": 2469.4, + "OWC3": 2464.3, + "PARAM1": 0.028, + "PARAM2": -0.68, + "PARAM3": 4162.86, + "REAL": 209.0, + "RMS_SEED": 1209.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.864, + "NTG1": 0.85, + "NTG2": 0.59, + "OWC1": 2537.1, + "OWC2": 2487.2, + "OWC3": 2414.8, + "PARAM1": 0.033, + "PARAM2": -0.87, + "PARAM3": 8807.35, + "REAL": 210.0, + "RMS_SEED": 1210.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.027, + "NTG1": 0.81, + "NTG2": 0.62, + "OWC1": 2542.8, + "OWC2": 2473.4, + "OWC3": 2418.7, + "PARAM1": 0.029, + "PARAM2": -0.2, + "PARAM3": 0.207, + "REAL": 211.0, + "RMS_SEED": 1211.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.003, + "NTG1": 0.81, + "NTG2": 0.65, + "OWC1": 2530.3, + "OWC2": 2461.6, + "OWC3": 2479.0, + "PARAM1": 0.033, + "PARAM2": 0.53, + "PARAM3": 0.0, + "REAL": 212.0, + "RMS_SEED": 1212.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.011, + "NTG1": 0.91, + "NTG2": 0.55, + "OWC1": 2521.7, + "OWC2": 2488.7, + "OWC3": 2432.1, + "PARAM1": 0.036, + "PARAM2": -0.84, + "PARAM3": 0.99, + "REAL": 213.0, + "RMS_SEED": 1213.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.458, + "NTG1": 0.95, + "NTG2": 0.58, + "OWC1": 2513.6, + "OWC2": 2469.1, + "OWC3": 2456.5, + "PARAM1": 0.029, + "PARAM2": -0.32, + "PARAM3": 0.0, + "REAL": 214.0, + "RMS_SEED": 1214.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.023, + "NTG1": 0.91, + "NTG2": 0.55, + "OWC1": 2516.1, + "OWC2": 2469.3, + "OWC3": 2446.3, + "PARAM1": 0.039, + "PARAM2": 0.23, + "PARAM3": 22.123, + "REAL": 215.0, + "RMS_SEED": 1215.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.098, + "NTG1": 0.79, + "NTG2": 0.59, + "OWC1": 2539.1, + "OWC2": 2470.6, + "OWC3": 2456.4, + "PARAM1": 0.029, + "PARAM2": 0.44, + "PARAM3": 0.006, + "REAL": 216.0, + "RMS_SEED": 1216.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.024, + "NTG1": 0.86, + "NTG2": 0.57, + "OWC1": 2544.7, + "OWC2": 2480.4, + "OWC3": 2409.0, + "PARAM1": 0.04, + "PARAM2": -0.09, + "PARAM3": 0.0, + "REAL": 217.0, + "RMS_SEED": 1217.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.014, + "NTG1": 0.94, + "NTG2": 0.61, + "OWC1": 2512.7, + "OWC2": 2442.9, + "OWC3": 2473.2, + "PARAM1": 0.032, + "PARAM2": 0.94, + "PARAM3": 0.0, + "REAL": 218.0, + "RMS_SEED": 1218.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.94, + "NTG2": 0.6, + "OWC1": 2542.6, + "OWC2": 2476.3, + "OWC3": 2429.8, + "PARAM1": 0.03, + "PARAM2": 0.19, + "PARAM3": 717.039, + "REAL": 219.0, + "RMS_SEED": 1219.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.192, + "NTG1": 0.81, + "NTG2": 0.58, + "OWC1": 2522.0, + "OWC2": 2480.8, + "OWC3": 2455.7, + "PARAM1": 0.034, + "PARAM2": -0.99, + "PARAM3": 0.0, + "REAL": 220.0, + "RMS_SEED": 1220.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.006, + "NTG1": 0.81, + "NTG2": 0.64, + "OWC1": 2527.2, + "OWC2": 2481.1, + "OWC3": 2435.0, + "PARAM1": 0.032, + "PARAM2": 0.74, + "PARAM3": 0.001, + "REAL": 221.0, + "RMS_SEED": 1221.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.83, + "NTG2": 0.63, + "OWC1": 2511.7, + "OWC2": 2444.3, + "OWC3": 2475.1, + "PARAM1": 0.028, + "PARAM2": 0.55, + "PARAM3": 2.186, + "REAL": 222.0, + "RMS_SEED": 1222.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.026, + "NTG1": 0.93, + "NTG2": 0.54, + "OWC1": 2542.9, + "OWC2": 2467.4, + "OWC3": 2453.6, + "PARAM1": 0.034, + "PARAM2": 0.57, + "PARAM3": 7.104, + "REAL": 223.0, + "RMS_SEED": 1223.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.125, + "NTG1": 0.87, + "NTG2": 0.63, + "OWC1": 2509.5, + "OWC2": 2433.0, + "OWC3": 2474.0, + "PARAM1": 0.041, + "PARAM2": 1.0, + "PARAM3": 0.0, + "REAL": 224.0, + "RMS_SEED": 1224.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.005, + "NTG1": 0.78, + "NTG2": 0.58, + "OWC1": 2542.0, + "OWC2": 2465.0, + "OWC3": 2436.2, + "PARAM1": 0.035, + "PARAM2": -0.47, + "PARAM3": 0.0, + "REAL": 225.0, + "RMS_SEED": 1225.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.007, + "NTG1": 0.8, + "NTG2": 0.63, + "OWC1": 2500.5, + "OWC2": 2455.2, + "OWC3": 2465.2, + "PARAM1": 0.038, + "PARAM2": -0.02, + "PARAM3": 144804000.0, + "REAL": 226.0, + "RMS_SEED": 1226.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.01, + "NTG1": 0.86, + "NTG2": 0.61, + "OWC1": 2540.4, + "OWC2": 2483.3, + "OWC3": 2448.9, + "PARAM1": 0.035, + "PARAM2": 0.35, + "PARAM3": 0.03, + "REAL": 227.0, + "RMS_SEED": 1227.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.008, + "NTG1": 0.81, + "NTG2": 0.6, + "OWC1": 2539.5, + "OWC2": 2467.9, + "OWC3": 2447.4, + "PARAM1": 0.035, + "PARAM2": -0.03, + "PARAM3": 0.086, + "REAL": 228.0, + "RMS_SEED": 1228.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.519, + "NTG1": 0.8, + "NTG2": 0.61, + "OWC1": 2541.2, + "OWC2": 2446.3, + "OWC3": 2470.7, + "PARAM1": 0.031, + "PARAM2": 0.16, + "PARAM3": 0.0, + "REAL": 229.0, + "RMS_SEED": 1229.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.025, + "NTG1": 0.99, + "NTG2": 0.61, + "OWC1": 2521.7, + "OWC2": 2491.2, + "OWC3": 2439.7, + "PARAM1": 0.033, + "PARAM2": -0.19, + "PARAM3": 0.005, + "REAL": 230.0, + "RMS_SEED": 1230.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.029, + "NTG1": 0.96, + "NTG2": 0.53, + "OWC1": 2522.1, + "OWC2": 2474.3, + "OWC3": 2445.0, + "PARAM1": 0.029, + "PARAM2": 0.22, + "PARAM3": 35448.0, + "REAL": 231.0, + "RMS_SEED": 1231.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.79, + "NTG2": 0.55, + "OWC1": 2502.1, + "OWC2": 2460.8, + "OWC3": 2469.4, + "PARAM1": 0.03, + "PARAM2": -0.85, + "PARAM3": 476.181, + "REAL": 232.0, + "RMS_SEED": 1232.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.186, + "NTG1": 0.81, + "NTG2": 0.6, + "OWC1": 2502.4, + "OWC2": 2447.4, + "OWC3": 2489.7, + "PARAM1": 0.044, + "PARAM2": -0.34, + "PARAM3": 6239.04, + "REAL": 233.0, + "RMS_SEED": 1233.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.99, + "NTG2": 0.57, + "OWC1": 2543.3, + "OWC2": 2460.5, + "OWC3": 2480.0, + "PARAM1": 0.036, + "PARAM2": 0.37, + "PARAM3": 0.002, + "REAL": 234.0, + "RMS_SEED": 1234.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.548, + "NTG1": 0.82, + "NTG2": 0.58, + "OWC1": 2510.0, + "OWC2": 2464.5, + "OWC3": 2450.4, + "PARAM1": 0.034, + "PARAM2": -0.58, + "PARAM3": 7.486, + "REAL": 235.0, + "RMS_SEED": 1235.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.007, + "NTG1": 0.8, + "NTG2": 0.57, + "OWC1": 2522.2, + "OWC2": 2438.3, + "OWC3": 2473.0, + "PARAM1": 0.035, + "PARAM2": -0.55, + "PARAM3": 0.0, + "REAL": 236.0, + "RMS_SEED": 1236.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.001, + "NTG1": 0.92, + "NTG2": 0.61, + "OWC1": 2519.1, + "OWC2": 2444.9, + "OWC3": 2469.5, + "PARAM1": 0.029, + "PARAM2": -0.53, + "PARAM3": 8.87, + "REAL": 237.0, + "RMS_SEED": 1237.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.003, + "NTG1": 0.77, + "NTG2": 0.56, + "OWC1": 2523.4, + "OWC2": 2448.6, + "OWC3": 2460.9, + "PARAM1": 0.044, + "PARAM2": -0.91, + "PARAM3": 2602.05, + "REAL": 238.0, + "RMS_SEED": 1238.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.005, + "NTG1": 0.83, + "NTG2": 0.59, + "OWC1": 2516.0, + "OWC2": 2474.4, + "OWC3": 2438.0, + "PARAM1": 0.037, + "PARAM2": -0.82, + "PARAM3": 19478.7, + "REAL": 239.0, + "RMS_SEED": 1239.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.007, + "NTG1": 0.86, + "NTG2": 0.62, + "OWC1": 2514.4, + "OWC2": 2466.8, + "OWC3": 2443.3, + "PARAM1": 0.034, + "PARAM2": -0.39, + "PARAM3": 2236.67, + "REAL": 240.0, + "RMS_SEED": 1240.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.1, + "NTG1": 0.84, + "NTG2": 0.57, + "OWC1": 2501.7, + "OWC2": 2459.3, + "OWC3": 2476.7, + "PARAM1": 0.038, + "PARAM2": -0.72, + "PARAM3": 313332.0, + "REAL": 241.0, + "RMS_SEED": 1241.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.003, + "NTG1": 0.91, + "NTG2": 0.63, + "OWC1": 2504.8, + "OWC2": 2445.7, + "OWC3": 2457.2, + "PARAM1": 0.045, + "PARAM2": -0.27, + "PARAM3": 759.979, + "REAL": 242.0, + "RMS_SEED": 1242.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.008, + "NTG1": 0.92, + "NTG2": 0.57, + "OWC1": 2531.8, + "OWC2": 2469.6, + "OWC3": 2443.4, + "PARAM1": 0.039, + "PARAM2": -0.16, + "PARAM3": 366904.0, + "REAL": 243.0, + "RMS_SEED": 1243.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.022, + "NTG1": 0.91, + "NTG2": 0.63, + "OWC1": 2534.0, + "OWC2": 2473.0, + "OWC3": 2461.5, + "PARAM1": 0.034, + "PARAM2": -0.04, + "PARAM3": 1.82, + "REAL": 244.0, + "RMS_SEED": 1244.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.84, + "NTG2": 0.63, + "OWC1": 2506.7, + "OWC2": 2466.2, + "OWC3": 2466.7, + "PARAM1": 0.029, + "PARAM2": 0.71, + "PARAM3": 0.0, + "REAL": 245.0, + "RMS_SEED": 1245.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.147, + "NTG1": 0.8, + "NTG2": 0.63, + "OWC1": 2513.9, + "OWC2": 2484.6, + "OWC3": 2447.0, + "PARAM1": 0.042, + "PARAM2": 0.82, + "PARAM3": 183.657, + "REAL": 246.0, + "RMS_SEED": 1246.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.358, + "NTG1": 0.85, + "NTG2": 0.58, + "OWC1": 2531.9, + "OWC2": 2487.9, + "OWC3": 2437.7, + "PARAM1": 0.042, + "PARAM2": 0.58, + "PARAM3": 4.148, + "REAL": 247.0, + "RMS_SEED": 1247.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.806, + "NTG1": 0.87, + "NTG2": 0.58, + "OWC1": 2504.4, + "OWC2": 2464.9, + "OWC3": 2453.1, + "PARAM1": 0.03, + "PARAM2": -0.4, + "PARAM3": 0.0, + "REAL": 248.0, + "RMS_SEED": 1248.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.039, + "NTG1": 0.83, + "NTG2": 0.61, + "OWC1": 2514.7, + "OWC2": 2479.3, + "OWC3": 2462.5, + "PARAM1": 0.029, + "PARAM2": -0.67, + "PARAM3": 5.797, + "REAL": 249.0, + "RMS_SEED": 1249.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.01, + "NTG1": 0.92, + "NTG2": 0.61, + "OWC1": 2511.5, + "OWC2": 2458.2, + "OWC3": 2449.7, + "PARAM1": 0.037, + "PARAM2": 0.03, + "PARAM3": 0.0, + "REAL": 250.0, + "RMS_SEED": 1250.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.691, + "NTG1": 0.77, + "NTG2": 0.56, + "OWC1": 2531.0, + "OWC2": 2475.9, + "OWC3": 2441.6, + "PARAM1": 0.042, + "PARAM2": 0.13, + "PARAM3": 2161.94, + "REAL": 251.0, + "RMS_SEED": 1251.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.79, + "NTG2": 0.59, + "OWC1": 2528.4, + "OWC2": 2469.5, + "OWC3": 2453.9, + "PARAM1": 0.041, + "PARAM2": 0.97, + "PARAM3": 70294.9, + "REAL": 252.0, + "RMS_SEED": 1252.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.37, + "NTG1": 0.91, + "NTG2": 0.59, + "OWC1": 2513.1, + "OWC2": 2485.3, + "OWC3": 2436.7, + "PARAM1": 0.036, + "PARAM2": -0.93, + "PARAM3": 448606000000000.0, + "REAL": 253.0, + "RMS_SEED": 1253.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.89, + "NTG2": 0.62, + "OWC1": 2518.9, + "OWC2": 2446.2, + "OWC3": 2455.0, + "PARAM1": 0.03, + "PARAM2": 0.75, + "PARAM3": 1074.78, + "REAL": 254.0, + "RMS_SEED": 1254.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.046, + "NTG1": 0.87, + "NTG2": 0.59, + "OWC1": 2522.9, + "OWC2": 2472.3, + "OWC3": 2441.1, + "PARAM1": 0.039, + "PARAM2": -0.44, + "PARAM3": 492590000.0, + "REAL": 255.0, + "RMS_SEED": 1255.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.054, + "NTG1": 0.85, + "NTG2": 0.62, + "OWC1": 2525.2, + "OWC2": 2482.1, + "OWC3": 2446.5, + "PARAM1": 0.033, + "PARAM2": -0.36, + "PARAM3": 0.005, + "REAL": 256.0, + "RMS_SEED": 1256.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.85, + "NTG2": 0.55, + "OWC1": 2515.2, + "OWC2": 2450.3, + "OWC3": 2483.9, + "PARAM1": 0.039, + "PARAM2": -0.69, + "PARAM3": 0.002, + "REAL": 257.0, + "RMS_SEED": 1257.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.155, + "NTG1": 0.82, + "NTG2": 0.58, + "OWC1": 2517.0, + "OWC2": 2449.3, + "OWC3": 2451.1, + "PARAM1": 0.027, + "PARAM2": 0.56, + "PARAM3": 29714.4, + "REAL": 258.0, + "RMS_SEED": 1258.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.306, + "NTG1": 0.82, + "NTG2": 0.61, + "OWC1": 2545.6, + "OWC2": 2478.1, + "OWC3": 2432.1, + "PARAM1": 0.032, + "PARAM2": -0.76, + "PARAM3": 25.441, + "REAL": 259.0, + "RMS_SEED": 1259.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.009, + "NTG1": 0.82, + "NTG2": 0.6, + "OWC1": 2506.9, + "OWC2": 2449.8, + "OWC3": 2458.5, + "PARAM1": 0.041, + "PARAM2": 0.83, + "PARAM3": 0.012, + "REAL": 260.0, + "RMS_SEED": 1260.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.062, + "NTG1": 0.83, + "NTG2": 0.65, + "OWC1": 2542.8, + "OWC2": 2488.4, + "OWC3": 2445.6, + "PARAM1": 0.035, + "PARAM2": 0.04, + "PARAM3": 0.0, + "REAL": 261.0, + "RMS_SEED": 1261.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.87, + "NTG2": 0.6, + "OWC1": 2501.1, + "OWC2": 2468.6, + "OWC3": 2460.7, + "PARAM1": 0.035, + "PARAM2": 0.08, + "PARAM3": 121.657, + "REAL": 262.0, + "RMS_SEED": 1262.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.322, + "NTG1": 0.92, + "NTG2": 0.59, + "OWC1": 2529.0, + "OWC2": 2481.4, + "OWC3": 2440.3, + "PARAM1": 0.036, + "PARAM2": -0.56, + "PARAM3": 20.237, + "REAL": 263.0, + "RMS_SEED": 1263.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.83, + "NTG2": 0.56, + "OWC1": 2500.8, + "OWC2": 2460.0, + "OWC3": 2467.1, + "PARAM1": 0.029, + "PARAM2": -0.58, + "PARAM3": 0.169, + "REAL": 264.0, + "RMS_SEED": 1264.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.8, + "NTG2": 0.61, + "OWC1": 2543.6, + "OWC2": 2442.4, + "OWC3": 2433.7, + "PARAM1": 0.034, + "PARAM2": 0.51, + "PARAM3": 0.011, + "REAL": 265.0, + "RMS_SEED": 1265.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.231, + "NTG1": 0.89, + "NTG2": 0.59, + "OWC1": 2547.6, + "OWC2": 2480.9, + "OWC3": 2452.0, + "PARAM1": 0.031, + "PARAM2": -0.33, + "PARAM3": 4.582, + "REAL": 266.0, + "RMS_SEED": 1266.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.991, + "NTG1": 0.83, + "NTG2": 0.6, + "OWC1": 2522.7, + "OWC2": 2475.7, + "OWC3": 2451.3, + "PARAM1": 0.039, + "PARAM2": 0.02, + "PARAM3": 4.379, + "REAL": 267.0, + "RMS_SEED": 1267.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.194, + "NTG1": 0.84, + "NTG2": 0.6, + "OWC1": 2501.8, + "OWC2": 2439.2, + "OWC3": 2477.8, + "PARAM1": 0.031, + "PARAM2": 0.87, + "PARAM3": 0.001, + "REAL": 268.0, + "RMS_SEED": 1268.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.88, + "NTG1": 0.83, + "NTG2": 0.56, + "OWC1": 2501.4, + "OWC2": 2453.5, + "OWC3": 2466.6, + "PARAM1": 0.033, + "PARAM2": 0.03, + "PARAM3": 0.001, + "REAL": 269.0, + "RMS_SEED": 1269.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.572, + "NTG1": 0.85, + "NTG2": 0.58, + "OWC1": 2541.6, + "OWC2": 2493.8, + "OWC3": 2412.6, + "PARAM1": 0.034, + "PARAM2": 0.92, + "PARAM3": 26369.7, + "REAL": 270.0, + "RMS_SEED": 1270.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.051, + "NTG1": 0.92, + "NTG2": 0.59, + "OWC1": 2525.3, + "OWC2": 2474.2, + "OWC3": 2454.4, + "PARAM1": 0.041, + "PARAM2": 0.21, + "PARAM3": 48.036, + "REAL": 271.0, + "RMS_SEED": 1271.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.79, + "NTG2": 0.6, + "OWC1": 2544.6, + "OWC2": 2459.1, + "OWC3": 2445.3, + "PARAM1": 0.037, + "PARAM2": 0.27, + "PARAM3": 3403.88, + "REAL": 272.0, + "RMS_SEED": 1272.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.114, + "NTG1": 0.9, + "NTG2": 0.52, + "OWC1": 2509.9, + "OWC2": 2456.3, + "OWC3": 2471.2, + "PARAM1": 0.03, + "PARAM2": -0.68, + "PARAM3": 0.0, + "REAL": 273.0, + "RMS_SEED": 1273.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.216, + "NTG1": 0.82, + "NTG2": 0.6, + "OWC1": 2500.0, + "OWC2": 2431.8, + "OWC3": 2496.4, + "PARAM1": 0.043, + "PARAM2": -0.5, + "PARAM3": 92990.6, + "REAL": 274.0, + "RMS_SEED": 1274.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.093, + "NTG1": 0.86, + "NTG2": 0.6, + "OWC1": 2533.5, + "OWC2": 2467.9, + "OWC3": 2443.7, + "PARAM1": 0.036, + "PARAM2": 0.33, + "PARAM3": 167.798, + "REAL": 275.0, + "RMS_SEED": 1275.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.059, + "NTG1": 0.83, + "NTG2": 0.56, + "OWC1": 2510.8, + "OWC2": 2472.3, + "OWC3": 2471.0, + "PARAM1": 0.038, + "PARAM2": -0.57, + "PARAM3": 4398.71, + "REAL": 276.0, + "RMS_SEED": 1276.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.016, + "NTG1": 0.95, + "NTG2": 0.61, + "OWC1": 2546.3, + "OWC2": 2498.7, + "OWC3": 2403.3, + "PARAM1": 0.029, + "PARAM2": -0.74, + "PARAM3": 9111100.0, + "REAL": 277.0, + "RMS_SEED": 1277.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.061, + "NTG1": 0.79, + "NTG2": 0.57, + "OWC1": 2536.0, + "OWC2": 2473.7, + "OWC3": 2437.0, + "PARAM1": 0.031, + "PARAM2": 0.33, + "PARAM3": 0.285, + "REAL": 278.0, + "RMS_SEED": 1278.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.8, + "NTG2": 0.58, + "OWC1": 2506.0, + "OWC2": 2449.4, + "OWC3": 2473.7, + "PARAM1": 0.037, + "PARAM2": -0.38, + "PARAM3": 809.6, + "REAL": 279.0, + "RMS_SEED": 1279.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.101, + "NTG1": 0.95, + "NTG2": 0.57, + "OWC1": 2540.9, + "OWC2": 2473.5, + "OWC3": 2432.8, + "PARAM1": 0.029, + "PARAM2": -0.21, + "PARAM3": 1.432, + "REAL": 280.0, + "RMS_SEED": 1280.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.01, + "NTG1": 0.81, + "NTG2": 0.57, + "OWC1": 2501.3, + "OWC2": 2458.8, + "OWC3": 2483.1, + "PARAM1": 0.026, + "PARAM2": 0.67, + "PARAM3": 1745.93, + "REAL": 281.0, + "RMS_SEED": 1281.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.005, + "NTG1": 0.78, + "NTG2": 0.55, + "OWC1": 2547.1, + "OWC2": 2478.4, + "OWC3": 2422.5, + "PARAM1": 0.033, + "PARAM2": -0.85, + "PARAM3": 419.857, + "REAL": 282.0, + "RMS_SEED": 1282.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.159, + "NTG1": 0.8, + "NTG2": 0.6, + "OWC1": 2522.9, + "OWC2": 2472.8, + "OWC3": 2457.3, + "PARAM1": 0.034, + "PARAM2": -0.7, + "PARAM3": 0.011, + "REAL": 283.0, + "RMS_SEED": 1283.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.005, + "NTG1": 0.88, + "NTG2": 0.6, + "OWC1": 2528.6, + "OWC2": 2476.9, + "OWC3": 2409.9, + "PARAM1": 0.037, + "PARAM2": -0.71, + "PARAM3": 336.359, + "REAL": 284.0, + "RMS_SEED": 1284.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.039, + "NTG1": 0.91, + "NTG2": 0.56, + "OWC1": 2512.1, + "OWC2": 2473.1, + "OWC3": 2455.9, + "PARAM1": 0.029, + "PARAM2": 0.28, + "PARAM3": 0.0, + "REAL": 285.0, + "RMS_SEED": 1285.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.016, + "NTG1": 0.85, + "NTG2": 0.63, + "OWC1": 2514.5, + "OWC2": 2465.4, + "OWC3": 2460.6, + "PARAM1": 0.032, + "PARAM2": -0.71, + "PARAM3": 10408.7, + "REAL": 286.0, + "RMS_SEED": 1286.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.238, + "NTG1": 0.87, + "NTG2": 0.61, + "OWC1": 2500.3, + "OWC2": 2454.3, + "OWC3": 2469.3, + "PARAM1": 0.038, + "PARAM2": -0.2, + "PARAM3": 0.001, + "REAL": 287.0, + "RMS_SEED": 1287.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.144, + "NTG1": 0.8, + "NTG2": 0.58, + "OWC1": 2544.4, + "OWC2": 2474.9, + "OWC3": 2438.1, + "PARAM1": 0.035, + "PARAM2": -0.52, + "PARAM3": 0.08, + "REAL": 288.0, + "RMS_SEED": 1288.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.008, + "NTG1": 0.96, + "NTG2": 0.64, + "OWC1": 2538.4, + "OWC2": 2463.3, + "OWC3": 2431.3, + "PARAM1": 0.038, + "PARAM2": 0.09, + "PARAM3": 21658.5, + "REAL": 289.0, + "RMS_SEED": 1289.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.229, + "NTG1": 0.83, + "NTG2": 0.62, + "OWC1": 2527.9, + "OWC2": 2451.6, + "OWC3": 2476.0, + "PARAM1": 0.028, + "PARAM2": -0.6, + "PARAM3": 11.941, + "REAL": 290.0, + "RMS_SEED": 1290.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.012, + "NTG1": 0.89, + "NTG2": 0.59, + "OWC1": 2511.2, + "OWC2": 2460.1, + "OWC3": 2482.7, + "PARAM1": 0.032, + "PARAM2": 0.18, + "PARAM3": 0.0, + "REAL": 291.0, + "RMS_SEED": 1291.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.129, + "NTG1": 0.96, + "NTG2": 0.63, + "OWC1": 2515.7, + "OWC2": 2461.7, + "OWC3": 2444.1, + "PARAM1": 0.042, + "PARAM2": -0.4, + "PARAM3": 0.0, + "REAL": 292.0, + "RMS_SEED": 1292.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.632, + "NTG1": 0.89, + "NTG2": 0.57, + "OWC1": 2516.6, + "OWC2": 2451.3, + "OWC3": 2457.1, + "PARAM1": 0.03, + "PARAM2": -0.48, + "PARAM3": 0.0, + "REAL": 293.0, + "RMS_SEED": 1293.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.94, + "NTG2": 0.62, + "OWC1": 2517.9, + "OWC2": 2456.9, + "OWC3": 2468.0, + "PARAM1": 0.041, + "PARAM2": -0.11, + "PARAM3": 11.641, + "REAL": 294.0, + "RMS_SEED": 1294.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.001, + "NTG1": 0.83, + "NTG2": 0.57, + "OWC1": 2503.0, + "OWC2": 2447.9, + "OWC3": 2484.9, + "PARAM1": 0.031, + "PARAM2": 0.97, + "PARAM3": 0.307, + "REAL": 295.0, + "RMS_SEED": 1295.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.106, + "NTG1": 0.82, + "NTG2": 0.57, + "OWC1": 2530.0, + "OWC2": 2462.3, + "OWC3": 2459.8, + "PARAM1": 0.036, + "PARAM2": 0.78, + "PARAM3": 3843.43, + "REAL": 296.0, + "RMS_SEED": 1296.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.221, + "NTG1": 0.84, + "NTG2": 0.58, + "OWC1": 2516.8, + "OWC2": 2462.8, + "OWC3": 2450.8, + "PARAM1": 0.042, + "PARAM2": 0.4, + "PARAM3": 192.296, + "REAL": 297.0, + "RMS_SEED": 1297.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.261, + "NTG1": 0.79, + "NTG2": 0.6, + "OWC1": 2524.2, + "OWC2": 2490.7, + "OWC3": 2428.4, + "PARAM1": 0.032, + "PARAM2": 0.61, + "PARAM3": 5.406, + "REAL": 298.0, + "RMS_SEED": 1298.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.022, + "NTG1": 0.81, + "NTG2": 0.6, + "OWC1": 2527.0, + "OWC2": 2477.6, + "OWC3": 2452.3, + "PARAM1": 0.04, + "PARAM2": -0.75, + "PARAM3": 12770100.0, + "REAL": 299.0, + "RMS_SEED": 1299.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.011, + "NTG1": 0.84, + "NTG2": 0.62, + "OWC1": 2508.7, + "OWC2": 2471.1, + "OWC3": 2447.8, + "PARAM1": 0.04, + "PARAM2": -0.41, + "PARAM3": 0.048, + "REAL": 300.0, + "RMS_SEED": 1300.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.138, + "NTG1": 0.83, + "NTG2": 0.58, + "OWC1": 2515.2, + "OWC2": 2464.2, + "OWC3": 2474.2, + "PARAM1": 0.04, + "PARAM2": 0.33, + "PARAM3": 9.375, + "REAL": 301.0, + "RMS_SEED": 1301.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.167, + "NTG1": 0.93, + "NTG2": 0.63, + "OWC1": 2521.4, + "OWC2": 2476.2, + "OWC3": 2452.2, + "PARAM1": 0.037, + "PARAM2": 0.07, + "PARAM3": 2.567, + "REAL": 302.0, + "RMS_SEED": 1302.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.141, + "NTG1": 0.98, + "NTG2": 0.59, + "OWC1": 2508.1, + "OWC2": 2465.7, + "OWC3": 2450.5, + "PARAM1": 0.042, + "PARAM2": 0.43, + "PARAM3": 261180000.0, + "REAL": 303.0, + "RMS_SEED": 1303.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.004, + "NTG1": 0.92, + "NTG2": 0.58, + "OWC1": 2517.2, + "OWC2": 2468.7, + "OWC3": 2437.5, + "PARAM1": 0.034, + "PARAM2": 0.25, + "PARAM3": 30086700.0, + "REAL": 304.0, + "RMS_SEED": 1304.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.007, + "NTG1": 0.9, + "NTG2": 0.62, + "OWC1": 2535.3, + "OWC2": 2483.1, + "OWC3": 2436.4, + "PARAM1": 0.035, + "PARAM2": 0.3, + "PARAM3": 5.207, + "REAL": 305.0, + "RMS_SEED": 1305.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.095, + "NTG1": 0.81, + "NTG2": 0.6, + "OWC1": 2546.6, + "OWC2": 2471.8, + "OWC3": 2416.9, + "PARAM1": 0.041, + "PARAM2": -0.86, + "PARAM3": 4.94, + "REAL": 306.0, + "RMS_SEED": 1306.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.2, + "NTG1": 0.88, + "NTG2": 0.55, + "OWC1": 2519.3, + "OWC2": 2442.6, + "OWC3": 2464.9, + "PARAM1": 0.032, + "PARAM2": -0.1, + "PARAM3": 1516.13, + "REAL": 307.0, + "RMS_SEED": 1307.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.025, + "NTG1": 0.89, + "NTG2": 0.63, + "OWC1": 2534.3, + "OWC2": 2491.3, + "OWC3": 2439.4, + "PARAM1": 0.038, + "PARAM2": -0.26, + "PARAM3": 1650.3, + "REAL": 308.0, + "RMS_SEED": 1308.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.087, + "NTG1": 0.86, + "NTG2": 0.64, + "OWC1": 2508.0, + "OWC2": 2473.2, + "OWC3": 2460.4, + "PARAM1": 0.038, + "PARAM2": 0.95, + "PARAM3": 2428.76, + "REAL": 309.0, + "RMS_SEED": 1309.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.959, + "NTG1": 0.84, + "NTG2": 0.57, + "OWC1": 2533.6, + "OWC2": 2459.6, + "OWC3": 2473.8, + "PARAM1": 0.042, + "PARAM2": -0.96, + "PARAM3": 32673.2, + "REAL": 310.0, + "RMS_SEED": 1310.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.024, + "NTG1": 0.89, + "NTG2": 0.61, + "OWC1": 2513.7, + "OWC2": 2480.6, + "OWC3": 2440.5, + "PARAM1": 0.031, + "PARAM2": 0.83, + "PARAM3": 0.001, + "REAL": 311.0, + "RMS_SEED": 1311.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.592, + "NTG1": 0.78, + "NTG2": 0.57, + "OWC1": 2532.7, + "OWC2": 2472.5, + "OWC3": 2453.4, + "PARAM1": 0.043, + "PARAM2": -0.03, + "PARAM3": 2.415, + "REAL": 312.0, + "RMS_SEED": 1312.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.021, + "NTG1": 0.94, + "NTG2": 0.59, + "OWC1": 2513.5, + "OWC2": 2478.7, + "OWC3": 2451.9, + "PARAM1": 0.041, + "PARAM2": -0.71, + "PARAM3": 7111350.0, + "REAL": 313.0, + "RMS_SEED": 1313.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.83, + "NTG2": 0.6, + "OWC1": 2549.5, + "OWC2": 2480.5, + "OWC3": 2428.5, + "PARAM1": 0.035, + "PARAM2": -0.17, + "PARAM3": 20.597, + "REAL": 314.0, + "RMS_SEED": 1314.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.009, + "NTG1": 0.88, + "NTG2": 0.6, + "OWC1": 2538.6, + "OWC2": 2461.2, + "OWC3": 2441.7, + "PARAM1": 0.037, + "PARAM2": 0.92, + "PARAM3": 64341.9, + "REAL": 315.0, + "RMS_SEED": 1315.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.008, + "NTG1": 0.78, + "NTG2": 0.58, + "OWC1": 2518.4, + "OWC2": 2435.8, + "OWC3": 2467.2, + "PARAM1": 0.037, + "PARAM2": 0.97, + "PARAM3": 1232470000000.0, + "REAL": 316.0, + "RMS_SEED": 1316.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.02, + "NTG1": 0.8, + "NTG2": 0.55, + "OWC1": 2505.0, + "OWC2": 2450.9, + "OWC3": 2490.8, + "PARAM1": 0.031, + "PARAM2": 0.14, + "PARAM3": 16.101, + "REAL": 317.0, + "RMS_SEED": 1317.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.87, + "NTG2": 0.62, + "OWC1": 2538.0, + "OWC2": 2489.0, + "OWC3": 2424.4, + "PARAM1": 0.037, + "PARAM2": -0.79, + "PARAM3": 0.242, + "REAL": 318.0, + "RMS_SEED": 1318.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.82, + "NTG2": 0.55, + "OWC1": 2517.4, + "OWC2": 2472.1, + "OWC3": 2459.3, + "PARAM1": 0.041, + "PARAM2": -0.51, + "PARAM3": 0.0, + "REAL": 319.0, + "RMS_SEED": 1319.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.246, + "NTG1": 0.84, + "NTG2": 0.59, + "OWC1": 2507.4, + "OWC2": 2481.8, + "OWC3": 2460.1, + "PARAM1": 0.032, + "PARAM2": 0.22, + "PARAM3": 0.002, + "REAL": 320.0, + "RMS_SEED": 1320.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.038, + "NTG1": 0.87, + "NTG2": 0.58, + "OWC1": 2524.2, + "OWC2": 2465.3, + "OWC3": 2446.2, + "PARAM1": 0.036, + "PARAM2": 0.84, + "PARAM3": 0.042, + "REAL": 321.0, + "RMS_SEED": 1321.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.018, + "NTG1": 0.87, + "NTG2": 0.61, + "OWC1": 2526.7, + "OWC2": 2471.4, + "OWC3": 2427.8, + "PARAM1": 0.034, + "PARAM2": -0.35, + "PARAM3": 346.387, + "REAL": 322.0, + "RMS_SEED": 1322.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.011, + "NTG1": 0.82, + "NTG2": 0.61, + "OWC1": 2500.7, + "OWC2": 2447.8, + "OWC3": 2493.5, + "PARAM1": 0.033, + "PARAM2": -0.73, + "PARAM3": 183689.0, + "REAL": 323.0, + "RMS_SEED": 1323.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.066, + "NTG1": 0.89, + "NTG2": 0.59, + "OWC1": 2509.2, + "OWC2": 2447.2, + "OWC3": 2463.0, + "PARAM1": 0.035, + "PARAM2": 0.49, + "PARAM3": 228019.0, + "REAL": 324.0, + "RMS_SEED": 1324.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.116, + "NTG1": 0.87, + "NTG2": 0.63, + "OWC1": 2503.4, + "OWC2": 2465.9, + "OWC3": 2460.2, + "PARAM1": 0.029, + "PARAM2": 0.58, + "PARAM3": 20246100.0, + "REAL": 325.0, + "RMS_SEED": 1325.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.018, + "NTG1": 0.85, + "NTG2": 0.61, + "OWC1": 2508.2, + "OWC2": 2459.5, + "OWC3": 2478.4, + "PARAM1": 0.039, + "PARAM2": 0.16, + "PARAM3": 51570200.0, + "REAL": 326.0, + "RMS_SEED": 1326.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.015, + "NTG1": 0.76, + "NTG2": 0.58, + "OWC1": 2521.3, + "OWC2": 2487.8, + "OWC3": 2447.1, + "PARAM1": 0.038, + "PARAM2": -0.23, + "PARAM3": 118.724, + "REAL": 327.0, + "RMS_SEED": 1327.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.31, + "NTG1": 0.89, + "NTG2": 0.59, + "OWC1": 2535.5, + "OWC2": 2471.7, + "OWC3": 2446.8, + "PARAM1": 0.038, + "PARAM2": -0.32, + "PARAM3": 0.007, + "REAL": 328.0, + "RMS_SEED": 1328.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.035, + "NTG1": 0.83, + "NTG2": 0.63, + "OWC1": 2525.7, + "OWC2": 2466.0, + "OWC3": 2448.3, + "PARAM1": 0.037, + "PARAM2": -0.49, + "PARAM3": 6910.68, + "REAL": 329.0, + "RMS_SEED": 1329.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.096, + "NTG1": 0.78, + "NTG2": 0.63, + "OWC1": 2517.5, + "OWC2": 2447.3, + "OWC3": 2478.3, + "PARAM1": 0.037, + "PARAM2": 0.6, + "PARAM3": 0.027, + "REAL": 330.0, + "RMS_SEED": 1330.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.11, + "NTG1": 0.83, + "NTG2": 0.63, + "OWC1": 2510.4, + "OWC2": 2434.5, + "OWC3": 2474.8, + "PARAM1": 0.04, + "PARAM2": -0.05, + "PARAM3": 16374.5, + "REAL": 331.0, + "RMS_SEED": 1331.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.84, + "NTG2": 0.57, + "OWC1": 2519.6, + "OWC2": 2444.7, + "OWC3": 2475.2, + "PARAM1": 0.03, + "PARAM2": 0.41, + "PARAM3": 5489190.0, + "REAL": 332.0, + "RMS_SEED": 1332.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.006, + "NTG1": 0.93, + "NTG2": 0.58, + "OWC1": 2537.0, + "OWC2": 2463.4, + "OWC3": 2438.5, + "PARAM1": 0.028, + "PARAM2": 0.48, + "PARAM3": 212.439, + "REAL": 333.0, + "RMS_SEED": 1333.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.93, + "NTG2": 0.57, + "OWC1": 2541.4, + "OWC2": 2471.9, + "OWC3": 2437.6, + "PARAM1": 0.034, + "PARAM2": 0.47, + "PARAM3": 0.0, + "REAL": 334.0, + "RMS_SEED": 1334.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.009, + "NTG1": 0.9, + "NTG2": 0.61, + "OWC1": 2535.7, + "OWC2": 2471.3, + "OWC3": 2451.7, + "PARAM1": 0.036, + "PARAM2": 0.51, + "PARAM3": 1247440.0, + "REAL": 335.0, + "RMS_SEED": 1335.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.007, + "NTG1": 0.85, + "NTG2": 0.62, + "OWC1": 2528.2, + "OWC2": 2455.1, + "OWC3": 2424.6, + "PARAM1": 0.033, + "PARAM2": -0.35, + "PARAM3": 83677.7, + "REAL": 336.0, + "RMS_SEED": 1336.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.92, + "NTG2": 0.62, + "OWC1": 2507.2, + "OWC2": 2453.0, + "OWC3": 2463.8, + "PARAM1": 0.036, + "PARAM2": 0.75, + "PARAM3": 230.34, + "REAL": 337.0, + "RMS_SEED": 1337.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.018, + "NTG1": 0.83, + "NTG2": 0.58, + "OWC1": 2526.8, + "OWC2": 2479.8, + "OWC3": 2439.3, + "PARAM1": 0.042, + "PARAM2": 0.16, + "PARAM3": 40833.4, + "REAL": 338.0, + "RMS_SEED": 1338.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.03, + "NTG1": 0.82, + "NTG2": 0.54, + "OWC1": 2533.8, + "OWC2": 2473.2, + "OWC3": 2445.2, + "PARAM1": 0.026, + "PARAM2": 0.28, + "PARAM3": 286.939, + "REAL": 339.0, + "RMS_SEED": 1339.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.41, + "NTG1": 0.89, + "NTG2": 0.6, + "OWC1": 2509.0, + "OWC2": 2464.6, + "OWC3": 2439.0, + "PARAM1": 0.038, + "PARAM2": 0.36, + "PARAM3": 17969.0, + "REAL": 340.0, + "RMS_SEED": 1340.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.727, + "NTG1": 0.82, + "NTG2": 0.6, + "OWC1": 2508.7, + "OWC2": 2450.6, + "OWC3": 2484.1, + "PARAM1": 0.036, + "PARAM2": -0.14, + "PARAM3": 0.096, + "REAL": 341.0, + "RMS_SEED": 1341.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.78, + "NTG2": 0.56, + "OWC1": 2504.2, + "OWC2": 2465.6, + "OWC3": 2455.3, + "PARAM1": 0.035, + "PARAM2": 0.53, + "PARAM3": 0.0, + "REAL": 342.0, + "RMS_SEED": 1342.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.204, + "NTG1": 0.86, + "NTG2": 0.61, + "OWC1": 2537.6, + "OWC2": 2476.5, + "OWC3": 2443.1, + "PARAM1": 0.032, + "PARAM2": -0.43, + "PARAM3": 22384700.0, + "REAL": 343.0, + "RMS_SEED": 1343.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.107, + "NTG1": 0.91, + "NTG2": 0.62, + "OWC1": 2532.5, + "OWC2": 2481.5, + "OWC3": 2422.9, + "PARAM1": 0.036, + "PARAM2": -0.28, + "PARAM3": 2710810000.0, + "REAL": 344.0, + "RMS_SEED": 1344.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.81, + "NTG2": 0.58, + "OWC1": 2505.7, + "OWC2": 2450.1, + "OWC3": 2453.8, + "PARAM1": 0.033, + "PARAM2": 0.46, + "PARAM3": 0.16, + "REAL": 345.0, + "RMS_SEED": 1345.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.9, + "NTG2": 0.61, + "OWC1": 2522.4, + "OWC2": 2456.7, + "OWC3": 2445.3, + "PARAM1": 0.03, + "PARAM2": -0.82, + "PARAM3": 0.001, + "REAL": 346.0, + "RMS_SEED": 1346.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.88, + "NTG2": 0.62, + "OWC1": 2549.9, + "OWC2": 2477.2, + "OWC3": 2416.5, + "PARAM1": 0.032, + "PARAM2": 0.93, + "PARAM3": 0.034, + "REAL": 347.0, + "RMS_SEED": 1347.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.04, + "NTG1": 0.8, + "NTG2": 0.56, + "OWC1": 2546.4, + "OWC2": 2474.7, + "OWC3": 2422.1, + "PARAM1": 0.034, + "PARAM2": -0.22, + "PARAM3": 0.039, + "REAL": 348.0, + "RMS_SEED": 1348.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.052, + "NTG1": 0.78, + "NTG2": 0.62, + "OWC1": 2542.6, + "OWC2": 2464.1, + "OWC3": 2441.8, + "PARAM1": 0.034, + "PARAM2": 0.73, + "PARAM3": 166683.0, + "REAL": 349.0, + "RMS_SEED": 1349.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.006, + "NTG1": 0.8, + "NTG2": 0.55, + "OWC1": 2534.6, + "OWC2": 2472.1, + "OWC3": 2444.4, + "PARAM1": 0.034, + "PARAM2": 0.62, + "PARAM3": 209.339, + "REAL": 350.0, + "RMS_SEED": 1350.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.086, + "NTG1": 0.87, + "NTG2": 0.62, + "OWC1": 2505.6, + "OWC2": 2475.5, + "OWC3": 2467.7, + "PARAM1": 0.037, + "PARAM2": 0.36, + "PARAM3": 0.88, + "REAL": 351.0, + "RMS_SEED": 1351.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.005, + "NTG1": 0.86, + "NTG2": 0.61, + "OWC1": 2547.5, + "OWC2": 2489.4, + "OWC3": 2404.8, + "PARAM1": 0.037, + "PARAM2": 0.23, + "PARAM3": 372.772, + "REAL": 352.0, + "RMS_SEED": 1352.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.178, + "NTG1": 0.79, + "NTG2": 0.59, + "OWC1": 2520.2, + "OWC2": 2468.5, + "OWC3": 2476.2, + "PARAM1": 0.028, + "PARAM2": 0.55, + "PARAM3": 0.002, + "REAL": 353.0, + "RMS_SEED": 1353.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.07, + "NTG1": 0.96, + "NTG2": 0.58, + "OWC1": 2528.8, + "OWC2": 2477.5, + "OWC3": 2451.4, + "PARAM1": 0.034, + "PARAM2": 0.96, + "PARAM3": 1308.85, + "REAL": 354.0, + "RMS_SEED": 1354.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.88, + "NTG2": 0.57, + "OWC1": 2539.1, + "OWC2": 2452.3, + "OWC3": 2446.1, + "PARAM1": 0.028, + "PARAM2": 0.77, + "PARAM3": 34.534, + "REAL": 355.0, + "RMS_SEED": 1355.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.251, + "NTG1": 0.88, + "NTG2": 0.57, + "OWC1": 2508.8, + "OWC2": 2464.2, + "OWC3": 2448.2, + "PARAM1": 0.034, + "PARAM2": 0.72, + "PARAM3": 3868.37, + "REAL": 356.0, + "RMS_SEED": 1356.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.815, + "NTG1": 0.81, + "NTG2": 0.58, + "OWC1": 2509.5, + "OWC2": 2456.5, + "OWC3": 2462.0, + "PARAM1": 0.04, + "PARAM2": 0.53, + "PARAM3": 0.0, + "REAL": 357.0, + "RMS_SEED": 1357.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.419, + "NTG1": 0.88, + "NTG2": 0.61, + "OWC1": 2524.7, + "OWC2": 2467.0, + "OWC3": 2467.6, + "PARAM1": 0.041, + "PARAM2": 0.04, + "PARAM3": 30498.5, + "REAL": 358.0, + "RMS_SEED": 1358.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.287, + "NTG1": 0.85, + "NTG2": 0.62, + "OWC1": 2514.8, + "OWC2": 2449.0, + "OWC3": 2487.4, + "PARAM1": 0.031, + "PARAM2": 0.38, + "PARAM3": 36.613, + "REAL": 359.0, + "RMS_SEED": 1359.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.012, + "NTG1": 0.88, + "NTG2": 0.59, + "OWC1": 2546.6, + "OWC2": 2468.9, + "OWC3": 2431.1, + "PARAM1": 0.035, + "PARAM2": 0.39, + "PARAM3": 0.15, + "REAL": 360.0, + "RMS_SEED": 1360.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.161, + "NTG1": 0.81, + "NTG2": 0.54, + "OWC1": 2544.0, + "OWC2": 2461.3, + "OWC3": 2447.2, + "PARAM1": 0.033, + "PARAM2": -0.65, + "PARAM3": 3248.35, + "REAL": 361.0, + "RMS_SEED": 1361.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.29, + "NTG1": 0.85, + "NTG2": 0.6, + "OWC1": 2510.6, + "OWC2": 2438.0, + "OWC3": 2492.5, + "PARAM1": 0.027, + "PARAM2": -0.15, + "PARAM3": 0.067, + "REAL": 362.0, + "RMS_SEED": 1362.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.213, + "NTG1": 0.85, + "NTG2": 0.59, + "OWC1": 2504.9, + "OWC2": 2470.3, + "OWC3": 2488.0, + "PARAM1": 0.039, + "PARAM2": -0.28, + "PARAM3": 76.398, + "REAL": 363.0, + "RMS_SEED": 1363.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.8, + "NTG2": 0.61, + "OWC1": 2529.4, + "OWC2": 2456.6, + "OWC3": 2465.6, + "PARAM1": 0.033, + "PARAM2": 0.11, + "PARAM3": 0.394, + "REAL": 364.0, + "RMS_SEED": 1364.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.022, + "NTG1": 0.91, + "NTG2": 0.61, + "OWC1": 2544.3, + "OWC2": 2474.6, + "OWC3": 2434.5, + "PARAM1": 0.032, + "PARAM2": -0.77, + "PARAM3": 0.0, + "REAL": 365.0, + "RMS_SEED": 1365.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.79, + "NTG2": 0.57, + "OWC1": 2545.1, + "OWC2": 2483.9, + "OWC3": 2431.9, + "PARAM1": 0.034, + "PARAM2": -0.53, + "PARAM3": 0.001, + "REAL": 366.0, + "RMS_SEED": 1366.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.502, + "NTG1": 0.81, + "NTG2": 0.6, + "OWC1": 2538.5, + "OWC2": 2466.4, + "OWC3": 2444.0, + "PARAM1": 0.034, + "PARAM2": 0.04, + "PARAM3": 30.804, + "REAL": 367.0, + "RMS_SEED": 1367.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.007, + "NTG1": 0.82, + "NTG2": 0.6, + "OWC1": 2530.4, + "OWC2": 2483.6, + "OWC3": 2434.8, + "PARAM1": 0.03, + "PARAM2": 0.47, + "PARAM3": 0.0, + "REAL": 368.0, + "RMS_SEED": 1368.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.83, + "NTG2": 0.57, + "OWC1": 2535.3, + "OWC2": 2471.5, + "OWC3": 2447.7, + "PARAM1": 0.038, + "PARAM2": -0.01, + "PARAM3": 2.832, + "REAL": 369.0, + "RMS_SEED": 1369.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.327, + "NTG1": 0.85, + "NTG2": 0.54, + "OWC1": 2535.2, + "OWC2": 2473.9, + "OWC3": 2425.8, + "PARAM1": 0.039, + "PARAM2": -0.29, + "PARAM3": 0.001, + "REAL": 370.0, + "RMS_SEED": 1370.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.006, + "NTG1": 0.86, + "NTG2": 0.6, + "OWC1": 2502.2, + "OWC2": 2448.4, + "OWC3": 2482.0, + "PARAM1": 0.033, + "PARAM2": 0.66, + "PARAM3": 1.202, + "REAL": 371.0, + "RMS_SEED": 1371.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.045, + "NTG1": 0.87, + "NTG2": 0.62, + "OWC1": 2501.9, + "OWC2": 2482.9, + "OWC3": 2465.7, + "PARAM1": 0.038, + "PARAM2": 0.86, + "PARAM3": 46.055, + "REAL": 372.0, + "RMS_SEED": 1372.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.97, + "NTG2": 0.62, + "OWC1": 2537.5, + "OWC2": 2468.2, + "OWC3": 2457.6, + "PARAM1": 0.035, + "PARAM2": -0.6, + "PARAM3": 28807800000.0, + "REAL": 373.0, + "RMS_SEED": 1373.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.006, + "NTG1": 0.8, + "NTG2": 0.63, + "OWC1": 2523.7, + "OWC2": 2471.0, + "OWC3": 2443.7, + "PARAM1": 0.032, + "PARAM2": -0.95, + "PARAM3": 0.02, + "REAL": 374.0, + "RMS_SEED": 1374.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.075, + "NTG1": 0.88, + "NTG2": 0.59, + "OWC1": 2512.3, + "OWC2": 2475.3, + "OWC3": 2461.4, + "PARAM1": 0.035, + "PARAM2": 0.14, + "PARAM3": 1895.11, + "REAL": 375.0, + "RMS_SEED": 1375.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.893, + "NTG1": 0.79, + "NTG2": 0.64, + "OWC1": 2548.6, + "OWC2": 2497.3, + "OWC3": 2408.9, + "PARAM1": 0.038, + "PARAM2": -0.47, + "PARAM3": 18.707, + "REAL": 376.0, + "RMS_SEED": 1376.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.198, + "NTG1": 0.77, + "NTG2": 0.57, + "OWC1": 2533.4, + "OWC2": 2464.4, + "OWC3": 2456.1, + "PARAM1": 0.032, + "PARAM2": 0.1, + "PARAM3": 0.0, + "REAL": 377.0, + "RMS_SEED": 1377.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.277, + "NTG1": 0.8, + "NTG2": 0.57, + "OWC1": 2513.3, + "OWC2": 2454.1, + "OWC3": 2455.1, + "PARAM1": 0.033, + "PARAM2": -0.98, + "PARAM3": 550197.0, + "REAL": 378.0, + "RMS_SEED": 1378.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.89, + "NTG2": 0.6, + "OWC1": 2549.7, + "OWC2": 2486.1, + "OWC3": 2442.9, + "PARAM1": 0.032, + "PARAM2": 0.8, + "PARAM3": 0.014, + "REAL": 379.0, + "RMS_SEED": 1379.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.048, + "NTG1": 0.9, + "NTG2": 0.58, + "OWC1": 2501.0, + "OWC2": 2438.6, + "OWC3": 2491.6, + "PARAM1": 0.035, + "PARAM2": -0.81, + "PARAM3": 7.046, + "REAL": 380.0, + "RMS_SEED": 1380.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.014, + "NTG1": 0.82, + "NTG2": 0.61, + "OWC1": 2536.2, + "OWC2": 2496.7, + "OWC3": 2425.6, + "PARAM1": 0.043, + "PARAM2": 0.85, + "PARAM3": 1.371, + "REAL": 381.0, + "RMS_SEED": 1381.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.105, + "NTG1": 0.78, + "NTG2": 0.55, + "OWC1": 2506.6, + "OWC2": 2441.8, + "OWC3": 2457.9, + "PARAM1": 0.035, + "PARAM2": 0.59, + "PARAM3": 0.0, + "REAL": 382.0, + "RMS_SEED": 1382.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.851, + "NTG1": 0.81, + "NTG2": 0.56, + "OWC1": 2548.1, + "OWC2": 2495.7, + "OWC3": 2429.0, + "PARAM1": 0.032, + "PARAM2": -0.4, + "PARAM3": 0.766, + "REAL": 383.0, + "RMS_SEED": 1383.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.057, + "NTG1": 0.84, + "NTG2": 0.6, + "OWC1": 2522.4, + "OWC2": 2473.6, + "OWC3": 2430.9, + "PARAM1": 0.035, + "PARAM2": 0.39, + "PARAM3": 46070.0, + "REAL": 384.0, + "RMS_SEED": 1384.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.007, + "NTG1": 0.77, + "NTG2": 0.61, + "OWC1": 2527.4, + "OWC2": 2441.2, + "OWC3": 2470.4, + "PARAM1": 0.032, + "PARAM2": -0.15, + "PARAM3": 52.829, + "REAL": 385.0, + "RMS_SEED": 1385.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.348, + "NTG1": 0.84, + "NTG2": 0.59, + "OWC1": 2534.3, + "OWC2": 2482.4, + "OWC3": 2432.6, + "PARAM1": 0.038, + "PARAM2": -0.87, + "PARAM3": 0.053, + "REAL": 386.0, + "RMS_SEED": 1386.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.89, + "NTG2": 0.64, + "OWC1": 2547.4, + "OWC2": 2492.8, + "OWC3": 2414.3, + "PARAM1": 0.034, + "PARAM2": -0.37, + "PARAM3": 6.413, + "REAL": 387.0, + "RMS_SEED": 1387.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.008, + "NTG1": 0.87, + "NTG2": 0.59, + "OWC1": 2533.9, + "OWC2": 2463.1, + "OWC3": 2444.8, + "PARAM1": 0.029, + "PARAM2": -0.57, + "PARAM3": 0.049, + "REAL": 388.0, + "RMS_SEED": 1388.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.005, + "NTG1": 0.88, + "NTG2": 0.56, + "OWC1": 2548.3, + "OWC2": 2472.6, + "OWC3": 2456.3, + "PARAM1": 0.036, + "PARAM2": -0.04, + "PARAM3": 0.0, + "REAL": 389.0, + "RMS_SEED": 1389.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.043, + "NTG1": 0.97, + "NTG2": 0.58, + "OWC1": 2521.0, + "OWC2": 2467.6, + "OWC3": 2440.7, + "PARAM1": 0.037, + "PARAM2": -0.26, + "PARAM3": 13868300.0, + "REAL": 390.0, + "RMS_SEED": 1390.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.175, + "NTG1": 0.93, + "NTG2": 0.58, + "OWC1": 2509.0, + "OWC2": 2445.9, + "OWC3": 2486.3, + "PARAM1": 0.026, + "PARAM2": 0.37, + "PARAM3": 5.739, + "REAL": 391.0, + "RMS_SEED": 1391.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.224, + "NTG1": 0.85, + "NTG2": 0.53, + "OWC1": 2545.3, + "OWC2": 2459.7, + "OWC3": 2433.4, + "PARAM1": 0.039, + "PARAM2": -0.59, + "PARAM3": 0.0, + "REAL": 392.0, + "RMS_SEED": 1392.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.436, + "NTG1": 0.82, + "NTG2": 0.62, + "OWC1": 2513.5, + "OWC2": 2472.4, + "OWC3": 2454.6, + "PARAM1": 0.034, + "PARAM2": 0.12, + "PARAM3": 0.0, + "REAL": 393.0, + "RMS_SEED": 1393.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.8, + "NTG2": 0.6, + "OWC1": 2526.1, + "OWC2": 2466.7, + "OWC3": 2484.5, + "PARAM1": 0.033, + "PARAM2": 0.89, + "PARAM3": 311.391, + "REAL": 394.0, + "RMS_SEED": 1394.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.451, + "NTG1": 0.89, + "NTG2": 0.56, + "OWC1": 2521.8, + "OWC2": 2476.0, + "OWC3": 2450.8, + "PARAM1": 0.043, + "PARAM2": 0.8, + "PARAM3": 502967.0, + "REAL": 395.0, + "RMS_SEED": 1395.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.073, + "NTG1": 0.86, + "NTG2": 0.61, + "OWC1": 2528.8, + "OWC2": 2485.4, + "OWC3": 2440.1, + "PARAM1": 0.032, + "PARAM2": 0.52, + "PARAM3": 0.026, + "REAL": 396.0, + "RMS_SEED": 1396.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.09, + "NTG1": 0.81, + "NTG2": 0.58, + "OWC1": 2515.1, + "OWC2": 2465.5, + "OWC3": 2446.6, + "PARAM1": 0.031, + "PARAM2": -0.64, + "PARAM3": 9396.82, + "REAL": 397.0, + "RMS_SEED": 1397.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.12, + "NTG1": 0.83, + "NTG2": 0.61, + "OWC1": 2531.7, + "OWC2": 2474.8, + "OWC3": 2422.2, + "PARAM1": 0.038, + "PARAM2": 0.07, + "PARAM3": 0.0, + "REAL": 398.0, + "RMS_SEED": 1398.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.38, + "NTG1": 0.87, + "NTG2": 0.6, + "OWC1": 2546.0, + "OWC2": 2455.0, + "OWC3": 2445.9, + "PARAM1": 0.036, + "PARAM2": 0.32, + "PARAM3": 1824950000.0, + "REAL": 399.0, + "RMS_SEED": 1399.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.003, + "NTG1": 0.8, + "NTG2": 0.55, + "OWC1": 2516.4, + "OWC2": 2468.0, + "OWC3": 2466.9, + "PARAM1": 0.036, + "PARAM2": 0.26, + "PARAM3": 0.0, + "REAL": 400.0, + "RMS_SEED": 1400.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.005, + "NTG1": 0.87, + "NTG2": 0.55, + "OWC1": 2527.8, + "OWC2": 2462.2, + "OWC3": 2431.7, + "PARAM1": 0.034, + "PARAM2": -0.42, + "PARAM3": 92.088, + "REAL": 401.0, + "RMS_SEED": 1401.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.049, + "NTG1": 0.86, + "NTG2": 0.57, + "OWC1": 2515.4, + "OWC2": 2456.9, + "OWC3": 2464.0, + "PARAM1": 0.034, + "PARAM2": 0.58, + "PARAM3": 0.0, + "REAL": 402.0, + "RMS_SEED": 1402.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.054, + "NTG1": 0.78, + "NTG2": 0.62, + "OWC1": 2536.3, + "OWC2": 2466.9, + "OWC3": 2461.9, + "PARAM1": 0.035, + "PARAM2": -0.63, + "PARAM3": 409930.0, + "REAL": 403.0, + "RMS_SEED": 1403.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.91, + "NTG2": 0.63, + "OWC1": 2548.4, + "OWC2": 2493.1, + "OWC3": 2407.9, + "PARAM1": 0.036, + "PARAM2": 0.79, + "PARAM3": 14647.7, + "REAL": 404.0, + "RMS_SEED": 1404.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.021, + "NTG1": 0.88, + "NTG2": 0.6, + "OWC1": 2548.8, + "OWC2": 2475.6, + "OWC3": 2450.1, + "PARAM1": 0.035, + "PARAM2": -0.45, + "PARAM3": 2620130.0, + "REAL": 405.0, + "RMS_SEED": 1405.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.181, + "NTG1": 0.81, + "NTG2": 0.56, + "OWC1": 2549.0, + "OWC2": 2465.8, + "OWC3": 2432.4, + "PARAM1": 0.03, + "PARAM2": -0.34, + "PARAM3": 44005.0, + "REAL": 406.0, + "RMS_SEED": 1406.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.011, + "NTG1": 0.84, + "NTG2": 0.55, + "OWC1": 2532.2, + "OWC2": 2480.3, + "OWC3": 2435.4, + "PARAM1": 0.037, + "PARAM2": -0.18, + "PARAM3": 0.0, + "REAL": 407.0, + "RMS_SEED": 1407.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.013, + "NTG1": 0.82, + "NTG2": 0.59, + "OWC1": 2514.1, + "OWC2": 2462.1, + "OWC3": 2485.5, + "PARAM1": 0.04, + "PARAM2": 0.42, + "PARAM3": 759399.0, + "REAL": 408.0, + "RMS_SEED": 1408.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.003, + "NTG1": 0.83, + "NTG2": 0.61, + "OWC1": 2549.2, + "OWC2": 2489.8, + "OWC3": 2424.2, + "PARAM1": 0.035, + "PARAM2": 0.0, + "PARAM3": 0.0, + "REAL": 409.0, + "RMS_SEED": 1409.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.043, + "NTG1": 0.86, + "NTG2": 0.62, + "OWC1": 2510.3, + "OWC2": 2476.6, + "OWC3": 2431.2, + "PARAM1": 0.037, + "PARAM2": 0.19, + "PARAM3": 17.485, + "REAL": 410.0, + "RMS_SEED": 1410.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.027, + "NTG1": 0.85, + "NTG2": 0.64, + "OWC1": 2524.5, + "OWC2": 2463.0, + "OWC3": 2467.3, + "PARAM1": 0.036, + "PARAM2": -0.52, + "PARAM3": 0.0, + "REAL": 411.0, + "RMS_SEED": 1411.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.81, + "NTG2": 0.56, + "OWC1": 2523.6, + "OWC2": 2469.7, + "OWC3": 2445.7, + "PARAM1": 0.036, + "PARAM2": -0.12, + "PARAM3": 0.451, + "REAL": 412.0, + "RMS_SEED": 1412.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.463, + "NTG1": 0.84, + "NTG2": 0.58, + "OWC1": 2517.3, + "OWC2": 2469.4, + "OWC3": 2452.9, + "PARAM1": 0.038, + "PARAM2": -0.89, + "PARAM3": 0.0, + "REAL": 413.0, + "RMS_SEED": 1413.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.3, + "NTG1": 0.88, + "NTG2": 0.62, + "OWC1": 2545.2, + "OWC2": 2460.3, + "OWC3": 2443.8, + "PARAM1": 0.034, + "PARAM2": -0.93, + "PARAM3": 0.0, + "REAL": 414.0, + "RMS_SEED": 1414.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.89, + "NTG2": 0.55, + "OWC1": 2534.7, + "OWC2": 2494.7, + "OWC3": 2427.7, + "PARAM1": 0.039, + "PARAM2": 0.76, + "PARAM3": 13.001, + "REAL": 415.0, + "RMS_SEED": 1415.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.491, + "NTG1": 0.87, + "NTG2": 0.62, + "OWC1": 2517.0, + "OWC2": 2452.3, + "OWC3": 2457.7, + "PARAM1": 0.031, + "PARAM2": 0.71, + "PARAM3": 0.0, + "REAL": 416.0, + "RMS_SEED": 1416.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.7, + "NTG1": 0.79, + "NTG2": 0.58, + "OWC1": 2541.8, + "OWC2": 2461.1, + "OWC3": 2428.1, + "PARAM1": 0.032, + "PARAM2": -0.5, + "PARAM3": 867.507, + "REAL": 417.0, + "RMS_SEED": 1417.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.212, + "NTG1": 0.93, + "NTG2": 0.59, + "OWC1": 2524.6, + "OWC2": 2477.4, + "OWC3": 2453.0, + "PARAM1": 0.034, + "PARAM2": -0.23, + "PARAM3": 0.0, + "REAL": 418.0, + "RMS_SEED": 1418.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.004, + "NTG1": 0.78, + "NTG2": 0.53, + "OWC1": 2520.2, + "OWC2": 2464.8, + "OWC3": 2442.6, + "PARAM1": 0.031, + "PARAM2": -0.88, + "PARAM3": 44.242, + "REAL": 419.0, + "RMS_SEED": 1419.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.131, + "NTG1": 0.94, + "NTG2": 0.64, + "OWC1": 2514.4, + "OWC2": 2460.4, + "OWC3": 2472.4, + "PARAM1": 0.033, + "PARAM2": 0.19, + "PARAM3": 18.06, + "REAL": 420.0, + "RMS_SEED": 1420.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.083, + "NTG1": 0.84, + "NTG2": 0.57, + "OWC1": 2511.5, + "OWC2": 2457.3, + "OWC3": 2471.9, + "PARAM1": 0.035, + "PARAM2": -0.18, + "PARAM3": 58.194, + "REAL": 421.0, + "RMS_SEED": 1421.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.034, + "NTG1": 0.88, + "NTG2": 0.56, + "OWC1": 2525.0, + "OWC2": 2452.8, + "OWC3": 2463.3, + "PARAM1": 0.037, + "PARAM2": -0.13, + "PARAM3": 261136.0, + "REAL": 422.0, + "RMS_SEED": 1422.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.254, + "NTG1": 0.96, + "NTG2": 0.61, + "OWC1": 2522.0, + "OWC2": 2479.5, + "OWC3": 2440.4, + "PARAM1": 0.028, + "PARAM2": 0.09, + "PARAM3": 0.014, + "REAL": 423.0, + "RMS_SEED": 1423.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.093, + "NTG1": 0.8, + "NTG2": 0.64, + "OWC1": 2520.7, + "OWC2": 2455.8, + "OWC3": 2456.9, + "PARAM1": 0.03, + "PARAM2": 0.57, + "PARAM3": 0.118, + "REAL": 424.0, + "RMS_SEED": 1424.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.82, + "NTG2": 0.58, + "OWC1": 2543.9, + "OWC2": 2470.6, + "OWC3": 2426.8, + "PARAM1": 0.037, + "PARAM2": -0.3, + "PARAM3": 310581.0, + "REAL": 425.0, + "RMS_SEED": 1425.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.04, + "NTG1": 0.81, + "NTG2": 0.57, + "OWC1": 2504.6, + "OWC2": 2461.8, + "OWC3": 2490.2, + "PARAM1": 0.031, + "PARAM2": -0.13, + "PARAM3": 31.235, + "REAL": 426.0, + "RMS_SEED": 1426.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.017, + "NTG1": 0.86, + "NTG2": 0.58, + "OWC1": 2515.9, + "OWC2": 2472.8, + "OWC3": 2454.1, + "PARAM1": 0.041, + "PARAM2": 0.17, + "PARAM3": 102650000.0, + "REAL": 427.0, + "RMS_SEED": 1427.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.155, + "NTG1": 0.77, + "NTG2": 0.58, + "OWC1": 2527.2, + "OWC2": 2482.5, + "OWC3": 2452.4, + "PARAM1": 0.032, + "PARAM2": 0.29, + "PARAM3": 4842770.0, + "REAL": 428.0, + "RMS_SEED": 1428.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.85, + "NTG2": 0.6, + "OWC1": 2512.1, + "OWC2": 2444.5, + "OWC3": 2487.0, + "PARAM1": 0.04, + "PARAM2": 0.12, + "PARAM3": 119614000.0, + "REAL": 429.0, + "RMS_SEED": 1429.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.975, + "NTG1": 0.88, + "NTG2": 0.56, + "OWC1": 2545.8, + "OWC2": 2472.6, + "OWC3": 2442.5, + "PARAM1": 0.033, + "PARAM2": -0.92, + "PARAM3": 0.584, + "REAL": 430.0, + "RMS_SEED": 1430.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.01, + "NTG1": 0.86, + "NTG2": 0.6, + "OWC1": 2534.2, + "OWC2": 2449.6, + "OWC3": 2480.5, + "PARAM1": 0.027, + "PARAM2": -0.99, + "PARAM3": 259.794, + "REAL": 431.0, + "RMS_SEED": 1431.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.036, + "NTG1": 0.91, + "NTG2": 0.63, + "OWC1": 2540.4, + "OWC2": 2448.9, + "OWC3": 2459.4, + "PARAM1": 0.041, + "PARAM2": -0.62, + "PARAM3": 0.001, + "REAL": 432.0, + "RMS_SEED": 1432.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.003, + "NTG1": 0.87, + "NTG2": 0.56, + "OWC1": 2504.9, + "OWC2": 2455.4, + "OWC3": 2448.5, + "PARAM1": 0.041, + "PARAM2": -0.16, + "PARAM3": 0.15, + "REAL": 433.0, + "RMS_SEED": 1433.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.509, + "NTG1": 0.78, + "NTG2": 0.57, + "OWC1": 2521.2, + "OWC2": 2475.7, + "OWC3": 2425.4, + "PARAM1": 0.037, + "PARAM2": -0.1, + "PARAM3": 0.84, + "REAL": 434.0, + "RMS_SEED": 1434.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.84, + "NTG2": 0.59, + "OWC1": 2537.7, + "OWC2": 2445.4, + "OWC3": 2446.5, + "PARAM1": 0.033, + "PARAM2": -0.27, + "PARAM3": 0.0, + "REAL": 435.0, + "RMS_SEED": 1435.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.004, + "NTG1": 0.8, + "NTG2": 0.6, + "OWC1": 2529.3, + "OWC2": 2462.5, + "OWC3": 2464.1, + "PARAM1": 0.033, + "PARAM2": 0.74, + "PARAM3": 0.0, + "REAL": 436.0, + "RMS_SEED": 1436.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.019, + "NTG1": 0.82, + "NTG2": 0.6, + "OWC1": 2541.1, + "OWC2": 2465.9, + "OWC3": 2426.4, + "PARAM1": 0.039, + "PARAM2": -0.48, + "PARAM3": 17014300.0, + "REAL": 437.0, + "RMS_SEED": 1437.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.006, + "NTG1": 0.81, + "NTG2": 0.59, + "OWC1": 2532.4, + "OWC2": 2456.4, + "OWC3": 2444.7, + "PARAM1": 0.033, + "PARAM2": 0.22, + "PARAM3": 414621000000.0, + "REAL": 438.0, + "RMS_SEED": 1438.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.003, + "NTG1": 0.82, + "NTG2": 0.53, + "OWC1": 2536.5, + "OWC2": 2481.7, + "OWC3": 2452.6, + "PARAM1": 0.03, + "PARAM2": -0.49, + "PARAM3": 0.506, + "REAL": 439.0, + "RMS_SEED": 1439.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.091, + "NTG1": 0.8, + "NTG2": 0.62, + "OWC1": 2516.3, + "OWC2": 2473.9, + "OWC3": 2440.2, + "PARAM1": 0.029, + "PARAM2": 0.7, + "PARAM3": 41.612, + "REAL": 440.0, + "RMS_SEED": 1440.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.02, + "NTG1": 0.82, + "NTG2": 0.56, + "OWC1": 2503.2, + "OWC2": 2461.5, + "OWC3": 2479.4, + "PARAM1": 0.039, + "PARAM2": -0.95, + "PARAM3": 679.412, + "REAL": 441.0, + "RMS_SEED": 1441.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.8, + "NTG2": 0.62, + "OWC1": 2549.3, + "OWC2": 2488.9, + "OWC3": 2403.0, + "PARAM1": 0.039, + "PARAM2": 0.79, + "PARAM3": 6784540.0, + "REAL": 442.0, + "RMS_SEED": 1442.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.027, + "NTG1": 0.9, + "NTG2": 0.59, + "OWC1": 2544.9, + "OWC2": 2444.1, + "OWC3": 2451.8, + "PARAM1": 0.031, + "PARAM2": -0.29, + "PARAM3": 24.875, + "REAL": 443.0, + "RMS_SEED": 1443.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.009, + "NTG1": 0.86, + "NTG2": 0.59, + "OWC1": 2523.9, + "OWC2": 2455.7, + "OWC3": 2455.4, + "PARAM1": 0.036, + "PARAM2": -0.5, + "PARAM3": 54780.1, + "REAL": 444.0, + "RMS_SEED": 1444.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.84, + "NTG2": 0.58, + "OWC1": 2530.7, + "OWC2": 2462.6, + "OWC3": 2449.9, + "PARAM1": 0.04, + "PARAM2": -0.2, + "PARAM3": 9.595, + "REAL": 445.0, + "RMS_SEED": 1445.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.026, + "NTG1": 0.8, + "NTG2": 0.59, + "OWC1": 2542.4, + "OWC2": 2478.6, + "OWC3": 2417.7, + "PARAM1": 0.043, + "PARAM2": -0.81, + "PARAM3": 0.01, + "REAL": 446.0, + "RMS_SEED": 1446.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.351, + "NTG1": 0.87, + "NTG2": 0.6, + "OWC1": 2505.5, + "OWC2": 2485.2, + "OWC3": 2451.5, + "PARAM1": 0.036, + "PARAM2": 0.99, + "PARAM3": 0.0, + "REAL": 447.0, + "RMS_SEED": 1447.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.427, + "NTG1": 0.84, + "NTG2": 0.54, + "OWC1": 2527.7, + "OWC2": 2477.0, + "OWC3": 2421.8, + "PARAM1": 0.034, + "PARAM2": -0.97, + "PARAM3": 0.009, + "REAL": 448.0, + "RMS_SEED": 1448.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.163, + "NTG1": 0.94, + "NTG2": 0.56, + "OWC1": 2526.6, + "OWC2": 2465.1, + "OWC3": 2454.0, + "PARAM1": 0.034, + "PARAM2": -0.05, + "PARAM3": 0.003, + "REAL": 449.0, + "RMS_SEED": 1449.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.171, + "NTG1": 0.96, + "NTG2": 0.6, + "OWC1": 2514.9, + "OWC2": 2463.6, + "OWC3": 2451.6, + "PARAM1": 0.033, + "PARAM2": 0.77, + "PARAM3": 0.017, + "REAL": 450.0, + "RMS_SEED": 1450.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.397, + "NTG1": 0.9, + "NTG2": 0.56, + "OWC1": 2542.0, + "OWC2": 2487.4, + "OWC3": 2435.3, + "PARAM1": 0.037, + "PARAM2": -0.63, + "PARAM3": 0.003, + "REAL": 451.0, + "RMS_SEED": 1451.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.484, + "NTG1": 0.91, + "NTG2": 0.58, + "OWC1": 2529.8, + "OWC2": 2467.3, + "OWC3": 2449.5, + "PARAM1": 0.043, + "PARAM2": -0.66, + "PARAM3": 178966000.0, + "REAL": 452.0, + "RMS_SEED": 1452.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.013, + "NTG1": 0.77, + "NTG2": 0.55, + "OWC1": 2519.9, + "OWC2": 2452.1, + "OWC3": 2464.6, + "PARAM1": 0.037, + "PARAM2": -0.42, + "PARAM3": 0.0, + "REAL": 453.0, + "RMS_SEED": 1453.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.085, + "NTG1": 0.83, + "NTG2": 0.6, + "OWC1": 2527.5, + "OWC2": 2486.1, + "OWC3": 2444.4, + "PARAM1": 0.039, + "PARAM2": -0.45, + "PARAM3": 0.046, + "REAL": 454.0, + "RMS_SEED": 1454.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.79, + "NTG2": 0.59, + "OWC1": 2547.8, + "OWC2": 2491.6, + "OWC3": 2422.7, + "PARAM1": 0.034, + "PARAM2": 0.06, + "PARAM3": 0.04, + "REAL": 455.0, + "RMS_SEED": 1455.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.008, + "NTG1": 0.95, + "NTG2": 0.63, + "OWC1": 2529.2, + "OWC2": 2478.9, + "OWC3": 2432.5, + "PARAM1": 0.026, + "PARAM2": 0.7, + "PARAM3": 141.136, + "REAL": 456.0, + "RMS_SEED": 1456.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.005, + "NTG1": 0.98, + "NTG2": 0.6, + "OWC1": 2512.9, + "OWC2": 2463.1, + "OWC3": 2431.6, + "PARAM1": 0.031, + "PARAM2": -0.45, + "PARAM3": 0.0, + "REAL": 457.0, + "RMS_SEED": 1457.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.047, + "NTG1": 0.9, + "NTG2": 0.59, + "OWC1": 2518.7, + "OWC2": 2476.4, + "OWC3": 2439.8, + "PARAM1": 0.033, + "PARAM2": 0.91, + "PARAM3": 0.0, + "REAL": 458.0, + "RMS_SEED": 1458.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.002, + "NTG1": 0.79, + "NTG2": 0.61, + "OWC1": 2529.6, + "OWC2": 2455.4, + "OWC3": 2437.9, + "PARAM1": 0.027, + "PARAM2": 0.84, + "PARAM3": 0.0, + "REAL": 459.0, + "RMS_SEED": 1459.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.14, + "NTG1": 0.79, + "NTG2": 0.52, + "OWC1": 2519.4, + "OWC2": 2452.1, + "OWC3": 2461.3, + "PARAM1": 0.03, + "PARAM2": -0.51, + "PARAM3": 0.0, + "REAL": 460.0, + "RMS_SEED": 1460.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.85, + "NTG2": 0.61, + "OWC1": 2518.9, + "OWC2": 2446.7, + "OWC3": 2477.5, + "PARAM1": 0.038, + "PARAM2": -0.07, + "PARAM3": 495.519, + "REAL": 461.0, + "RMS_SEED": 1461.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.003, + "NTG1": 0.92, + "NTG2": 0.56, + "OWC1": 2519.5, + "OWC2": 2485.9, + "OWC3": 2440.9, + "PARAM1": 0.038, + "PARAM2": -0.65, + "PARAM3": 0.022, + "REAL": 462.0, + "RMS_SEED": 1462.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.078, + "NTG1": 0.76, + "NTG2": 0.62, + "OWC1": 2500.2, + "OWC2": 2433.6, + "OWC3": 2488.6, + "PARAM1": 0.035, + "PARAM2": 0.05, + "PARAM3": 998.174, + "REAL": 463.0, + "RMS_SEED": 1463.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.87, + "NTG2": 0.58, + "OWC1": 2543.7, + "OWC2": 2476.0, + "OWC3": 2442.3, + "PARAM1": 0.037, + "PARAM2": 0.67, + "PARAM3": 0.0, + "REAL": 464.0, + "RMS_SEED": 1464.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.007, + "NTG1": 0.92, + "NTG2": 0.58, + "OWC1": 2507.4, + "OWC2": 2462.7, + "OWC3": 2479.6, + "PARAM1": 0.033, + "PARAM2": -0.34, + "PARAM3": 0.013, + "REAL": 465.0, + "RMS_SEED": 1465.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.074, + "NTG1": 0.92, + "NTG2": 0.54, + "OWC1": 2532.3, + "OWC2": 2448.8, + "OWC3": 2463.1, + "PARAM1": 0.038, + "PARAM2": 0.98, + "PARAM3": 59130.5, + "REAL": 466.0, + "RMS_SEED": 1466.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.001, + "NTG1": 0.95, + "NTG2": 0.59, + "OWC1": 2542.3, + "OWC2": 2478.3, + "OWC3": 2410.5, + "PARAM1": 0.042, + "PARAM2": -0.55, + "PARAM3": 0.18, + "REAL": 467.0, + "RMS_SEED": 1467.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.008, + "NTG1": 0.85, + "NTG2": 0.63, + "OWC1": 2531.8, + "OWC2": 2443.4, + "OWC3": 2449.4, + "PARAM1": 0.035, + "PARAM2": -0.08, + "PARAM3": 626.263, + "REAL": 468.0, + "RMS_SEED": 1468.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.044, + "NTG1": 0.82, + "NTG2": 0.57, + "OWC1": 2509.3, + "OWC2": 2460.7, + "OWC3": 2459.2, + "PARAM1": 0.031, + "PARAM2": 0.31, + "PARAM3": 0.002, + "REAL": 469.0, + "RMS_SEED": 1469.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.209, + "NTG1": 0.79, + "NTG2": 0.62, + "OWC1": 2530.5, + "OWC2": 2474.6, + "OWC3": 2433.6, + "PARAM1": 0.035, + "PARAM2": 0.86, + "PARAM3": 0.48, + "REAL": 470.0, + "RMS_SEED": 1470.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.019, + "NTG1": 0.78, + "NTG2": 0.58, + "OWC1": 2539.9, + "OWC2": 2479.6, + "OWC3": 2418.8, + "PARAM1": 0.036, + "PARAM2": -0.14, + "PARAM3": 2277410.0, + "REAL": 471.0, + "RMS_SEED": 1471.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.001, + "NTG1": 0.8, + "NTG2": 0.59, + "OWC1": 2538.2, + "OWC2": 2477.3, + "OWC3": 2449.4, + "PARAM1": 0.029, + "PARAM2": 0.69, + "PARAM3": 0.019, + "REAL": 472.0, + "RMS_SEED": 1472.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.028, + "NTG1": 0.82, + "NTG2": 0.57, + "OWC1": 2535.5, + "OWC2": 2466.6, + "OWC3": 2424.8, + "PARAM1": 0.035, + "PARAM2": -0.36, + "PARAM3": 9542600.0, + "REAL": 473.0, + "RMS_SEED": 1473.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.81, + "NTG2": 0.62, + "OWC1": 2503.9, + "OWC2": 2440.9, + "OWC3": 2478.8, + "PARAM1": 0.034, + "PARAM2": 0.43, + "PARAM3": 0.112, + "REAL": 474.0, + "RMS_SEED": 1474.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.112, + "NTG1": 0.83, + "NTG2": 0.57, + "OWC1": 2515.5, + "OWC2": 2453.4, + "OWC3": 2441.8, + "PARAM1": 0.038, + "PARAM2": -0.9, + "PARAM3": 0.0, + "REAL": 475.0, + "RMS_SEED": 1475.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.001, + "NTG1": 0.91, + "NTG2": 0.59, + "OWC1": 2535.7, + "OWC2": 2470.2, + "OWC3": 2438.2, + "PARAM1": 0.03, + "PARAM2": -0.8, + "PARAM3": 0.534, + "REAL": 476.0, + "RMS_SEED": 1476.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.037, + "NTG1": 0.82, + "NTG2": 0.6, + "OWC1": 2534.8, + "OWC2": 2479.8, + "OWC3": 2450.7, + "PARAM1": 0.034, + "PARAM2": -0.2, + "PARAM3": 0.0, + "REAL": 477.0, + "RMS_SEED": 1477.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.029, + "NTG1": 0.76, + "NTG2": 0.57, + "OWC1": 2505.3, + "OWC2": 2449.9, + "OWC3": 2473.5, + "PARAM1": 0.031, + "PARAM2": 0.17, + "PARAM3": 0.697, + "REAL": 478.0, + "RMS_SEED": 1478.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.02, + "NTG1": 0.91, + "NTG2": 0.62, + "OWC1": 2548.0, + "OWC2": 2471.4, + "OWC3": 2405.7, + "PARAM1": 0.038, + "PARAM2": -0.13, + "PARAM3": 0.0, + "REAL": 479.0, + "RMS_SEED": 1479.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.059, + "NTG1": 0.79, + "NTG2": 0.61, + "OWC1": 2545.8, + "OWC2": 2496.3, + "OWC3": 2412.9, + "PARAM1": 0.028, + "PARAM2": -0.06, + "PARAM3": 0.025, + "REAL": 480.0, + "RMS_SEED": 1480.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.763, + "NTG1": 0.79, + "NTG2": 0.6, + "OWC1": 2509.6, + "OWC2": 2467.5, + "OWC3": 2458.3, + "PARAM1": 0.027, + "PARAM2": -0.56, + "PARAM3": 0.0, + "REAL": 481.0, + "RMS_SEED": 1481.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.624, + "NTG1": 0.84, + "NTG2": 0.64, + "OWC1": 2535.0, + "OWC2": 2471.1, + "OWC3": 2443.0, + "PARAM1": 0.031, + "PARAM2": -0.0, + "PARAM3": 4.011, + "REAL": 482.0, + "RMS_SEED": 1482.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.013, + "NTG1": 0.84, + "NTG2": 0.54, + "OWC1": 2507.7, + "OWC2": 2450.4, + "OWC3": 2472.7, + "PARAM1": 0.036, + "PARAM2": -0.61, + "PARAM3": 1.565, + "REAL": 483.0, + "RMS_SEED": 1483.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.014, + "NTG1": 0.86, + "NTG2": 0.61, + "OWC1": 2525.0, + "OWC2": 2463.9, + "OWC3": 2429.2, + "PARAM1": 0.04, + "PARAM2": 0.44, + "PARAM3": 1783160.0, + "REAL": 484.0, + "RMS_SEED": 1484.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.004, + "NTG1": 0.86, + "NTG2": 0.56, + "OWC1": 2531.5, + "OWC2": 2469.0, + "OWC3": 2441.1, + "PARAM1": 0.03, + "PARAM2": 0.45, + "PARAM3": 55.897, + "REAL": 485.0, + "RMS_SEED": 1485.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.565, + "NTG1": 0.84, + "NTG2": 0.57, + "OWC1": 2544.1, + "OWC2": 2463.5, + "OWC3": 2461.2, + "PARAM1": 0.028, + "PARAM2": -0.18, + "PARAM3": 0.235, + "REAL": 486.0, + "RMS_SEED": 1486.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.146, + "NTG1": 0.78, + "NTG2": 0.56, + "OWC1": 2512.8, + "OWC2": 2440.2, + "OWC3": 2479.8, + "PARAM1": 0.039, + "PARAM2": 0.57, + "PARAM3": 11579.5, + "REAL": 487.0, + "RMS_SEED": 1487.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.002, + "NTG1": 0.93, + "NTG2": 0.63, + "OWC1": 2548.7, + "OWC2": 2482.0, + "OWC3": 2421.3, + "PARAM1": 0.042, + "PARAM2": 0.13, + "PARAM3": 238.771, + "REAL": 488.0, + "RMS_SEED": 1488.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.006, + "NTG1": 0.82, + "NTG2": 0.56, + "OWC1": 2532.9, + "OWC2": 2452.6, + "OWC3": 2459.6, + "PARAM1": 0.037, + "PARAM2": -0.69, + "PARAM3": 12879.7, + "REAL": 489.0, + "RMS_SEED": 1489.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.002, + "NTG1": 0.85, + "NTG2": 0.63, + "OWC1": 2500.5, + "OWC2": 2441.6, + "OWC3": 2485.8, + "PARAM1": 0.037, + "PARAM2": 0.26, + "PARAM3": 10.639, + "REAL": 490.0, + "RMS_SEED": 1490.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.021, + "NTG1": 0.91, + "NTG2": 0.57, + "OWC1": 2505.2, + "OWC2": 2434.8, + "OWC3": 2492.1, + "PARAM1": 0.043, + "PARAM2": 0.51, + "PARAM3": 1.313, + "REAL": 491.0, + "RMS_SEED": 1491.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.109, + "NTG1": 0.87, + "NTG2": 0.62, + "OWC1": 2529.7, + "OWC2": 2480.1, + "OWC3": 2435.2, + "PARAM1": 0.031, + "PARAM2": 0.17, + "PARAM3": 0.017, + "REAL": 492.0, + "RMS_SEED": 1492.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.591, + "NTG1": 0.87, + "NTG2": 0.63, + "OWC1": 2548.6, + "OWC2": 2484.1, + "OWC3": 2419.5, + "PARAM1": 0.034, + "PARAM2": 0.24, + "PARAM3": 0.0, + "REAL": 493.0, + "RMS_SEED": 1493.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.031, + "NTG1": 0.93, + "NTG2": 0.62, + "OWC1": 2518.3, + "OWC2": 2454.4, + "OWC3": 2468.4, + "PARAM1": 0.031, + "PARAM2": 0.07, + "PARAM3": 154753.0, + "REAL": 494.0, + "RMS_SEED": 1494.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.058, + "NTG1": 0.81, + "NTG2": 0.61, + "OWC1": 2523.1, + "OWC2": 2469.9, + "OWC3": 2452.6, + "PARAM1": 0.036, + "PARAM2": 0.54, + "PARAM3": 3750340.0, + "REAL": 495.0, + "RMS_SEED": 1495.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.019, + "NTG1": 0.8, + "NTG2": 0.61, + "OWC1": 2530.1, + "OWC2": 2466.2, + "OWC3": 2455.2, + "PARAM1": 0.036, + "PARAM2": -0.24, + "PARAM3": 3.26, + "REAL": 496.0, + "RMS_SEED": 1496.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-02", + "DERIVED_PARAM1": 1.0, + "DERIVED_PARAM2": "a", + "FAULTSEAL": 0.012, + "NTG1": 0.8, + "NTG2": 0.55, + "OWC1": 2503.7, + "OWC2": 2457.4, + "OWC3": 2468.2, + "PARAM1": 0.037, + "PARAM2": 0.24, + "PARAM3": 0.001, + "REAL": 497.0, + "RMS_SEED": 1497.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-04", + "DERIVED_PARAM1": 3.0, + "DERIVED_PARAM2": "c", + "FAULTSEAL": 0.388, + "NTG1": 0.97, + "NTG2": 0.57, + "OWC1": 2517.8, + "OWC2": 2452.9, + "OWC3": 2462.4, + "PARAM1": 0.04, + "PARAM2": -0.21, + "PARAM3": 0.798, + "REAL": 498.0, + "RMS_SEED": 1498.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + }, + { + "DATO": "2018-11-03", + "DERIVED_PARAM1": 2.0, + "DERIVED_PARAM2": "b", + "FAULTSEAL": 0.005, + "NTG1": 0.8, + "NTG2": 0.54, + "OWC1": 2524.4, + "OWC2": 2470.8, + "OWC3": 2454.6, + "PARAM1": 0.04, + "PARAM2": 0.94, + "PARAM3": 4969.53, + "REAL": 499.0, + "RMS_SEED": 1499.0, + "SENSCASE": "p10_p90", + "SENSNAME": "montecarlo" + } + ] +} diff --git a/tests/ert/unit_tests/config/fmudesign/test_create_design.py b/tests/ert/unit_tests/config/fmudesign/test_create_design.py new file mode 100644 index 00000000000..f90fa8c96e7 --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/test_create_design.py @@ -0,0 +1,697 @@ +"""Testing code for generation of design matrices""" + +import json +import math +import shutil +from datetime import datetime +from pathlib import Path + +import numpy as np +import pandas as pd +import pytest +from scipy import stats + +from ert.config.fmudesign import DesignMatrix, excel_to_dict +from ert.config.fmudesign._excel_to_dict import _read_defaultvalues +from ert.config.fmudesign.design_distributions import read_correlations +from ert.config.fmudesign.quality_report import print_corrmat + +TESTDATA = Path(__file__).parent / "data" + + +@pytest.mark.parametrize("correlations", [True, False]) +def test_distribution_statistis(use_tmpdir, monkeypatch, correlations): + """This test ensures that if any large-sample statistics for any distribution + changes, we will likely pick it up in the future. + """ + + NUM_SAMPLES = 10**5 + + def gl(paramname, distname, p1, p2, p3="", p4=""): + """GL = Generate Line. Generates a line in the input sheet.""" + return [ + "", + pd.NA, + "", + paramname, + "", + pd.NA, + "", + pd.NA, + distname, + p1, + p2, + p3, + p4, + pd.NA, + "corr1" if correlations else "", + "", + ] + + # General input sheet + general_input = pd.DataFrame( + data=[ + ["designtype", "onebyone"], + ["repeats", 1], + ["rms_seeds", "default"], + ["background", "None"], + ["distribution_seed", 42], + ] + ) + + # Design input sheet + design_input = pd.DataFrame( + data=[ + # Normal has params (mean, std, low=-inf, high=inf) + gl("NORMAL", "normal", 0, 2), + gl("TRUNCNORM", "normal", 0, 1, -1, 2), + # Lognormal has params (mean, sigma) + gl("LOGNORMAL", "logn", 1.5, 0.5), + gl("TRUNCLOGNORMAL", "logn", 1.5, 0.5, 5, 15), + # Uniform has params (low, high) + gl("UNIFORM", "unif", -5, 0), + # Triangular has params (low, mode, high) + gl("TRIANG", "triang", -5, 0, 5), + # Pert has has params (low, mode, high, scale=4) + gl("DEFAULTPERT", "pert", -5, 0, 5), + gl("SCALEPERT", "pert", -5, 0, 5, 1), + # Loguniform has params (low, high) + gl("LOGUNIFORM", "logunif", 1, 5), + # P10/P90 versions + gl("NORMALP10P90", "normal_p10_p90", -2, 3), + gl("UNIFORMP10P90", "uniform_p10_p90", -2, 3), + gl("TRIANGULARP10P90", "triangular_p10_p90", -2, 2, 3), + gl("PERTP10P90", "pert_p10_p90", -2, 2, 3), + ], + columns=[ + "sensname", + "numreal", + "type", + "param_name", + "senscase1", + "value1", + "senscase2", + "value2", + "dist_name", + "dist_param1", + "dist_param2", + "dist_param3", + "dist_param4", + "decimals", + "corr_sheet", + "extern_file", + ], + ) + design_input.iloc[0, :3] = ["distr_test", (NUM_SAMPLES), "dist"] + + # Default values sheet + defaultvalues = pd.DataFrame( + { + "param_name": list(design_input["param_name"]), + "default_value": [0.5] * (len(design_input)), + } + ) + + # Correlation sheet + num_vars = len(design_input["param_name"]) + corr_values = np.zeros(shape=(num_vars, num_vars)) + 0.2 + np.fill_diagonal(corr_values, val=1.0) + upper_idx = np.triu_indices_from(corr_values, k=1) + # Set upper triangle to blank on the numpy array before creating the DataFrame, + # since DataFrame.to_numpy() returns a copy in pandas 3 (CoW). + str_values = corr_values.astype(str) + str_values[upper_idx] = "" + corr_sheet = pd.DataFrame( + str_values, + columns=list(design_input["param_name"]), + index=list(design_input["param_name"]), + ) + # Create a file to do the save => load roundtrip and test that too + FILENAME = "designinput.xlsx" + with pd.ExcelWriter(FILENAME, engine="openpyxl") as writer: + general_input.to_excel( + writer, sheet_name="general_input", index=False, header=None + ) + design_input.to_excel(writer, sheet_name="designinput", index=False) + defaultvalues.to_excel(writer, sheet_name="defaultvalues", index=False) + corr_sheet.to_excel(writer, sheet_name="corr1") + + # Read the file and draw samples + input_dict = excel_to_dict(FILENAME) + design = DesignMatrix() + design.generate(input_dict) + assert len(design.designvalues) == NUM_SAMPLES + df = design.designvalues + + # Test statistical properties and boundaries of all variables. + # There were either derived using analytical properties, or empirically + # by drawing 10 million samples. + # Tolerance must be high enough to not pick up on rng differences, but low + # enough to pick up meaningful changes. + atol = 0.005 + + assert np.isclose(df["NORMAL"].mean(), 0.0, atol=atol) + assert np.isclose(df["NORMAL"].std(), 2.0, atol=atol) + + assert np.isclose(df["TRUNCNORM"].mean(), 0.229637, atol=atol) + assert np.isclose(df["TRUNCNORM"].std(), 0.720945, atol=atol) + assert df["TRUNCNORM"].min() >= -1 + assert df["TRUNCNORM"].max() <= 2 + + assert np.isclose(df["LOGNORMAL"].mean(), 5.078418, atol=atol) + assert np.isclose(df["LOGNORMAL"].std(), 2.706487, atol=atol) + + assert df["TRUNCLOGNORMAL"].min() >= 5 + assert df["TRUNCLOGNORMAL"].max() <= 15 + + assert df["UNIFORM"].min() >= -5 + assert df["UNIFORM"].max() <= 0 + assert np.isclose(df["UNIFORM"].mean(), -2.5, atol=atol) + assert np.isclose(df["UNIFORM"].std(), 1.443375, atol=atol) + + assert df["TRIANG"].min() >= -5 + assert df["TRIANG"].max() <= 5 + assert np.isclose(df["TRIANG"].mean(), 0, atol=atol) + assert np.isclose(df["TRIANG"].std(), 2.041241, atol=atol) + + assert df["DEFAULTPERT"].min() >= -5 + assert df["DEFAULTPERT"].max() <= 5 + assert np.isclose(df["DEFAULTPERT"].mean(), 0, atol=atol) + assert np.isclose(df["DEFAULTPERT"].std(), 1.889822, atol=atol) + + assert df["SCALEPERT"].min() >= -5 + assert df["SCALEPERT"].max() <= 5 + assert np.isclose(df["SCALEPERT"].mean(), 0, atol=atol) + assert np.isclose(df["SCALEPERT"].std(), 2.5, atol=atol) + + assert np.isclose(df["LOGUNIFORM"].mean(), 2.485339, atol=atol) + assert np.isclose(df["LOGUNIFORM"].std(), 1.130975, atol=atol) + + # The P10/P90 distributions are all defined to have P10=-2 and P90=3, + # so we test them by checking that the observed percentiles match + assert np.isclose(df["NORMALP10P90"].quantile(0.1), -2, atol=atol) + assert np.isclose(df["NORMALP10P90"].quantile(0.9), 3, atol=atol) + + assert np.isclose(df["UNIFORMP10P90"].quantile(0.1), -2, atol=atol) + assert np.isclose(df["UNIFORMP10P90"].quantile(0.9), 3, atol=atol) + + assert np.isclose(df["TRIANGULARP10P90"].quantile(0.1), -2, atol=atol) + assert np.isclose(df["TRIANGULARP10P90"].quantile(0.9), 3, atol=atol) + + assert np.isclose(df["PERTP10P90"].quantile(0.1), -2, atol=atol) + assert np.isclose(df["PERTP10P90"].quantile(0.9), 3, atol=atol) + + # Check that correlations are close + if correlations: + obs_corr = df[design_input["param_name"]].corr().to_numpy() + assert np.sqrt(np.mean((obs_corr - corr_values) ** 2)) < 0.02 + + +def test_generate_onebyone(use_tmpdir): + """Test generation of onebyone design""" + + inputfile = TESTDATA / "config/design_input_example1.xlsx" + + input_dict = excel_to_dict(inputfile) + + # Note that repeats are set to 10 in general_input sheet. + # So, there are 10 rows for each senscase of type seed and scenario. + # However, there are 20 rows for multz because numreal is set to 20 in designinput. + rows_in_design_matrix = 80 + + design = DesignMatrix() + design.generate(input_dict) + # Checking dimensions of design matrix + assert design.designvalues.shape == (rows_in_design_matrix, 10) + + # Write to disk and check some validity + design.to_xlsx("designmatrix.xlsx") + assert Path("designmatrix.xlsx").exists + diskdesign = pd.read_excel("designmatrix.xlsx", engine="openpyxl") + + assert ( + diskdesign.columns + == [ + "REAL", + "SENSNAME", + "SENSCASE", + "RMS_SEED", + "FAULT_POSITION", + "DC_MODEL", + "OWC1", + "OWC2", + "OWC3", + "MULTZ_ILE", + ] + ).all() + assert (diskdesign["REAL"].to_numpy() == np.arange(rows_in_design_matrix)).all() + ensemble_size = 10 + sensname = ( + ["rms_seed"] * ensemble_size + + ["faults"] * 2 * ensemble_size # 2 senscases, east and west + + ["velmodel"] * ensemble_size + + ["contacts"] * 2 * ensemble_size # 2 contacts, shallow and deep + + ["multz"] * 20 + ) + assert (diskdesign["SENSNAME"] == sensname).all() + # Sensitivities of type seed like rms_seed automatically get senscase p10_p90, + # so that P10/P90 is calculated for the tornado plot. + assert ( + diskdesign[diskdesign["SENSNAME"] == "rms_seed"]["SENSCASE"] == "p10_p90" + ).all() + assert ( + diskdesign[diskdesign["SENSNAME"] == "faults"]["SENSCASE"] + == ["east"] * ensemble_size + ["west"] * ensemble_size + ).all() + assert ( + diskdesign[diskdesign["SENSNAME"] == "velmodel"]["SENSCASE"] == "alternative" + ).all() + assert ( + diskdesign[diskdesign["SENSNAME"] == "contacts"]["SENSCASE"] + == ["shallow"] * ensemble_size + ["deep"] * ensemble_size + ).all() + assert ( + diskdesign[diskdesign["SENSNAME"] == "multz"]["SENSCASE"] == ["p10_p90"] * 20 + ).all() + + # When rms_seed is set to default it means that RMS_SEED numbers + # 1000, 1001,... are used. + # Note that for most senscases, RMS_SEED goes from 1000 to 1009, + # but that it goes from 1000 to 1019 for multz because numreal + # is set to 20 in the designinput sheet. + assert ( + diskdesign["RMS_SEED"] + == list(range(1000, 1000 + ensemble_size)) * 6 + list(range(1000, 1000 + 20)) + ).all() + + diskdefaults = pd.read_excel( + "designmatrix.xlsx", sheet_name="DefaultValues", header=None, engine="openpyxl" + ) + assert (diskdefaults.columns == [0, 1]).all() + assert ( + diskdefaults.iloc[:, 0] + == [ + "RMS_SEED", + "FAULT_POSITION", + "DC_MODEL", + "OWC1", + "OWC2", + "OWC3", + "MULTZ_ILE", + "PARAM1", + "PARAM2", + "PARAM3", + "PARAM4", + ] + ).all() + + diskdefaults = diskdefaults.set_index(0) + + # FAULT_POSITION has two senscases, east with value -1 and west with value 1, + # so we expect ensemble_size number of rows with -1s and ensemble_size rows with 1s. + # We expect the remaining rows to be set to the base value + # set in the defaultvalues sheet. + fault_position_base = diskdefaults.loc["FAULT_POSITION"].to_list() + fault_position = ( + fault_position_base * ensemble_size + + [-1] * ensemble_size + + [1] * ensemble_size + + fault_position_base * (rows_in_design_matrix - 3 * ensemble_size) + ) + assert (diskdesign["FAULT_POSITION"] == fault_position).all() + + dc_model_base = diskdefaults.loc["DC_MODEL"].to_list() + dc_model = ( + dc_model_base * 3 * ensemble_size + + ["alternative"] * ensemble_size + + dc_model_base * (rows_in_design_matrix - 4 * ensemble_size) + ) + assert (diskdesign["DC_MODEL"] == dc_model).all() + + owc1_base = diskdefaults.loc["OWC1"].to_list() + owc1 = ( + owc1_base * 4 * ensemble_size + + [2600] * ensemble_size + + [2700] * ensemble_size + + owc1_base * (rows_in_design_matrix - 6 * ensemble_size) + ) + assert (diskdesign["OWC1"] == owc1).all() + + owc2_base = diskdefaults.loc["OWC2"].to_list() + owc2 = ( + owc2_base * 4 * ensemble_size + + [2700] * ensemble_size + + [2800] * ensemble_size + + owc2_base * (rows_in_design_matrix - 6 * ensemble_size) + ) + assert (diskdesign["OWC2"] == owc2).all() + + owc3_base = diskdefaults.loc["OWC3"].to_list() + owc3 = ( + owc3_base * 4 * ensemble_size + + [2800] * ensemble_size + + [2900] * ensemble_size + + owc3_base * (rows_in_design_matrix - 6 * ensemble_size) + ) + assert (diskdesign["OWC3"] == owc3).all() + + # MULTZ_ILE contains random numbers so we won't test it here. + + diskmetadata = pd.read_excel( + "designmatrix.xlsx", sheet_name="Metadata", engine="openpyxl" + ) + + assert (diskmetadata.columns == ["Description", "Value"]).all() + assert diskmetadata["Description"].iloc[1] == "Created on:" + + # For the timestamp, we can't check the exact value since it will differ + # each time the test runs. Instead, we can verify it's a valid datetime string + # by attempting to parse it + timestamp = diskmetadata["Value"].iloc[1] + try: + datetime.fromisoformat(timestamp) + except ValueError: + pytest.fail("Timestamp in Metadata sheet is not in expected format") + + +def test_generate_full_mc_snapshot(snapshot): + """Test that full monte carlo design matrix generation remains consistent. + + This is a snapshot test that verifies the entire output of the design matrix + generation process, including both the design values and default values. + """ + # Setup + inputfile = TESTDATA / "config/design_input_mc_with_correls.xlsx" + input_dict = excel_to_dict(inputfile) + design = DesignMatrix() + + # Generate the design matrix + design.generate(input_dict) + + # Round to N significant figures + df_rounded = design.designvalues.map( + lambda x: x if isinstance(x, str) else float(f"{x:.6g}") + ) + + # Prepare data for snapshot comparison + snapshot_dict = { + "designvalues": df_rounded.to_dict("records"), + "defaultvalues": dict(design.defaultvalues), + } + + # Serialize to string for snapshot comparison + snapshot_str = ( + json.dumps( + snapshot_dict, + indent=2, + sort_keys=True, + ) + + "\n" # The snapshot needs newline to satisfy formatting + ) + + # Verify against snapshot + snapshot.assert_match(snapshot_str, "design_output_mc_with_correls.json") + + +def test_generate_full_mc(use_tmpdir): + """Test generation of full monte carlo""" + inputfile = TESTDATA / "config/design_input_mc_with_correls.xlsx" + input_dict = excel_to_dict(inputfile) + + design = DesignMatrix() + design.generate(input_dict) + + # Checking dimensions of design matrix + assert design.designvalues.shape == (500, 16) + + # Write to disk and check some validity + design.to_xlsx("designmatrix.xlsx") + assert Path("designmatrix.xlsx").exists + diskdesign = pd.read_excel( + "designmatrix.xlsx", sheet_name="DesignSheet01", engine="openpyxl" + ) + assert "REAL" in diskdesign + assert "SENSNAME" in diskdesign + assert "SENSCASE" in diskdesign + assert not diskdesign.empty + + diskdefaults = pd.read_excel( + "designmatrix.xlsx", sheet_name="DefaultValues", engine="openpyxl" + ) + assert not diskdefaults.empty + assert len(diskdefaults.columns) == 2 + + # Make sure adding dependent discrete parameters works. + disk_depends = pd.read_excel(inputfile, sheet_name="depend1", engine="openpyxl") + df_merged = diskdesign.merge(disk_depends, on="DATO", how="inner") + assert (df_merged["DERIVED_PARAM1_x"] == df_merged["DERIVED_PARAM1_y"]).all() + assert (df_merged["DERIVED_PARAM2_x"] == df_merged["DERIVED_PARAM2_y"]).all() + + # Check that variables are correlated using Pearson correlation + # Using 95% confidence intervals for correlation coefficients. + # + # The confidence interval calculation assumes: + # - Large sample size (n > 30) + # - Bivariate normal distribution of variables + # - Linear relationship between variables + # When these assumptions are violated (e.g. with skewed distributions), + # the intervals become less reliable + r_obj = stats.pearsonr(diskdesign["OWC1"], diskdesign["OWC2"]) + r_ci = r_obj.confidence_interval(confidence_level=0.95) + assert r_ci[0] <= 0.5 <= r_ci[1] + + r_obj = stats.pearsonr(diskdesign["OWC2"], diskdesign["OWC3"]) + r_ci = r_obj.confidence_interval(confidence_level=0.95) + assert r_ci[0] <= -0.7 <= r_ci[1] + + r_obj = stats.pearsonr(diskdesign["PARAM1"], diskdesign["PARAM2"]) + r_ci = r_obj.confidence_interval(confidence_level=0.95) + assert r_ci[0] <= 0 <= r_ci[1] + + # Using wide tolerance because the non-linear transformation between normal + # and target distributions can alter correlation strength. + assert np.isclose( + stats.spearmanr(diskdesign["PARAM1"], diskdesign["PARAM3"])[0], 0.2, atol=0.1 + ) + + # Check that we can add correlations to discrete variables. + # DATO is stored as strings, so convert to ordinals: spearmanr needs + # numeric input, otherwise scipy passes an object array to np.cov. + dato_ordinal = pd.to_datetime(diskdesign["DATO"]).astype("int64") + assert np.isclose( + stats.spearmanr(dato_ordinal, diskdesign["NTG1"])[0], 0.8, atol=0.1 + ) + + date_fractions = diskdesign["DATO"].value_counts(normalize=True) + assert math.isclose(date_fractions.loc["2018-11-02"], 0.3) + assert math.isclose(date_fractions.loc["2018-11-03"], 0.4) + assert math.isclose(date_fractions.loc["2018-11-04"], 0.3) + + +def test_generate_background(use_tmpdir): + inputfile = TESTDATA / "config/design_input_background.xlsx" + input_dict = excel_to_dict(inputfile) + source_file = TESTDATA / "config/doe1.xlsx" + dest_file = "doe1.xlsx" + shutil.copy2(source_file, dest_file) + + design = DesignMatrix() + design.generate(input_dict) + + # Check that background parameters have same values in different sensitivities. + background_params = ["PARAM17", "PARAM18", "PARAM19"] + + background_vals = design.designvalues.loc[ + design.designvalues["SENSNAME"] == "background", background_params + ] + velmodel_vals = design.designvalues.loc[ + design.designvalues["SENSNAME"] == "velmodel", background_params + ] + + assert (background_vals.to_numpy() == velmodel_vals.to_numpy()).all() + + faults_vals = design.designvalues.loc[ + design.designvalues["SENSNAME"] == "faults", background_params + ] + contacts_vals = design.designvalues.loc[ + design.designvalues["SENSNAME"] == "contacts", background_params + ] + + assert (faults_vals.to_numpy() == contacts_vals.to_numpy()).all() + + sens6 = design.designvalues[design.designvalues["SENSNAME"] == "sens6"] + # PARAM5 ~ TruncatedNormal(3, 1, 1, 5) + # PARAM6 ~ Uniform(0, 1) + assert np.isclose( + stats.spearmanr(sens6["PARAM5"], sens6["PARAM6"])[0], + 0.8, + atol=0.1, + ) + sens7 = design.designvalues[design.designvalues["SENSNAME"] == "sens7"] + + # PARAM9 and PARAM10 have a target correlation of 0.9 in the design config. + # The input correlation matrix is not positive semi-definite and is + # transformed to the closest positive semi-definite correlation matrix. + # The new correlation coefficient is 0.8. + # Using wide tolerance because the non-linear transformation between normal + # and target distributions can alter correlation strength. + assert np.isclose( + stats.spearmanr(sens7["PARAM9"], sens7["PARAM10"])[0], + 0.8, + atol=0.2, + ) + + assert np.isclose( + stats.spearmanr(sens7["PARAM10"], sens7["PARAM11"])[0], + 0.8, + atol=0.20, + ) + + +def test_read_defaultvalues_duplicate_error(use_tmpdir, monkeypatch): + """Test that read_defaultvalues raises ValueError for duplicate parameter names.""" + + # Create a simple Excel file with duplicate parameter names in defaultvalues + defaultvalues = pd.DataFrame( + columns=["param_name", "default_value"], + data=[ + ["a", 1.0], + ["b", 2.0], + [" a", 3.0], # Should be treated as duplicate of "a" after stripping + ["c", 4.0], + ["c ", 5.0], # Should be treated as duplicate of "c" after stripping + ], + ) + + defaultvalues.to_excel( + "test_defaults.xlsx", sheet_name="defaultvalues", index=False + ) + + # Test that ValueError is raised with the exact expected message + with pytest.raises( + ValueError, + match=( + "Duplicate parameter names found in sheet " + r"'defaultvalues': a, c\. All parameter names must be unique\." + ), + ): + _read_defaultvalues("test_defaults.xlsx", "defaultvalues") + + +def _write_correlation_excel(filepath, names, lower_values): + """Helper: write a correlation sheet with given lower-triangular values.""" + n = len(names) + arr = np.full((n, n), np.nan) + for i in range(n): + for j in range(i + 1): + arr[i, j] = lower_values[i][j] + df = pd.DataFrame(arr, index=names, columns=names) + with pd.ExcelWriter(filepath, engine="openpyxl") as w: + df.to_excel(w, sheet_name="corr1") + + +def test_read_correlations_returns_symmetric_matrix(tmp_path): + names = ["A", "B", "C"] + lower = [[1.0], [0.5, 1.0], [0.3, 0.4, 1.0]] + filepath = tmp_path / "corr.xlsx" + _write_correlation_excel(filepath, names, lower) + + result = read_correlations(str(filepath), corr_sheet="corr1") + arr = result.to_numpy() + + np.testing.assert_array_almost_equal(arr, arr.T) + np.testing.assert_array_almost_equal(np.diag(arr), [1.0, 1.0, 1.0]) + assert np.isclose(arr[1, 0], 0.5) + assert np.isclose(arr[0, 1], 0.5) + + +def test_read_correlations_preserves_index_and_columns(tmp_path): + names = ["X", "Y"] + lower = [[1.0], [0.8, 1.0]] + filepath = tmp_path / "corr.xlsx" + _write_correlation_excel(filepath, names, lower) + + result = read_correlations(str(filepath), corr_sheet="corr1") + + assert list(result.index) == names + assert list(result.columns) == names + + +def test_read_correlations_to_numpy_is_writable(tmp_path): + """The returned DataFrame's to_numpy(copy=True) should be writable.""" + names = ["A", "B"] + lower = [[1.0], [0.5, 1.0]] + filepath = tmp_path / "corr.xlsx" + _write_correlation_excel(filepath, names, lower) + + result = read_correlations(str(filepath), corr_sheet="corr1") + arr = result.to_numpy(copy=True) + arr[0, 1] = 0.99 # Should not raise + + +def test_print_corrmat_handles_negative_zeros(capsys): + values = np.array([[1, -0.0, 0.9], [-0.0, 1, 0], [0.9, 0, 1.0]]) + df = pd.DataFrame(values, index=["A", "B", "C"], columns=["A", "B", "C"]) + print_corrmat(df) + output = capsys.readouterr().out + assert "1.00" in output + assert ".90" in output + + +def test_print_corrmat_does_not_mutate_input(): + values = np.array([[1, -0.0, 0.9], [-0.0, 1, 0], [0.9, 0, 1.0]]) + df = pd.DataFrame(values, index=["A", "B", "C"], columns=["A", "B", "C"]) + original = df.copy() + print_corrmat(df) + pd.testing.assert_frame_equal(df, original) + + +def test_fill_with_background_values_no_index_column(): + dm = DesignMatrix() + dm.designvalues = pd.DataFrame( + { + "SENSNAME": ["s1", "s1"], + "SENSCASE": ["c1", "c1"], + "param1": [np.nan, np.nan], + } + ) + dm.backgroundvalues = pd.DataFrame({"param1": [1.0, 2.0]}) + dm._fill_with_background_values() + + assert "index" not in dm.designvalues.columns + + +def test_fill_with_background_values_are_filled(): + dm = DesignMatrix() + dm.designvalues = pd.DataFrame( + { + "SENSNAME": ["s1", "s1"], + "SENSCASE": ["c1", "c1"], + "param1": [np.nan, np.nan], + } + ) + dm.backgroundvalues = pd.DataFrame({"param1": [10.0, 20.0]}) + dm._fill_with_background_values() + + assert dm.designvalues["param1"].tolist() == [10.0, 20.0] + + +if __name__ == "__main__": + import pytest + + pytest.main(args=[__file__, "--doctest-modules", "-v", "-l"]) + + +def test_that_fewer_seeds_than_realizations_are_repeated_and_informs_user(capsys): + reals = 5 + seeds = [1, 2, 3] + + rms_seeds = DesignMatrix().create_rms_seeds(seeds, max_reals=reals) + + assert rms_seeds == [1, 2, 3, 1, 2] + stdout = capsys.readouterr().out + assert ( + "Provided number of seed values (3) in external file is " + "lower than the maximum number of realisations (5)" in stdout + ) + assert "Seeds will be repeated, e.g. [1, 2, 3] => [1, 2, 3, 1, 2, ...]" in stdout diff --git a/tests/ert/unit_tests/config/fmudesign/test_designmatrix.py b/tests/ert/unit_tests/config/fmudesign/test_designmatrix.py new file mode 100644 index 00000000000..290976a100b --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/test_designmatrix.py @@ -0,0 +1,152 @@ +"""Testing generating design matrices from dictionary input""" + +import re +import shutil +import subprocess +from pathlib import Path + +import pandas as pd + +from ert.config.fmudesign import DesignMatrix + +TESTDATA = Path(__file__).parent / "data" + + +def matches(pattern: str, text: str) -> bool: + """Match text against a pattern where acts as a wildcard. + + Examples + -------- + >>> matches("my name is !", "my name is John!") + True + >>> matches("my is !", "my name is John!") + True + >>> matches("my is !", "my name are John!") + False + """ + regex_pattern = re.escape(pattern) + regex_pattern = regex_pattern.replace("", ".+?") + regex_pattern = f"^{regex_pattern}$" + return bool(re.match(regex_pattern, text)) + + +def valid_designmatrix(dframe): + """Performs general checks on a design matrix, that should always be valid""" + assert "REAL" in dframe + + # REAL always starts at 0 and is consecutive + assert dframe["REAL"][0] == 0 + assert dframe["REAL"].diff().dropna().unique() == 1 + + assert "SENSNAME" in dframe.columns + assert "SENSCASE" in dframe.columns + + # There should be no empty cells in the dataframe: + assert not dframe.isna().sum().sum() + + +def test_designmatrix(): + """Test the DesignMatrix class""" + + design = DesignMatrix() + + mock_dict = { + "designtype": "onebyone", + "seeds": "default", + "repeats": 10, + "distribution_seed": 42, + "defaultvalues": {}, + "sensitivities": { + "rms_seed": { + "seedname": "RMS_SEED", + "senstype": "seed", + "parameters": None, + "dependencies": {}, + } + }, + } + + design.generate(mock_dict) + valid_designmatrix(design.designvalues) + assert len(design.designvalues) == 10 + assert isinstance(design.defaultvalues, dict) + + +def test_endpoint(use_tmpdir, monkeypatch): + """Test the installed endpoint + + Will write generated design matrices to the pytest tmpdir directory, + usually /tmp/pytest-of-/ + """ + designfile = TESTDATA / "config/design_input_onebyone.xlsx" + + # The xlsx file contains a relative path, relative to the input design sheet: + dependency = ( + pd.read_excel(designfile, header=None, engine="openpyxl") + .set_index([0])[1] + .to_dict()["background"] + ) + + # Copy over input files: + shutil.copy(str(designfile), ".") + shutil.copy(Path(designfile).parent / dependency, ".") + + result = subprocess.run( + ["fmudesign", str(designfile)], check=True, capture_output=True, text=True + ) + + # Use in the string below to match anything in CLI output + expected_output = """Reading file: design_input_onebyone.xlsx' + Reading background values from: doe1.xlsx + Generating sensitivity : seed + Generating sensitivity : faults + Generating sensitivity : velmodel + Generating sensitivity : contacts + Generating sensitivity : multz + Generating sensitivity : sens6 + Generating sensitivity : sens7 + Sampling 4 parameters in correlation group 'corr1' + + Warning: Correlation matrix 'corr1' is inconsistent + Requirements: + - All diagonal elements must be 1 + - All elements must be between -1 and 1 + - The matrix must be positive semi-definite + + Input correlation matrix: + | | (1) | (2) | (3) | (4) | + |:------------|------:|------:|------:|------:| + | (1) PARAM9 | 1.00 | | | | + | (2) PARAM10 | 0.90 | 1.00 | | | + | (3) PARAM11 | 0.00 | 0.90 | 1.00 | | + | (4) PARAM12 | 0.00 | 0.00 | 0.00 | 1.00 | + + Adjusted to nearest consistent correlation matrix: + | | (1) | (2) | (3) | (4) | + |:------------|------:|------:|------:|------:| + | (1) PARAM9 | 1.00 | | | | + | (2) PARAM10 | 0.74 | 1.00 | | | + | (3) PARAM11 | 0.11 | 0.74 | 1.00 | | + | (4) PARAM12 | 0.00 | 0.00 | 0.00 | 1.00 | + Generating sensitivity : sens8 +Provided number of background values (11) is smaller than number of realisations for sensitivity ('sens7', 'p10_p90') and parameter PARAM13. Will be filled with default values. +Provided number of background values (11) is smaller than number of realisations for sensitivity ('sens7', 'p10_p90') and parameter PARAM14. Will be filled with default values. +Provided number of background values (11) is smaller than number of realisations for sensitivity ('sens7', 'p10_p90') and parameter PARAM15. Will be filled with default values. +Provided number of background values (11) is smaller than number of realisations for sensitivity ('sens7', 'p10_p90') and parameter PARAM16. Will be filled with default values. +Design matrix of shape (91, 22) written to: 'generateddesignmatrix.xlsx' + + Thank you for using fmudesign + - Documentation: https://equinor.github.io/fmu-tools/fmudesign.html + - Course docs: https://fmu-docs.equinor.com/docs/fmu-coursedocs/fmu-howto/sensitivities/index.html + - Issues/feature requests: https://github.com/equinor/semeio/issues""" # ruff: ignore[line-too-long] + + for stdout_line, expected_line in zip( + result.stdout.split(), expected_output.split(), strict=False + ): + assert matches(expected_line, stdout_line) + + assert Path("generateddesignmatrix.xlsx").exists # Default output file + valid_designmatrix(pd.read_excel("generateddesignmatrix.xlsx", engine="openpyxl")) + + subprocess.run(["fmudesign", str(designfile), "anotheroutput.xlsx"], check=True) + assert Path("anotheroutput.xlsx").exists diff --git a/tests/ert/unit_tests/config/fmudesign/test_designsummary.py b/tests/ert/unit_tests/config/fmudesign/test_designsummary.py new file mode 100644 index 00000000000..fa294d746bf --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/test_designsummary.py @@ -0,0 +1,53 @@ +from pathlib import Path + +from ert.config.fmudesign import summarize_design + +TESTDATA = Path(__file__).parent / "data" + + +def test_designsummary(): + """Test import and summary of design matrix""" + + snorrebergdesign = summarize_design( + TESTDATA / "distributions/design.xlsx", "DesignSheet01" + ) + # checking dimensions and some values in summary of design matrix + assert snorrebergdesign.shape == (7, 9) + + assert ( + snorrebergdesign.columns + == [ + "sensno", + "sensname", + "senstype", + "casename1", + "startreal1", + "endreal1", + "casename2", + "startreal2", + "endreal2", + ] + ).all() + assert snorrebergdesign["sensname"][0] == "rms_seed" + assert snorrebergdesign["senstype"][0] == "mc" + assert snorrebergdesign["casename1"][0] == "P10_P90" + assert snorrebergdesign["startreal1"][0] == 0 + assert snorrebergdesign["endreal1"][0] == 9 + assert snorrebergdesign["casename2"][0] is None + assert snorrebergdesign["startreal2"][0] is None + assert snorrebergdesign["endreal2"][0] is None + + assert snorrebergdesign["sensname"][6] == "relp_go" + assert snorrebergdesign["senstype"][6] == "scalar" + assert snorrebergdesign["casename1"][6] == "lc" + assert snorrebergdesign["startreal1"][6] == 90 + assert snorrebergdesign["endreal1"][6] == 99 + assert snorrebergdesign["casename2"][6] == "hc" + assert snorrebergdesign["startreal2"][6] == 100 + assert snorrebergdesign["endreal2"][6] == 109 + + assert snorrebergdesign["endreal1"].sum() == 333 + + # Test same also when design matrix is in .csv format + designcsv = summarize_design(TESTDATA / "distributions/design.csv") + assert snorrebergdesign.equals(designcsv) diff --git a/tests/ert/unit_tests/config/fmudesign/test_excel_to_dict.py b/tests/ert/unit_tests/config/fmudesign/test_excel_to_dict.py new file mode 100644 index 00000000000..9b7138b6df7 --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/test_excel_to_dict.py @@ -0,0 +1,249 @@ +"""Testing excel_to_dict""" + +from pathlib import Path + +import numpy as np +import openpyxl +import pandas as pd +import pytest + +from ert.config.fmudesign import excel_to_dict, inputdict_to_yaml +from ert.config.fmudesign._excel_to_dict import _assert_no_merged_cells, _has_value + +MOCK_GENERAL_INPUT = pd.DataFrame( + data=[ + ["designtype", "onebyone"], + ["repeats", "10"], + ["rms_seeds", "default"], + ["background", "None"], + ["distribution_seed", 42], + ] +) + +MOCK_DESIGNINPUT = pd.DataFrame( + data=[["sensname", "numreal", "type", "param_name"], ["rms_seed", "", "seed"]] +) + + +def test_excel_to_dict(tmpdir, monkeypatch): + """Test that we can convert an Excelfile to a dictionary""" + monkeypatch.chdir(tmpdir) + defaultvalues = pd.DataFrame() + # pylint: disable=abstract-class-instantiated + writer = pd.ExcelWriter("designinput.xlsx", engine="openpyxl") + MOCK_GENERAL_INPUT.to_excel( + writer, sheet_name="general_input", index=False, header=None + ) + MOCK_DESIGNINPUT.to_excel( + writer, sheet_name="designinput", index=False, header=None + ) + defaultvalues.to_excel(writer, sheet_name="defaultvalues", index=False, header=None) + writer.close() + + dict_design = excel_to_dict("designinput.xlsx") + assert isinstance(dict_design, dict) + assert dict_design["designtype"] == "onebyone" + assert dict_design["distribution_seed"] == 42 + assert "defaultvalues" in dict_design + + assert isinstance(dict_design["defaultvalues"], dict) + assert not dict_design["defaultvalues"] # (it is empty) + + assert isinstance(dict_design["sensitivities"], dict) + + sens = dict_design["sensitivities"] + # This now contains a key for each sensitivity to make + assert "rms_seed" in sens + assert isinstance(sens["rms_seed"], dict) + assert sens["rms_seed"]["seedname"] == "RMS_SEED" + assert sens["rms_seed"]["senstype"] == "seed" # upper-cased + + # Check that we can vary some strings + writer = pd.ExcelWriter("designinput2.xlsx", engine="openpyxl") + MOCK_GENERAL_INPUT.to_excel( + writer, sheet_name="Generalinput", index=False, header=None + ) + MOCK_DESIGNINPUT.to_excel( + writer, sheet_name="Design_input", index=False, header=None + ) + defaultvalues.to_excel(writer, sheet_name="DefaultValues", index=False, header=None) + writer.close() + + dict_design = excel_to_dict("designinput2.xlsx") + assert isinstance(dict_design, dict) + assert dict_design["sensitivities"]["rms_seed"]["senstype"] == "seed" + + # Dump to yaml: + inputdict_to_yaml(dict_design, "dictdesign.yaml") + assert Path("dictdesign.yaml").exists() + assert "RMS_SEED" in Path("dictdesign.yaml").read_text(encoding="utf-8") + + +def test_duplicate_sensname_exception(tmpdir, monkeypatch): + """Test that exceptions are raised for erroneous sensnames""" + # pylint: disable=abstract-class-instantiated + mock_erroneous_designinput = pd.DataFrame( + data=[ + ["sensname", "numreal", "type", "param_name"], + ["rms_seed", "", "seed"], + ["rms_seed", "", "seed"], + [np.nan, "", "seed"], # NaN sensname - should be ignored + ["", "", "seed"], # Empty string - should be ignored + ["valid_name", "", "seed"], # Valid unique name + ] + ) + monkeypatch.chdir(tmpdir) + defaultvalues = pd.DataFrame() + + writer = pd.ExcelWriter("designinput3.xlsx", engine="openpyxl") + MOCK_GENERAL_INPUT.to_excel( + writer, sheet_name="general_input", index=False, header=None + ) + mock_erroneous_designinput.to_excel( + writer, sheet_name="designinput", index=False, header=None + ) + defaultvalues.to_excel(writer, sheet_name="defaultvalues", index=False, header=None) + writer.close() + + with pytest.raises( + ValueError, match="Two sensitivities can not share the same sensname" + ): + excel_to_dict("designinput3.xlsx") + + +def test_strip_spaces(tmpdir, monkeypatch): + """Spaces before and after parameter names are probably + invisible user errors in Excel sheets. Remove them. + """ + # pylint: disable=abstract-class-instantiated + mock_spacious_designinput = pd.DataFrame( + data=[ + ["sensname", "numreal", "type", "param_name"], + ["rms_seed ", "", "seed"], + ] + ) + defaultvalues_spacious = pd.DataFrame( + data=[ + ["parametername", "value"], + [" spacious_multiplier", 1.2], + ["spacious2 ", 3.3], + ] + ) + monkeypatch.chdir(tmpdir) + writer = pd.ExcelWriter("designinput_spaces.xlsx", engine="openpyxl") + MOCK_GENERAL_INPUT.to_excel( + writer, sheet_name="general_input", index=False, header=None + ) + mock_spacious_designinput.to_excel( + writer, sheet_name="designinput", index=False, header=None + ) + defaultvalues_spacious.to_excel( + writer, sheet_name="defaultvalues", index=False, header=None + ) + writer.close() + + dict_design = excel_to_dict("designinput_spaces.xlsx") + assert next(iter(dict_design["sensitivities"].keys())) == "rms_seed" + + # Check default values parameter names: + def_params = list(dict_design["defaultvalues"].keys()) + assert [par.strip() for par in def_params] == def_params + + +def test_mixed_senstype_exception(tmpdir, monkeypatch): + """Test that exceptions are raised for mixups in user input on types""" + # pylint: disable=abstract-class-instantiated + mock_erroneous_designinput = pd.DataFrame( + data=[ + ["sensname", "numreal", "type", "param_name"], + ["rms_seed", "", "seed"], + ["", "", "dist"], + ] + ) + monkeypatch.chdir(tmpdir) + defaultvalues = pd.DataFrame() + + writer = pd.ExcelWriter("designinput4.xlsx", engine="openpyxl") + MOCK_GENERAL_INPUT.to_excel( + writer, sheet_name="general_input", index=False, header=None + ) + mock_erroneous_designinput.to_excel( + writer, sheet_name="designinput", index=False, header=None + ) + defaultvalues.to_excel(writer, sheet_name="defaultvalues", index=False, header=None) + writer.close() + + with pytest.raises(ValueError, match="contains more than one sensitivity type"): + excel_to_dict("designinput4.xlsx") + + +def test_has_value(): + """Test a function that is used to check if xlsx-cells are empty or not""" + assert _has_value(1) + assert not _has_value(np.nan) + + # This possibly makes no sense, but is the current implementation: + assert _has_value(None) + + +def test_background_sheet(tmpdir, monkeypatch): + """Test loading background values from a sheet""" + monkeypatch.chdir(tmpdir) + general_input = pd.DataFrame( + data=[ + ["designtype", "onebyone"], + ["repeats", 3], + ["rms_seeds", "default"], + ["background", "backgroundsheet"], + ["distribution_seed", 42], + ] + ) + defaultvalues = pd.DataFrame( + columns=["param_name", "default_value"], data=[["extraseed", "0"]] + ) + background = pd.DataFrame( + data=[ + ["param_name", "dist_name", "dist_param1"], + ["extraseed", "scenario", "30,40,50"], + ] + ) + + writer = pd.ExcelWriter("designinput.xlsx", engine="openpyxl") + general_input.to_excel(writer, sheet_name="general_input", index=False, header=None) + MOCK_DESIGNINPUT.to_excel( + writer, sheet_name="design_input", index=False, header=None + ) + defaultvalues.to_excel(writer, sheet_name="defaultvalues", index=False) + background.to_excel(writer, sheet_name="backgroundsheet", index=False, header=None) + writer.close() + + dict_design = excel_to_dict("designinput.xlsx") + + # Assert it has been interpreted correctly from input files: + assert dict_design["background"]["parameters"]["extraseed"] == [ + "scenario", + ["30,40,50"], + None, + ] + assert dict_design["repeats"] == 3 + assert dict_design["defaultvalues"]["extraseed"] == 0 + + +def test_assert_no_merged_cells(use_tmpdir, monkeypatch): + """Test that assert_no_merged_cells detects merged cells""" + + # Create Excel file with merged cells + test_data = pd.DataFrame({"A": [1, 2], "B": [3, 4]}) + writer = pd.ExcelWriter("test_file.xlsx", engine="openpyxl") + test_data.to_excel(writer, sheet_name="sheet1", index=False) + writer.close() + + # Add merged cells + workbook = openpyxl.load_workbook("test_file.xlsx") + workbook["sheet1"].merge_cells("A1:B1") + workbook.save("test_file.xlsx") + workbook.close() + + # Should raise exception + with pytest.raises(Exception, match="Merged cells"): + _assert_no_merged_cells("test_file.xlsx") diff --git a/tests/ert/unit_tests/config/fmudesign/test_use_cases.py b/tests/ert/unit_tests/config/fmudesign/test_use_cases.py new file mode 100644 index 00000000000..355dbf7be1e --- /dev/null +++ b/tests/ert/unit_tests/config/fmudesign/test_use_cases.py @@ -0,0 +1,198 @@ +"""Example use cases for semeio.fmudesign""" + +import shutil +import subprocess +from pathlib import Path + +import pandas as pd +import pytest + +from ert.config.fmudesign import DesignMatrix, excel_to_dict +from ert.config.fmudesign.fmudesignrunner import EXAMPLES + +EXAMPLE_FILES = [ex.filename for ex in EXAMPLES] + +TESTDATA = Path(__file__).parent / "data" +TEST_FILES = list((TESTDATA / "config").glob("design_input*.xlsx")) + + +@pytest.mark.slow +def test_prediction_rejection_sampled_ensemble(use_tmpdir, monkeypatch): + """Test making a design matrix for prediction realizations based on an + ensemble made with manual history matching (rejection sampling). + + In the use-case this test is modelled on, the design matrix is used + to set up a prediction ensemble where each DATA file points to another + Eclipse run on disk which contains the history, identified by the + realization index ("HMREAL") in the history match run. + """ + general_input = pd.DataFrame( + data=[ + ["designtype", "onebyone"], + ["repeats", 3], # This matches the number of HM-samples we have. + ["rms_seeds", "default"], # Geogrid from HM realization is used + ["background", "hmrealizations.xlsx"], + ["distribution_seed", 42], + ] + ) + defaultvalues = pd.DataFrame( + columns=["param_name", "default_value"], + data=[ + # All background parameters must be mentioned in + # DefaultValues (but these defaults are not used in + # this particular test scenario) + ["HMREAL", "-1"], + ["ORAT", 6000], + ["RESTARTPATH", "FOO"], + ["HMITER", "-1"], + ], + ) + + # Background to separate file, these define some history realizations that + # all scenarios should run over: + pd.DataFrame( + columns=["RESTARTPATH", "HMREAL", "HMITER"], + data=[ + ["/scratch/foo/2020a_hm3/", 31, 3], + ["/scratch/foo/2020a_hm3/", 38, 3], + ["/scratch/foo/2020a_hm3/", 54, 3], + ], + ).to_excel("hmrealizations.xlsx") + + writer = pd.ExcelWriter("designinput.xlsx", engine="openpyxl") + general_input.to_excel(writer, sheet_name="general_input", index=False, header=None) + pd.DataFrame( + columns=[ + "sensname", + "numreal", + "type", + "param_name", + "dist_name", + "dist_param1", + "dist_param2", + ], + data=[ + ["ref", None, "background", None], + ["oil_rate", None, "dist", "ORAT", "uniform", 5000, 9000], + ], + ).to_excel(writer, sheet_name="design_input", index=False) + defaultvalues.to_excel(writer, sheet_name="defaultvalues", index=False) + writer.close() + + dict_design = excel_to_dict("designinput.xlsx") + design = DesignMatrix() + design.generate(dict_design) + + assert set(design.designvalues["RESTARTPATH"]) == {"/scratch/foo/2020a_hm3/"} + assert set(design.designvalues["HMITER"]) == {3} + assert all(design.designvalues["REAL"] == [0, 1, 2, 3, 4, 5]) + assert all( + design.designvalues["SENSNAME"] + == [ + "ref", + "ref", + "ref", + "oil_rate", + "oil_rate", + "oil_rate", + ] + ) + + # This is the most important bit in this test function, that the realization + # list in the background xlsx is repeated for each sensitivity: + assert all(design.designvalues["HMREAL"] == [31, 38, 54, 31, 38, 54]) + + +@pytest.mark.parametrize( + "gen_input_sheet", ["general_input", "General_Input", "GENERALINPUT"] +) +@pytest.mark.slow +def test_constant_distribution(use_tmpdir, monkeypatch, gen_input_sheet): + """Create a design matrix workbook with a single constant parameter 'a'.""" + + # General input configuration + general_input = pd.DataFrame( + data=[ + ["designtype", "onebyone"], + ["repeats", 1], + ["rms_seeds", "default"], + ["distribution_seed", 42], + ] + ) + + # Default values for parameters + defaultvalues = pd.DataFrame( + columns=["param_name", "default_value"], + data=[ + ["a", 1.0], + ], + ) + + # Design input with single constant parameter + design_input = pd.DataFrame( + columns=[ + "sensname", + "numreal", + "type", + "param_name", + "dist_name", + "dist_param1", + ], + data=[ + ["montecarlo", 100, "dist", "a", "const", 1.0], + ], + ) + + # Create Excel workbook with all sheets + writer = pd.ExcelWriter("designinput.xlsx", engine="openpyxl") + general_input.to_excel(writer, sheet_name=gen_input_sheet, index=False, header=None) + design_input.to_excel(writer, sheet_name="designinput", index=False) + defaultvalues.to_excel(writer, sheet_name="defaultvalues", index=False) + writer.close() + + # Generate design matrix + dict_design = excel_to_dict("designinput.xlsx", gen_input_sheet="generalinput") + design = DesignMatrix() + design.generate(dict_design) + + # Print results + print(f"Parameter 'a' values: {set(design.designvalues['a'])}") + print(f"Number of realizations: {len(design.designvalues)}") + print(f"Sensitivity name: {set(design.designvalues['SENSNAME'])}") + + +@pytest.mark.parametrize("designfile", TEST_FILES, ids=[p.stem for p in TEST_FILES]) +@pytest.mark.parametrize("verbosity", [0, 1, 2]) +@pytest.mark.slow +def test_all_input_files(use_tmpdir, monkeypatch, designfile, verbosity): + """Smoketest all files.""" + + # Copy all example files over, to guarantee existence of dependency files + for filename in designfile.parent.glob("*"): + if Path(filename).is_file(): + shutil.copy(filename, ".") + + # Run the CLI tool (test will fail on non-zero status code) + verbose = ["--verbose"] * verbosity + subprocess.run( + ["fmudesign", designfile, *verbose], check=True, capture_output=True, text=True + ) + + +@pytest.mark.parametrize("designfile", EXAMPLE_FILES, ids=EXAMPLE_FILES) +@pytest.mark.parametrize("verbosity", [0]) +@pytest.mark.slow +def test_all_example_files_cmd_init(use_tmpdir, monkeypatch, designfile, verbosity): + """Smoketest all files available in fmudesign init subcommand.""" + subprocess.run( + ["fmudesign", "init", designfile], check=True, capture_output=True, text=True + ) + + # Run the CLI tool (test will fail on non-zero status code) + verbose = ["--verbose"] * verbosity + subprocess.run( + ["fmudesign", "run", designfile, *verbose], + check=True, + capture_output=True, + text=True, + ) diff --git a/uv.lock b/uv.lock index db87c428002..fd4de9ec776 100644 --- a/uv.lock +++ b/uv.lock @@ -622,6 +622,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/98/2b/f97f1c193fb855c345d678f5077d6926034db0722df74c8f057020e05a25/charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5", size = 64538, upload-time = "2026-07-07T14:34:56.993Z" }, ] +[[package]] +name = "clarabel" +version = "0.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, + { name = "numpy" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/81/e2/47f692161779dbd98876015de934943effb667a014e6f79a6d746b3e4c2a/clarabel-0.11.1.tar.gz", hash = "sha256:e7c41c47f0e59aeab99aefff9e58af4a8753ee5269bbeecbd5526fc6f41b9598", size = 253949, upload-time = "2025-06-11T16:49:05.864Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/f7/f82698b6d00a40a80c67e9a32b2628886aadfaf7f7b32daa12a463e44571/clarabel-0.11.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c39160e4222040f051f2a0598691c4f9126b4d17f5b9e7678f76c71d611e12d8", size = 1039511, upload-time = "2025-06-11T16:48:58.525Z" }, + { url = "https://files.pythonhosted.org/packages/b0/8f/13650cfe25762b51175c677330e6471d5d2c5851a6fbd6df77f0681bb34e/clarabel-0.11.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:8963687ee250d27310d139eea5a6816f9c3ae31f33691b56579ca4f0f0b64b63", size = 935135, upload-time = "2025-06-11T16:48:59.901Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9e/7af10d2b540b39f1a05d1ebba604fce933cc9bc0e65e88ec3b7a84976425/clarabel-0.11.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4837b9d0db01e98239f04b1e3526a6cf568529d3c19a8b3f591befdc467f9bb", size = 1079226, upload-time = "2025-06-11T16:49:00.987Z" }, + { url = "https://files.pythonhosted.org/packages/6b/a9/c76edf781ca3283186ff4b54a9a4fb51367fd04313a68e2b09f062407439/clarabel-0.11.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8c41aaa6f3f8c0f3bd9d86c3e568dcaee079562c075bd2ec9fb3a80287380ef", size = 1164345, upload-time = "2025-06-11T16:49:02.675Z" }, + { url = "https://files.pythonhosted.org/packages/41/e6/4eee3062088c221e5a18b054e51c69f616e0bb0dc1b0a1a5e0fe90dfa18e/clarabel-0.11.1-cp39-abi3-win_amd64.whl", hash = "sha256:557d5148a4377ae1980b65d00605ae870a8f34f95f0f6a41e04aa6d3edf67148", size = 887310, upload-time = "2025-06-11T16:49:04.277Z" }, +] + [[package]] name = "click" version = "8.4.2" @@ -846,6 +864,43 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/0c/7bb51e3acfafd16c48875bf3db03607674df16f5b6ef8d056586af7e2b8b/cssselect-1.4.0-py3-none-any.whl", hash = "sha256:c0ec5c0191c8ee39fcc8afc1540331d8b55b0183478c50e9c8a79d44dbceb1d8", size = 18540, upload-time = "2026-01-29T07:00:24.994Z" }, ] +[[package]] +name = "cvxpy" +version = "1.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "clarabel" }, + { name = "highspy" }, + { name = "numpy" }, + { name = "osqp" }, + { name = "qdldl" }, + { name = "scipy" }, + { name = "scs" }, + { name = "sparsediffpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/b7/209c6df38f3621fc2f32298c93e7d0310b8a1ee4ef15e5fa59d90492fa6f/cvxpy-1.9.2.tar.gz", hash = "sha256:b2e939f197a7081a300d5a95812fec8643fabaf23a149abf7e67ca7f89671d92", size = 1916772, upload-time = "2026-06-22T04:37:31.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/43/929526a0801cdd56fbb8350f2200cec49739344d12f310f0aafea1f3506e/cvxpy-1.9.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bc9082110ac7f9d9a121f4dea73936f9b65ec043af91562677478edf4962905b", size = 1635177, upload-time = "2026-06-22T04:32:07.194Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0b/3be49d69c0a90e22572b5ed1c568d4f2357f14f013597a4314f4ea98a2da/cvxpy-1.9.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba59da053c4d15fffa54921dc4b8b929d5a11937692703133858c2be6329107b", size = 1425036, upload-time = "2026-06-22T04:32:08.444Z" }, + { url = "https://files.pythonhosted.org/packages/28/70/80e2ec67a9588cf6e2b99f3e528c4508457cba16c5f5a2a8195c255d043e/cvxpy-1.9.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fa6e86a6ecd19a63751b470a3ed44d5fba6663ab9e05d6040bb954e80a4f7551", size = 4379465, upload-time = "2026-06-22T04:37:29.121Z" }, + { url = "https://files.pythonhosted.org/packages/56/6b/f0f804c7b626917edfe1801baddb85076cdb2fc0e52ed49ff112db82f980/cvxpy-1.9.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:074897ae8f2378174099c082feef5a93b44f4c8dc9b3e960397c31fa3cebf722", size = 4427785, upload-time = "2026-06-22T04:37:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/60/54/81871ee6599d33e3a60907829aafff78e713e1c3a34ce57d1e4ef26fdb5d/cvxpy-1.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:1cc56d04515201a3e2f58a16ea59812a0126dd1419f0726f8322e6dc227a9062", size = 1386030, upload-time = "2026-06-22T04:35:23.856Z" }, + { url = "https://files.pythonhosted.org/packages/9d/0a/40f3ef2bd1a89002a4716fbe3f6aa9f55f92ee7a095a73d23242b528463a/cvxpy-1.9.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5dbbd7e149f191e21e21ec5bda41ab562d05c5d553d0103cabe3c7b8f7f5f90b", size = 1635226, upload-time = "2026-06-22T04:35:21.744Z" }, + { url = "https://files.pythonhosted.org/packages/20/26/0c0b02d6a116997412c311481b12fa628a8c43f128a405a1afea41b25040/cvxpy-1.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f649df44a798420c5a2fec75e073c067ffda92fb00a6d64d2221bef275d2d065", size = 1425026, upload-time = "2026-06-22T04:35:23.099Z" }, + { url = "https://files.pythonhosted.org/packages/80/3b/86e06eb6cc5d42166f02b67956403a0f2dc44e35fe0f94912659bc343d8b/cvxpy-1.9.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae51f459010fa8d8ecb4b19bb8a8c63781592fc070ba2e3d119c6b9c10995e26", size = 4379643, upload-time = "2026-06-22T04:35:59.328Z" }, + { url = "https://files.pythonhosted.org/packages/80/81/19e6a2b66124dc42eee0e542c3fa47d2b4dd6c2c9f0030543698c7a50be7/cvxpy-1.9.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a48e498cbe2ced52a20dd3a1b14bcd2aa939fa0a51a766c443aa8a75081285ce", size = 4427686, upload-time = "2026-06-22T04:36:00.695Z" }, + { url = "https://files.pythonhosted.org/packages/54/bd/6cbe32217d3221578211518efce0a1edc45761d7b60fb360d027d576005d/cvxpy-1.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:956b292452a5eed7cacffed25d7d1848618e97ca6ea4a83302591a46149f8f2f", size = 1386056, upload-time = "2026-06-22T04:35:41.799Z" }, + { url = "https://files.pythonhosted.org/packages/79/5f/db68cbe59c20a21e477ecba53c1fe93d34785f7d44e114d447b02f3ad5d2/cvxpy-1.9.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:54a34e4ff10b80659023ba5f1517f4171ea9b905e90c824b467a7a4234379faf", size = 1636070, upload-time = "2026-06-22T04:34:15.021Z" }, + { url = "https://files.pythonhosted.org/packages/8a/e4/f01d7f8921a7e3ccce2848459b2265a4712bd132d199c03e6c60119cfc0a/cvxpy-1.9.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:908b0423e1fd29768b076547aa2328876e6c09b4d3550d1a37409423f907dd6e", size = 1425490, upload-time = "2026-06-22T04:34:16.175Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b6/a88a61cea293d90a1751b39c77a5d5775b8a3dd4907f4461d0b34e7aa558/cvxpy-1.9.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:417a2881d6490f3a13b3b88ee98b3ece5bbc1f1a76aa7a374e0690735f14ba40", size = 4376093, upload-time = "2026-06-22T04:36:45.174Z" }, + { url = "https://files.pythonhosted.org/packages/a3/e0/e7b8caba3b0fc86e9402452b7c3d037af2e995110385d9760e3bc984b491/cvxpy-1.9.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44ca674f9427d7d8019bf80e71fd1035f1aa9eabc6a09b5e6bad52f352f830e5", size = 4423171, upload-time = "2026-06-22T04:36:46.518Z" }, + { url = "https://files.pythonhosted.org/packages/44/08/03871e44cfef2b604fcbe0649d6c02893c60737748580d641a6084ebc532/cvxpy-1.9.2-cp314-cp314-win_amd64.whl", hash = "sha256:d25f16ab7da70ac3a44b49df985f00afbe89e64c44625afd38379ca5d77f4787", size = 1392074, upload-time = "2026-06-22T04:33:59.083Z" }, + { url = "https://files.pythonhosted.org/packages/63/b8/2be562808af2ca22edc3c7b74caeace9ebcae3e7e3467ac67e19d5a8f836/cvxpy-1.9.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:fb6aa08b89aedfee2a3c62902551df67d5c6b8684038e019fbe8e5a472142845", size = 1643586, upload-time = "2026-06-22T04:35:11.342Z" }, + { url = "https://files.pythonhosted.org/packages/66/a1/ab623b3e94533e7bfd34abd881d2215956864d706313f244b79d4964aba5/cvxpy-1.9.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8cc42bfa468cc474609900de211b1f6db69ca1215c850cbf00f2646d06d5cbf9", size = 1429833, upload-time = "2026-06-22T04:35:12.604Z" }, + { url = "https://files.pythonhosted.org/packages/90/8a/5fa9717f974d30b573c34b49d0704afab1379d12a7b1b0ebc928dd777c4f/cvxpy-1.9.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27d0d08dfc1484eed29cbb98616409a677be41a81e58c91c2b954b8c19968dfa", size = 4362226, upload-time = "2026-06-22T04:37:39.135Z" }, + { url = "https://files.pythonhosted.org/packages/07/9e/5711925094fba396062ef700f95427a8be6614631a28fa255a3e526333ce/cvxpy-1.9.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a07593837d772edd5efafee3dbd069a5299f78633c944004469ce2728e1c0ac", size = 4414598, upload-time = "2026-06-22T04:37:40.586Z" }, +] + [[package]] name = "cwrap" version = "1.6.16" @@ -992,6 +1047,7 @@ dependencies = [ { name = "netcdf4" }, { name = "networkx" }, { name = "numpy" }, + { name = "openpyxl" }, { name = "opentelemetry-api" }, { name = "opentelemetry-instrumentation-threading" }, { name = "opentelemetry-sdk" }, @@ -1000,6 +1056,7 @@ dependencies = [ { name = "pandas" }, { name = "pluggy" }, { name = "polars" }, + { name = "probabilit" }, { name = "progressbar2" }, { name = "psutil" }, { name = "pyarrow" }, @@ -1108,6 +1165,7 @@ requires-dist = [ { name = "netcdf4" }, { name = "networkx" }, { name = "numpy" }, + { name = "openpyxl", specifier = ">=3.1.5" }, { name = "opentelemetry-api" }, { name = "opentelemetry-instrumentation-threading" }, { name = "opentelemetry-sdk" }, @@ -1116,6 +1174,7 @@ requires-dist = [ { name = "pandas" }, { name = "pluggy", specifier = ">=1.3.0" }, { name = "polars", specifier = ">=1.36.0" }, + { name = "probabilit", specifier = ">=0.4.2" }, { name = "progressbar2" }, { name = "psutil" }, { name = "pyarrow" }, @@ -1199,6 +1258,15 @@ types = [ { name = "types-tqdm" }, ] +[[package]] +name = "et-xmlfile" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" }, +] + [[package]] name = "execnet" version = "2.1.2" @@ -1638,6 +1706,47 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/14/32cf2aae083c74b95678875e11d25d0cb9e51a33d27f4218eb9aeacfcd70/hdf5plugin-7.0.0-py3-none-win_amd64.whl", hash = "sha256:2e052af8d7848e8bac92646584617503a08bb9b466cfa810a49ecd93e89b7ffa", size = 3523827, upload-time = "2026-06-25T20:59:37.758Z" }, ] +[[package]] +name = "highspy" +version = "1.15.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/87/02/c6b658f79911fee921721da728b9ab8f5e19ff06121fff36f90f77127f4d/highspy-1.15.1.tar.gz", hash = "sha256:20ed2fbf1cb64bf3044ee6632364b7e2653d93e6901e2b19fd3d5df10702e8c5", size = 1703256, upload-time = "2026-07-02T12:03:25.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/59/b79a7b1711ddfcca36674ddb41759e98eb1797f4a94513e7dd215e32e94d/highspy-1.15.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a781dc8432568ea990fcdcc8d6e4365e67aa4848ca1f99275db096645b27cae3", size = 4878738, upload-time = "2026-07-02T12:02:03.82Z" }, + { url = "https://files.pythonhosted.org/packages/5e/e4/ae08124f71187628471a177e6db1ed2c1c45e9dceadc45f7111dfd7c2254/highspy-1.15.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9499d631edeb9642fc08dee59ca6c5815be1764c13a336c58ab7ba063011aa24", size = 4473938, upload-time = "2026-07-02T12:02:05.754Z" }, + { url = "https://files.pythonhosted.org/packages/ff/7f/185b8c9579a9e4ef88eda45d1fdaf8d23a3a640f73c403a7b29fc0f0c4be/highspy-1.15.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef048fa722cdeb80062d271b8ba211cd6650ab73419762d80da7642bbd4a8420", size = 4636755, upload-time = "2026-07-02T12:02:07.996Z" }, + { url = "https://files.pythonhosted.org/packages/82/6b/18bec60d8585df860b8d33d310e99e7893eaabe3c8e9ebfa7e387ba9d2a4/highspy-1.15.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9730647160a6481426729f46d9989a0507d05f3cf96f9fb180f4ab9891bea67b", size = 5034168, upload-time = "2026-07-02T12:02:09.89Z" }, + { url = "https://files.pythonhosted.org/packages/d4/51/e43f06e64e994ccb41a336ff78802c0dae63aed46c17acd52167b5ca3d76/highspy-1.15.1-cp312-cp312-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:6a6a2f21ee31a9205a928fbbc3f8c054893c1aec34f6a7c56588317e2800e673", size = 5861937, upload-time = "2026-07-02T12:02:11.801Z" }, + { url = "https://files.pythonhosted.org/packages/d4/2a/5501a23cac55926e4b0554352b4285734b417dbec385c593f2ae405ea637/highspy-1.15.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9a6760962b3e813814dc5e88301890d7cce975de5ce97cc3aed589cfdd461811", size = 6192004, upload-time = "2026-07-02T12:02:14.544Z" }, + { url = "https://files.pythonhosted.org/packages/94/08/fb7d30ea0e6c83fb943b16bf31951ba13a5be01a638ec13962a477009b91/highspy-1.15.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:787c92d5ff274256ba8848ab174cfc65d5af696f51bffe87423c85b2ea25c3fe", size = 7233098, upload-time = "2026-07-02T12:02:16.609Z" }, + { url = "https://files.pythonhosted.org/packages/23/77/9a07df7181834cfb61dafa5594e5eedc78369797c6487806bd3221d20667/highspy-1.15.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dd9ee8e139e7260ec1306a48e30f1bd7937d9cfb8cb201d25da10e1099e5129b", size = 6636717, upload-time = "2026-07-02T12:02:18.72Z" }, + { url = "https://files.pythonhosted.org/packages/9a/25/5083d8e3d5cf5ff5edf5bcc03e3f693630ab59142c9d0a0bcbb2d315c50e/highspy-1.15.1-cp312-cp312-win32.whl", hash = "sha256:01c6585e83938ecf4139248b074b2ee736816d63716a20dc608b1d2fc9637b66", size = 2306753, upload-time = "2026-07-02T12:02:20.837Z" }, + { url = "https://files.pythonhosted.org/packages/d4/01/05521ca6b38e34e68d707888c378d3bcac34e62715b739e7c0c9b9887993/highspy-1.15.1-cp312-cp312-win_amd64.whl", hash = "sha256:8c548165270608a40147a7ea6d985fd62a65fabf0f075b3c0c59ea910b724223", size = 2711114, upload-time = "2026-07-02T12:02:22.621Z" }, + { url = "https://files.pythonhosted.org/packages/3f/1e/283ea32eac82dd24fe86c439013d7c7666f4889de89f0957362ea5fa425e/highspy-1.15.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db297486a7a42a18656d1cc0ea9e1596fe45b8f7f75669a0c55b9081531ee0a", size = 4878819, upload-time = "2026-07-02T12:02:24.668Z" }, + { url = "https://files.pythonhosted.org/packages/7f/1c/c6518fc7c2bd5c90d86bd7a8f3cf16c1ea0ace4335a80d45b8d3f96c0cba/highspy-1.15.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:818256db731339605a7b2c31cabfcbf820fe50402ff5e9b7aa8410ead06e8735", size = 4474016, upload-time = "2026-07-02T12:02:26.572Z" }, + { url = "https://files.pythonhosted.org/packages/2f/97/4b5e345affc107f1f315c55dd0b6f35f13be07092feccbdfe1d9bfe38e63/highspy-1.15.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:383cd3f28cce0753dec8e949719b10864e068c53a485624fcab4c6b585496dd7", size = 4636833, upload-time = "2026-07-02T12:02:28.467Z" }, + { url = "https://files.pythonhosted.org/packages/ca/6e/f00e914f2bd88e2b73a8b3ea1b47171a85cfa23d1a06dc373ca797f43208/highspy-1.15.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:238b2ee88b974b21c7e9ef198139502a7d87451939cae143dce789bbda121182", size = 5034140, upload-time = "2026-07-02T12:02:30.294Z" }, + { url = "https://files.pythonhosted.org/packages/61/03/8f821d39dc8ee06a35e0fa54c754ab592139640c1e839b587e60068ad822/highspy-1.15.1-cp313-cp313-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:b6dcc545235c0765b48fc736122b105e174d907622d20986ac653c5b2a04911f", size = 5862229, upload-time = "2026-07-02T12:02:32.065Z" }, + { url = "https://files.pythonhosted.org/packages/ea/55/708b7523ad80106b91fb66471ab8b1c178a8c8adc222c839cc14147542cd/highspy-1.15.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e1f8a21a0f48aedb129a5a60d4cad9ee0767de271cd7450de16192440671b38", size = 6191747, upload-time = "2026-07-02T12:02:34.034Z" }, + { url = "https://files.pythonhosted.org/packages/8d/cd/737f43e9c56163ebae501ab21fdbc37dd2dde3e02fd18e37d0062b9b9c7c/highspy-1.15.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9ea683af80e4fb7c9d712b5df4bae34c63fa9e6afc78d750ba2d9f5e6f3203e0", size = 7233066, upload-time = "2026-07-02T12:02:36.109Z" }, + { url = "https://files.pythonhosted.org/packages/33/60/b9ae92e8454f42cb5c5ccca63862a75f5d43afead1f725f3b8af19f507f5/highspy-1.15.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:565cf6a6e7c84e36c101b118a3c5fd09bc14aeece599bba12625e79b5ab0cecb", size = 6636826, upload-time = "2026-07-02T12:02:37.863Z" }, + { url = "https://files.pythonhosted.org/packages/54/0b/35e5e63be2e70951c3224ed33c4300f1cd37fcfe4eb6d25e259e13571e0f/highspy-1.15.1-cp313-cp313-win32.whl", hash = "sha256:6cc7008b82094b2a2377338398b38f5b6c306397bd23282e55dec46a101a2dac", size = 2306720, upload-time = "2026-07-02T12:02:39.839Z" }, + { url = "https://files.pythonhosted.org/packages/ca/63/2e104bab0117415c68950f249e42f0974f74665d0313dfeddceb1f74c47d/highspy-1.15.1-cp313-cp313-win_amd64.whl", hash = "sha256:46fe314b918257361c54170852bc561c78d0f84d94e2ad263859d818127e6e76", size = 2711119, upload-time = "2026-07-02T12:02:41.861Z" }, + { url = "https://files.pythonhosted.org/packages/0c/73/8cd42c3ca7baf4857494a0294ef068f2216f1216173f3f298046820a7a57/highspy-1.15.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a7b11dc80781052a6e7c163b5c2696fe9e06c72927cfdb48f67f7e8c77096f4f", size = 4879694, upload-time = "2026-07-02T12:02:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/fb/5b/308821aeefa0e85f90645e15a86bc63c156bf08b00e33a0a906a0c430b41/highspy-1.15.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9a00e1278ea46a426b1eaa0aea69df9d72ed1d75b18227cad992384ebbdc0c74", size = 4475059, upload-time = "2026-07-02T12:02:45.455Z" }, + { url = "https://files.pythonhosted.org/packages/a3/20/9c75531c03c7121d576ef0ff8415bfb255fdd060c435f9f26e5b103b0559/highspy-1.15.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:193b9751d3705bc948552b138800af0ad8af17a5b801d5940d7db7ff1ffc4f10", size = 4637880, upload-time = "2026-07-02T12:02:47.239Z" }, + { url = "https://files.pythonhosted.org/packages/89/ea/6d6136f01ce82c049740b00380a39999a15c689a9a4d43fdb1ea25090c2b/highspy-1.15.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6298b6ef691e83544d395d45fa4e856874c44b32936d85c36564f7697d27bb0b", size = 5034792, upload-time = "2026-07-02T12:02:49.044Z" }, + { url = "https://files.pythonhosted.org/packages/38/9d/ccf4a0d4e7a4fa4141dbabe9f78e94fa9d37b6b5becafe8a61e8369031eb/highspy-1.15.1-cp314-cp314-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:9d436b5f8d50b01497d494606695746147e15b8e22eec6ae475a60cb8b22c1d7", size = 5861891, upload-time = "2026-07-02T12:02:51.432Z" }, + { url = "https://files.pythonhosted.org/packages/19/b4/655f6ce06e17159c001456c97c4be84dcb1448477e3ea52bd5401f5c27c3/highspy-1.15.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bbb22b7ceed298c0b75237186eb4671915b1c41c07f966e527643af10493671e", size = 6195707, upload-time = "2026-07-02T12:02:53.446Z" }, + { url = "https://files.pythonhosted.org/packages/ea/93/a35495b3326cdc0c2ff59de69d26f2600f41399d9381b59f4826742c054e/highspy-1.15.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:74c1eb71d3c0fa0c190492d9c0c67266d1dd6b4244c93b53e95a687504db309d", size = 7235019, upload-time = "2026-07-02T12:02:55.989Z" }, + { url = "https://files.pythonhosted.org/packages/20/5e/8b21c908ee94db28f2de58326c8a25e361b3d504f145f7972f096028a908/highspy-1.15.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cb8b8298a74786e1cbc1a9e102b7749e2bbd9c41826ffd4a1d7ba738232646ff", size = 6637185, upload-time = "2026-07-02T12:02:58.165Z" }, + { url = "https://files.pythonhosted.org/packages/25/81/8f984e500536ca40a8fb1d74ecb7a213e170683adcfd01edee8e21e5735b/highspy-1.15.1-cp314-cp314-win32.whl", hash = "sha256:780c021441f548711818833d3a986fcb253849734aa00c3bf83d342c38b03629", size = 2362473, upload-time = "2026-07-02T12:03:00.147Z" }, + { url = "https://files.pythonhosted.org/packages/bf/97/e85d751aaba8231e86915077532fd584711d30aa9eb85c26331e2bd87596/highspy-1.15.1-cp314-cp314-win_amd64.whl", hash = "sha256:864258c59aeaea9d3bd7ccdd10c03258e2be764e2cf1e21f829fd1f8d8c15d57", size = 2813851, upload-time = "2026-07-02T12:03:01.836Z" }, +] + [[package]] name = "hpack" version = "4.2.0" @@ -3314,6 +3423,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b6/31/ee7747c1d66b064f95bc756b35119879b805f96da288df17aac516813c83/oil_reservoir_synthesizer-0.2.0-py3-none-any.whl", hash = "sha256:5cb9aeaeac121892e8291f987b151b544be7db5a28659c08cb723fc0bca33a62", size = 19654, upload-time = "2023-12-08T10:21:18.587Z" }, ] +[[package]] +name = "openpyxl" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "et-xmlfile" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" }, +] + [[package]] name = "opentelemetry-api" version = "1.44.0" @@ -3435,6 +3556,41 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/16/21/5a3f1e8913103b703a436a5664238e5b965ec392b555fe68943ea3691e6b/orjson-3.11.9-cp314-cp314-win_arm64.whl", hash = "sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9", size = 126687, upload-time = "2026-05-06T15:11:06.602Z" }, ] +[[package]] +name = "osqp" +version = "1.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b0/7f/b441062e4766851fdf1d066857134c4c3bcf7e0089e4a1d007b6114cecd5/osqp-1.1.3.tar.gz", hash = "sha256:48f53ef5ec89e6ce99ffa955bc6ea0cf2eec09ea3d40905f0c9fadc939609907", size = 57816, upload-time = "2026-06-12T16:59:27.208Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d2/f21ddf1b41ecc14784186129125c4e9c19d8f6f7ade0f2e0efd4a44dded6/osqp-1.1.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2b59e8094fe29d928d568cad0156a42daa44257ce142fb7808400016a62dc28c", size = 328512, upload-time = "2026-06-12T16:58:49.796Z" }, + { url = "https://files.pythonhosted.org/packages/de/45/1f99a9f25dc9534323b8ef9e578dc93acb33e2b762d5be267e1380b2dda5/osqp-1.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e5620abbdb259190da6f0e5421b9fdfd9386b46690210ce82aea6102cc85c67f", size = 308891, upload-time = "2026-06-12T16:58:51.07Z" }, + { url = "https://files.pythonhosted.org/packages/d5/25/176dbb33c3c3605367c0de8720945c6bdd8f9b0d411e0a94ef747085f034/osqp-1.1.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e44ad08234cfbd6d9f2a823118547e683b038676887e096533935b9fcc15fd3c", size = 328135, upload-time = "2026-06-12T16:58:52.185Z" }, + { url = "https://files.pythonhosted.org/packages/77/89/96e2e4de3b89e7363931c70eb58bded22656f5512bde18eb7a9272ce48d8/osqp-1.1.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6ceef7fb4f332892b6e0bbc17323d5c9e028c3f9db726b62a15d876d0f81cc06", size = 354077, upload-time = "2026-06-12T16:58:53.379Z" }, + { url = "https://files.pythonhosted.org/packages/c4/4b/6a1e4f5aa28117bc0a78be5e9f4071b6a11c00a33a01bc673c3faf2a0a65/osqp-1.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:e7e9bd3939e47e726673218a7b04b9784ecbf9ef0b8bc69107d20cc659836ac1", size = 316733, upload-time = "2026-06-12T16:58:54.397Z" }, + { url = "https://files.pythonhosted.org/packages/14/f8/9f74aa53b35cb9c552ff1348abe5a17d22b4e65b0dfbe987980874c8bd36/osqp-1.1.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff6cf15a5404b28a4d9aaada72ae73c6b179120892321ec9b70f52ecb7f34261", size = 328538, upload-time = "2026-06-12T16:58:55.702Z" }, + { url = "https://files.pythonhosted.org/packages/6d/4e/4a7197f508cfa62abf40f7eacc7efa2f6147e6d9f7bbb22b18e8e10d6736/osqp-1.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a9c46b4adf2b1f76a40ef8f72426be5aa014c94efca20ac5acf8afa52e352afa", size = 308914, upload-time = "2026-06-12T16:58:56.906Z" }, + { url = "https://files.pythonhosted.org/packages/e7/1d/e967f4f1e3709baf6500914abd212d863a54fc90e90cd61dbbb0af14d6a4/osqp-1.1.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcca27693d0506c6816f989cf38e6352ed74ac8eaada9babc5487456d0cb0bf8", size = 328191, upload-time = "2026-06-12T16:58:58.211Z" }, + { url = "https://files.pythonhosted.org/packages/5f/dc/7c06a4ce4d1de3e5fbf294cf435ee351a39e44d534154647b2a1a18bc6a2/osqp-1.1.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2d3ee63e8c65ef89fce979c068d05bfc3ed92b1bbc4246fbacc663f86cbe02b2", size = 354138, upload-time = "2026-06-12T16:58:59.398Z" }, + { url = "https://files.pythonhosted.org/packages/05/22/2b4198a40847bff9b19230f3e55ac7537fe275a55a27eccebfdfee77fecb/osqp-1.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:9b9fe3daa15313d281233babeb102007062933241a855f6b399becd03ec5f1e3", size = 316744, upload-time = "2026-06-12T16:59:00.702Z" }, + { url = "https://files.pythonhosted.org/packages/e3/54/bdb0611de308ddf9868d7bd75e61d62ca8a3bacca71260e1876a354ebd71/osqp-1.1.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f5eade025877e5d2fb61efdd91337cc6f259335b2783ca59bce10e7be61c1d12", size = 328883, upload-time = "2026-06-12T16:59:02.162Z" }, + { url = "https://files.pythonhosted.org/packages/84/7f/4bca14a7a0402e5dd865225f193074217f019273f7a91e2d0018853b1ad5/osqp-1.1.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e730047c4cba86ad97ca73c03ea4c3cca765b22fa79c3fbefff11b3cce317742", size = 309534, upload-time = "2026-06-12T16:59:03.427Z" }, + { url = "https://files.pythonhosted.org/packages/b6/0d/8e5ca2e9f4630f249602e91cb78b052b61744fac042f91b22a9e4d86088b/osqp-1.1.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1547e515c16feb1ab2889b64bcd4eecbbc59c40af4faf67258047a199780b98a", size = 328836, upload-time = "2026-06-12T16:59:04.833Z" }, + { url = "https://files.pythonhosted.org/packages/83/17/cb502af2a69da5f915d487db565b61e67684c65d3a4e5ae1ea42cece31f7/osqp-1.1.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bdcbe47c2c37bf7296971a40811a883e793923699394a73a9d677ab7a9093e8", size = 354268, upload-time = "2026-06-12T16:59:06.014Z" }, + { url = "https://files.pythonhosted.org/packages/56/09/56bb7302f545fafbdfd9f0ad1042424c51c7a89407569bf005cc012b8a0f/osqp-1.1.3-cp314-cp314-win_amd64.whl", hash = "sha256:e80447b95d7b7dec3d13cc9e5a67ef4c5eaac3affee60fd83d1ce461e9270816", size = 322177, upload-time = "2026-06-12T16:59:07.175Z" }, + { url = "https://files.pythonhosted.org/packages/93/11/b4edd9cf7f3ceac4785357203f98b7661ae489b2721f30d994a2870aaa09/osqp-1.1.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:97df452d5e3b000b075fcce1c9f628289411501a2c0ea9a94acea281ed57bbd3", size = 336601, upload-time = "2026-06-12T16:59:08.521Z" }, + { url = "https://files.pythonhosted.org/packages/51/0f/ebc13231f58eaf4a7f73d5c2116c05214a871f49e777d63ff2cc80ee2439/osqp-1.1.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3efaf5fa72b45bec9b67dcaf5ae58a4e2d1bd5d8053b249c0ecd5b8b60c1bc0e", size = 318836, upload-time = "2026-06-12T16:59:09.684Z" }, + { url = "https://files.pythonhosted.org/packages/22/0b/b74016cdd06cf37e4efb9d7540ce56e466d77a803ccd1ffc80a8b3e3d489/osqp-1.1.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1d6cf30cdccf07baecb7232dc5fe22a1421ea3278a88a40580df3563a419d64", size = 330294, upload-time = "2026-06-12T16:59:11.094Z" }, + { url = "https://files.pythonhosted.org/packages/e0/22/d9a756198d1e48931ddf6363df7162a5c13aecdca5af1f1489bebfa92a7d/osqp-1.1.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8ae5b09be77b987421216dae535b4c007a14f6c034a844ad6eb4244289a881d", size = 355773, upload-time = "2026-06-12T16:59:12.274Z" }, + { url = "https://files.pythonhosted.org/packages/07/fc/07ad9b479417934c7533e137be82ed0c0ef76663d6d67a1af5e068a44466/osqp-1.1.3-cp314-cp314t-win_amd64.whl", hash = "sha256:f5d66a344ff483eeb5a9213521b91427d2d898885d7e2db0712f648664482264", size = 337988, upload-time = "2026-06-12T16:59:13.366Z" }, +] + [[package]] name = "packaging" version = "26.2" @@ -3641,6 +3797,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fb/49/bc925106abcdac498074f2cbe6137e94e09f418dd2b7775df5b577dc0313/pre_commit-4.6.1-py2.py3-none-any.whl", hash = "sha256:0e3b2942510d1fb34eec167a3ec57331bf8442122f1153a9fb8b58f5c49b2717", size = 226186, upload-time = "2026-07-21T20:56:57.064Z" }, ] +[[package]] +name = "probabilit" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cvxpy" }, + { name = "networkx" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "scipy" }, + { name = "seaborn" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/21/2fcad34174930358637b4a8311e5af459f1aba2f3698153595d8c3de01a4/probabilit-0.4.2.tar.gz", hash = "sha256:e3d4a0b5dd87a61f6dfc1836408fabbd3269a69366ce64238bed927523b57bff", size = 60611, upload-time = "2026-03-18T08:29:41.784Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/9c/bb72fd8d74e02b9850ed6e124b565e7be0bfdd2c9922e220a28c9e40f38a/probabilit-0.4.2-py3-none-any.whl", hash = "sha256:3e16f4e7a348da560c67804d7143e1d8d4395237f4d1201af26d86bae0d27170", size = 50023, upload-time = "2026-03-18T08:29:40.517Z" }, +] + [[package]] name = "progressbar2" version = "4.5.0" @@ -4397,6 +4570,48 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, ] +[[package]] +name = "qdldl" +version = "0.1.9.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/51/4e/452984a63df9421cf8e7d25e8e6a44832cf0247a5e7b65e437cd516a0f8f/qdldl-0.1.9.post1.tar.gz", hash = "sha256:da2016d541c26cefc79bca4d8b5bebfa00f35db19704abb20efbd1c08df3b4c7", size = 76295, upload-time = "2026-02-19T16:48:36.651Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/ed/2ae64314f84211cb963136168fb119e595d1aea42d1f03a1e84ef7d04d68/qdldl-0.1.9.post1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:25525962e90f1b9bfe3c4fb565222daf2bd77249bb6ffb9ae20b7da551f73538", size = 122478, upload-time = "2026-02-19T16:47:51.279Z" }, + { url = "https://files.pythonhosted.org/packages/15/45/767d8a6da3a04ee3c7262f897c1dd81e92d156c60eb5b43bcab4f2bc5af5/qdldl-0.1.9.post1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a2c005c9365dea6389a9feacf636028453790cace114b54e40fd302d6f4bf91c", size = 117691, upload-time = "2026-02-19T16:47:52.287Z" }, + { url = "https://files.pythonhosted.org/packages/1f/58/cb80bb5d379a7e570a160a198ff6bff2398d6c61b5514462736348218013/qdldl-0.1.9.post1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee5b35c1dd419cbf388664d26d410c89a3e0c7e055e25223b6d28bd920349c8a", size = 1449354, upload-time = "2026-02-19T16:47:53.163Z" }, + { url = "https://files.pythonhosted.org/packages/43/11/8d89f71d4e1cb3152e4e3262db667282e0df6788d21800725195ee2384c0/qdldl-0.1.9.post1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa0e9721d272467c95a9748e6acea8911a12041ef3d8b20176aff829388ce57d", size = 1476880, upload-time = "2026-02-19T16:47:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/d4/19/b30374cd37f145c4ee086642eca46c1a0b29d16027e02417b825d3708602/qdldl-0.1.9.post1-cp312-cp312-win_amd64.whl", hash = "sha256:f5a9bcda38dd19f75d72e47558f5132a99e5443238e5153a984c6f552bc4f4ac", size = 104542, upload-time = "2026-02-19T16:47:55.558Z" }, + { url = "https://files.pythonhosted.org/packages/22/51/2a683eddd1f0cf50440e0d173ccc4cb500775a8449e27651963873cdb4df/qdldl-0.1.9.post1-cp312-cp312-win_arm64.whl", hash = "sha256:ba3e19399553821b5ceee0c082fdb4453d00a38bd420b76dddec92ce2a5a065c", size = 98901, upload-time = "2026-02-19T16:47:56.553Z" }, + { url = "https://files.pythonhosted.org/packages/42/f6/5ab7f37e7607396eb7a61736471b54be881fc5697bb18e57992fb14a0867/qdldl-0.1.9.post1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00331a5e45cc60bf6f75f027ae2a2c137295de0b5e1a0af358a37aaa07427476", size = 122503, upload-time = "2026-02-19T16:47:57.435Z" }, + { url = "https://files.pythonhosted.org/packages/e1/49/144ec3c6b7cfe650191dac35a21d93eebfcc043a3ecd8b499adb3b7cec1d/qdldl-0.1.9.post1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbfb46f7290917146b076449fb3fee1eefdf018e710c7033c11739ae1723da07", size = 117760, upload-time = "2026-02-19T16:47:58.407Z" }, + { url = "https://files.pythonhosted.org/packages/82/a1/f8d58f100140d416f40912a7bf8bc28ab8276e7e8e6a24a8889a4e5c895a/qdldl-0.1.9.post1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e881f51dc779441c0910dc5a9d89bfd40a459daaf8088934aebf6f4c84adf1e0", size = 1448988, upload-time = "2026-02-19T16:47:59.377Z" }, + { url = "https://files.pythonhosted.org/packages/f3/7d/6d621819d3340f2cb4555e5263481be1e741578634d09569c67acc186ff0/qdldl-0.1.9.post1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bc0f30e521da345d25e4fa5308fda4964e25beacd10e8de9f08d084a600a42e2", size = 1476075, upload-time = "2026-02-19T16:48:00.583Z" }, + { url = "https://files.pythonhosted.org/packages/76/97/423a7cbe11add0b7b6afe97c9d6e934776c632a8c6e1d2a457c1f9dffbf6/qdldl-0.1.9.post1-cp313-cp313-win_amd64.whl", hash = "sha256:27b02a730c39b2dba205bb5c08dca5deb994f655f6eeacee687ac006c50b3366", size = 104586, upload-time = "2026-02-19T16:48:01.586Z" }, + { url = "https://files.pythonhosted.org/packages/ca/dc/425dfec0bd5a18ad43790764f091567fba18d63d9f9d6b202a796a8fd9ca/qdldl-0.1.9.post1-cp313-cp313-win_arm64.whl", hash = "sha256:98a13e234ea335484cf76441b95638d0f9ecdd43242dd5a073f77c758977d980", size = 98954, upload-time = "2026-02-19T16:48:02.486Z" }, + { url = "https://files.pythonhosted.org/packages/7f/a4/bc38a8f2edd88adc3bd87a53493e3ddfcab1c173a0310dcfe7f56063d254/qdldl-0.1.9.post1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:576edaf8b847d087806e3d2a860a06d52a435aa3192b21bbc39e69a55187805d", size = 129346, upload-time = "2026-02-19T16:48:03.325Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/0b157bd706ee91838d22d57dd0bd3a7ea0837142fb97b5df3d8acfad9f6c/qdldl-0.1.9.post1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:547f73046ef615827317fbedb21b5e1b11f5082d304e8d775e9e17d6c447a598", size = 124236, upload-time = "2026-02-19T16:48:04.313Z" }, + { url = "https://files.pythonhosted.org/packages/30/ab/185e0620e424fab6eeafd3e37f37723e72c80a795419556575d47b27d4c5/qdldl-0.1.9.post1-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cb2e82b4f40cb18638da47adf491a016d76d0d82f25377c4c330453a8785f94", size = 1494339, upload-time = "2026-02-19T16:48:05.364Z" }, + { url = "https://files.pythonhosted.org/packages/1a/55/0982ba5565863e3fa4306891158cb509088a875e76a5eeb683744d8a1610/qdldl-0.1.9.post1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ddd5b43b760ffb4cc85ca1acfb0eb139bff78bcc7bd30cad4c55564074685d4", size = 1517878, upload-time = "2026-02-19T16:48:06.517Z" }, + { url = "https://files.pythonhosted.org/packages/79/bf/b75b0fee2ea07e0dd2c8824356cd78200ac429172fa24f12a2cf84f95bd8/qdldl-0.1.9.post1-cp313-cp313t-win_amd64.whl", hash = "sha256:0fba64949c3197c6691c8fe4c3fbcb4f95d6e85b314824ba75981efcdf06d98c", size = 113642, upload-time = "2026-02-19T16:48:07.858Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/cc4bfa56f8d29a5ed7956c97ede9dfc4ec408f61e4b75ecd9e19232a64a8/qdldl-0.1.9.post1-cp313-cp313t-win_arm64.whl", hash = "sha256:31296314679c6ccfad8760704dbc9e25b5e49fd442f803638a2aaa1886724f7d", size = 104321, upload-time = "2026-02-19T16:48:08.79Z" }, + { url = "https://files.pythonhosted.org/packages/08/28/9b991fdcc16569b1bc7119ae1f62495c948033d791d469c031058d7b2c4c/qdldl-0.1.9.post1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0d69a8d011f47f287c5e7668b92b9e3574798b9687bc751af6f89c15037aa26e", size = 122733, upload-time = "2026-02-19T16:48:09.694Z" }, + { url = "https://files.pythonhosted.org/packages/18/92/56437eb5a31edb9275450dac94a94f7df252147527974ef50ba56cbb8d66/qdldl-0.1.9.post1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:496bebf154c002fb7a36443b9a26cc0f7251e8e9251d3742590300cd2edec7a8", size = 117977, upload-time = "2026-02-19T16:48:10.606Z" }, + { url = "https://files.pythonhosted.org/packages/b2/7e/9594e0cea5aaf33c2579f722ad02e5117ede62e99aca62245f2c2d3df0d5/qdldl-0.1.9.post1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1922c11ddb59419ab969cd1a069e85da9e37db9b14d92b0900e73be94d25c318", size = 1448404, upload-time = "2026-02-19T16:48:11.497Z" }, + { url = "https://files.pythonhosted.org/packages/bf/85/c5e380aeaa3f5d61cbf21b815b3caac5909a165c747aadd5675500fa92dc/qdldl-0.1.9.post1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8c0148de01346722ef07ce9434485b97b8f3aa7042cac5c341b58a728fe7588", size = 1474644, upload-time = "2026-02-19T16:48:12.831Z" }, + { url = "https://files.pythonhosted.org/packages/b6/a7/a3b62d9ec100604778d0596910f4bd20eaf23445af20bdd1d3cac77b6632/qdldl-0.1.9.post1-cp314-cp314-win_amd64.whl", hash = "sha256:9adb8625012e96ceb6c24a8278b8aa9477727ae8fde35dee730988747ab95144", size = 107693, upload-time = "2026-02-19T16:48:14.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/ec/55b21669cad250f55fee6a8ae0fe65dfb547baeb3463f576e8642795e392/qdldl-0.1.9.post1-cp314-cp314-win_arm64.whl", hash = "sha256:0db9f197fb51c6fa96ff1964707e2ba9a89b7b0d91c305e6e0b668e1bcb66fbf", size = 102546, upload-time = "2026-02-19T16:48:15.226Z" }, + { url = "https://files.pythonhosted.org/packages/43/e8/09c59c9f4a1df9b2b415cbc13eb0daadab418e252c698f622d94e4dcb026/qdldl-0.1.9.post1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:25da2bcd44dd272435db3b4208b47943837503f43db4d24c02e5e15b7d5ddf33", size = 129500, upload-time = "2026-02-19T16:48:16.221Z" }, + { url = "https://files.pythonhosted.org/packages/86/03/dcf73d806a4c3f0250a56cc56dafadc2dfacccf5df9caf8f7f181a5e3a89/qdldl-0.1.9.post1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e3438e9cb3f8a26531a24f25bb05152a7446112f4c8ff62d537debfb8147435c", size = 124224, upload-time = "2026-02-19T16:48:17.17Z" }, + { url = "https://files.pythonhosted.org/packages/5b/2e/7770f0ad70c6cc834041c2c19262c3315d312d0d3e72ac33ecb7c94f2f9a/qdldl-0.1.9.post1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a2aed01dbdc705bcab71270ce20753a016bd7b112ea7e06d1166d897e7483cb", size = 1485196, upload-time = "2026-02-19T16:48:18.415Z" }, + { url = "https://files.pythonhosted.org/packages/0b/6d/f1919ae97e1482484239edcda8b4f29aaba11817c808c775403e8a35aa54/qdldl-0.1.9.post1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd08bbb431f138c2946a0d99cb70fbfe67435c8b3dc1dbf23e4e80edfd2b1456", size = 1509644, upload-time = "2026-02-19T16:48:20.273Z" }, + { url = "https://files.pythonhosted.org/packages/7a/33/89ca4741cb651385a12600c0e93d24ad20eef5a954bb2b7ddc596442fc8c/qdldl-0.1.9.post1-cp314-cp314t-win_amd64.whl", hash = "sha256:213f6125564f61d9597d5d36c5556d4c898225bc31a99f8c87fd549b2e65b60a", size = 117569, upload-time = "2026-02-19T16:48:21.459Z" }, + { url = "https://files.pythonhosted.org/packages/63/48/34fa827457aa0e373fb50dab4490757350076f9afcf7eb749a71926023af/qdldl-0.1.9.post1-cp314-cp314t-win_arm64.whl", hash = "sha256:fcc2184cac1e502ed624efe7f00c1c215b95cfd324a8cacf7f0053c00fa524f5", size = 107844, upload-time = "2026-02-19T16:48:22.899Z" }, +] + [[package]] name = "referencing" version = "0.37.0" @@ -4839,6 +5054,38 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/19/969dc072906c84dd0a3b05dcf57ea750936087d7873549e408b35cfc3f97/scipy-1.18.0-cp314-cp314t-win_arm64.whl", hash = "sha256:368e0a705903c466aa5f08eefb39e6b1b6b2d659e7352a31fd9e2438365be0f8", size = 25279661, upload-time = "2026-06-19T15:01:40.817Z" }, ] +[[package]] +name = "scs" +version = "3.2.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/59/5cb7f9612a5a3ff6efd4ab2d899902a536cc5974a7edb589084c5577291c/scs-3.2.11.tar.gz", hash = "sha256:2a5455cf2093d07f84f2f848c199faed52e79cdb3a11fe250b5622b6bbac4913", size = 1691825, upload-time = "2026-01-09T17:53:54.074Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/74/87a97e5fc2aac7ab3661c2555a25115121734c51eb4ebbabc2127f53bd83/scs-3.2.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad646848375b5cf2d3e45a9ebefd87ccc37a53da9c32f2bf30ea5ad0e84d9e5b", size = 96302, upload-time = "2026-01-09T17:53:01.95Z" }, + { url = "https://files.pythonhosted.org/packages/24/0c/e34764a320249465dc6c11e67a6d34e2e53a9186a64f21759e94dfb043ee/scs-3.2.11-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f30821521a74f6930924b13e731e9455b6bdcfc964f66d5623d3c8d3fdd98126", size = 5071418, upload-time = "2026-01-09T17:53:03.59Z" }, + { url = "https://files.pythonhosted.org/packages/db/3d/dd17a1c1890ce25efd3908f7ab67a56b208e89c5a5d60a2dedaf99394dcb/scs-3.2.11-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a89c71ebacd4790c461d3032a47e59ed4759e11c0f03fa79b5b84086ef9c7bc", size = 12079957, upload-time = "2026-01-09T17:53:05.439Z" }, + { url = "https://files.pythonhosted.org/packages/38/63/6f83bfa17e074c92b17e16a9bd897aedeec64f10f9200c86588d7fc583c2/scs-3.2.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4e37dc60081dd742bdcd63eeb5b260db116b3803162bcf6084eb203ebedcb080", size = 11973936, upload-time = "2026-01-09T17:53:07.926Z" }, + { url = "https://files.pythonhosted.org/packages/1a/fe/5d8f6048a90abc3aa053b5ac2acf3885dc46af94c3baf7d9ccf201a1ce19/scs-3.2.11-cp312-cp312-win_amd64.whl", hash = "sha256:2504266ff8e6a226f7ecb987567c93e6e996534cbf479a60a5a886549446205e", size = 7478461, upload-time = "2026-01-09T17:53:11.899Z" }, + { url = "https://files.pythonhosted.org/packages/90/1b/6611b98b114621444078da50be9e83c43fadc4079ef0df867091b5c9ee38/scs-3.2.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a42696b0a26c3e749b8da8d2ffc57a93af4f0f500fc3a83acb50daad92386de4", size = 96309, upload-time = "2026-01-09T17:53:13.589Z" }, + { url = "https://files.pythonhosted.org/packages/52/16/e49eff778292000bc7dca204952e430bc138c21e7eb1c4348341f3bd2ef5/scs-3.2.11-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50d204ae417c014a1756be36e8c0b857ed39c7b64e2c63b6afb1ff64c0a465d0", size = 5071425, upload-time = "2026-01-09T17:53:14.966Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f4/b7b2df5bece1b7e5f11d2bf21744c9fa346f3cea0a849cb54dabb9b83055/scs-3.2.11-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:594c09207395de922e0ff40ced562453e46f4f197dd0128022cb82c096f06615", size = 12079963, upload-time = "2026-01-09T17:53:16.976Z" }, + { url = "https://files.pythonhosted.org/packages/d6/78/11db8c58c071ece82aaefe53c7f6d5932fe8dafe381b2f6fd35fcc22cf33/scs-3.2.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fd672701ed81744e8c300df71d823700b05e7fe3d6a26f8b19b74b0a31fe3c8a", size = 11973938, upload-time = "2026-01-09T17:53:19.239Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ca/cd9cc63fc22f452188b9cda41a8d65d4124e733bc54f34f706b9c5939f92/scs-3.2.11-cp313-cp313-win_amd64.whl", hash = "sha256:2f4ebc0be14783ce3fcda61c616a7e922ac528af033e44a0da952dda0fe98091", size = 7478466, upload-time = "2026-01-09T17:53:21.494Z" }, + { url = "https://files.pythonhosted.org/packages/94/8a/52facc80a6515edd6560d918a68a0dd9186299a709e64c180ad24551aeb8/scs-3.2.11-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fe43181c3822bed600363c25c7566a643b319e0edb0c2af385c5f086a9c826d2", size = 96344, upload-time = "2026-01-09T17:53:22.949Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/c125e6b01aa6936f604e1b46a4b8c37e126af703cc228af7e9d0fe012bcb/scs-3.2.11-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3c59ce43585d3ea0c6771c5ce3df272b6c8239231acbb9567876be5d0a0474d", size = 5071403, upload-time = "2026-01-09T17:53:24.327Z" }, + { url = "https://files.pythonhosted.org/packages/58/ae/94055cafac0d9b81ffa2a12f7050c394c39182ec901faff42a471cca50cc/scs-3.2.11-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c46f597892c9f8c5551bb9a3a680dfb86e86a1a6c3bc67b09a5af2e89ba5357", size = 12079963, upload-time = "2026-01-09T17:53:26.2Z" }, + { url = "https://files.pythonhosted.org/packages/d8/72/43ff8bc4a281e84d4ae8f13dcf7436ff030bc5f67fba02368c829537386d/scs-3.2.11-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:513131af6991fb4983f84c4ba276c756c0a3574003c2790dda891c68d5b6da30", size = 11973979, upload-time = "2026-01-09T17:53:29.979Z" }, + { url = "https://files.pythonhosted.org/packages/af/55/695c509c0852bc32695b1995ff12227dfc78e9d91867ccf637d7cf85a948/scs-3.2.11-cp314-cp314-win_amd64.whl", hash = "sha256:7b2c37e87baca0389f005fe19a0ca8209d43c0f1e9136a1a6fde23cae1735db9", size = 7569717, upload-time = "2026-01-09T17:53:32.938Z" }, + { url = "https://files.pythonhosted.org/packages/4e/a1/b30e470a7440c57ed53a1d92a9e58f17ecf548888b4eea658be047500ae5/scs-3.2.11-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29c0a5c233fb5a964ea5f7523ec2b2209f000217c0a24423ab5dcd8b8922f37d", size = 97042, upload-time = "2026-01-09T17:53:35.676Z" }, + { url = "https://files.pythonhosted.org/packages/14/31/86b6aa0fca4be4701b59bcfcf29007b16dea118051a5b46a43396f2a4543/scs-3.2.11-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7519c2f436e793b004d1eae4aaf98c18857e519f8169219d1167fe88b3b0a568", size = 5072473, upload-time = "2026-01-09T17:53:37.021Z" }, + { url = "https://files.pythonhosted.org/packages/98/eb/2c07015938c50f46e9323e379e9799c3e28e0d07c9bae8b6735a6ecf1b6c/scs-3.2.11-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c166768dc87c389b2d000b5dcd472bb0ba40f96b4cf0e63c0fb603a4a5c80db", size = 12080259, upload-time = "2026-01-09T17:53:38.897Z" }, + { url = "https://files.pythonhosted.org/packages/f2/1b/d52e3b17554791726ba788abff053f4b27df157a49438f01134fec3c859d/scs-3.2.11-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f51a14a5315974fae4ca4e1b4dc8926f872eca7e66b42e070dbdcfa6904b7860", size = 11974311, upload-time = "2026-01-09T17:53:41.003Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d7/023ba290cfaf97b21c710b675b8a860b97d8226f62e35d7a08e37ddbb6d3/scs-3.2.11-cp314-cp314t-win_amd64.whl", hash = "sha256:7fe26e8a0efc96232f4c5b7649817e48dae04a61be911417e925071091b8cbf6", size = 7570221, upload-time = "2026-01-09T17:53:42.845Z" }, +] + [[package]] name = "seaborn" version = "0.13.2" @@ -4900,6 +5147,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl", hash = "sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c", size = 17610, upload-time = "2026-01-14T06:27:35.218Z" }, ] +[[package]] +name = "setuptools" +version = "83.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/26/f5d29e25ffdb535afef2d35cdb55b325298f96debd670da4c325e08d70f4/setuptools-83.0.0.tar.gz", hash = "sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef", size = 1154254, upload-time = "2026-07-04T15:31:22.699Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/40/e1e72872c6354b306daef1703549e8e83b4d43cfea356311bf722a043752/setuptools-83.0.0-py3-none-any.whl", hash = "sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3", size = 1008090, upload-time = "2026-07-04T15:31:20.885Z" }, +] + [[package]] name = "shapely" version = "2.1.2" @@ -4987,6 +5243,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0f/2c/437fe806897c2d6cfdc3ee43a18da8bf8e568530a4ae9bac781541ca9896/soupsieve-2.9.1-py3-none-any.whl", hash = "sha256:4f4477399246b7a0c720a88ca2454b11cd6bb9ae4c9d170140786e916776c14c", size = 37404, upload-time = "2026-07-21T16:57:16.421Z" }, ] +[[package]] +name = "sparsediffpy" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/e7/6a3227a25a79a440e5ec5eff1e90f5911515a7c219ee95fc6dfe5d74ec30/sparsediffpy-0.3.0.tar.gz", hash = "sha256:fdd9115db63ee228d09e1917365b263a16811645c6d32ee7dce50ada09b3d5a5", size = 180927, upload-time = "2026-05-14T06:57:48.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/82/c2eb05d191fdeaee1f03d7ed5bc7f796256fd975eceb344a2a23fe6225e2/sparsediffpy-0.3.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:22848d97852554c8814cd5a0bffc4f4f41930aa7155f2193e99332e8a9cf6f6d", size = 207399, upload-time = "2026-05-14T06:57:18.379Z" }, + { url = "https://files.pythonhosted.org/packages/12/8a/31b924d6756469af09e44ac93507e6cf9b80c3de3cae63e7185a89f0605f/sparsediffpy-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc49c774a44776afd728aca4ee1f062756416ee25366acbf32ad6416bdfb2630", size = 138478, upload-time = "2026-05-14T06:57:20.077Z" }, + { url = "https://files.pythonhosted.org/packages/23/4b/46834436ee28b2aa1404ac0b9fa2a3fcef4ee249d5fa624b0b16c50bee42/sparsediffpy-0.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:31560dc28732401d922cb910d997adabed72f26338dbf03409e1a3c6639d1908", size = 5091184, upload-time = "2026-05-14T06:57:21.78Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b7/e23622b87b93bdcca8ac3bd0ffe825a670ab7710ccafda7f4ca0d7d0af1b/sparsediffpy-0.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:614ba5d5fbdd64c3f53fa9b6dbd37d6794c55176093eba4b58f3618cf20d62bf", size = 12099967, upload-time = "2026-05-14T06:57:24.009Z" }, + { url = "https://files.pythonhosted.org/packages/a6/a7/487fcf2157472235411e30795f1b8270e311db73e1bb58b3fe73d70c19d3/sparsediffpy-0.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:695be68fedc2c1b6fc258d05e37e20b4081c38e020ec5c9d862e42266d1ece84", size = 130146, upload-time = "2026-05-14T06:57:26.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/e0/c9bc5b18b025567b02df87198d434c286777f491bc3c0b38949861e2e039/sparsediffpy-0.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aae700842a43bfdf09c7709c23354999d8e34da7f82dbc78d933a008fd63c285", size = 207404, upload-time = "2026-05-14T06:57:28.183Z" }, + { url = "https://files.pythonhosted.org/packages/11/ca/021de6a523e739a038f6e527bf71acab6ccb5181ddd5beff304f349e968e/sparsediffpy-0.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:afcc042d56af4e978e9a798c8c41a7432d9ff715d993cc2ac733565d72080a5e", size = 138483, upload-time = "2026-05-14T06:57:29.899Z" }, + { url = "https://files.pythonhosted.org/packages/76/64/e5ffb808435040177345cbaeed5623ebb49bc5567665e2001373197d6239/sparsediffpy-0.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6bc0720d58f4858ed28b1a760a96bc328d4a9591da5abf2c2c46955bcd2d6f59", size = 5091193, upload-time = "2026-05-14T06:57:32.066Z" }, + { url = "https://files.pythonhosted.org/packages/8f/17/670c5fd1f0b4da16e4b691d48963b195092d7bcf3d9afb92722a6a878f42/sparsediffpy-0.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73df847a5ae8fbb14b4af9b8eb8e0c2e96f2c8479da2eff8afd89adc55752c5d", size = 12099975, upload-time = "2026-05-14T06:57:34.696Z" }, + { url = "https://files.pythonhosted.org/packages/6e/1c/8c2a4f03e10b418dc957db87287a777cda74b58cf39779cecefccd5f4b2d/sparsediffpy-0.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:b018a3e9783ae547a83a82049f26d72a6f0a5dfb61f42eb88ed921412f8aa087", size = 130147, upload-time = "2026-05-14T06:57:36.83Z" }, + { url = "https://files.pythonhosted.org/packages/80/f0/0b8b505563699767fa125a453cd40004476084c3e7a1975e7dfca957ca3a/sparsediffpy-0.3.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:b62d0531c6470d6cea800ff60952857d16b7a3e177369c729a8e5f31dba9a4ea", size = 207430, upload-time = "2026-05-14T06:57:38.273Z" }, + { url = "https://files.pythonhosted.org/packages/56/8c/9be63f71098b8c3ffe82ab4094195ea95a33822787fa67b97e8eb5e13b77/sparsediffpy-0.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:5140ee4bb70c877d01ad1e07cee76a375c684af8e3672bf37c1de424e6f8b3b7", size = 138542, upload-time = "2026-05-14T06:57:40.124Z" }, + { url = "https://files.pythonhosted.org/packages/77/01/e2f5cc15d0fd7244c26632a4ee746e94d2721e5e44f49c2a3988b3e23d87/sparsediffpy-0.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a746cc822c2bce50dd696ef7a7c59f4e795f2c4c0a24750146b7c106809e12a", size = 5091213, upload-time = "2026-05-14T06:57:41.842Z" }, + { url = "https://files.pythonhosted.org/packages/48/03/6656660e7f0564c99405173848c65d92408af0372bbd30b8a6728d9bcee2/sparsediffpy-0.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6a28052dc02a9424b84406a0ac8c573f19471ccbf3f0ee4331588549e4de5dbe", size = 12099943, upload-time = "2026-05-14T06:57:44.524Z" }, + { url = "https://files.pythonhosted.org/packages/20/ce/57472c85900e2937b921ccc1aa492e9449a1babf8b4c6a228f892f5d3b7f/sparsediffpy-0.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:2c13dd751963611419273d7cf99c9f7e0c7793c7edba2941a57847cc62f3aa18", size = 132153, upload-time = "2026-05-14T06:57:46.598Z" }, +] + [[package]] name = "sphinx" version = "9.1.0"