diff --git a/.github/scripts/pre_pyflakes.sh b/.github/scripts/pre_pyflakes.sh deleted file mode 100644 index b0f238cb..00000000 --- a/.github/scripts/pre_pyflakes.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# copied from https://github.com/XENONnT/straxen/blob/master/.github/scripts/pre_pyflakes.sh -# Pyflakes does not like the way we do __all__ += []. This simple script -# Changes all the files in appletree to abide by this convention and -# removes the lines that have such a signature. -start="$(pwd)" -echo $start - -cd appletree -sed -e '/__all__ +=/ s/^#*/#/' -i ./*.py - -cd plugins -sed -e '/__all__ +=/ s/^#*/#/' -i ./*.py - -cd $start -echo "done" diff --git a/.github/workflows/code_style.yml b/.github/workflows/code_style.yml deleted file mode 100644 index 6466e2bb..00000000 --- a/.github/workflows/code_style.yml +++ /dev/null @@ -1,28 +0,0 @@ -# copied from https://github.com/XENONnT/straxen/blob/master/.github/workflows/code_style.yml - -name: Python style -on: - pull_request: - # types: [opened] -jobs: - qa: - name: Quality check - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v3 - - name: Change __all__ exports for pyflake - run: | - bash .github/scripts/pre_pyflakes.sh - - name: Set up Python - uses: actions/setup-python@master - with: - python-version: 3.8 - - name: patch reviewdog - run: sudo chown -R root:root $GITHUB_WORKSPACE - - name: Wemake Python Styleguide - uses: wemake-services/wemake-python-styleguide@0.16.1 - continue-on-error: true - with: - reporter: 'github-pr-review' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..b4fc3853 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,44 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + +- repo: https://github.com/psf/black + rev: 23.7.0 + hooks: + - id: black + args: [--safe, --line-length=100] + - id: black-jupyter + args: [--safe, --line-length=100] + language_version: python3.9 + +- repo: https://github.com/pycqa/docformatter + rev: v1.7.5 + hooks: + - id: docformatter + +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.5.1 + hooks: + - id: mypy + additional_dependencies: [types-PyYAML, types-tqdm] + +- repo: https://github.com/pycqa/doc8 + rev: v1.1.1 + hooks: + - id: doc8 + files: ^docs/.*\.(rst|md)$ + +- repo: https://github.com/pycqa/flake8 + rev: 6.1.0 + hooks: + - id: flake8 + +ci: + autoupdate_schedule: weekly diff --git a/README.md b/README.md index edd7a1cf..0707fa57 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ A high-Performance Program simuLatEs and fiTs REsponse of xEnon. [![PyPI version shields.io](https://img.shields.io/pypi/v/appletree.svg)](https://pypi.python.org/pypi/appletree/) [![Readthedocs Badge](https://readthedocs.org/projects/appletree/badge/?version=latest)](https://appletree.readthedocs.io/en/latest/?badge=latest) [![CodeFactor](https://www.codefactor.io/repository/github/xenonnt/appletree/badge)](https://www.codefactor.io/repository/github/xenonnt/appletree) +[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/XENONnT/appletree/master.svg)](https://results.pre-commit.ci/latest/github/XENONnT/appletree/master) ## Installation and Set-Up @@ -54,7 +55,7 @@ Then you are now good to go! ## Usage -The best way to start with the `appletree` package is to have a look at the tutorial `notebooks`. +The best way to start with the `appletree` package is to have a look at the tutorial `notebooks`. ## Contributing diff --git a/appletree/__init__.py b/appletree/__init__.py index 35ed0b90..a776b142 100644 --- a/appletree/__init__.py +++ b/appletree/__init__.py @@ -1,70 +1,62 @@ -__version__ = '0.2.3' +__version__ = "0.2.3" # stop jax to preallocate memory import os -os.environ['XLA_PYTHON_CLIENT_PREALLOCATE'] = 'false' -os.environ['XLA_PYTHON_CLIENT_ALLOCATOR'] = 'platform' + +os.environ["XLA_PYTHON_CLIENT_PREALLOCATE"] = "false" +os.environ["XLA_PYTHON_CLIENT_ALLOCATOR"] = "platform" from . import utils from .utils import * -from . import hist from .hist import * -from . import interpolation from .interpolation import * -from . import config from .config import * -from . import parameter from .parameter import * -from . import randgen from .randgen import * -from . import share from .share import * from . import plugins -from . import plugin from .plugin import * -from . import components from .components import * -from . import component from .component import * -from . import likelihood from .likelihood import * -from . import contexts from .contexts import * -from . import context from .context import * # check CUDA support setup from warnings import warn + platform = utils.get_platform() -if platform == 'cpu': - warning = 'You are running appletree on CPU, which usually results in low performance.' +if platform == "cpu": + warning = "You are running appletree on CPU, which usually results in low performance." warn(warning) try: import jax + # try allocate something jax.numpy.ones(1) except BaseException: - if platform == 'gpu': - print('Can not allocate memory on GPU, please check your CUDA version.') - raise ImportError(f'Appletree is not correctly setup to be used on {platform.upper()}.') + if platform == "gpu": + print("Can not allocate memory on GPU, please check your CUDA version.") + raise ImportError(f"Appletree is not correctly setup to be used on {platform.upper()}.") try: import aptext + HAVE_APTEXT = True - print('Using aptext package from https://github.com/XENONnT/applefiles') + print("Using aptext package from https://github.com/XENONnT/applefiles") except ImportError: HAVE_APTEXT = False - print('Can not find aptext') + print("Can not find aptext") diff --git a/appletree/component.py b/appletree/component.py index dbba7ae6..4dc6a2ce 100644 --- a/appletree/component.py +++ b/appletree/component.py @@ -1,12 +1,13 @@ from warnings import warn from functools import partial +from typing import Tuple, List, Dict, Optional, Union, Set import numpy as np import pandas as pd from jax import numpy as jnp -import appletree from appletree import utils +from appletree.config import OMITTED from appletree.plugin import Plugin from appletree.share import _cached_configs, _cached_functions, set_global_config from appletree.utils import exporter, load_data @@ -17,19 +18,16 @@ @export class Component: - """Base class of component""" + """Base class of component.""" # Do not initialize this class because it is base __is_base = True - rate_name: str = '' - norm_type: str = '' + rate_name: str = "" + norm_type: str = "" add_eps_to_hist: bool = True - def __init__(self, - name: str = None, - llh_name: str = None, - **kwargs): + def __init__(self, name: Optional[str] = None, llh_name: Optional[str] = None, **kwargs): """Initialization. :param bins: bins to generate the histogram. @@ -37,33 +35,34 @@ def __init__(self, * For irreg bins_type, bins must be bin edges of the two dimensions. * For meshgrid bins_type, bins are sent to jnp.histogramdd. :param bins_type: binning scheme, can be either irreg or meshgrid. + """ if name is None: self.name = self.__class__.__name__ else: self.name = name if llh_name is None: - self.llh_name = self.__class__.__name__ + '_llh' + self.llh_name = self.__class__.__name__ + "_llh" else: self.llh_name = llh_name - self.needed_parameters = set() + self.needed_parameters: Set[str] = set() - if 'bins' in kwargs.keys() and 'bins_type' in kwargs.keys(): + if "bins" in kwargs.keys() and "bins_type" in kwargs.keys(): self.set_binning(**kwargs) def set_binning(self, **kwargs): - """Set binning of component""" - if 'bins' not in kwargs.keys() or 'bins_type' not in kwargs.keys(): - raise ValueError('bins and bins_type must be set!') - self.bins = kwargs.get('bins') - self.bins_type = kwargs.get('bins_type') - - if self.bins_type == 'meshgrid': - warning = 'The usage of meshgrid binning is highly discouraged.' + """Set binning of component.""" + if "bins" not in kwargs.keys() or "bins_type" not in kwargs.keys(): + raise ValueError("bins and bins_type must be set!") + self.bins = kwargs.get("bins") + self.bins_type = kwargs.get("bins_type") + + if self.bins_type == "meshgrid": + warning = "The usage of meshgrid binning is highly discouraged." warn(warning) def _clip(self, result: list): - """Clip simulated result""" + """Clip simulated result.""" mask = np.ones(len(result[-1]), dtype=bool) for i in range(len(result) - 1): mask &= result[i] > np.array(self.bins[i]).min() @@ -74,16 +73,14 @@ def _clip(self, result: list): @property def _use_mcinput(self): - return 'Bootstrap' in self._plugin_class_registry['energy'].__name__ + return "Bootstrap" in self._plugin_class_registry["energy"].__name__ def simulate_hist(self, *args, **kwargs): """Hook for simulation with histogram output.""" raise NotImplementedError def multiple_simulations(self, key, batch_size, parameters, times): - """Simulate many times and - move results to CPU because the memory limit of GPU - """ + """Simulate many times and move results to CPU because the memory limit of GPU.""" results_pile = [] for _ in range(times): key, results = self.simulate(key, batch_size, parameters) @@ -91,19 +88,21 @@ def multiple_simulations(self, key, batch_size, parameters, times): return key, np.hstack(results_pile) def multiple_simulations_compile(self, key, batch_size, parameters, times): - """Simulate many times after new compilation and - move results to CPU because the memory limit of GPU - """ + """Simulate many times after new compilation and move results to CPU because the memory + limit of GPU.""" results_pile = [] for _ in range(times): - if _cached_configs['g4'] and self._use_mcinput: - if isinstance(_cached_configs['g4'], dict): - g4_file_name = _cached_configs['g4'][self.llh_name][0] - _cached_configs['g4'][self.llh_name] = [ - g4_file_name, batch_size, key.sum().item()] + if _cached_configs["g4"] and self._use_mcinput: + if isinstance(_cached_configs["g4"], dict): + g4_file_name = _cached_configs["g4"][self.llh_name][0] + _cached_configs["g4"][self.llh_name] = [ + g4_file_name, + batch_size, + key.sum().item(), + ] else: - g4_file_name = _cached_configs['g4'][0] - _cached_configs['g4'] = [g4_file_name, batch_size, key.sum().item()] + g4_file_name = _cached_configs["g4"][0] + _cached_configs["g4"] = [g4_file_name, batch_size, key.sum().item()] self.compile() key, results = self.multiple_simulations(key, batch_size, parameters, 1) results_pile.append(results) @@ -112,34 +111,37 @@ def multiple_simulations_compile(self, key, batch_size, parameters, times): def implement_binning(self, mc, eff): """Apply binning to MC data. - :param mc: data from simulation. - :param eff: efficiency of each event, as the weight when making a histogram. + :param mc: data from simulation. :param eff: efficiency of each event, as the weight when + making a histogram. + """ - if self.bins_type == 'irreg': + if self.bins_type == "irreg": hist = make_hist_irreg_bin_2d(mc, *self.bins, weights=eff) - elif self.bins_type == 'meshgrid': + elif self.bins_type == "meshgrid": hist = make_hist_mesh_grid(mc, bins=self.bins, weights=eff) else: - raise ValueError(f'Unsupported bins_type {self.bins_type}!') + raise ValueError(f"Unsupported bins_type {self.bins_type}!") if self.add_eps_to_hist: # as an uncertainty to prevent blowing up - hist = jnp.clip(hist, 1., jnp.inf) + hist = jnp.clip(hist, 1.0, jnp.inf) return hist def get_normalization(self, hist, parameters, batch_size=None): """Return the normalization factor of the histogram.""" - if self.norm_type == 'on_pdf': + if self.norm_type == "on_pdf": normalization_factor = 1 / jnp.sum(hist) * parameters[self.rate_name] - elif self.norm_type == 'on_sim': + elif self.norm_type == "on_sim": if self._use_mcinput: - bootstrap_name = self._plugin_class_registry['energy'].__name__ - bootstrap_name = bootstrap_name + '_' + self.name - n_events_selected = _cached_functions[self.llh_name][bootstrap_name].g4.n_events_selected + bootstrap_name = self._plugin_class_registry["energy"].__name__ + bootstrap_name = bootstrap_name + "_" + self.name + n_events_selected = _cached_functions[self.llh_name][ + bootstrap_name + ].g4.n_events_selected normalization_factor = 1 / n_events_selected * parameters[self.rate_name] else: normalization_factor = 1 / batch_size * parameters[self.rate_name] else: - raise ValueError(f'Unsupported norm_type {self.norm_type}!') + raise ValueError(f"Unsupported norm_type {self.norm_type}!") return normalization_factor def deduce(self, *args, **kwargs): @@ -158,12 +160,8 @@ class ComponentSim(Component): # Do not initialize this class because it is base __is_base = True - code: str = None - old_code: str = None - - def __init__(self, - *args, **kwargs): - """Initialization""" + def __init__(self, *args, **kwargs): + """Initialization.""" super().__init__(*args, **kwargs) self._plugin_class_registry = dict() @@ -184,7 +182,6 @@ def register(self, plugin_class): already_seen = [] for plugin in self._plugin_class_registry.values(): - if plugin in already_seen: continue already_seen.append(plugin) @@ -198,18 +195,22 @@ def register(self, plugin_class): if items.default == new_items.default: continue else: - mes = f'Two plugins have a different file name' - mes += f' for the same config. The config' - mes += f' "{new_config}" in "{plugin.__name__}" takes' - mes += f' the file name as "{new_items.default}" while in' - mes += f' "{plugin_class.__name__}" the file name' - mes += f' is set to "{items.default}". Please change' - mes += f' one of the file names.' + mes = ( + f"Two plugins have a different file name " + f"for the same config. The config " + f"'{new_config}' in '{plugin.__name__}' takes " + f"the file name as '{new_items.default}' while in " + f"'{plugin_class.__name__}' the file name " + f"is set to '{items.default}'. Please change " + f"one of the file names." + ) raise ValueError(mes) def register_all(self, module): """Register all plugins defined in module. + Can pass a list/tuple of modules to register all in each. + """ if isinstance(module, (tuple, list)): # Shortcut for multiple registration @@ -224,15 +225,17 @@ def register_all(self, module): if issubclass(x, Plugin): self.register(x) - def dependencies_deduce(self, - data_names: list = ('cs1', 'cs2', 'eff'), - dependencies: list = None, - nodep_data_name: str = 'batch_size') -> list: + def dependencies_deduce( + self, + data_names: Union[List[str], Tuple[str]] = ["cs1", "cs2", "eff"], + dependencies: Optional[List[Dict]] = None, + nodep_data_name: str = "batch_size", + ) -> list: """Deduce dependencies. - :param data_names: data names that simulation will output. - :param dependencies: dependency tree. - :param nodep_data_name: data_name without dependency will not be deduced + :param data_names: data names that simulation will output. :param dependencies: dependency + tree. :param nodep_data_name: data_name without dependency will not be deduced + """ if dependencies is None: dependencies = [] @@ -242,13 +245,15 @@ def dependencies_deduce(self, if data_name == nodep_data_name: continue try: - dependencies.append({ - 'plugin': self._plugin_class_registry[data_name], - 'provides': data_name, - 'depends_on': self._plugin_class_registry[data_name].depends_on, - }) + dependencies.append( + { + "plugin": self._plugin_class_registry[data_name], + "provides": data_name, + "depends_on": self._plugin_class_registry[data_name].depends_on, + } + ) except KeyError: - raise ValueError(f'Can not find dependency for {data_name}') + raise ValueError(f"Can not find dependency for {data_name}") for data_name in data_names: # `batch_size` has no dependency @@ -268,63 +273,65 @@ def dependencies_simplify(self, dependencies): self.worksheet = [] self.needed_parameters.add(self.rate_name) for plugin in dependencies[::-1]: - plugin = plugin['plugin'] + plugin = plugin["plugin"] if plugin.__name__ in already_seen: continue self.worksheet.append([plugin.__name__, plugin.provides, plugin.depends_on]) already_seen.append(plugin.__name__) self.needed_parameters |= set(plugin.parameters) - def flush_source_code(self, - data_names: list = ['cs1', 'cs2', 'eff'], - func_name: str = 'simulate', - nodep_data_name: str = 'batch_size'): + def flush_source_code( + self, + data_names: Union[List[str], Tuple[str]] = ["cs1", "cs2", "eff"], + func_name: str = "simulate", + nodep_data_name: str = "batch_size", + ): """Infer the simulation code from the dependency tree.""" self.func_name = func_name if not isinstance(data_names, (list, str)): - raise RuntimeError(f'data_names must be list or str, but given {type(data_names)}') + raise RuntimeError(f"data_names must be list or str, but given {type(data_names)}") if isinstance(data_names, str): data_names = [data_names] - code = '' - indent = ' ' * 4 + code = "" + indent = " " * 4 - code += 'from functools import partial\n' - code += 'from jax import jit\n' + code += "from functools import partial\n" + code += "from jax import jit\n" # import needed plugins for work in self.worksheet: plugin = work[0] - code += f'from appletree.plugins import {plugin}\n' + code += f"from appletree.plugins import {plugin}\n" # initialize new instances for work in self.worksheet: plugin = work[0] - instance = plugin + '_' + self.name + instance = plugin + "_" + self.name code += f"{instance} = {plugin}('{self.llh_name}')\n" # define functions - code += '\n' - if nodep_data_name == 'batch_size': - code += '@partial(jit, static_argnums=(1, ))\n' + code += "\n" + if nodep_data_name == "batch_size": + code += "@partial(jit, static_argnums=(1, ))\n" else: - code += '@jit\n' - code += f'def {func_name}(key, {nodep_data_name}, parameters):\n' + code += "@jit\n" + code += f"def {func_name}(key, {nodep_data_name}, parameters):\n" for work in self.worksheet: - provides = 'key, ' + ', '.join(work[1]) - depends_on = ', '.join(work[2]) - instance = work[0] + '_' + self.name - code += f'{indent}{provides} = {instance}(key, parameters, {depends_on})\n' - output = 'key, ' + '[' + ', '.join(data_names) + ']' - code += f'{indent}return {output}\n' + provides = "key, " + ", ".join(work[1]) + depends_on = ", ".join(work[2]) + instance = work[0] + "_" + self.name + code += f"{indent}{provides} = {instance}(key, parameters, {depends_on})\n" + output = "key, " + "[" + ", ".join(data_names) + "]" + code += f"{indent}return {output}\n" self.code = code if func_name in _cached_functions[self.llh_name].keys(): - warning = f'Function name {func_name} is already cached. ' - warning += 'Running compile() will overwrite it.' + warning = f"Function name {func_name} is already cached. " + warning += "Running compile() will overwrite it." warn(warning) @property @@ -339,26 +346,29 @@ def code(self, code): _cached_functions[self.llh_name] = dict() self._compile = partial(exec, self.code, _cached_functions[self.llh_name]) - def deduce(self, - data_names: list = ('cs1', 'cs2'), - func_name: str = 'simulate', - nodep_data_name: str = 'batch_size', - force_no_eff: bool = False): + def deduce( + self, + data_names: Union[List[str], Tuple[str]] = ["cs1", "cs2"], + func_name: str = "simulate", + nodep_data_name: str = "batch_size", + force_no_eff: bool = False, + ): """Deduce workflow and code. - :param data_names: data names that simulation will output. - :param func_name: name of the simulation function, used to cache it. - :param nodep_data_name: data_name without dependency will not be deduced - :param force_no_eff: force to ignore the efficiency, used in yield prediction + :param data_names: data names that simulation will output. :param func_name: name of the + simulation function, used to cache it. :param nodep_data_name: data_name without dependency + will not be deduced :param force_no_eff: force to ignore the efficiency, used in yield + prediction + """ if not isinstance(data_names, (list, tuple)): - raise ValueError(f'Unsupported data_names type {type(data_names)}!') + raise ValueError(f"Unsupported data_names type {type(data_names)}!") # make sure that 'eff' is the last data_name - if 'eff' in data_names: + if "eff" in data_names: data_names = list(data_names) - data_names.remove('eff') + data_names.remove("eff") if not force_no_eff: - data_names = list(data_names) + ['eff'] + data_names = list(data_names) + ["eff"] dependencies = self.dependencies_deduce(data_names, nodep_data_name=nodep_data_name) self.dependencies_simplify(dependencies) @@ -369,15 +379,13 @@ def compile(self): self._compile() self.simulate = _cached_functions[self.llh_name][self.func_name] - def simulate_hist(self, - key, - batch_size, - parameters): + def simulate_hist(self, key, batch_size, parameters): """Simulate and return histogram. - :param key: key used for pseudorandom generator. - :param batch_size: number of events to be simulated. - :param parameters: a dictionary that contains all parameters needed in simulation. + :param key: key used for pseudorandom generator. :param batch_size: number of events to be + simulated. :param parameters: a dictionary that contains all parameters needed in + simulation. + """ key, result = self.simulate(key, batch_size, parameters) mc = result[:-1] @@ -391,10 +399,7 @@ def simulate_hist(self, return key, hist - def simulate_weighted_data(self, - key, - batch_size, - parameters): + def simulate_weighted_data(self, key, batch_size, parameters): """Simulate and return histogram.""" key, result = self.simulate(key, batch_size, parameters) # Move data to CPU @@ -404,7 +409,9 @@ def simulate_weighted_data(self, mc = result[:-1] assert len(mc) == len(self.bins), "Length of bins must be the same as length of bins_on!" mc = jnp.asarray(mc).T - eff = jnp.asarray(result[-1]) # we guarantee that the last output is efficiency in self.deduce + eff = jnp.asarray( + result[-1] + ) # we guarantee that the last output is efficiency in self.deduce hist = self.implement_binning(mc, eff) normalization_factor = self.get_normalization(hist, parameters, batch_size) @@ -414,36 +421,37 @@ def simulate_weighted_data(self, def save_code(self, file_path): """Save the code to file.""" - with open(file_path, 'w') as f: + with open(file_path, "w") as f: f.write(self.code) - def lineage(self, data_name: str = 'cs2'): + def lineage(self, data_name: str = "cs2"): """Return lineage of plugins.""" assert isinstance(data_name, str) pass def set_config(self, configs): - """Set new global configuration options + """Set new global configuration options. :param configs: dict, configuration file name or dictionary + """ set_global_config(configs) - def show_config(self, data_names: list = ('cs1', 'cs2', 'eff')): - """ - Return configuration options that affect data_names. + def show_config(self, data_names: Union[List[str], Tuple[str]] = ["cs1", "cs2", "eff"]): + """Return configuration options that affect data_names. :param data_names: Data type name + """ dependencies = self.dependencies_deduce( data_names, - nodep_data_name='batch_size', + nodep_data_name="batch_size", ) r = [] seen = [] for dep in dependencies: - p = dep['plugin'] + p = dep["plugin"] # Track plugins we already saw, so options from # multi-output plugins don't come up several times if p in seen: @@ -454,16 +462,19 @@ def show_config(self, data_names: list = ('cs1', 'cs2', 'eff')): try: default = config.get_default() except ValueError: - default = appletree.OMITTED + default = OMITTED current = _cached_configs.get(config.name, None) if isinstance(current, dict): current = current[self.llh_name] - r.append(dict( - option=config.name, - default=default, - current=current, - applies_to=p.provides, - help=config.help)) + r.append( + dict( + option=config.name, + default=default, + current=current, + applies_to=p.provides, + help=config.help, + ) + ) if len(r): df = pd.DataFrame(r, columns=r[0].keys()) else: @@ -473,24 +484,21 @@ def show_config(self, data_names: list = ('cs1', 'cs2', 'eff')): # straxen.dataframe_to_wiki(df, title=f'{data_names}', float_digits=1) return df - def new_component(self, llh_name: str = None, pass_binning: bool = True): - """ - Generate new component with same binning, - usually used on predicting yields - """ + def new_component(self, llh_name: Optional[str] = None, pass_binning: bool = True): + """Generate new component with same binning, usually used on predicting yields.""" if pass_binning: - if hasattr(self, 'bins') and hasattr(self, 'bins_type'): + if hasattr(self, "bins") and hasattr(self, "bins_type"): component = self.__class__( - name=self.name + '_copy', + name=self.name + "_copy", llh_name=llh_name, bins=self.bins, bins_type=self.bins, ) else: - raise ValueError('Should provide bins and bins_type if you want to pass binning!') + raise ValueError("Should provide bins and bins_type if you want to pass binning!") else: component = self.__class__( - name=self.name + '_copy', + name=self.name + "_copy", llh_name=llh_name, ) return component @@ -503,17 +511,15 @@ class ComponentFixed(Component): # Do not initialize this class because it is base __is_base = True - def __init__(self, - *args, **kwargs): - """Initialization""" - if not kwargs.get('file_name', None): - raise ValueError('Should provide file_name for ComponentFixed!') + def __init__(self, *args, **kwargs): + """Initialization.""" + if not kwargs.get("file_name", None): + raise ValueError("Should provide file_name for ComponentFixed!") else: - self._file_name = kwargs.get('file_name', None) + self._file_name = kwargs.get("file_name", None) super().__init__(*args, **kwargs) - def deduce(self, - data_names: list = ('cs1', 'cs2')): + def deduce(self, data_names: Union[List[str], Tuple[str]] = ["cs1", "cs2"]): """Deduce the needed parameters and make the fixed histogram.""" self.data = load_data(self._file_name)[list(data_names)].to_numpy() self.eff = jnp.ones(len(self.data)) @@ -524,16 +530,12 @@ def simulate(self): """Fixed component does not need to simulate.""" raise NotImplementedError - def simulate_hist(self, - parameters, - *args, **kwargs): + def simulate_hist(self, parameters, *args, **kwargs): """Return the fixed histogram.""" normalization_factor = self.get_normalization(self.hist, parameters, len(self.data)) return self.hist * normalization_factor - def simulate_weighted_data(self, - parameters, - *args, **kwargs): + def simulate_weighted_data(self, parameters, *args, **kwargs): """Simulate and return histogram.""" result = [r for r in self.data.T] result.append(np.array(self.eff)) @@ -547,11 +549,11 @@ def simulate_weighted_data(self, @export def add_component_extensions(module1, module2, force=False): - """Add components of module2 to module1""" + """Add components of module2 to module1.""" utils.add_extensions(module1, module2, Component, force=force) @export def _add_component_extension(module, component, force=False): - """Add component to module""" + """Add component to module.""" utils._add_extension(module, component, Component, force=force) diff --git a/appletree/components/ac.py b/appletree/components/ac.py index ecc2da60..3e47d1d7 100644 --- a/appletree/components/ac.py +++ b/appletree/components/ac.py @@ -2,4 +2,4 @@ class AC(ComponentFixed): - norm_type = 'on_pdf' + norm_type = "on_pdf" diff --git a/appletree/components/er.py b/appletree/components/er.py index afa4c400..f1bc463b 100644 --- a/appletree/components/er.py +++ b/appletree/components/er.py @@ -4,7 +4,7 @@ class ERBand(ComponentSim): - norm_type = 'on_pdf' + norm_type = "on_pdf" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -18,7 +18,7 @@ def __init__(self, *args, **kwargs): class ERPeak(ComponentSim): - norm_type = 'on_pdf' + norm_type = "on_pdf" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/appletree/components/nr.py b/appletree/components/nr.py index 4914fd3d..13ddd036 100644 --- a/appletree/components/nr.py +++ b/appletree/components/nr.py @@ -4,7 +4,7 @@ class NR(ComponentSim): - norm_type = 'on_pdf' + norm_type = "on_pdf" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/appletree/config.py b/appletree/config.py index 67882d4b..cdc3e764 100644 --- a/appletree/config.py +++ b/appletree/config.py @@ -1,4 +1,4 @@ -import typing as ty +from typing import Optional, Union, Any from immutabledict import immutabledict from jax import numpy as jnp @@ -7,15 +7,21 @@ import numpy as np from appletree.share import _cached_configs -from appletree.utils import exporter, load_json, get_file_path, integrate_midpoint, cum_integrate_midpoint +from appletree.utils import ( + exporter, + load_json, + get_file_path, + integrate_midpoint, + cum_integrate_midpoint, +) from appletree import interpolation from appletree.interpolation import FLOAT_POS_MIN, FLOAT_POS_MAX export, __all__ = exporter() -OMITTED = '' +OMITTED = "" -__all__ += 'OMITTED'.split() +__all__.extend(["OMITTED"]) @export @@ -23,6 +29,7 @@ def takes_config(*configs): """Decorator for plugin classes, to specify which configs it takes. :param configs: Config instances of configs this plugin takes. + """ def wrapped(plugin_class): @@ -36,15 +43,13 @@ def wrapped(plugin_class): config.taken_by = plugin_class.__name__ result[config.name] = config - if (hasattr(plugin_class, 'takes_config') and len(plugin_class.takes_config)): + if hasattr(plugin_class, "takes_config") and len(plugin_class.takes_config): # Already have some configs set, e.g. because of subclassing # where both child and parent have a takes_config decorator for config in result.values(): if config.name in plugin_class.takes_config: - raise RuntimeError( - f'Attempt to specify config {config.name} twice') - plugin_class.takes_config = immutabledict({ - **plugin_class.takes_config, **result}) + raise RuntimeError(f"Attempt to specify config {config.name} twice") + plugin_class.takes_config = immutabledict({**plugin_class.takes_config, **result}) else: plugin_class.takes_config = immutabledict(result) @@ -55,20 +60,21 @@ def wrapped(plugin_class): @export -class Config(): - """Configuration option taken by a appletree plugin""" - - def __init__(self, - name: str, - type: ty.Union[type, tuple, list] = OMITTED, - default: ty.Any = OMITTED, - help: str = ''): +class Config: + """Configuration option taken by a appletree plugin.""" + + def __init__( + self, + name: str, + type: Union[type, tuple, list, str] = OMITTED, + default: Any = OMITTED, + help: str = "", + ): """Initialization. - :param name: name of the map - :param type: Excepted type of the option's value. - :param default: Default value the option takes. - :param help: description of the map + :param name: name of the map :param type: Excepted type of the option's value. :param + default: Default value the option takes. :param help: description of the map + """ self.name = name self.type = type @@ -82,26 +88,25 @@ def __init__(self, ) def get_default(self): - """Get default value of configuration""" + """Get default value of configuration.""" if self.default is not OMITTED: return self.default - raise ValueError(f"Missing option {self.name} " - f"required by {self.taken_by}") + raise ValueError(f"Missing option {self.name} " f"required by {self.taken_by}") - def build(self, llh_name: str = None): - """Build configuration, set attributes to Config instance""" + def build(self, llh_name: Optional[str] = None): + """Build configuration, set attributes to Config instance.""" raise NotImplementedError @export class Constant(Config): - """Constant is a special config which takes only certain value""" + """Constant is a special config which takes only certain value.""" value = None - def build(self, llh_name: str = None): - """Set value of Constant""" + def build(self, llh_name: Optional[str] = None): + """Set value of Constant.""" if self.name in _cached_configs: value = _cached_configs[self.name] else: @@ -113,10 +118,11 @@ def build(self, llh_name: str = None): try: self.value = value[llh_name] except KeyError: - mesg = f'You specified {self.name} as a dictionary. ' - mesg += f'The key of it should be the name of one ' - mesg += f'of the likelihood, ' - mesg += f'but it is {llh_name}.' + mesg = ( + f"You specified {self.name} as a dictionary. " + f"The key of it should be the name of one " + f"of the likelihood, but it is {llh_name}." + ) raise ValueError(mesg) else: self.value = value @@ -124,16 +130,17 @@ def build(self, llh_name: str = None): @export class Map(Config): - """ - Map is a special config that takes input files. + """Map is a special config that takes input files. + The method `apply` is dynamically assigned. - When using points, the `apply` will be `map_point`, + When using points, the `apply` will be `map_point`, while using regular binning, the `apply` will be `map_regbin`. When using log-binning, we will first convert the positions to log space. + """ - def build(self, llh_name: str = None): - """Cache the map to jnp.array""" + def build(self, llh_name: Optional[str] = None): + """Cache the map to jnp.array.""" if self.name in _cached_configs: file_path = _cached_configs[self.name] @@ -146,10 +153,11 @@ def build(self, llh_name: str = None): try: self.file_path = file_path[llh_name] except KeyError: - mesg = f'You specified {self.name} as a dictionary. ' - mesg += f'The key of it should be the name of one ' - mesg += f'of the likelihood, ' - mesg += f'but it is {llh_name}.' + mesg = ( + f"You specified {self.name} as a dictionary. " + f"The key of it should be the name of one " + f"of the likelihood, but it is {llh_name}." + ) raise ValueError(mesg) else: self.file_path = file_path @@ -159,47 +167,47 @@ def build(self, llh_name: str = None): except Exception: raise ValueError(f"Cannot load {self.name} from {self.file_path}!") - coordinate_type = data['coordinate_type'] - if coordinate_type == 'point' or coordinate_type == 'log_point': + coordinate_type = data["coordinate_type"] + if coordinate_type == "point" or coordinate_type == "log_point": self.build_point(data) - elif coordinate_type == 'regbin' or coordinate_type == 'log_regbin': + elif coordinate_type == "regbin" or coordinate_type == "log_regbin": self.build_regbin(data) else: raise ValueError("map_type must be either 'point' or 'regbin'!") def build_point(self, data): - """Cache the map to jnp.array if bins_type is point""" - if data['coordinate_name'] == 'pdf' or data['coordinate_name'] == 'cdf': - if data['coordinate_type'] == 'log_point': + """Cache the map to jnp.array if bins_type is point.""" + if data["coordinate_name"] == "pdf" or data["coordinate_name"] == "cdf": + if data["coordinate_type"] == "log_point": raise ValueError( - f'It is not a good idea to use log pdf nor cdf ' - f'in map {self.file_path}. ' - f'Because its coordinate type is log-binned. ' + f"It is not a good idea to use log pdf nor cdf " + f"in map {self.file_path}. " + f"Because its coordinate type is log-binned. " ) - if data['coordinate_name'] == 'pdf': - warn(f'Convert {self.name} from (x, pdf) to (cdf, x).') - x, cdf = self.pdf_to_cdf(data['coordinate_system'], data['map']) - data['coordinate_name'] = 'cdf' - data['coordinate_system'] = cdf - data['map'] = x + if data["coordinate_name"] == "pdf": + warn(f"Convert {self.name} from (x, pdf) to (cdf, x).") + x, cdf = self.pdf_to_cdf(data["coordinate_system"], data["map"]) + data["coordinate_name"] = "cdf" + data["coordinate_system"] = cdf + data["map"] = x - self.coordinate_type = data['coordinate_type'] - self.coordinate_name = data['coordinate_name'] - self.coordinate_system = jnp.asarray(data['coordinate_system'], dtype=float) - self.map = jnp.asarray(data['map'], dtype=float) + self.coordinate_type = data["coordinate_type"] + self.coordinate_name = data["coordinate_name"] + self.coordinate_system = jnp.asarray(data["coordinate_system"], dtype=float) + self.map = jnp.asarray(data["map"], dtype=float) - setattr(self, 'interpolator', interpolation.curve_interpolator) - if self.coordinate_type == 'log_point': + setattr(self, "interpolator", interpolation.curve_interpolator) + if self.coordinate_type == "log_point": if jnp.any(self.coordinate_system <= 0): raise ValueError( - f'Find non-positive coordinate system in map {self.file_path}, ' - f'which is specified as {self.coordinate_type}' + f"Find non-positive coordinate system in map {self.file_path}, " + f"which is specified as {self.coordinate_type}" ) - setattr(self, 'preprocess', self.log_pos) + setattr(self, "preprocess", self.log_pos) else: - setattr(self, 'preprocess', self.linear_pos) - setattr(self, 'apply', self.map_point) + setattr(self, "preprocess", self.linear_pos) + setattr(self, "apply", self.map_point) def map_point(self, pos): val = self.interpolator( @@ -210,37 +218,37 @@ def map_point(self, pos): return val def build_regbin(self, data): - """Cache the map to jnp.array if bins_type is regbin""" - if 'pdf' in data['coordinate_name'] or 'cdf' in data['coordinate_name']: - if data['coordinate_type'] == 'log_regbin': + """Cache the map to jnp.array if bins_type is regbin.""" + if "pdf" in data["coordinate_name"] or "cdf" in data["coordinate_name"]: + if data["coordinate_type"] == "log_regbin": raise ValueError( - f'It is not a good idea to use log pdf nor cdf ' - f'in map {self.file_path}. ' - f'Because its coordinate type is log-binned. ' + f"It is not a good idea to use log pdf nor cdf " + f"in map {self.file_path}. " + f"Because its coordinate type is log-binned. " ) - self.coordinate_type = data['coordinate_type'] - self.coordinate_name = data['coordinate_name'] - self.coordinate_lowers = jnp.asarray(data['coordinate_lowers'], dtype=float) - self.coordinate_uppers = jnp.asarray(data['coordinate_uppers'], dtype=float) - self.map = jnp.asarray(data['map'], dtype=float) + self.coordinate_type = data["coordinate_type"] + self.coordinate_name = data["coordinate_name"] + self.coordinate_lowers = jnp.asarray(data["coordinate_lowers"], dtype=float) + self.coordinate_uppers = jnp.asarray(data["coordinate_uppers"], dtype=float) + self.map = jnp.asarray(data["map"], dtype=float) if len(self.coordinate_lowers) == 1: - setattr(self, 'interpolator', interpolation.map_interpolator_regular_binning_1d) + setattr(self, "interpolator", interpolation.map_interpolator_regular_binning_1d) elif len(self.coordinate_lowers) == 2: - setattr(self, 'interpolator', interpolation.map_interpolator_regular_binning_2d) + setattr(self, "interpolator", interpolation.map_interpolator_regular_binning_2d) elif len(self.coordinate_lowers) == 3: - setattr(self, 'interpolator', interpolation.map_interpolator_regular_binning_3d) - if self.coordinate_type == 'log_regbin': + setattr(self, "interpolator", interpolation.map_interpolator_regular_binning_3d) + if self.coordinate_type == "log_regbin": if jnp.any(self.coordinate_lowers <= 0) or jnp.any(self.coordinate_uppers <= 0): raise ValueError( - f'Find non-positive coordinate system in map {self.file_path}, ' - f'which is specified as {self.coordinate_type}' + f"Find non-positive coordinate system in map {self.file_path}, " + f"which is specified as {self.coordinate_type}" ) - setattr(self, 'preprocess', self.log_pos) + setattr(self, "preprocess", self.log_pos) else: - setattr(self, 'preprocess', self.linear_pos) - setattr(self, 'apply', self.map_regbin) + setattr(self, "preprocess", self.linear_pos) + setattr(self, "apply", self.map_regbin) def map_regbin(self, pos): val = self.interpolator( @@ -258,7 +266,7 @@ def log_pos(self, pos): return jnp.log10(jnp.clip(pos, a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX)) def pdf_to_cdf(self, x, pdf): - """Convert pdf map to cdf map""" + """Convert pdf map to cdf map.""" norm = integrate_midpoint(x, pdf) x, cdf = cum_integrate_midpoint(x, pdf) cdf /= norm @@ -267,16 +275,17 @@ def pdf_to_cdf(self, x, pdf): @export class SigmaMap(Config): - """ - Maps with uncertainty. + """Maps with uncertainty. + Default value is a list whose order is: [median, lower, upper, (parameter)] Each map is assigned as attribute of SigmaMap. If the last element in the list is the required parameter. + """ - def build(self, llh_name: str = None): - """Read maps""" + def build(self, llh_name: Optional[str] = None): + """Read maps.""" self.llh_name = llh_name if self.name in _cached_configs: _configs = _cached_configs[self.name] @@ -289,10 +298,11 @@ def build(self, llh_name: str = None): try: self._configs = _configs[llh_name] except KeyError: - mesg = f'You specified {self.name} as a dictionary. ' - mesg += f'The key of it should be the name of one ' - mesg += f'of the likelihood, ' - mesg += f'but it is {llh_name}.' + mesg = ( + f"You specified {self.name} as a dictionary. " + f"The key of it should be the name of one " + f"of the likelihood, but it is {llh_name}." + ) raise ValueError(mesg) else: self._configs = _configs @@ -300,38 +310,36 @@ def build(self, llh_name: str = None): self._configs_default = self.get_default() maps = dict() - sigmas = ['median', 'lower', 'upper'] + sigmas = ["median", "lower", "upper"] for i, sigma in enumerate(sigmas): - maps[sigma] = Map( - name=self.name + f'_{sigma}', - default=self._configs_default[i]) + maps[sigma] = Map(name=self.name + f"_{sigma}", default=self._configs_default[i]) if maps[sigma].name not in _cached_configs.keys(): _cached_configs[maps[sigma].name] = dict() if isinstance(_cached_configs[maps[sigma].name], dict): # In case some plugins only use the median # and may already update the map name in `_cached_configs` - _cached_configs[maps[sigma].name].update( - {self.llh_name: self._configs[i]}) + _cached_configs[maps[sigma].name].update({self.llh_name: self._configs[i]}) setattr(self, sigma, maps[sigma]) - self.median.build(llh_name=self.llh_name) - self.lower.build(llh_name=self.llh_name) - self.upper.build(llh_name=self.llh_name) + self.median.build(llh_name=self.llh_name) # type: ignore + self.lower.build(llh_name=self.llh_name) # type: ignore + self.upper.build(llh_name=self.llh_name) # type: ignore if len(self._configs) > 4: - raise ValueError(f'You give too much information in {self.name} configs.') + raise ValueError(f"You give too much information in {self.name} configs.") # Find required parameter if len(self._configs) == 4: self.required_parameter = self._configs[-1] print( - f'{self.llh_name} is using the parameter ' - f'{self.required_parameter} in {self.name} map.') + f"{self.llh_name} is using the parameter " + f"{self.required_parameter} in {self.name} map." + ) else: - self.required_parameter = self.name + '_sigma' + self.required_parameter = self.name + "_sigma" def apply(self, pos, parameters): - """Apply SigmaMap with sigma and position""" + """Apply SigmaMap with sigma and position.""" sigma = parameters[self.required_parameter] median = self.median.apply(pos) lower = self.lower.apply(pos) @@ -344,17 +352,16 @@ def apply(self, pos, parameters): @export class ConstantSet(Config): - """ - ConstantSet is a special config which takes a set of values + """ConstantSet is a special config which takes a set of values. + + We will not specify any hard-coded distribution or function here. User should be careful with + the actual function implemented. Fortunately, we only use these values as keyword arguments, so + mismatch will be catched when running. - We will not specify any hard-coded distribution or function here. - User should be careful with the actual function implemented. - Fortunately, we only use these values as keyword arguments, - so mismatch will be catched when running. """ - def build(self, llh_name: str = None): - """Set value of Constant""" + def build(self, llh_name: Optional[str] = None): + """Set value of Constant.""" if self.name in _cached_configs: value = _cached_configs[self.name] else: @@ -366,10 +373,11 @@ def build(self, llh_name: str = None): try: self.value = value[llh_name] except KeyError: - mesg = f'You specified {self.name} as a dictionary. ' - mesg += f'The key of it should be the name of one ' - mesg += f'of the likelihood, ' - mesg += f'but it is {llh_name}.' + mesg = ( + f"You specified {self.name} as a dictionary. " + f"The key of it should be the name of one " + f"of the likelihood, but it is {llh_name}." + ) raise ValueError(mesg) else: self.value = value @@ -380,10 +388,10 @@ def build(self, llh_name: str = None): def _sanity_check(self): """Check if parameter set lengths are same.""" - mesg = 'The given values should follow [names, values] format.' + mesg = "The given values should follow [names, values] format." assert len(self.value) == 2, mesg - mesg = 'Parameters and their names should have same length' + mesg = "Parameters and their names should have same length" assert len(self.value[0]) == len(self.value[1]), mesg volumes = [len(v) for v in self.value[1]] - mesg = 'Parameter set lengths should be the same' + mesg = "Parameter set lengths should be the same" assert np.all(np.isclose(volumes, volumes[0])), mesg diff --git a/appletree/context.py b/appletree/context.py index a05416c4..58756803 100644 --- a/appletree/context.py +++ b/appletree/context.py @@ -4,6 +4,8 @@ import json import importlib from datetime import datetime +from typing import Set, Optional + import numpy as np import emcee import h5py @@ -14,99 +16,94 @@ from appletree.utils import load_json from appletree.share import _cached_configs, set_global_config -os.environ['OMP_NUM_THREADS'] = '1' +os.environ["OMP_NUM_THREADS"] = "1" -class Context(): - """Combine all likelihood (e.g. Rn220, Ar37), - handle MCMC and post-fitting analysis - """ +class Context: + """Combine all likelihood (e.g. Rn220, Ar37), handle MCMC and post-fitting analysis.""" def __init__(self, instruct, par_config=None): - """Create an appletree context + """Create an appletree context. :param instruct: dict or str, instruct file name or dictionary + """ if isinstance(instruct, str): instruct = load_json(instruct) # url_base and configs are not mandatory - if 'url_base' in instruct.keys(): - self.update_url_base(instruct['url_base']) + if "url_base" in instruct.keys(): + self.update_url_base(instruct["url_base"]) self.set_instruct(instruct) - if 'configs' in instruct.keys(): - self.set_config(instruct['configs']) + if "configs" in instruct.keys(): + self.set_config(instruct["configs"]) - self.backend_h5 = instruct.get('backend_h5', None) + self.backend_h5 = instruct.get("backend_h5", None) self.likelihoods = dict() if par_config is not None: self.par_config = copy.deepcopy(par_config) - print('Manually set a parameters list!') + print("Manually set a parameters list!") else: - self.par_config = self.get_parameter_config(instruct['par_config']) - self.needed_parameters = self.update_parameter_config(instruct['likelihoods']) + self.par_config = self.get_parameter_config(instruct["par_config"]) + self.needed_parameters = self.update_parameter_config(instruct["likelihoods"]) self.par_manager = Parameter(self.par_config) self.register_all_likelihood(instruct) def __getitem__(self, keys): - """Get likelihood in context""" + """Get likelihood in context.""" return self.likelihoods[keys] def register_all_likelihood(self, config): - """Create all appletree likelihoods + """Create all appletree likelihoods. :param config: dict, configuration file name or dictionary + """ - components = importlib.import_module('appletree.components') + components = importlib.import_module("appletree.components") - for key, value in config['likelihoods'].items(): + for key, value in config["likelihoods"].items(): likelihood = copy.deepcopy(value) self.register_likelihood(key, likelihood) - for k, v in likelihood['components'].items(): + for k, v in likelihood["components"].items(): # dynamically import components if isinstance(v, str): self.register_component(key, getattr(components, v), k) else: self.register_component( key, - getattr(components, v['component_cls']), + getattr(components, v["component_cls"]), k, - v.get('file_name', None), + v.get("file_name", None), ) - def register_likelihood(self, - likelihood_name, - likelihood_config): - """Create an appletree likelihood + def register_likelihood(self, likelihood_name, likelihood_config): + """Create an appletree likelihood. + + :param likelihood_name: name of Likelihood :param likelihood_config: dict of likelihood + configuration - :param likelihood_name: name of Likelihood - :param likelihood_config: dict of likelihood configuration """ if likelihood_name in self.likelihoods: - raise ValueError(f'Likelihood named {likelihood_name} already existed!') - likelihood = getattr(apt, likelihood_config.get('type', 'Likelihood')) + raise ValueError(f"Likelihood named {likelihood_name} already existed!") + likelihood = getattr(apt, likelihood_config.get("type", "Likelihood")) self.likelihoods[likelihood_name] = likelihood( name=likelihood_name, **likelihood_config, ) - def register_component(self, - likelihood_name, - component_cls, - component_name, - file_name=None): - """Register component to likelihood + def register_component(self, likelihood_name, component_cls, component_name, file_name=None): + """Register component to likelihood. + + :param likelihood_name: name of Likelihood :param component_cls: class of Component :param + component_name: name of Component - :param likelihood_name: name of Likelihood - :param component_cls: class of Component - :param component_name: name of Component """ self[likelihood_name].register_component( component_cls, @@ -120,32 +117,34 @@ def print_context_summary(self, short=True): """Print summary of the context.""" self._sanity_check() - print('\n'+'='*40) + print("\n" + "=" * 40) for key, likelihood in self.likelihoods.items(): - print(f'LIKELIHOOD {key}') + print(f"LIKELIHOOD {key}") likelihood.print_likelihood_summary(short=short) - print('\n'+'='*40) + print("\n" + "=" * 40) def get_num_events_accepted(self, parameters, batch_size=1_000_000): """Get number of events in the histogram under given parameters. - :param batch_size: int of number of simulated events - :param parameters: dict of parameters used in simulation + :param batch_size: int of number of simulated events :param parameters: dict of parameters + used in simulation + """ n_events = 0 for likelihood in self.likelihoods.values(): - if hasattr(likelihood, 'data_hist'): + if hasattr(likelihood, "data_hist"): n_events += likelihood.get_num_events_accepted(batch_size, parameters) else: - warning = f'{likelihood.name} will be omitted.' + warning = f"{likelihood.name} will be omitted." warn(warning) return n_events def log_posterior(self, parameters, batch_size=1_000_000): - """Get log likelihood of given parameters + """Get log likelihood of given parameters. + + :param batch_size: int of number of simulated events :param parameters: dict of parameters + used in simulation - :param batch_size: int of number of simulated events - :param parameters: dict of parameters used in simulation """ self.par_manager.set_parameter(parameters) @@ -171,19 +170,15 @@ def _ndim(self): def _set_backend(self, nwalkers=100, read_only=True): if self.backend_h5 is None: self._backend = None - print('With no backend') + print("With no backend") else: - self._backend = emcee.backends.HDFBackend( - self.backend_h5, read_only=read_only) + self._backend = emcee.backends.HDFBackend(self.backend_h5, read_only=read_only) if not read_only: self._backend.reset(nwalkers, self._ndim) - print(f'With h5 backend {self.backend_h5}') + print(f"With h5 backend {self.backend_h5}") - def pre_fitting(self, - nwalkers=100, - read_only=True, - batch_size=1_000_000): - """Prepare for fitting, initialize backend and sampler""" + def pre_fitting(self, nwalkers=100, read_only=True, batch_size=1_000_000): + """Prepare for fitting, initialize backend and sampler.""" self._set_backend(nwalkers, read_only=read_only) self.sampler = emcee.EnsembleSampler( nwalkers, @@ -192,14 +187,15 @@ def pre_fitting(self, backend=self._backend, blobs_dtype=np.float32, parameter_names=self.par_manager.parameter_fit, - kwargs = {'batch_size': batch_size}, + kwargs={"batch_size": batch_size}, ) def fitting(self, nwalkers=200, iteration=500, batch_size=1_000_000): - """Fitting posterior distribution of needed parameters + """Fitting posterior distribution of needed parameters. + + :param nwalkers: int, number of walkers in the ensemble :param iteration: int, number of + steps to generate - :param nwalkers: int, number of walkers in the ensemble - :param iteration: int, number of steps to generate """ self._sanity_check() @@ -208,10 +204,7 @@ def fitting(self, nwalkers=200, iteration=500, batch_size=1_000_000): self.par_manager.sample_init() p0.append(self.par_manager.parameter_fit_array) - self.pre_fitting( - nwalkers=nwalkers, - read_only=False, - batch_size=batch_size) + self.pre_fitting(nwalkers=nwalkers, read_only=False, batch_size=batch_size) result = self.sampler.run_mcmc( p0, @@ -224,10 +217,10 @@ def fitting(self, nwalkers=200, iteration=500, batch_size=1_000_000): return result def continue_fitting(self, context, iteration=500, batch_size=1_000_000): - """Continue a fitting of another context + """Continue a fitting of another context. + + :param context: appletree context :param iteration: int, number of steps to generate - :param context: appletree context - :param iteration: int, number of steps to generate """ # Final iteration final_iteration = context.sampler.get_chain()[-1, :, :] @@ -236,10 +229,7 @@ def continue_fitting(self, context, iteration=500, batch_size=1_000_000): nwalkers = len(p0) # Init sampler for current context - self.pre_fitting( - nwalkers=nwalkers, - read_only=False, - batch_size=batch_size) + self.pre_fitting(nwalkers=nwalkers, read_only=False, batch_size=batch_size) result = self.sampler.run_mcmc( p0, @@ -253,7 +243,7 @@ def continue_fitting(self, context, iteration=500, batch_size=1_000_000): return result def get_post_parameters(self): - """Get parameters correspondes to max posterior""" + """Get parameters correspondes to max posterior.""" logp = self.sampler.get_log_prob(flat=True) chain = self.sampler.get_chain(flat=True) mpe_parameters = chain[np.argmax(logp)] @@ -266,58 +256,60 @@ def get_post_parameters(self): return parameters def get_all_post_parameters(self, **kwargs): - """Return all posterior parameters""" + """Return all posterior parameters.""" chain = self.sampler.get_chain(**kwargs) return chain def dump_post_parameters(self, file_name): - """Dump max posterior parameter in .json file""" + """Dump max posterior parameter in .json file.""" parameters = self.get_post_parameters() - with open(file_name, 'w') as fp: + with open(file_name, "w") as fp: json.dump(parameters, fp) def _dump_meta(self, metadata=None): - """Save parameters name as attributes""" + """Save parameters name as attributes.""" if metadata is None: metadata = { - 'version': apt.__version__, - 'date': datetime.now().strftime('%Y%m%d_%H:%M:%S'), + "version": apt.__version__, + "date": datetime.now().strftime("%Y%m%d_%H:%M:%S"), } if self.backend_h5 is not None: name = self.sampler.backend.name - with h5py.File(self.backend_h5, 'r+') as opt: - opt[name].attrs['metadata'] = json.dumps(metadata) + with h5py.File(self.backend_h5, "r+") as opt: + opt[name].attrs["metadata"] = json.dumps(metadata) # parameters prior configuration - opt[name].attrs['par_config'] = json.dumps(self.par_manager.par_config) + opt[name].attrs["par_config"] = json.dumps(self.par_manager.par_config) # max posterior parameters - opt[name].attrs['post_parameters'] = json.dumps(self.get_post_parameters()) + opt[name].attrs["post_parameters"] = json.dumps(self.get_post_parameters()) # the order of parameters saved in backend - opt[name].attrs['parameter_fit'] = self.par_manager.parameter_fit + opt[name].attrs["parameter_fit"] = self.par_manager.parameter_fit # instructions - opt[name].attrs['instruct'] = json.dumps(self.instruct) + opt[name].attrs["instruct"] = json.dumps(self.instruct) # configs - opt[name].attrs['config'] = json.dumps(self.config) + opt[name].attrs["config"] = json.dumps(self.config) # configurations, maybe users will manually add some maps - opt[name].attrs['_cached_configs'] = json.dumps(_cached_configs) - - def get_template(self, - likelihood_name: str, - component_name: str, - batch_size: int = 1_000_000, - seed: int = None): - """Get parameters correspondes to max posterior - - :param likelihood_name: name of Likelihood - :param component_name: name of Component - :param batch_size: int of number of simulated events - :param seed: random seed + opt[name].attrs["_cached_configs"] = json.dumps(_cached_configs) + + def get_template( + self, + likelihood_name: str, + component_name: str, + batch_size: int = 1_000_000, + seed: Optional[int] = None, + ): + """Get parameters correspondes to max posterior. + + :param likelihood_name: name of Likelihood :param component_name: name of Component :param + batch_size: int of number of simulated events :param seed: random seed + """ parameters = self.get_post_parameters() key = randgen.get_key(seed=seed) key, result = self[likelihood_name][component_name].simulate( key, - batch_size, parameters, + batch_size, + parameters, ) return result @@ -327,36 +319,39 @@ def _sanity_check(self): provided = set(self.par_manager.get_all_parameter().keys()) # We will not update unneeded parameters! if not provided.issubset(needed): - mes = f'Parameter manager should provide needed parameters only, ' - mes += f'{provided - needed} not needed' + mes = ( + f"Parameter manager should provide needed parameters only, " + f"{provided - needed} not needed." + ) raise RuntimeError(mes) def update_url_base(self, url_base): - """Update url_base in appletree.share""" - print(f'Updated url_base to {url_base}') - set_global_config({'url_base': url_base}) + """Update url_base in appletree.share.""" + print(f"Updated url_base to {url_base}") + set_global_config({"url_base": url_base}) def get_parameter_config(self, par_config): - """Get configuration for parameter manager + """Get configuration for parameter manager. :param par_config: str, parameters configuration file + """ par_config = load_json(par_config) return par_config def update_parameter_config(self, likelihoods): - needed_parameters = set() + needed_parameters: Set[str] = set() needed_rate_parameters = [] from_parameters = [] for likelihood in likelihoods.values(): - for k, v in likelihood['copy_parameters'].items(): + for k, v in likelihood["copy_parameters"].items(): # specify rate scale # normalization factor, for AC & ER, etc. self.par_config.update({k: self.par_config[v]}) from_parameters.append(v) needed_parameters.add(k) - for k in likelihood['components'].keys(): - needed_rate_parameters.append(k + '_rate') + for k in likelihood["components"].keys(): + needed_rate_parameters.append(k + "_rate") for p in from_parameters: if p not in needed_rate_parameters and p in self.par_config: # Drop unused parameters @@ -364,22 +359,24 @@ def update_parameter_config(self, likelihoods): return needed_parameters def set_instruct(self, instructs): - """Set instruction + """Set instruction. :param instructs: dict, instruction file name or dictionary + """ - if not hasattr(self, 'instruct'): + if not hasattr(self, "instruct"): self.instruct = dict() # update instructuration only in this Context self.instruct.update(instructs) def set_config(self, configs): - """Set new configuration options + """Set new configuration options. :param configs: dict, configuration file name or dictionary + """ - if not hasattr(self, 'config'): + if not hasattr(self, "config"): self.config = dict() # update configuration only in this Context @@ -388,7 +385,7 @@ def set_config(self, configs): # also store required configurations to appletree.share set_global_config(configs) - def lineage(self, data_name: str = 'cs2'): + def lineage(self, data_name: str = "cs2"): """Return lineage of plugins.""" assert isinstance(data_name, str) pass diff --git a/appletree/contexts/er_only.py b/appletree/contexts/er_only.py index 2a025ae5..d50ddcc0 100644 --- a/appletree/contexts/er_only.py +++ b/appletree/contexts/er_only.py @@ -3,18 +3,18 @@ class ContextRn220(Context): - """A specified context for ER response by Rn220 fit""" + """A specified context for ER response by Rn220 fit.""" def __init__(self): - """Initialization""" - config = get_file_path('rn220.json') + """Initialization.""" + config = get_file_path("rn220.json") super().__init__(config) class ContextRn220Ar37(Context): - """A specified context for ER response by Rn220 & Ar37 combined fit""" + """A specified context for ER response by Rn220 & Ar37 combined fit.""" def __init__(self): - """Initialization""" - config = get_file_path('rn220_ar37.json') + """Initialization.""" + config = get_file_path("rn220_ar37.json") super().__init__(config) diff --git a/appletree/hist.py b/appletree/hist.py index b1f01fdc..08614afb 100644 --- a/appletree/hist.py +++ b/appletree/hist.py @@ -19,20 +19,19 @@ def make_hist_mesh_grid(sample, bins=10, weights=None): def make_hist_irreg_bin_2d(sample, bins_x, bins_y, weights): """Make a histogram with irregular binning. - :param sample: array with shape (N, 2) - :param bins_x: array with shape (M1, ) - :param bins_y: array with shape (M1-1, M2) - :param weights: array with shape (N, ) + :param sample: array with shape (N, 2) :param bins_x: array with shape (M1, ) :param bins_y: + array with shape (M1-1, M2) :param weights: array with shape (N, ) + """ x = sample[:, 0] y = sample[:, 1] ind_x = jnp.searchsorted(bins_x, x) - ind_y = vmap(jnp.searchsorted, (0, 0), 0)(bins_y[ind_x-1], y) + ind_y = vmap(jnp.searchsorted, (0, 0), 0)(bins_y[ind_x - 1], y) bin_ind = jnp.stack((ind_x, ind_y)) - output_shape = (len(bins_x)+1, bins_y.shape[-1]+1) + output_shape = (len(bins_x) + 1, bins_y.shape[-1] + 1) hist = jnp.zeros(output_shape) hist = hist.at[tuple(bin_ind)].add(weights) diff --git a/appletree/interpolation.py b/appletree/interpolation.py index 52a1dced..e0486416 100644 --- a/appletree/interpolation.py +++ b/appletree/interpolation.py @@ -15,9 +15,9 @@ def _L2_dist2(pos1, pos2): """Calculate L2 distance between pos1 and pos2. - :param pos1: array with shape (N, D) - :param pos2: array with shape (M, D) - :return: L2 distance squared with shape (N, M) + :param pos1: array with shape (N, D) :param pos2: array with shape (M, D) :return: L2 distance + squared with shape (N, M) + """ dr = jnp.expand_dims(pos1, axis=1) - jnp.expand_dims(pos2, axis=0) return jnp.sum(dr * dr, axis=-1) @@ -28,11 +28,11 @@ def _L2_dist2(pos1, pos2): def map_interpolator_knn(pos, ref_pos, ref_val, k=3): """Inverse distance weighting average as interpolation using KNN. - :param pos: array with shape (N, D), as the points to be interpolated. - :param ref_pos: array with shape (M, D), as the reference points. - :param ref_val: array with shape (M, ), as the reference values. - :return: interpolated values with shape (N, ), weighted by the inverse of - the distance to k nearest neighbors. + :param pos: array with shape (N, D), as the points to be interpolated. :param ref_pos: array + with shape (M, D), as the reference points. :param ref_val: array with shape (M, ), as the + reference values. :return: interpolated values with shape (N, ), weighted by the inverse of the + distance to k nearest neighbors. + """ pos = jnp.asarray(pos) ref_pos = jnp.asarray(ref_pos) @@ -40,7 +40,7 @@ def map_interpolator_knn(pos, ref_pos, ref_val, k=3): dr2 = -_L2_dist2(pos, ref_pos) dr2, ind = lax.top_k(dr2, k) - weights = 1.0 / jnp.clip(jnp.sqrt(-dr2), 1e-6, float('inf')) + weights = 1.0 / jnp.clip(jnp.sqrt(-dr2), 1e-6, float("inf")) val = jnp.take(ref_val, ind) val = jnp.sum(val * weights, axis=1) / jnp.sum(weights, axis=1) @@ -52,17 +52,17 @@ def map_interpolator_knn(pos, ref_pos, ref_val, k=3): def curve_interpolator(pos, ref_pos, ref_val): """Inverse distance weighting average as interpolation using KNN (K=2) for 1D map. - :param pos: array with shape (N, ), as the points to be interpolated. - :param ref_pos: array with shape (M, ), as the reference points. - :param ref_val: array with shape (M, ), as the reference values. - :return: interpolated values with shape (N, ), weighted by the inverse of - the distance to k nearest neighbors. + :param pos: array with shape (N, ), as the points to be interpolated. :param ref_pos: array with + shape (M, ), as the reference points. :param ref_val: array with shape (M, ), as the reference + values. :return: interpolated values with shape (N, ), weighted by the inverse of the + distance to k nearest neighbors. + """ right = jnp.searchsorted(ref_pos, pos) left = right - 1 - right = jnp.clip(right, 0, len(ref_pos)-1) - left = jnp.clip(left, 0, len(ref_pos)-1) + right = jnp.clip(right, 0, len(ref_pos) - 1) + left = jnp.clip(left, 0, len(ref_pos) - 1) val_right = ref_val[right] val_left = ref_val[left] @@ -71,8 +71,8 @@ def curve_interpolator(pos, ref_pos, ref_val): dist_left = jnp.abs(pos - ref_pos[left]) val = jnp.where( - (dist_right+dist_left) > 0, - (val_right*dist_left+val_left*dist_right)/(dist_right+dist_left), + (dist_right + dist_left) > 0, + (val_right * dist_left + val_left * dist_right) / (dist_right + dist_left), val_right, ) return val @@ -81,13 +81,14 @@ def curve_interpolator(pos, ref_pos, ref_val): @export @jit def map_interpolator_regular_binning_1d(pos, ref_pos_lowers, ref_pos_uppers, ref_val): - """Inverse distance weighting average as 1D interpolation using KNN(K=2). - A uniform mesh grid binning is assumed. + """Inverse distance weighting average as 1D interpolation using KNN(K=2). A uniform mesh grid + binning is assumed. + + :param pos: array with shape (N, ), positions at which the interp is calculated. :param + ref_pos_lowers: array with shape (1, ), the lower edges of the binning on each dimension. :param + ref_pos_uppers: array with shape (1, ), the upper edges of the binning on each dimension. :param + ref_val: array with shape (M1, ), map values. - :param pos: array with shape (N, ), positions at which the interp is calculated. - :param ref_pos_lowers: array with shape (1, ), the lower edges of the binning on each dimension. - :param ref_pos_uppers: array with shape (1, ), the upper edges of the binning on each dimension. - :param ref_val: array with shape (M1, ), map values. """ ref_pos = jnp.linspace(ref_pos_lowers, ref_pos_uppers, len(ref_val)) val = curve_interpolator(pos, ref_pos, ref_val) @@ -98,13 +99,14 @@ def map_interpolator_regular_binning_1d(pos, ref_pos_lowers, ref_pos_uppers, ref @export @jit def map_interpolator_regular_binning_2d(pos, ref_pos_lowers, ref_pos_uppers, ref_val): - """Inverse distance weighting average as 2D interpolation using KNN(K=4). - A uniform mesh grid binning is assumed. + """Inverse distance weighting average as 2D interpolation using KNN(K=4). A uniform mesh grid + binning is assumed. + + :param pos: array with shape (N, 2), positions at which the interp is calculated. :param + ref_pos_lowers: array with shape (2, ), the lower edges of the binning on each dimension. :param + ref_pos_uppers: array with shape (2, ), the upper edges of the binning on each dimension. :param + ref_val: array with shape (M1, M2), map values. - :param pos: array with shape (N, 2), positions at which the interp is calculated. - :param ref_pos_lowers: array with shape (2, ), the lower edges of the binning on each dimension. - :param ref_pos_uppers: array with shape (2, ), the upper edges of the binning on each dimension. - :param ref_val: array with shape (M1, M2), map values. """ num_bins = jnp.asarray(jnp.shape(ref_val)) bin_sizes = (ref_pos_uppers - ref_pos_lowers) / (num_bins - 1) @@ -112,7 +114,7 @@ def map_interpolator_regular_binning_2d(pos, ref_pos_lowers, ref_pos_uppers, ref bin_sizes = bin_sizes[jnp.newaxis, :] ind1 = jnp.floor((pos - ref_pos_lowers) / bin_sizes) - ind1 = jnp.clip(ind1, a_min=0, a_max=num_bins-1) + ind1 = jnp.clip(ind1, a_min=0, a_max=num_bins - 1) ind1 = jnp.asarray(ind1, dtype=int) ind2 = ind1.at[:, 0].add(1) ind3 = ind1.at[:, 1].add(1) @@ -128,13 +130,21 @@ def map_interpolator_regular_binning_2d(pos, ref_pos_lowers, ref_pos_uppers, ref ref_pos3 = ref_pos_lowers + bin_sizes * ind3 ref_pos4 = ref_pos_lowers + bin_sizes * ind4 - dr1 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos1 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr2 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos2 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr3 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos3 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr4 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos4 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) + dr1 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos1 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr2 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos2 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr3 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos3 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr4 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos4 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) - val = (val1/dr1+val2/dr2+val3/dr3+val4/dr4) - val /= (1./dr1+1./dr2+1./dr3+1./dr4) + val = val1 / dr1 + val2 / dr2 + val3 / dr3 + val4 / dr4 + val /= 1.0 / dr1 + 1.0 / dr2 + 1.0 / dr3 + 1.0 / dr4 return val @@ -142,13 +152,14 @@ def map_interpolator_regular_binning_2d(pos, ref_pos_lowers, ref_pos_uppers, ref @export @jit def map_interpolator_regular_binning_3d(pos, ref_pos_lowers, ref_pos_uppers, ref_val): - """Inverse distance weighting average as 3D interpolation using KNN(K=8). - A uniform mesh grid binning is assumed. + """Inverse distance weighting average as 3D interpolation using KNN(K=8). A uniform mesh grid + binning is assumed. + + :param pos: array with shape (N, 3), positions at which the interp is calculated. :param + ref_pos_lowers: array with shape (3, ), the lower edges of the binning on each dimension. :param + ref_pos_uppers: array with shape (3, ), the upper edges of the binning on each dimension. :param + ref_val: array with shape (M1, M2, M3), map values. - :param pos: array with shape (N, 3), positions at which the interp is calculated. - :param ref_pos_lowers: array with shape (3, ), the lower edges of the binning on each dimension. - :param ref_pos_uppers: array with shape (3, ), the upper edges of the binning on each dimension. - :param ref_val: array with shape (M1, M2, M3), map values. """ num_bins = jnp.asarray(jnp.shape(ref_val)) bin_sizes = (ref_pos_uppers - ref_pos_lowers) / (num_bins - 1) @@ -156,7 +167,7 @@ def map_interpolator_regular_binning_3d(pos, ref_pos_lowers, ref_pos_uppers, ref bin_sizes = bin_sizes[jnp.newaxis, :] ind1 = jnp.floor((pos - ref_pos_lowers) / bin_sizes) - ind1 = jnp.clip(ind1, a_min=0, a_max=num_bins-1) + ind1 = jnp.clip(ind1, a_min=0, a_max=num_bins - 1) ind1 = jnp.asarray(ind1, dtype=int) ind2 = ind1.at[:, 0].add(1) ind3 = ind1.at[:, 1].add(1) @@ -184,16 +195,50 @@ def map_interpolator_regular_binning_3d(pos, ref_pos_lowers, ref_pos_uppers, ref ref_pos7 = ref_pos_lowers + bin_sizes * ind7 ref_pos8 = ref_pos_lowers + bin_sizes * ind8 - dr1 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos1 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr2 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos2 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr3 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos3 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr4 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos4 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr5 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos5 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr6 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos6 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr7 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos7 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - dr8 = jnp.clip(jnp.sqrt(jnp.sum((ref_pos8 - pos)**2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX) - - val = (val1/dr1+val2/dr2+val3/dr3+val4/dr4+val5/dr5+val6/dr6+val7/dr7+val8/dr8) - val /= (1./dr1+1./dr2+1./dr3+1./dr4+1./dr5+1./dr6+1./dr7+1./dr8) + dr1 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos1 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr2 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos2 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr3 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos3 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr4 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos4 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr5 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos5 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr6 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos6 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr7 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos7 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + dr8 = jnp.clip( + jnp.sqrt(jnp.sum((ref_pos8 - pos) ** 2, axis=-1)), a_min=FLOAT_POS_MIN, a_max=FLOAT_POS_MAX + ) + + val = ( + val1 / dr1 + + val2 / dr2 + + val3 / dr3 + + val4 / dr4 + + val5 / dr5 + + val6 / dr6 + + val7 / dr7 + + val8 / dr8 + ) + val /= ( + 1.0 / dr1 + + 1.0 / dr2 + + 1.0 / dr3 + + 1.0 / dr4 + + 1.0 / dr5 + + 1.0 / dr6 + + 1.0 / dr7 + + 1.0 / dr8 + ) return val diff --git a/appletree/likelihood.py b/appletree/likelihood.py index c984efec..69826d7a 100644 --- a/appletree/likelihood.py +++ b/appletree/likelihood.py @@ -1,4 +1,5 @@ from warnings import warn +from typing import Type, Dict, Set, Optional, cast import numpy as np from jax import numpy as jnp @@ -13,10 +14,10 @@ class Likelihood: - """Combine all components (e.g. ER, AC, Wall), and calculate log posterior likelihood""" + """Combine all components (e.g. ER, AC, Wall), and calculate log posterior likelihood.""" - def __init__(self, name: str = None, **config): - """Create an appletree likelihood + def __init__(self, name: Optional[str] = None, **config): + """Create an appletree likelihood. :param config: Dictionary with configuration options that will be applied, should include: @@ -24,55 +25,56 @@ def __init__(self, name: str = None, **config): * bins_type: either meshgrid or equiprob * bins_on: observables where we will perform inference on, usually [cs1, cs2] * x_clip, y_clip: ROI of the fitting, should be list of upper and lower boundary + """ if name is None: self.name = self.__class__.__name__ else: self.name = name - self.components = dict() + self.components = cast(Dict[str, Component], dict()) self._config = config - self._data_file_name = config['data_file_name'] - self._bins_type = config['bins_type'] - self._bins_on = config['bins_on'] - self._bins = config['bins'] + self._data_file_name = config["data_file_name"] + self._bins_type = config["bins_type"] + self._bins_on = config["bins_on"] + self._bins = config["bins"] self._dim = len(self._bins_on) if self._dim != 2: - raise ValueError('Currently only support 2D fitting') - self.needed_parameters = set() + raise ValueError("Currently only support 2D fitting") + self.needed_parameters: Set[str] = set() self._sanity_check() self.data = load_data(self._data_file_name)[self._bins_on].to_numpy() - mask = (self.data[:, 0] > config['x_clip'][0]) - mask &= (self.data[:, 0] < config['x_clip'][1]) - mask &= (self.data[:, 1] > config['y_clip'][0]) - mask &= (self.data[:, 1] < config['y_clip'][1]) + mask = self.data[:, 0] > config["x_clip"][0] + mask &= self.data[:, 0] < config["x_clip"][1] + mask &= self.data[:, 1] > config["y_clip"][0] + mask &= self.data[:, 1] < config["y_clip"][1] self.data = self.data[mask] self.set_binning(config) def __getitem__(self, keys): - """Get component in likelihood""" + """Get component in likelihood.""" return self.components[keys] def set_binning(self, config): - """Set binning of likelihood""" - if self._bins_type == 'meshgrid': - warning = f'The usage of meshgrid binning is highly discouraged.' + """Set binning of likelihood.""" + if self._bins_type == "meshgrid": + warning = "The usage of meshgrid binning is highly discouraged." warn(warning) - self.component_bins_type = 'meshgrid' + self.component_bins_type = "meshgrid" if isinstance(self._bins[0], int): - x_bins = jnp.linspace(*config['x_clip'], self._bins[0] + 1) + x_bins = jnp.linspace(*config["x_clip"], self._bins[0] + 1) else: x_bins = jnp.array(self._bins[0]) - if 'x_clip' in config: - warning = f'x_clip is ignored when bins_type is meshgrid and bins is not int' + if "x_clip" in config: + warning = "x_clip is ignored when bins_type is meshgrid and bins is not int" warn(warning) if isinstance(self._bins[1], int): - y_bins = jnp.linspace(*config['y_clip'], self._bins[1] + 1) + y_bins = jnp.linspace(*config["y_clip"], self._bins[1] + 1) else: y_bins = jnp.array(self._bins[1]) - if 'y_clip' in config: - warning = f'y_clip is ignored when bins_type is meshgrid and bins is not int' + if "y_clip" in config: + warning = "y_clip is ignored when bins_type is meshgrid and bins is not int" warn(warning) self._bins = (x_bins, y_bins) self.data_hist = make_hist_mesh_grid( @@ -80,38 +82,39 @@ def set_binning(self, config): bins=self._bins, weights=jnp.ones(len(self.data)), ) - elif self._bins_type == 'equiprob': + elif self._bins_type == "equiprob": if self._dim != 2: - raise RuntimeError('only 2D equiprob binned likelihood is supported!') + raise RuntimeError("only 2D equiprob binned likelihood is supported!") if isinstance(self._bins[0], int) and isinstance(self._bins[1], int): pass else: - raise RuntimeError('bins can only be int if bins_type is equiprob') + raise RuntimeError("bins can only be int if bins_type is equiprob") self._bins = get_equiprob_bins_2d( self.data, self._bins, - x_clip=config['x_clip'], - y_clip=config['y_clip'], - which_np=jnp) - self.component_bins_type = 'irreg' + x_clip=config["x_clip"], + y_clip=config["y_clip"], + which_np=jnp, + ) + self.component_bins_type = "irreg" self.data_hist = make_hist_irreg_bin_2d( self.data, bins_x=self._bins[0], bins_y=self._bins[1], weights=jnp.ones(len(self.data)), ) - elif self._bins_type == 'irreg': + elif self._bins_type == "irreg": if self._dim != 2: - raise RuntimeError('only 2D irregular binned likelihood is supported!') + raise RuntimeError("only 2D irregular binned likelihood is supported!") self._bins[0] = jnp.array(self._bins[0]) self._bins[1] = jnp.array(self._bins[1]) - self.component_bins_type = 'irreg' + self.component_bins_type = "irreg" # x-binning should 1 longer than y-binning mask0 = len(self._bins[0]) != len(self._bins[1]) + 1 # all y-binning should have the same length mask1 = not all(len(b) == len(self._bins[1][0]) for b in self._bins[1]) if mask0 or mask1: - raise ValueError(f'Please check the binning in {self.name}!') + raise ValueError(f"Please check the binning in {self.name}!") self.data_hist = make_hist_irreg_bin_2d( self.data, bins_x=self._bins[0], @@ -121,18 +124,17 @@ def set_binning(self, config): else: raise ValueError("'bins_type' should either be meshgrid, equiprob or irreg") - def register_component(self, - component_cls: Component, - component_name: str, - file_name: str = None): + def register_component( + self, component_cls: Type[Component], component_name: str, file_name: Optional[str] = None + ): """Create an appletree likelihood. - :param component_cls: class of Component - :param component_name: name of Component - :param file_name: file used in ComponentFixed + :param component_cls: class of Component :param component_name: name of Component :param + file_name: file used in ComponentFixed + """ if component_name in self.components: - raise ValueError(f'Component named {component_name} already existed!') + raise ValueError(f"Component named {component_name} already existed!") # Initialize component component = component_cls( @@ -142,11 +144,11 @@ def register_component(self, bins_type=self.component_bins_type, file_name=file_name, ) - component.rate_name = component_name + '_rate' - kwargs = {'data_names': self._bins_on} + component.rate_name = component_name + "_rate" + kwargs = {"data_names": self._bins_on} if isinstance(component, ComponentSim): - kwargs['func_name'] = self.name + '_' + component_name + '_sim' - kwargs['data_names'] = self._bins_on + ['eff'] + kwargs["func_name"] = self.name + "_" + component_name + "_sim" + kwargs["data_names"] = self._bins_on + ["eff"] component.deduce(**kwargs) component.compile() @@ -157,16 +159,16 @@ def register_component(self, self.needed_parameters |= self.components[component_name].needed_parameters def _sanity_check(self): - """Check equality between number of bins group and observables""" + """Check equality between number of bins group and observables.""" if len(self._bins_on) != len(self._bins): - raise RuntimeError('Length of bins must be the same as length of bins_on!') + raise RuntimeError("Length of bins must be the same as length of bins_on!") def _simulate_model_hist(self, key, batch_size, parameters): """Histogram of simulated observables. - :param key: a pseudo-random number generator (PRNG) key - :param batch_size: int of number of simulated events - :param parameters: dict of parameters used in simulation + :param key: a pseudo-random number generator (PRNG) key :param batch_size: int of number of + simulated events :param parameters: dict of parameters used in simulation + """ hist = jnp.zeros_like(self.data_hist) for component_name, component in self.components.items(): @@ -175,16 +177,16 @@ def _simulate_model_hist(self, key, batch_size, parameters): elif isinstance(component, ComponentFixed): _hist = component.simulate_hist(parameters) else: - raise TypeError(f'unsupported component type for {component_name}!') + raise TypeError(f"unsupported component type for {component_name}!") hist += _hist return key, hist def simulate_weighted_data(self, key, batch_size, parameters): """Simulate weighted histogram. - :param key: a pseudo-random number generator (PRNG) key - :param batch_size: int of number of simulated events - :param parameters: dict of parameters used in simulation + :param key: a pseudo-random number generator (PRNG) key :param batch_size: int of number of + simulated events :param parameters: dict of parameters used in simulation + """ result = [] for component_name, component in self.components.items(): @@ -193,7 +195,7 @@ def simulate_weighted_data(self, key, batch_size, parameters): elif isinstance(component, ComponentFixed): _result = component.simulate_weighted_data(parameters) else: - raise TypeError(f'unsupported component type for {component_name}!') + raise TypeError(f"unsupported component type for {component_name}!") result.append(_result) result = list(r for r in np.hstack(result)) return key, result @@ -201,9 +203,9 @@ def simulate_weighted_data(self, key, batch_size, parameters): def get_log_likelihood(self, key, batch_size, parameters): """Get log likelihood of given parameters. - :param key: a pseudo-random number generator (PRNG) key - :param batch_size: int of number of simulated events - :param parameters: dict of parameters used in simulation + :param key: a pseudo-random number generator (PRNG) key :param batch_size: int of number of + simulated events :param parameters: dict of parameters used in simulation + """ key, model_hist = self._simulate_model_hist(key, batch_size, parameters) # Poisson likelihood @@ -216,76 +218,75 @@ def get_log_likelihood(self, key, batch_size, parameters): def get_num_events_accepted(self, batch_size, parameters): """Get number of events in the histogram under given parameters. - :param batch_size: int of number of simulated events - :param parameters: dict of parameters used in simulation + :param batch_size: int of number of simulated events :param parameters: dict of parameters + used in simulation + """ key = randgen.get_key() _, model_hist = self._simulate_model_hist(key, batch_size, parameters) return model_hist.sum() - def print_likelihood_summary(self, - indent: str = ' '*4, - short: bool = True): + def print_likelihood_summary(self, indent: str = " " * 4, short: bool = True): """Print likelihood summary: components, bins, file names. :param indent: str of indent :param short: bool, whether only print short summary """ - print('\n'+'-'*40) + print("\n" + "-" * 40) - print(f'BINNING\n') - print(f'{indent}bins_type: {self._bins_type}') - print(f'{indent}bins_on: {self._bins_on}') + print("BINNING\n") + print(f"{indent}bins_type: {self._bins_type}") + print(f"{indent}bins_on: {self._bins_on}") if not short: - print(f'{indent}bins: {self._bins}') - print('\n'+'-'*40) + print(f"{indent}bins: {self._bins}") + print("\n" + "-" * 40) - print(f'DATA\n') - print(f'{indent}file_name: {self._data_file_name}') - print(f'{indent}data_rate: {float(self.data_hist.sum())}') - print('\n'+'-'*40) + print("DATA\n") + print(f"{indent}file_name: {self._data_file_name}") + print(f"{indent}data_rate: {float(self.data_hist.sum())}") + print("\n" + "-" * 40) - print('MODEL\n') + print("MODEL\n") for i, component_name in enumerate(self.components): name = component_name component = self[component_name] need = component.needed_parameters - print(f'{indent}COMPONENT {i}: {name}') + print(f"{indent}COMPONENT {i}: {name}") if isinstance(component, ComponentSim): - print(f'{indent*2}type: simulation') - print(f'{indent*2}rate_par: {component.rate_name}') - print(f'{indent*2}pars: {need}') + print(f"{indent*2}type: simulation") + print(f"{indent*2}rate_par: {component.rate_name}") + print(f"{indent*2}pars: {need}") if not short: - print(f'{indent*2}worksheet: {component.worksheet}') + print(f"{indent*2}worksheet: {component.worksheet}") elif isinstance(component, ComponentFixed): - print(f'{indent*2}type: fixed') - print(f'{indent*2}file_name: {component._file_name}') - print(f'{indent*2}rate_par: {component.rate_name}') - print(f'{indent*2}pars: {need}') + print(f"{indent*2}type: fixed") + print(f"{indent*2}file_name: {component._file_name}") + print(f"{indent*2}rate_par: {component.rate_name}") + print(f"{indent*2}pars: {need}") if not short: - print(f'{indent*2}from_file: {component.file_name}') + print(f"{indent*2}from_file: {component._file_name}") else: pass print() - print('-'*40) + print("-" * 40) class LikelihoodLit(Likelihood): - """ - Using literature constraint to build LLH + """Using literature constraint to build LLH. + + The idea is to simulate light and charge yields directly with given energy distribution. And + then fit the result with provided literature measurement points. The energy distribution will + always be twohalfnorm(TwoHalfNorm), norm or band, which is specified by - The idea is to simulate light and charge yields directly with given energy distribution. - And then fit the result with provided literature measurement points. - The energy distribution will always be twohalfnorm(TwoHalfNorm), norm or band, - which is specified by """ - def __init__(self, name: str = None, **config): - """Create an appletree likelihood + def __init__(self, name: Optional[str] = None, **config): + """Create an appletree likelihood. :param config: Dictionary with configuration options that will be applied, should include: + """ if name is None: self.name = self.__class__.__name__ @@ -295,49 +296,45 @@ def __init__(self, name: str = None, **config): self._config = config self._bins = None self._bins_type = None - self._bins_on = config['bins_on'] + self._bins_on = config["bins_on"] self._dim = len(self._bins_on) - self.needed_parameters = set() + self.needed_parameters: Set[str] = set() self.component_bins_type = None - logpdf_args = self._config['logpdf_args'] - self.logpdf_args = { - k: np.array(v) for k, v in zip(*logpdf_args)} + logpdf_args = self._config["logpdf_args"] + self.logpdf_args = {k: np.array(v) for k, v in zip(*logpdf_args)} - self.variable_type = config['variable_type'] - self.warning = 'Currently only support one dimensional inference' + self.variable_type = config["variable_type"] + self.warning = "Currently only support one dimensional inference" self._sanity_check() - if self.variable_type == 'twohalfnorm': - setattr(self, 'logpdf', lambda x, y: TwoHalfNorm.logpdf( - x=y, **self.logpdf_args)) - elif self.variable_type == 'norm': - setattr(self, 'logpdf', lambda x, y: norm.logpdf( - x=y, **self.logpdf_args)) - elif self.variable_type == 'band': + if self.variable_type == "twohalfnorm": + setattr(self, "logpdf", lambda x, y: TwoHalfNorm.logpdf(x=y, **self.logpdf_args)) + elif self.variable_type == "norm": + setattr(self, "logpdf", lambda x, y: norm.logpdf(x=y, **self.logpdf_args)) + elif self.variable_type == "band": self.bandtwohalfnorm = BandTwoHalfNorm(**self.logpdf_args) - setattr(self, 'logpdf', lambda x, y: self.bandtwohalfnorm.logpdf(x=x, y=y)) + setattr(self, "logpdf", lambda x, y: self.bandtwohalfnorm.logpdf(x=x, y=y)) else: raise NotImplementedError def _sanity_check(self): - """Check sanities of supported distribution and dimension""" - if self.variable_type not in ['twohalfnorm', 'norm', 'band']: - raise RuntimeError('Currently only twohalfnorm, norm and band are supported') + """Check sanities of supported distribution and dimension.""" + if self.variable_type not in ["twohalfnorm", "norm", "band"]: + raise RuntimeError("Currently only twohalfnorm, norm and band are supported") if self._dim != 2: raise AssertionError(self.warning) def _simulate_yields(self, key, batch_size, parameters): """Histogram of simulated observables. - :param key: a pseudo-random number generator (PRNG) key - :param batch_size: int of number of simulated events - :param parameters: dict of parameters used in simulation + :param key: a pseudo-random number generator (PRNG) key :param batch_size: int of number of + simulated events :param parameters: dict of parameters used in simulation + """ if len(self.components) != 1: raise AssertionError(self.warning) - key, result = self.components[self.only_component].simulate( - key, batch_size, parameters) + key, result = self.components[self.only_component].simulate(key, batch_size, parameters) # Move data to CPU result = [np.array(r) for r in result] return key, result @@ -352,13 +349,15 @@ def register_component(self, *args, **kwargs): def get_log_likelihood(self, key, batch_size, parameters): """Get log likelihood of given parameters. - :param key: a pseudo-random number generator (PRNG) key - :param batch_size: int of number of simulated events - :param parameters: dict of parameters used in simulation + :param key: a pseudo-random number generator (PRNG) key :param batch_size: int of number of + simulated events :param parameters: dict of parameters used in simulation + """ if batch_size != 1: - warning = f'You specified the batch_size larger than 1, '\ - 'but it should and will be changed to 1 in literature fitting!' + warning = ( + "You specified the batch_size larger than 1, " + "but it should and will be changed to 1 in literature fitting!" + ) warn(warning) key, result = self._simulate_yields(key, 1, parameters) energies, yields, eff = result @@ -369,49 +368,47 @@ def get_log_likelihood(self, key, batch_size, parameters): llh = -np.inf return key, llh - def print_likelihood_summary(self, - indent: str = ' '*4, - short: bool = True): + def print_likelihood_summary(self, indent: str = " " * 4, short: bool = True): """Print likelihood summary: components, bins, file names. :param indent: str of indent :param short: bool, whether only print short summary """ - print('\n'+'-'*40) + print("\n" + "-" * 40) - print(f'BINNING\n') - print(f'{indent}variable_type: {self.variable_type}') - print(f'{indent}variable: {self._bins_on}') - print('\n'+'-'*40) + print("BINNING\n") + print(f"{indent}variable_type: {self.variable_type}") + print(f"{indent}variable: {self._bins_on}") + print("\n" + "-" * 40) - print(f'LOGPDF\n') - print(f'{indent}logpdf_args:') + print("LOGPDF\n") + print(f"{indent}logpdf_args:") for k, v in self.logpdf_args.items(): - print(f'{indent*2}{k}: {v}') - print('\n'+'-'*40) + print(f"{indent*2}{k}: {v}") + print("\n" + "-" * 40) - print('MODEL\n') + print("MODEL\n") for i, component_name in enumerate(self.components): name = component_name component = self[component_name] need = component.needed_parameters - print(f'{indent}COMPONENT {i}: {name}') + print(f"{indent}COMPONENT {i}: {name}") if isinstance(component, ComponentSim): - print(f'{indent*2}type: simulation') - print(f'{indent*2}rate_par: {component.rate_name}') - print(f'{indent*2}pars: {need}') + print(f"{indent*2}type: simulation") + print(f"{indent*2}rate_par: {component.rate_name}") + print(f"{indent*2}pars: {need}") if not short: - print(f'{indent*2}worksheet: {component.worksheet}') + print(f"{indent*2}worksheet: {component.worksheet}") elif isinstance(component, ComponentFixed): - print(f'{indent*2}type: fixed') - print(f'{indent*2}file_name: {component._file_name}') - print(f'{indent*2}rate_par: {component.rate_name}') - print(f'{indent*2}pars: {need}') + print(f"{indent*2}type: fixed") + print(f"{indent*2}file_name: {component._file_name}") + print(f"{indent*2}rate_par: {component.rate_name}") + print(f"{indent*2}pars: {need}") if not short: - print(f'{indent*2}from_file: {component.file_name}') + print(f"{indent*2}from_file: {component._file_name}") else: pass print() - print('-'*40) + print("-" * 40) diff --git a/appletree/maps/_3fold_recon_eff.json b/appletree/maps/_3fold_recon_eff.json index 7b540264..745936da 100644 --- a/appletree/maps/_3fold_recon_eff.json +++ b/appletree/maps/_3fold_recon_eff.json @@ -1 +1 @@ -{"coordinate_system": [0.0, 1.0, 2.0, 3.0, 4.0, 5.0], "coordinate_type": "point", "coordinate_name": "hit", "map": [0.0, 0.0, 0.0, 1.0, 1.0, 1.0]} \ No newline at end of file +{"coordinate_system": [0.0, 1.0, 2.0, 3.0, 4.0, 5.0], "coordinate_type": "point", "coordinate_name": "hit", "map": [0.0, 0.0, 0.0, 1.0, 1.0, 1.0]} diff --git a/appletree/maps/_elife.json b/appletree/maps/_elife.json index 990961e7..94ed205e 100644 --- a/appletree/maps/_elife.json +++ b/appletree/maps/_elife.json @@ -1 +1 @@ -{"coordinate_system": [0, 0.5, 1.0], "coordinate_type": "point", "coordinate_name": "cdf", "map": [12000.0, 12000.0, 12000.0]} \ No newline at end of file +{"coordinate_system": [0, 0.5, 1.0], "coordinate_type": "point", "coordinate_name": "cdf", "map": [12000.0, 12000.0, 12000.0]} diff --git a/appletree/maps/_nr_ly.json b/appletree/maps/_nr_ly.json index e205916a..4b34633e 100644 --- a/appletree/maps/_nr_ly.json +++ b/appletree/maps/_nr_ly.json @@ -1 +1 @@ -{"coordinate_system": [0.1, 0.1198, 0.1396, 0.15940000000000001, 0.17920000000000003, 0.199, 0.21880000000000002, 0.2386, 0.2584, 0.2782, 0.29800000000000004, 0.3178, 0.3376, 0.35740000000000005, 0.3772, 0.397, 0.41680000000000006, 0.4366, 0.45640000000000003, 0.47620000000000007, 0.496, 0.5158, 0.5356000000000001, 0.5554, 0.5752, 0.5950000000000001, 0.6148, 0.6346, 0.6544, 0.6742, 0.6940000000000001, 0.7138, 0.7336, 0.7534000000000001, 0.7732, 0.793, 0.8128000000000001, 0.8326, 0.8524, 0.8722000000000001, 0.892, 0.9118, 0.9316000000000001, 0.9514, 0.9712000000000001, 0.9910000000000001, 1.0108000000000001, 1.0306000000000002, 1.0504000000000002, 1.0702, 1.09, 1.1098000000000001, 1.1296000000000002, 1.1494000000000002, 1.1692000000000002, 1.1890000000000003, 1.2088, 1.2286000000000001, 1.2484000000000002, 1.2682000000000002, 1.2880000000000003, 1.3078000000000003, 1.3276000000000001, 1.3474000000000002, 1.3672000000000002, 1.3870000000000002, 1.4068000000000003, 1.4266, 1.4464000000000001, 1.4662000000000002, 1.4860000000000002, 1.5058000000000002, 1.5256000000000003, 1.5454, 1.5652000000000001, 1.5850000000000002, 1.6048000000000002, 1.6246000000000003, 1.6444000000000003, 1.6642000000000001, 1.6840000000000002, 1.7038000000000002, 1.7236000000000002, 1.7434000000000003, 1.7632000000000003, 1.7830000000000001, 1.8028000000000002, 1.8226000000000002, 1.8424000000000003, 1.8622000000000003, 1.8820000000000003, 1.9018000000000002, 1.9216000000000002, 1.9414000000000002, 1.9612000000000003, 1.9810000000000003, 2.0008000000000004, 2.0206, 2.0404, 2.0602, 2.08, 2.0998, 2.1196, 2.1394, 2.1592000000000002, 2.1790000000000003, 2.1988000000000003, 2.2186000000000003, 2.2384000000000004, 2.2582000000000004, 2.2780000000000005, 2.2978, 2.3176, 2.3374, 2.3572, 2.3770000000000002, 2.3968000000000003, 2.4166000000000003, 2.4364000000000003, 2.4562000000000004, 2.4760000000000004, 2.4958000000000005, 2.5156000000000005, 2.5354, 2.5552, 2.575, 2.5948, 2.6146000000000003, 2.6344000000000003, 2.6542000000000003, 2.6740000000000004, 2.6938000000000004, 2.7136000000000005, 2.7334000000000005, 2.7532, 2.773, 2.7928, 2.8126, 2.8324000000000003, 2.8522000000000003, 2.8720000000000003, 2.8918000000000004, 2.9116000000000004, 2.9314000000000004, 2.9512000000000005, 2.9710000000000005, 2.9908, 3.0106, 3.0304, 3.0502000000000002, 3.0700000000000003, 3.0898000000000003, 3.1096000000000004, 3.1294000000000004, 3.1492000000000004, 3.1690000000000005, 3.1888000000000005, 3.2086000000000006, 3.2284, 3.2482, 3.2680000000000002, 3.2878000000000003, 3.3076000000000003, 3.3274000000000004, 3.3472000000000004, 3.3670000000000004, 3.3868000000000005, 3.4066000000000005, 3.4264000000000006, 3.4462, 3.466, 3.4858000000000002, 3.5056000000000003, 3.5254000000000003, 3.5452000000000004, 3.5650000000000004, 3.5848000000000004, 3.6046000000000005, 3.6244000000000005, 3.6442000000000005, 3.6640000000000006, 3.6838, 3.7036000000000002, 3.7234000000000003, 3.7432000000000003, 3.7630000000000003, 3.7828000000000004, 3.8026000000000004, 3.8224000000000005, 3.8422000000000005, 3.8620000000000005, 3.8818000000000006, 3.9016000000000006, 3.9214, 3.9412000000000003, 3.9610000000000003, 3.9808000000000003, 4.0006, 4.0204, 4.0402000000000005, 4.0600000000000005, 4.0798000000000005, 4.099600000000001, 4.1194, 4.1392, 4.159, 4.1788, 4.1986, 4.2184, 4.2382, 4.258, 4.2778, 4.2976, 4.3174, 4.3372, 4.357, 4.3768, 4.3966, 4.4164, 4.4362, 4.456, 4.4758000000000004, 4.4956, 4.5154, 4.5352, 4.555, 4.5748, 4.5946, 4.6144, 4.6342, 4.654, 4.6738, 4.6936, 4.7134, 4.7332, 4.753, 4.7728, 4.7926, 4.8124, 4.8322, 4.852, 4.8718, 4.8916, 4.9114, 4.9312000000000005, 4.951, 4.9708, 4.9906, 5.0104, 5.0302, 5.05, 5.0698, 5.0896, 5.1094, 5.1292, 5.149, 5.1688, 5.1886, 5.2084, 5.2282, 5.248, 5.2678, 5.2876, 5.3074, 5.3272, 5.347, 5.3668000000000005, 5.3866000000000005, 5.4064, 5.4262, 5.446, 5.4658, 5.4856, 5.5054, 5.5252, 5.545, 5.5648, 5.5846, 5.6044, 5.6242, 5.644, 5.6638, 5.6836, 5.7034, 5.7232, 5.743, 5.7628, 5.7826, 5.8024000000000004, 5.8222000000000005, 5.8420000000000005, 5.8618, 5.8816, 5.9014, 5.9212, 5.941, 5.9608, 5.9806, 6.0004, 6.0202, 6.04, 6.0598, 6.0796, 6.0994, 6.1192, 6.139, 6.1588, 6.1786, 6.1984, 6.2182, 6.238, 6.2578000000000005, 6.2776000000000005, 6.2974000000000006, 6.317200000000001, 6.337, 6.3568, 6.3766, 6.3964, 6.4162, 6.436, 6.4558, 6.4756, 6.4954, 6.5152, 6.535, 6.5548, 6.5746, 6.5944, 6.6142, 6.634, 6.6538, 6.6736, 6.6934000000000005, 6.7132000000000005, 6.7330000000000005, 6.752800000000001, 6.772600000000001, 6.7924, 6.8122, 6.832, 6.8518, 6.8716, 6.8914, 6.9112, 6.931, 6.9508, 6.9706, 6.9904, 7.0102, 7.03, 7.0498, 7.0696, 7.0894, 7.1092, 7.1290000000000004, 7.1488000000000005, 7.1686000000000005, 7.188400000000001, 7.208200000000001, 7.228000000000001, 7.2478, 7.2676, 7.2874, 7.3072, 7.327, 7.3468, 7.3666, 7.3864, 7.4062, 7.426, 7.4458, 7.4656, 7.4854, 7.5052, 7.525, 7.5448, 7.5646, 7.5844000000000005, 7.6042000000000005, 7.6240000000000006, 7.643800000000001, 7.663600000000001, 7.683400000000001, 7.703200000000001, 7.723, 7.7428, 7.7626, 7.7824, 7.8022, 7.822, 7.8418, 7.8616, 7.8814, 7.9012, 7.921, 7.9408, 7.9606, 7.9804, 8.000200000000001, 8.020000000000001, 8.039800000000001, 8.059600000000001, 8.079400000000001, 8.099200000000002, 8.119, 8.1388, 8.1586, 8.1784, 8.1982, 8.218, 8.2378, 8.2576, 8.2774, 8.2972, 8.317, 8.3368, 8.3566, 8.3764, 8.3962, 8.416, 8.4358, 8.4556, 8.4754, 8.4952, 8.515, 8.5348, 8.5546, 8.5744, 8.5942, 8.614, 8.6338, 8.6536, 8.6734, 8.693200000000001, 8.713000000000001, 8.732800000000001, 8.752600000000001, 8.772400000000001, 8.792200000000001, 8.812000000000001, 8.831800000000001, 8.851600000000001, 8.8714, 8.8912, 8.911, 8.9308, 8.9506, 8.9704, 8.9902, 9.01, 9.0298, 9.0496, 9.0694, 9.0892, 9.109, 9.1288, 9.1486, 9.1684, 9.1882, 9.208, 9.2278, 9.2476, 9.2674, 9.2872, 9.307, 9.3268, 9.3466, 9.3664, 9.3862, 9.406, 9.4258, 9.4456, 9.4654, 9.4852, 9.505, 9.5248, 9.5446, 9.564400000000001, 9.584200000000001, 9.604000000000001, 9.623800000000001, 9.643600000000001, 9.663400000000001, 9.683200000000001, 9.703000000000001, 9.722800000000001, 9.742600000000001, 9.762400000000001, 9.7822, 9.802, 9.8218, 9.8416, 9.8614, 9.8812, 9.901, 9.9208, 9.9406, 9.9604, 9.9802, 10.0], "coordinate_type": "point", "coordinate_name": "recoil energy", "map": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.4514653126076977, 2.6604837656389835, 2.84489845055094, 3.0061243511255307, 3.146201151105191, 3.267459426258895, 3.3722876644356963, 3.4629820104445246, 3.541658776462535, 3.610211608498467, 3.6702985533097614, 3.7233478488961205, 3.770574440202374, 3.813001776021941, 3.851485363909359, 3.8867359335231666, 3.9193410002104887, 3.9497842402588157, 3.9784624796552897, 4.0057003312025925, 4.031762643303362, 4.05686498508651, 4.081182412514401, 4.1048567558346525, 4.128002651360612, 4.150712517091565, 4.173060646368659, 4.195106569052597, 4.216897806899978, 4.238472129488681, 4.259859399354513, 4.281083079865123, 4.302161466562253, 4.323108691984798, 4.343935545066805, 4.364650138821607, 4.385258453935101, 4.405764780884732, 4.4261720790928205, 4.446482268256957, 4.466696464245479, 4.486815169692683, 4.506838427586199, 4.526765944632779, 4.546597189957468, 4.566331473684108, 4.585968009121683, 4.605505961606953, 4.624944486502135, 4.644282758394567, 4.663519993174966, 4.68265546436736, 4.701688514834806, 4.720618564780722, 4.739445116797925, 4.758167758579841, 4.7767861637951645, 4.795300091534485, 4.813709384660902, 4.832013967334139, 4.850213841926113, 4.868309085503589, 4.886299846019028, 4.90418633832215, 4.921968840081563, 4.939647687686677, 4.9572232721846605, 4.974696035294412, 4.992066465529276, 5.0093350944518535, 5.026502493077535, 5.04356926843785, 5.060536060310543, 5.077403538119639, 5.094172398006227, 5.1108433600684195, 5.127417165767388, 5.14389457549509, 5.160276366298463, 5.176563329754096, 5.192756269987059, 5.208856001827249, 5.224863349096447, 5.240779143019338, 5.2566042207516945, 5.272339424019171, 5.28798559786015, 5.303543589466476, 5.319014247116034, 5.334398419191348, 5.349696953278775, 5.364910695342937, 5.380040488971519, 5.3950871746856235, 5.410051589311257, 5.424934565407782, 5.439736930749291, 5.454459507855249, 5.469103113566902, 5.483668558666107, 5.498156647533642, 5.512568177843973, 5.526903940293902, 5.54116471836253, 5.555351288100213, 5.569464417944311, 5.5835048685596975, 5.59747339270211, 5.611370735102594, 5.625197632371379, 5.638954812919639, 5.652642996897728, 5.666262896148545, 5.67981521417481, 5.693300646119074, 5.70671987875543, 5.7200735904919195, 5.733362451382691, 5.746587123149094, 5.75974825920891, 5.772846504712949, 5.785882496588377, 5.798856863588111, 5.811770226345726, 5.824623197435287, 5.837416381435652, 5.8501503749987505, 5.862825766921431, 5.875443138220442, 5.888003062210226, 5.900506104583181, 5.912952823492002, 5.925343769633945, 5.937679486336623, 5.949960509645177, 5.962187368410515, 5.97436058437851, 5.98648067227986, 5.998548139920514, 6.0105634882724805, 6.022527211564826, 6.034439797374798, 6.046301726718912, 6.058113474143889, 6.069875507817326, 6.081588289618059, 6.0932522752260745, 6.104867914211911, 6.11643565012551, 6.127955920584389, 6.139429157361167, 6.150855786470277, 6.162236228253961, 6.17357089746736, 6.184860203362779, 6.196104549773019, 6.207304335193815, 6.218459952865267, 6.229571790852335, 6.24064023212432, 6.2516656546333484, 6.262648431391817, 6.273588930548826, 6.28448751546553, 6.2953445447895175, 6.306160372528061, 6.316935348120365, 6.327669816508732, 6.338364118208716, 6.349018589378171, 6.359633561885312, 6.370209363375676, 6.380746317338107, 6.391244743169654, 6.401704956239498, 6.412127267951806, 6.422511985807654, 6.4328594134658825, 6.443169850802987, 6.453443593972079, 6.4636809354607925, 6.473882164148319, 6.484047565361442, 6.494177420929671, 6.504272009239433, 6.514331605287386, 6.524356480732793, 6.534346903949053, 6.544303140074342, 6.554225451061384, 6.564114095726411, 6.573969329797242, 6.583791405960591, 6.593580573908518, 6.603337080384127, 6.613061169226456, 6.622753081414597, 6.6324130551110745, 6.642041325704463, 6.6516381258512665, 6.6612036855171075, 6.670738232017167, 6.680241990055956, 6.68971518176638, 6.699158026748171, 6.708570742105598, 6.717953542484588, 6.727306640109147, 6.7366302448172215, 6.745924564095886, 6.755189803115953, 6.764426164765989, 6.773633849685727, 6.782813056298944, 6.791963980845714, 6.801086817414188, 6.810181757971748, 6.8192489923956945, 6.828288708503375, 6.837301092081797, 6.846286326916772, 6.855244594821519, 6.864176075664802, 6.873080947398603, 6.881959386085307, 6.89081156592444, 6.899637659278934, 6.908437836700991, 6.917212266957465, 6.925961117054847, 6.934684552263821, 6.943382736143414, 6.952055830564735, 6.960703995734329, 6.969327390217129, 6.977926170959027, 6.98650049330909, 6.995050511041386, 7.003576376376459, 7.012078240002457, 7.02055625109589, 7.029010557342061, 7.037441304955193, 7.045848638698148, 7.0542327019019115, 7.062593636484703, 7.070931582970792, 7.079246680509018, 7.087539066891, 7.09580887856906, 7.104056250673843, 7.112281317031656, 7.120484210181573, 7.128665061392186, 7.136824000678167, 7.144961156816503, 7.153076657362524, 7.161170628665644, 7.169243195884862, 7.17729448300403, 7.185324612846858, 7.193333707091705, 7.201321886286122, 7.209289269861186, 7.217235976145576, 7.225162122379486, 7.233067824728262, 7.240953198295868, 7.248818357138129, 7.256663414275773, 7.264488481707264, 7.27229367042146, 7.280079090410046, 7.287844850679818, 7.295591059264734, 7.3033178232378155, 7.311025248722855, 7.318713440905958, 7.326382504046886, 7.334032541490267, 7.341663655676599, 7.34927594815311, 7.356869519584472, 7.364444469763301, 7.372000897620573, 7.379538901235815, 7.387058577847215, 7.394560023861518, 7.402043334863825, 7.40950860562722, 7.416955930122259, 7.424385401526359, 7.43179711223298, 7.4391911538607385, 7.446567617262357, 7.453926592533482, 7.461268169021396, 7.468592435333589, 7.475899479346207, 7.483189388212384, 7.490462248370458, 7.497718145552068, 7.504957164790118, 7.512179390426671, 7.519384906120693, 7.526573794855688, 7.533746138947266, 7.540902020050561, 7.548041519167557, 7.5551647166543345, 7.562271692228179, 7.569362524974632, 7.576437293354406, 7.583496075210228, 7.590538947773588, 7.597565987671381, 7.604577270932465, 7.611572872994148, 7.6185528687085435, 7.625517332348888, 7.632466337615746, 7.639399957643126, 7.646318265004531, 7.653221331718925, 7.660109229256616, 7.6669820285450365, 7.6738397999745125, 7.680682613403873, 7.68751053816604, 7.694323643073541, 7.701121996423931, 7.707905666005124, 7.714674719100725, 7.7214292224952175, 7.728169242479114, 7.734894844854052, 7.741606094937798, 7.748303057569198, 7.754985797113076, 7.761654377465051, 7.768308862056291, 7.774949313858221, 7.781575795387168, 7.788188368708935, 7.794787095443321, 7.801372036768588, 7.8079432534258855, 7.814500805723577, 7.821044753541547, 7.827575156335456, 7.834092073140914, 7.8405955625776285, 7.847085682853494, 7.853562491768609, 7.8600260467192795, 7.8664764047019515, 7.87291362231709, 7.879337755773013, 7.8857488608897, 7.892146993102534, 7.898532207465986, 7.904904558657273, 7.911264100979987, 7.917610888367631, 7.923944974387158, 7.930266412242453, 7.93657525477776, 7.942871554481077, 7.949155363487528, 7.955426733582668, 7.961685716205736, 7.967932362452933, 7.974166723080593, 7.9803888485083405, 7.986598788822234, 7.99279659377782, 7.99898231280322, 8.005155995002106, 8.01131768915671, 8.01746744373074, 8.023605306872303, 8.029731326416789, 8.035845549889688, 8.041948024509415, 8.048038797190086, 8.054117914544255, 8.060185422885631, 8.066241368231752, 8.072285796306646, 8.07831875254344, 8.084340282086963, 8.0903504297963, 8.096349240247308, 8.102336757735152, 8.108313026276754, 8.114278089613249, 8.120231991212403, 8.126174774271005, 8.132106481717226, 8.138027156212983, 8.143936840156213, 8.149835575683186, 8.155723404670772, 8.161600368738657, 8.16746650925157, 8.173321867321464, 8.179166483809677, 8.185000399329095, 8.19082365424623, 8.196636288683349, 8.202438342520525, 8.20822985539768, 8.214010866716645, 8.219781415643117, 8.22554154110868, 8.231291281812746, 8.237030676224506, 8.242759762584836, 8.248478578908198, 8.254187162984547, 8.25988555238115, 8.26557378444444, 8.271251896301845, 8.276919924863583, 8.282577906824425, 8.2882258786655, 8.29386387665598, 8.299491936854862, 8.305110095112633, 8.310718387073, 8.31631684817452, 8.321905513652286, 8.327484418539548, 8.333053597669347, 8.338613085676101, 8.34416291699722, 8.349703125874639, 8.355233746356406, 8.36075481229822, 8.36626635736493, 8.37176841503206, 8.377261018587298, 8.382744201131988, 8.388217995582565, 8.39368243467202, 8.39913755095134, 8.404583376790907, 8.410019944381915, 8.41544728573777, 8.420865432695441, 8.426274416916845, 8.431674269890198, 8.437065022931323, 8.442446707185011, 8.447819353626302, 8.453182993061793, 8.458537656130925, 8.463883373307251, 8.469220174899688, 8.474548091053784, 8.479867151752925, 8.485177386819581, 8.490478825916506, 8.49577149854794, 8.501055434060795, 8.506330661645825, 8.51159721033881, 8.516855109021684, 8.522104386423699, 8.527345071122546, 8.53257719154547, 8.537800775970398, 8.543015852527013, 8.548222449197876, 8.553420593819478, 8.558610314083307, 8.56379163753693, 8.568964591585024, 8.574129203490424, 8.579285500375125, 8.58443350922135, 8.589573256872523, 8.594704770034266, 8.599828075275415, 8.604943199028998, 8.610050167593176, 8.615149007132255, 8.620239743677597, 8.6253224031286, 8.630397011253612, 8.635463593690869, 8.640522175949421, 8.645572783410033, 8.650615441326096, 8.655650174824519]} \ No newline at end of file +{"coordinate_system": [0.1, 0.1198, 0.1396, 0.15940000000000001, 0.17920000000000003, 0.199, 0.21880000000000002, 0.2386, 0.2584, 0.2782, 0.29800000000000004, 0.3178, 0.3376, 0.35740000000000005, 0.3772, 0.397, 0.41680000000000006, 0.4366, 0.45640000000000003, 0.47620000000000007, 0.496, 0.5158, 0.5356000000000001, 0.5554, 0.5752, 0.5950000000000001, 0.6148, 0.6346, 0.6544, 0.6742, 0.6940000000000001, 0.7138, 0.7336, 0.7534000000000001, 0.7732, 0.793, 0.8128000000000001, 0.8326, 0.8524, 0.8722000000000001, 0.892, 0.9118, 0.9316000000000001, 0.9514, 0.9712000000000001, 0.9910000000000001, 1.0108000000000001, 1.0306000000000002, 1.0504000000000002, 1.0702, 1.09, 1.1098000000000001, 1.1296000000000002, 1.1494000000000002, 1.1692000000000002, 1.1890000000000003, 1.2088, 1.2286000000000001, 1.2484000000000002, 1.2682000000000002, 1.2880000000000003, 1.3078000000000003, 1.3276000000000001, 1.3474000000000002, 1.3672000000000002, 1.3870000000000002, 1.4068000000000003, 1.4266, 1.4464000000000001, 1.4662000000000002, 1.4860000000000002, 1.5058000000000002, 1.5256000000000003, 1.5454, 1.5652000000000001, 1.5850000000000002, 1.6048000000000002, 1.6246000000000003, 1.6444000000000003, 1.6642000000000001, 1.6840000000000002, 1.7038000000000002, 1.7236000000000002, 1.7434000000000003, 1.7632000000000003, 1.7830000000000001, 1.8028000000000002, 1.8226000000000002, 1.8424000000000003, 1.8622000000000003, 1.8820000000000003, 1.9018000000000002, 1.9216000000000002, 1.9414000000000002, 1.9612000000000003, 1.9810000000000003, 2.0008000000000004, 2.0206, 2.0404, 2.0602, 2.08, 2.0998, 2.1196, 2.1394, 2.1592000000000002, 2.1790000000000003, 2.1988000000000003, 2.2186000000000003, 2.2384000000000004, 2.2582000000000004, 2.2780000000000005, 2.2978, 2.3176, 2.3374, 2.3572, 2.3770000000000002, 2.3968000000000003, 2.4166000000000003, 2.4364000000000003, 2.4562000000000004, 2.4760000000000004, 2.4958000000000005, 2.5156000000000005, 2.5354, 2.5552, 2.575, 2.5948, 2.6146000000000003, 2.6344000000000003, 2.6542000000000003, 2.6740000000000004, 2.6938000000000004, 2.7136000000000005, 2.7334000000000005, 2.7532, 2.773, 2.7928, 2.8126, 2.8324000000000003, 2.8522000000000003, 2.8720000000000003, 2.8918000000000004, 2.9116000000000004, 2.9314000000000004, 2.9512000000000005, 2.9710000000000005, 2.9908, 3.0106, 3.0304, 3.0502000000000002, 3.0700000000000003, 3.0898000000000003, 3.1096000000000004, 3.1294000000000004, 3.1492000000000004, 3.1690000000000005, 3.1888000000000005, 3.2086000000000006, 3.2284, 3.2482, 3.2680000000000002, 3.2878000000000003, 3.3076000000000003, 3.3274000000000004, 3.3472000000000004, 3.3670000000000004, 3.3868000000000005, 3.4066000000000005, 3.4264000000000006, 3.4462, 3.466, 3.4858000000000002, 3.5056000000000003, 3.5254000000000003, 3.5452000000000004, 3.5650000000000004, 3.5848000000000004, 3.6046000000000005, 3.6244000000000005, 3.6442000000000005, 3.6640000000000006, 3.6838, 3.7036000000000002, 3.7234000000000003, 3.7432000000000003, 3.7630000000000003, 3.7828000000000004, 3.8026000000000004, 3.8224000000000005, 3.8422000000000005, 3.8620000000000005, 3.8818000000000006, 3.9016000000000006, 3.9214, 3.9412000000000003, 3.9610000000000003, 3.9808000000000003, 4.0006, 4.0204, 4.0402000000000005, 4.0600000000000005, 4.0798000000000005, 4.099600000000001, 4.1194, 4.1392, 4.159, 4.1788, 4.1986, 4.2184, 4.2382, 4.258, 4.2778, 4.2976, 4.3174, 4.3372, 4.357, 4.3768, 4.3966, 4.4164, 4.4362, 4.456, 4.4758000000000004, 4.4956, 4.5154, 4.5352, 4.555, 4.5748, 4.5946, 4.6144, 4.6342, 4.654, 4.6738, 4.6936, 4.7134, 4.7332, 4.753, 4.7728, 4.7926, 4.8124, 4.8322, 4.852, 4.8718, 4.8916, 4.9114, 4.9312000000000005, 4.951, 4.9708, 4.9906, 5.0104, 5.0302, 5.05, 5.0698, 5.0896, 5.1094, 5.1292, 5.149, 5.1688, 5.1886, 5.2084, 5.2282, 5.248, 5.2678, 5.2876, 5.3074, 5.3272, 5.347, 5.3668000000000005, 5.3866000000000005, 5.4064, 5.4262, 5.446, 5.4658, 5.4856, 5.5054, 5.5252, 5.545, 5.5648, 5.5846, 5.6044, 5.6242, 5.644, 5.6638, 5.6836, 5.7034, 5.7232, 5.743, 5.7628, 5.7826, 5.8024000000000004, 5.8222000000000005, 5.8420000000000005, 5.8618, 5.8816, 5.9014, 5.9212, 5.941, 5.9608, 5.9806, 6.0004, 6.0202, 6.04, 6.0598, 6.0796, 6.0994, 6.1192, 6.139, 6.1588, 6.1786, 6.1984, 6.2182, 6.238, 6.2578000000000005, 6.2776000000000005, 6.2974000000000006, 6.317200000000001, 6.337, 6.3568, 6.3766, 6.3964, 6.4162, 6.436, 6.4558, 6.4756, 6.4954, 6.5152, 6.535, 6.5548, 6.5746, 6.5944, 6.6142, 6.634, 6.6538, 6.6736, 6.6934000000000005, 6.7132000000000005, 6.7330000000000005, 6.752800000000001, 6.772600000000001, 6.7924, 6.8122, 6.832, 6.8518, 6.8716, 6.8914, 6.9112, 6.931, 6.9508, 6.9706, 6.9904, 7.0102, 7.03, 7.0498, 7.0696, 7.0894, 7.1092, 7.1290000000000004, 7.1488000000000005, 7.1686000000000005, 7.188400000000001, 7.208200000000001, 7.228000000000001, 7.2478, 7.2676, 7.2874, 7.3072, 7.327, 7.3468, 7.3666, 7.3864, 7.4062, 7.426, 7.4458, 7.4656, 7.4854, 7.5052, 7.525, 7.5448, 7.5646, 7.5844000000000005, 7.6042000000000005, 7.6240000000000006, 7.643800000000001, 7.663600000000001, 7.683400000000001, 7.703200000000001, 7.723, 7.7428, 7.7626, 7.7824, 7.8022, 7.822, 7.8418, 7.8616, 7.8814, 7.9012, 7.921, 7.9408, 7.9606, 7.9804, 8.000200000000001, 8.020000000000001, 8.039800000000001, 8.059600000000001, 8.079400000000001, 8.099200000000002, 8.119, 8.1388, 8.1586, 8.1784, 8.1982, 8.218, 8.2378, 8.2576, 8.2774, 8.2972, 8.317, 8.3368, 8.3566, 8.3764, 8.3962, 8.416, 8.4358, 8.4556, 8.4754, 8.4952, 8.515, 8.5348, 8.5546, 8.5744, 8.5942, 8.614, 8.6338, 8.6536, 8.6734, 8.693200000000001, 8.713000000000001, 8.732800000000001, 8.752600000000001, 8.772400000000001, 8.792200000000001, 8.812000000000001, 8.831800000000001, 8.851600000000001, 8.8714, 8.8912, 8.911, 8.9308, 8.9506, 8.9704, 8.9902, 9.01, 9.0298, 9.0496, 9.0694, 9.0892, 9.109, 9.1288, 9.1486, 9.1684, 9.1882, 9.208, 9.2278, 9.2476, 9.2674, 9.2872, 9.307, 9.3268, 9.3466, 9.3664, 9.3862, 9.406, 9.4258, 9.4456, 9.4654, 9.4852, 9.505, 9.5248, 9.5446, 9.564400000000001, 9.584200000000001, 9.604000000000001, 9.623800000000001, 9.643600000000001, 9.663400000000001, 9.683200000000001, 9.703000000000001, 9.722800000000001, 9.742600000000001, 9.762400000000001, 9.7822, 9.802, 9.8218, 9.8416, 9.8614, 9.8812, 9.901, 9.9208, 9.9406, 9.9604, 9.9802, 10.0], "coordinate_type": "point", "coordinate_name": "recoil energy", "map": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.4514653126076977, 2.6604837656389835, 2.84489845055094, 3.0061243511255307, 3.146201151105191, 3.267459426258895, 3.3722876644356963, 3.4629820104445246, 3.541658776462535, 3.610211608498467, 3.6702985533097614, 3.7233478488961205, 3.770574440202374, 3.813001776021941, 3.851485363909359, 3.8867359335231666, 3.9193410002104887, 3.9497842402588157, 3.9784624796552897, 4.0057003312025925, 4.031762643303362, 4.05686498508651, 4.081182412514401, 4.1048567558346525, 4.128002651360612, 4.150712517091565, 4.173060646368659, 4.195106569052597, 4.216897806899978, 4.238472129488681, 4.259859399354513, 4.281083079865123, 4.302161466562253, 4.323108691984798, 4.343935545066805, 4.364650138821607, 4.385258453935101, 4.405764780884732, 4.4261720790928205, 4.446482268256957, 4.466696464245479, 4.486815169692683, 4.506838427586199, 4.526765944632779, 4.546597189957468, 4.566331473684108, 4.585968009121683, 4.605505961606953, 4.624944486502135, 4.644282758394567, 4.663519993174966, 4.68265546436736, 4.701688514834806, 4.720618564780722, 4.739445116797925, 4.758167758579841, 4.7767861637951645, 4.795300091534485, 4.813709384660902, 4.832013967334139, 4.850213841926113, 4.868309085503589, 4.886299846019028, 4.90418633832215, 4.921968840081563, 4.939647687686677, 4.9572232721846605, 4.974696035294412, 4.992066465529276, 5.0093350944518535, 5.026502493077535, 5.04356926843785, 5.060536060310543, 5.077403538119639, 5.094172398006227, 5.1108433600684195, 5.127417165767388, 5.14389457549509, 5.160276366298463, 5.176563329754096, 5.192756269987059, 5.208856001827249, 5.224863349096447, 5.240779143019338, 5.2566042207516945, 5.272339424019171, 5.28798559786015, 5.303543589466476, 5.319014247116034, 5.334398419191348, 5.349696953278775, 5.364910695342937, 5.380040488971519, 5.3950871746856235, 5.410051589311257, 5.424934565407782, 5.439736930749291, 5.454459507855249, 5.469103113566902, 5.483668558666107, 5.498156647533642, 5.512568177843973, 5.526903940293902, 5.54116471836253, 5.555351288100213, 5.569464417944311, 5.5835048685596975, 5.59747339270211, 5.611370735102594, 5.625197632371379, 5.638954812919639, 5.652642996897728, 5.666262896148545, 5.67981521417481, 5.693300646119074, 5.70671987875543, 5.7200735904919195, 5.733362451382691, 5.746587123149094, 5.75974825920891, 5.772846504712949, 5.785882496588377, 5.798856863588111, 5.811770226345726, 5.824623197435287, 5.837416381435652, 5.8501503749987505, 5.862825766921431, 5.875443138220442, 5.888003062210226, 5.900506104583181, 5.912952823492002, 5.925343769633945, 5.937679486336623, 5.949960509645177, 5.962187368410515, 5.97436058437851, 5.98648067227986, 5.998548139920514, 6.0105634882724805, 6.022527211564826, 6.034439797374798, 6.046301726718912, 6.058113474143889, 6.069875507817326, 6.081588289618059, 6.0932522752260745, 6.104867914211911, 6.11643565012551, 6.127955920584389, 6.139429157361167, 6.150855786470277, 6.162236228253961, 6.17357089746736, 6.184860203362779, 6.196104549773019, 6.207304335193815, 6.218459952865267, 6.229571790852335, 6.24064023212432, 6.2516656546333484, 6.262648431391817, 6.273588930548826, 6.28448751546553, 6.2953445447895175, 6.306160372528061, 6.316935348120365, 6.327669816508732, 6.338364118208716, 6.349018589378171, 6.359633561885312, 6.370209363375676, 6.380746317338107, 6.391244743169654, 6.401704956239498, 6.412127267951806, 6.422511985807654, 6.4328594134658825, 6.443169850802987, 6.453443593972079, 6.4636809354607925, 6.473882164148319, 6.484047565361442, 6.494177420929671, 6.504272009239433, 6.514331605287386, 6.524356480732793, 6.534346903949053, 6.544303140074342, 6.554225451061384, 6.564114095726411, 6.573969329797242, 6.583791405960591, 6.593580573908518, 6.603337080384127, 6.613061169226456, 6.622753081414597, 6.6324130551110745, 6.642041325704463, 6.6516381258512665, 6.6612036855171075, 6.670738232017167, 6.680241990055956, 6.68971518176638, 6.699158026748171, 6.708570742105598, 6.717953542484588, 6.727306640109147, 6.7366302448172215, 6.745924564095886, 6.755189803115953, 6.764426164765989, 6.773633849685727, 6.782813056298944, 6.791963980845714, 6.801086817414188, 6.810181757971748, 6.8192489923956945, 6.828288708503375, 6.837301092081797, 6.846286326916772, 6.855244594821519, 6.864176075664802, 6.873080947398603, 6.881959386085307, 6.89081156592444, 6.899637659278934, 6.908437836700991, 6.917212266957465, 6.925961117054847, 6.934684552263821, 6.943382736143414, 6.952055830564735, 6.960703995734329, 6.969327390217129, 6.977926170959027, 6.98650049330909, 6.995050511041386, 7.003576376376459, 7.012078240002457, 7.02055625109589, 7.029010557342061, 7.037441304955193, 7.045848638698148, 7.0542327019019115, 7.062593636484703, 7.070931582970792, 7.079246680509018, 7.087539066891, 7.09580887856906, 7.104056250673843, 7.112281317031656, 7.120484210181573, 7.128665061392186, 7.136824000678167, 7.144961156816503, 7.153076657362524, 7.161170628665644, 7.169243195884862, 7.17729448300403, 7.185324612846858, 7.193333707091705, 7.201321886286122, 7.209289269861186, 7.217235976145576, 7.225162122379486, 7.233067824728262, 7.240953198295868, 7.248818357138129, 7.256663414275773, 7.264488481707264, 7.27229367042146, 7.280079090410046, 7.287844850679818, 7.295591059264734, 7.3033178232378155, 7.311025248722855, 7.318713440905958, 7.326382504046886, 7.334032541490267, 7.341663655676599, 7.34927594815311, 7.356869519584472, 7.364444469763301, 7.372000897620573, 7.379538901235815, 7.387058577847215, 7.394560023861518, 7.402043334863825, 7.40950860562722, 7.416955930122259, 7.424385401526359, 7.43179711223298, 7.4391911538607385, 7.446567617262357, 7.453926592533482, 7.461268169021396, 7.468592435333589, 7.475899479346207, 7.483189388212384, 7.490462248370458, 7.497718145552068, 7.504957164790118, 7.512179390426671, 7.519384906120693, 7.526573794855688, 7.533746138947266, 7.540902020050561, 7.548041519167557, 7.5551647166543345, 7.562271692228179, 7.569362524974632, 7.576437293354406, 7.583496075210228, 7.590538947773588, 7.597565987671381, 7.604577270932465, 7.611572872994148, 7.6185528687085435, 7.625517332348888, 7.632466337615746, 7.639399957643126, 7.646318265004531, 7.653221331718925, 7.660109229256616, 7.6669820285450365, 7.6738397999745125, 7.680682613403873, 7.68751053816604, 7.694323643073541, 7.701121996423931, 7.707905666005124, 7.714674719100725, 7.7214292224952175, 7.728169242479114, 7.734894844854052, 7.741606094937798, 7.748303057569198, 7.754985797113076, 7.761654377465051, 7.768308862056291, 7.774949313858221, 7.781575795387168, 7.788188368708935, 7.794787095443321, 7.801372036768588, 7.8079432534258855, 7.814500805723577, 7.821044753541547, 7.827575156335456, 7.834092073140914, 7.8405955625776285, 7.847085682853494, 7.853562491768609, 7.8600260467192795, 7.8664764047019515, 7.87291362231709, 7.879337755773013, 7.8857488608897, 7.892146993102534, 7.898532207465986, 7.904904558657273, 7.911264100979987, 7.917610888367631, 7.923944974387158, 7.930266412242453, 7.93657525477776, 7.942871554481077, 7.949155363487528, 7.955426733582668, 7.961685716205736, 7.967932362452933, 7.974166723080593, 7.9803888485083405, 7.986598788822234, 7.99279659377782, 7.99898231280322, 8.005155995002106, 8.01131768915671, 8.01746744373074, 8.023605306872303, 8.029731326416789, 8.035845549889688, 8.041948024509415, 8.048038797190086, 8.054117914544255, 8.060185422885631, 8.066241368231752, 8.072285796306646, 8.07831875254344, 8.084340282086963, 8.0903504297963, 8.096349240247308, 8.102336757735152, 8.108313026276754, 8.114278089613249, 8.120231991212403, 8.126174774271005, 8.132106481717226, 8.138027156212983, 8.143936840156213, 8.149835575683186, 8.155723404670772, 8.161600368738657, 8.16746650925157, 8.173321867321464, 8.179166483809677, 8.185000399329095, 8.19082365424623, 8.196636288683349, 8.202438342520525, 8.20822985539768, 8.214010866716645, 8.219781415643117, 8.22554154110868, 8.231291281812746, 8.237030676224506, 8.242759762584836, 8.248478578908198, 8.254187162984547, 8.25988555238115, 8.26557378444444, 8.271251896301845, 8.276919924863583, 8.282577906824425, 8.2882258786655, 8.29386387665598, 8.299491936854862, 8.305110095112633, 8.310718387073, 8.31631684817452, 8.321905513652286, 8.327484418539548, 8.333053597669347, 8.338613085676101, 8.34416291699722, 8.349703125874639, 8.355233746356406, 8.36075481229822, 8.36626635736493, 8.37176841503206, 8.377261018587298, 8.382744201131988, 8.388217995582565, 8.39368243467202, 8.39913755095134, 8.404583376790907, 8.410019944381915, 8.41544728573777, 8.420865432695441, 8.426274416916845, 8.431674269890198, 8.437065022931323, 8.442446707185011, 8.447819353626302, 8.453182993061793, 8.458537656130925, 8.463883373307251, 8.469220174899688, 8.474548091053784, 8.479867151752925, 8.485177386819581, 8.490478825916506, 8.49577149854794, 8.501055434060795, 8.506330661645825, 8.51159721033881, 8.516855109021684, 8.522104386423699, 8.527345071122546, 8.53257719154547, 8.537800775970398, 8.543015852527013, 8.548222449197876, 8.553420593819478, 8.558610314083307, 8.56379163753693, 8.568964591585024, 8.574129203490424, 8.579285500375125, 8.58443350922135, 8.589573256872523, 8.594704770034266, 8.599828075275415, 8.604943199028998, 8.610050167593176, 8.615149007132255, 8.620239743677597, 8.6253224031286, 8.630397011253612, 8.635463593690869, 8.640522175949421, 8.645572783410033, 8.650615441326096, 8.655650174824519]} diff --git a/appletree/maps/_nr_qy.json b/appletree/maps/_nr_qy.json index 0bd0dc31..15da01db 100644 --- a/appletree/maps/_nr_qy.json +++ b/appletree/maps/_nr_qy.json @@ -1 +1 @@ -{"coordinate_system": [0.1, 0.1198, 0.1396, 0.15940000000000001, 0.17920000000000003, 0.199, 0.21880000000000002, 0.2386, 0.2584, 0.2782, 0.29800000000000004, 0.3178, 0.3376, 0.35740000000000005, 0.3772, 0.397, 0.41680000000000006, 0.4366, 0.45640000000000003, 0.47620000000000007, 0.496, 0.5158, 0.5356000000000001, 0.5554, 0.5752, 0.5950000000000001, 0.6148, 0.6346, 0.6544, 0.6742, 0.6940000000000001, 0.7138, 0.7336, 0.7534000000000001, 0.7732, 0.793, 0.8128000000000001, 0.8326, 0.8524, 0.8722000000000001, 0.892, 0.9118, 0.9316000000000001, 0.9514, 0.9712000000000001, 0.9910000000000001, 1.0108000000000001, 1.0306000000000002, 1.0504000000000002, 1.0702, 1.09, 1.1098000000000001, 1.1296000000000002, 1.1494000000000002, 1.1692000000000002, 1.1890000000000003, 1.2088, 1.2286000000000001, 1.2484000000000002, 1.2682000000000002, 1.2880000000000003, 1.3078000000000003, 1.3276000000000001, 1.3474000000000002, 1.3672000000000002, 1.3870000000000002, 1.4068000000000003, 1.4266, 1.4464000000000001, 1.4662000000000002, 1.4860000000000002, 1.5058000000000002, 1.5256000000000003, 1.5454, 1.5652000000000001, 1.5850000000000002, 1.6048000000000002, 1.6246000000000003, 1.6444000000000003, 1.6642000000000001, 1.6840000000000002, 1.7038000000000002, 1.7236000000000002, 1.7434000000000003, 1.7632000000000003, 1.7830000000000001, 1.8028000000000002, 1.8226000000000002, 1.8424000000000003, 1.8622000000000003, 1.8820000000000003, 1.9018000000000002, 1.9216000000000002, 1.9414000000000002, 1.9612000000000003, 1.9810000000000003, 2.0008000000000004, 2.0206, 2.0404, 2.0602, 2.08, 2.0998, 2.1196, 2.1394, 2.1592000000000002, 2.1790000000000003, 2.1988000000000003, 2.2186000000000003, 2.2384000000000004, 2.2582000000000004, 2.2780000000000005, 2.2978, 2.3176, 2.3374, 2.3572, 2.3770000000000002, 2.3968000000000003, 2.4166000000000003, 2.4364000000000003, 2.4562000000000004, 2.4760000000000004, 2.4958000000000005, 2.5156000000000005, 2.5354, 2.5552, 2.575, 2.5948, 2.6146000000000003, 2.6344000000000003, 2.6542000000000003, 2.6740000000000004, 2.6938000000000004, 2.7136000000000005, 2.7334000000000005, 2.7532, 2.773, 2.7928, 2.8126, 2.8324000000000003, 2.8522000000000003, 2.8720000000000003, 2.8918000000000004, 2.9116000000000004, 2.9314000000000004, 2.9512000000000005, 2.9710000000000005, 2.9908, 3.0106, 3.0304, 3.0502000000000002, 3.0700000000000003, 3.0898000000000003, 3.1096000000000004, 3.1294000000000004, 3.1492000000000004, 3.1690000000000005, 3.1888000000000005, 3.2086000000000006, 3.2284, 3.2482, 3.2680000000000002, 3.2878000000000003, 3.3076000000000003, 3.3274000000000004, 3.3472000000000004, 3.3670000000000004, 3.3868000000000005, 3.4066000000000005, 3.4264000000000006, 3.4462, 3.466, 3.4858000000000002, 3.5056000000000003, 3.5254000000000003, 3.5452000000000004, 3.5650000000000004, 3.5848000000000004, 3.6046000000000005, 3.6244000000000005, 3.6442000000000005, 3.6640000000000006, 3.6838, 3.7036000000000002, 3.7234000000000003, 3.7432000000000003, 3.7630000000000003, 3.7828000000000004, 3.8026000000000004, 3.8224000000000005, 3.8422000000000005, 3.8620000000000005, 3.8818000000000006, 3.9016000000000006, 3.9214, 3.9412000000000003, 3.9610000000000003, 3.9808000000000003, 4.0006, 4.0204, 4.0402000000000005, 4.0600000000000005, 4.0798000000000005, 4.099600000000001, 4.1194, 4.1392, 4.159, 4.1788, 4.1986, 4.2184, 4.2382, 4.258, 4.2778, 4.2976, 4.3174, 4.3372, 4.357, 4.3768, 4.3966, 4.4164, 4.4362, 4.456, 4.4758000000000004, 4.4956, 4.5154, 4.5352, 4.555, 4.5748, 4.5946, 4.6144, 4.6342, 4.654, 4.6738, 4.6936, 4.7134, 4.7332, 4.753, 4.7728, 4.7926, 4.8124, 4.8322, 4.852, 4.8718, 4.8916, 4.9114, 4.9312000000000005, 4.951, 4.9708, 4.9906, 5.0104, 5.0302, 5.05, 5.0698, 5.0896, 5.1094, 5.1292, 5.149, 5.1688, 5.1886, 5.2084, 5.2282, 5.248, 5.2678, 5.2876, 5.3074, 5.3272, 5.347, 5.3668000000000005, 5.3866000000000005, 5.4064, 5.4262, 5.446, 5.4658, 5.4856, 5.5054, 5.5252, 5.545, 5.5648, 5.5846, 5.6044, 5.6242, 5.644, 5.6638, 5.6836, 5.7034, 5.7232, 5.743, 5.7628, 5.7826, 5.8024000000000004, 5.8222000000000005, 5.8420000000000005, 5.8618, 5.8816, 5.9014, 5.9212, 5.941, 5.9608, 5.9806, 6.0004, 6.0202, 6.04, 6.0598, 6.0796, 6.0994, 6.1192, 6.139, 6.1588, 6.1786, 6.1984, 6.2182, 6.238, 6.2578000000000005, 6.2776000000000005, 6.2974000000000006, 6.317200000000001, 6.337, 6.3568, 6.3766, 6.3964, 6.4162, 6.436, 6.4558, 6.4756, 6.4954, 6.5152, 6.535, 6.5548, 6.5746, 6.5944, 6.6142, 6.634, 6.6538, 6.6736, 6.6934000000000005, 6.7132000000000005, 6.7330000000000005, 6.752800000000001, 6.772600000000001, 6.7924, 6.8122, 6.832, 6.8518, 6.8716, 6.8914, 6.9112, 6.931, 6.9508, 6.9706, 6.9904, 7.0102, 7.03, 7.0498, 7.0696, 7.0894, 7.1092, 7.1290000000000004, 7.1488000000000005, 7.1686000000000005, 7.188400000000001, 7.208200000000001, 7.228000000000001, 7.2478, 7.2676, 7.2874, 7.3072, 7.327, 7.3468, 7.3666, 7.3864, 7.4062, 7.426, 7.4458, 7.4656, 7.4854, 7.5052, 7.525, 7.5448, 7.5646, 7.5844000000000005, 7.6042000000000005, 7.6240000000000006, 7.643800000000001, 7.663600000000001, 7.683400000000001, 7.703200000000001, 7.723, 7.7428, 7.7626, 7.7824, 7.8022, 7.822, 7.8418, 7.8616, 7.8814, 7.9012, 7.921, 7.9408, 7.9606, 7.9804, 8.000200000000001, 8.020000000000001, 8.039800000000001, 8.059600000000001, 8.079400000000001, 8.099200000000002, 8.119, 8.1388, 8.1586, 8.1784, 8.1982, 8.218, 8.2378, 8.2576, 8.2774, 8.2972, 8.317, 8.3368, 8.3566, 8.3764, 8.3962, 8.416, 8.4358, 8.4556, 8.4754, 8.4952, 8.515, 8.5348, 8.5546, 8.5744, 8.5942, 8.614, 8.6338, 8.6536, 8.6734, 8.693200000000001, 8.713000000000001, 8.732800000000001, 8.752600000000001, 8.772400000000001, 8.792200000000001, 8.812000000000001, 8.831800000000001, 8.851600000000001, 8.8714, 8.8912, 8.911, 8.9308, 8.9506, 8.9704, 8.9902, 9.01, 9.0298, 9.0496, 9.0694, 9.0892, 9.109, 9.1288, 9.1486, 9.1684, 9.1882, 9.208, 9.2278, 9.2476, 9.2674, 9.2872, 9.307, 9.3268, 9.3466, 9.3664, 9.3862, 9.406, 9.4258, 9.4456, 9.4654, 9.4852, 9.505, 9.5248, 9.5446, 9.564400000000001, 9.584200000000001, 9.604000000000001, 9.623800000000001, 9.643600000000001, 9.663400000000001, 9.683200000000001, 9.703000000000001, 9.722800000000001, 9.742600000000001, 9.762400000000001, 9.7822, 9.802, 9.8218, 9.8416, 9.8614, 9.8812, 9.901, 9.9208, 9.9406, 9.9604, 9.9802, 10.0], "coordinate_type": "point", "coordinate_name": "recoil energy", "map": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.399698834317144, 2.6757041167692246, 2.9389584467645196, 3.1879387364333605, 3.4218464263881017, 3.640438747706453, 3.8438826185759316, 4.032633922322844, 4.207341398232108, 4.368772506786422, 4.517757871618573, 4.655150818029523, 4.781798810972488, 4.898524040066033, 5.006110883169805, 5.105298437153001, 5.196776704242026, 5.281185355360305, 5.359114260149574, 5.4311051842129014, 5.497654216711703, 5.559214614913085, 5.616199844819526, 5.668986665561592, 5.717918155452077, 5.763306613975364, 5.805436300013317, 5.8445659849700355, 5.880931312186183, 5.9147469626578575, 5.9462086327354795, 5.9754948330189075, 6.002768519707652, 6.028178570664022, 6.051861118732537, 6.073940754669365, 6.094531611541286, 6.1137383417757745, 6.131656997266583, 6.148375822121101, 6.163975966816124, 6.178532131732728, 6.192113147285232, 6.204782497152356, 6.216598790465547, 6.227616188210844, 6.2378847885561495, 6.247450975322641, 6.256357733374619, 6.264644934302595, 6.272349595416272, 6.279506114743732, 6.286146484446773, 6.29230048480688, 6.297995860708476, 6.303258482342988, 6.308112491676312, 6.312580436061036, 6.316683390231179, 6.3204410677891305, 6.323871923180462, 6.326993245050581, 6.329821241786351, 6.3323711199649795, 6.334657156360061, 6.336692764090129, 6.338490553437281, 6.340062387811787, 6.3414194352923605, 6.342572216130294, 6.343530646568537, 6.344304079293457, 6.344901340807084, 6.345330765980769, 6.345600230026956, 6.345717178104053, 6.345688652749733, 6.345521319320338, 6.3452214895981225, 6.344795143713659, 6.34424795051771, 6.3435852865251405, 6.342812253542752, 6.341933695083314, 6.34095421165928, 6.339878175041808, 6.338709741563437, 6.337452864536266, 6.33611130585156, 6.334688646821199, 6.333188298316586, 6.3316135102560445, 6.329967380487659, 6.328252863110799, 6.32647277627616, 6.32462980950096, 6.322726530533191, 6.320765391796111, 6.318748736441836, 6.316678804040675, 6.314557735930852, 6.312387580251373, 6.310170296679195, 6.30790776089021, 6.305601768762126, 6.303254040336128, 6.300866223552819, 6.298439897776962, 6.295976577124459, 6.2934777136040365, 6.290944700085308, 6.288378873103965, 6.285781515514199, 6.2831538589977365, 6.280497086438177, 6.27781233416884, 6.275100694101677, 6.272363215744355, 6.269600908112143, 6.2668147415407685, 6.2640056494060605, 6.261174529755742, 6.258322246858472, 6.255449632674856, 6.252557488254865, 6.249646585065797, 6.246717666254715, 6.243771447848973, 6.240808619898294, 6.2378298475615575, 6.234835772141394, 6.231827012069344, 6.228804163844293, 6.225767802926673, 6.2227184845907795, 6.21965674473743, 6.216583100669038, 6.213498051829076, 6.2104020805077695, 6.2072956525157545, 6.204179217827378, 6.201053211195141, 6.197918052736768, 6.1947741484963, 6.191621890980469, 6.188461659671619, 6.185293821518319, 6.18211873140476, 6.178936732599992, 6.175748157187949, 6.17255332647922, 6.169352551405439, 6.166146132897085, 6.162934362245543, 6.159717521450128, 6.156495883550765, 6.15326971294704, 6.150039265704216, 6.14680478984684, 6.143566525640485, 6.14032470586219, 6.137079556060111, 6.133831294802851, 6.1305801339189605, 6.127326278727007, 6.124069928256684, 6.120811275461304, 6.117550507422104, 6.114287805544667, 6.111023345747856, 6.107757298645548, 6.1044898297214845, 6.10122109949755, 6.097951263695735, 6.094680473394073, 6.091408875176782, 6.088136611278882, 6.084863819725484, 6.081590634466014, 6.078317185503532, 6.075043599019406, 6.07176999749346, 6.06849649981985, 6.065223221418809, 6.0619502743444, 6.058677767388495, 6.055405806181095, 6.052134493287127, 6.048863928299894, 6.045594207931272, 6.042325426098806, 6.039057674009821, 6.035791040242641, 6.032525610825078, 6.029261469310236, 6.025998696849778, 6.022737372264733, 6.019477572113928, 6.016219370760174, 6.0129628404342235, 6.0097080512966565, 6.006455071497714, 6.003203967235193, 5.9999548028104535, 5.9967076406826045, 5.9934625415209535, 5.990219564255785, 5.986978766127489, 5.983740202734144, 5.9805039280775985, 5.9772699946080765, 5.97403845326741, 5.970809353530893, 5.967582743447848, 5.964358669680937, 5.961137177544235, 5.9579183110401654, 5.95470211289527, 5.951488624594915, 5.94827788641692, 5.945069937464193, 5.941864815696348, 5.938662557960415, 5.93546320002059, 5.9322667765871255, 5.92907332134435, 5.925882866977873, 5.922695445200971, 5.919511086780211, 5.9163298215603195, 5.913151678488335, 5.909976685637046, 5.906804870227775, 5.903636258652468, 5.900470876495201, 5.897308748553026, 5.8941498988562415, 5.890994350688107, 5.8878421266039656, 5.8846932484498415, 5.881547737380531, 5.878405613877172, 5.875266897764313, 5.872131608226546, 5.8689997638246325, 5.86587138251122, 5.8627464816461075, 5.859625078011108, 5.856507187824489, 5.853392826755032, 5.850282009935706, 5.8471747519769774, 5.844071066979749, 5.840970968547966, 5.8378744698008855, 5.834781583384992, 5.831692321485638, 5.8286066958383485, 5.825524717739826, 5.8224463980586885, 5.819371747245898, 5.816300775344936, 5.81323349200171, 5.810169906474193, 5.80711002764183, 5.804053864014689, 5.801001423742367, 5.79795271462271, 5.79490774411025, 5.7918665193244765, 5.78882904705787, 5.785795333783746, 5.782765385663897, 5.779739208556025, 5.776716808021024, 5.773698189330052, 5.77068335747142, 5.767672317157338, 5.764665072830481, 5.761661628670371, 5.758661988599642, 5.755666156290112, 5.752674135168731, 5.749685928423378, 5.746701539008506, 5.7437209696506635, 5.7407442228538725, 5.73777130090488, 5.734802205878285, 5.7318369396415365, 5.728875503859817, 5.725917900000805, 5.722964129339318, 5.72001419296187, 5.717068091771076, 5.71412582649001, 5.711187397666397, 5.708252805676765, 5.705322050730449, 5.7023951328735425, 5.699472051992726, 5.696552807819022, 5.693637399931456, 5.690725827760643, 5.68781809059227, 5.684914187570522, 5.682014117701412, 5.679117879856035, 5.67622547277377, 5.6733368950653595, 5.670452145215989, 5.6675712215882195, 5.664694122424915, 5.661820845852078, 5.658951389881598, 5.656085752413997, 5.653223931241049, 5.6503659240483834, 5.647511728418015, 5.644661341830811, 5.641814761668913, 5.638971985218107, 5.636133009670129, 5.633297832124924, 5.630466449592865, 5.6276388589969075, 5.624815057174699, 5.62199504088065, 5.619178806787966, 5.6163663514906075, 5.613557671505229, 5.610752763273075, 5.6079516231618225, 5.605154247467393, 5.6023606324157305, 5.5995707741645155, 5.596784668804874, 5.594002312363026, 5.5912237008019146, 5.588448830022778, 5.585677695866724, 5.582910294116222, 5.580146620496607, 5.577386670677528, 5.57463044027437, 5.571877924849648, 5.56912911991437, 5.566384020929362, 5.563642623306588, 5.560904922410418, 5.558170913558873, 5.555440592024863, 5.55271395303737, 5.54999099178263, 5.547271703405273, 5.544556083009456, 5.541844125659953, 5.539135826383238, 5.536431180168533, 5.533730181968844, 5.53103282670197, 5.528339109251492, 5.525649024467736, 5.522962567168735, 5.520279732141136, 5.517600514141129, 5.514924907895323, 5.512252908101624, 5.509584509430087, 5.50691970652375, 5.504258493999447, 5.501600866448624, 5.4989468184381085, 5.496296344510881, 5.493649439186836, 5.4910060969635035, 5.488366312316785, 5.485730079701653, 5.48309739355284, 5.4804682482855265, 5.477842638295993, 5.4752205579622775, 5.472602001644807, 5.469986963687029, 5.4673754384160125, 5.464767420143055, 5.462162903164255, 5.459561881761108, 5.456964350201048, 5.454370302738003, 5.451779733612942, 5.4491926370543915, 5.446609007278967, 5.444028838491865, 5.441452124887369, 5.438878860649328, 5.4363090399516425, 5.433742656958719, 5.431179705825943, 5.428620180700104, 5.4260640757198555, 5.423511385016131, 5.420962102712571, 5.418416222925927, 5.415873739766473, 5.413334647338401, 5.410798939740197, 5.4082666110650335, 5.405737655401135, 5.403212066832137, 5.4006898394374465, 5.398170967292595, 5.3956554444695755, 5.393143265037172, 5.390634423061299, 5.388128912605308, 5.38562672773032, 5.383127862495514, 5.380632310958442, 5.37814006717532, 5.375651125201311, 5.37316547909082, 5.370683122897764, 5.368204050675839, 5.365728256478798, 5.363255734360701, 5.360786478376175, 5.3583204825806545, 5.355857741030647, 5.353398247783942, 5.350941996899876, 5.348488982439535, 5.346039198466, 5.343592639044549, 5.341149298242891, 5.338709170131358, 5.336272248783124, 5.3338385282744, 5.331408002684632, 5.3289806660967, 5.326556512597097, 5.324135536276125, 5.321717731228068, 5.319303091551372, 5.316891611348819, 5.314483284727695, 5.3120781057999595, 5.309676068682402, 5.307277167496804, 5.3048813963700985, 5.302488749434512, 5.300099220827726, 5.29771280469301, 5.295329495179369, 5.292949286441685, 5.290572172640848, 5.288198147943896, 5.285827206524133, 5.2834593425612715, 5.281094550241539, 5.2787328237578155, 5.276374157309746, 5.274018545103849, 5.2716659813536415, 5.269316460279746, 5.26696997610999, 5.264626523079527, 5.262286095430927, 5.259948687414279, 5.257614293287297, 5.255282907315408, 5.252954523771851, 5.2506291369377625, 5.248306741102272, 5.245987330562584, 5.243670899624072, 5.241357442600348, 5.2390469538133555, 5.236739427593438, 5.23443485827943, 5.232133240218714, 5.229834567767313, 5.227538835289943, 5.225246037160101, 5.222956167760116, 5.220669221481225, 5.2183851927236375, 5.216104075896592, 5.213825865418419, 5.211550555716607, 5.209278141227849, 5.207008616398109, 5.204741975682669, 5.20247821354619, 5.200217324462751]} \ No newline at end of file +{"coordinate_system": [0.1, 0.1198, 0.1396, 0.15940000000000001, 0.17920000000000003, 0.199, 0.21880000000000002, 0.2386, 0.2584, 0.2782, 0.29800000000000004, 0.3178, 0.3376, 0.35740000000000005, 0.3772, 0.397, 0.41680000000000006, 0.4366, 0.45640000000000003, 0.47620000000000007, 0.496, 0.5158, 0.5356000000000001, 0.5554, 0.5752, 0.5950000000000001, 0.6148, 0.6346, 0.6544, 0.6742, 0.6940000000000001, 0.7138, 0.7336, 0.7534000000000001, 0.7732, 0.793, 0.8128000000000001, 0.8326, 0.8524, 0.8722000000000001, 0.892, 0.9118, 0.9316000000000001, 0.9514, 0.9712000000000001, 0.9910000000000001, 1.0108000000000001, 1.0306000000000002, 1.0504000000000002, 1.0702, 1.09, 1.1098000000000001, 1.1296000000000002, 1.1494000000000002, 1.1692000000000002, 1.1890000000000003, 1.2088, 1.2286000000000001, 1.2484000000000002, 1.2682000000000002, 1.2880000000000003, 1.3078000000000003, 1.3276000000000001, 1.3474000000000002, 1.3672000000000002, 1.3870000000000002, 1.4068000000000003, 1.4266, 1.4464000000000001, 1.4662000000000002, 1.4860000000000002, 1.5058000000000002, 1.5256000000000003, 1.5454, 1.5652000000000001, 1.5850000000000002, 1.6048000000000002, 1.6246000000000003, 1.6444000000000003, 1.6642000000000001, 1.6840000000000002, 1.7038000000000002, 1.7236000000000002, 1.7434000000000003, 1.7632000000000003, 1.7830000000000001, 1.8028000000000002, 1.8226000000000002, 1.8424000000000003, 1.8622000000000003, 1.8820000000000003, 1.9018000000000002, 1.9216000000000002, 1.9414000000000002, 1.9612000000000003, 1.9810000000000003, 2.0008000000000004, 2.0206, 2.0404, 2.0602, 2.08, 2.0998, 2.1196, 2.1394, 2.1592000000000002, 2.1790000000000003, 2.1988000000000003, 2.2186000000000003, 2.2384000000000004, 2.2582000000000004, 2.2780000000000005, 2.2978, 2.3176, 2.3374, 2.3572, 2.3770000000000002, 2.3968000000000003, 2.4166000000000003, 2.4364000000000003, 2.4562000000000004, 2.4760000000000004, 2.4958000000000005, 2.5156000000000005, 2.5354, 2.5552, 2.575, 2.5948, 2.6146000000000003, 2.6344000000000003, 2.6542000000000003, 2.6740000000000004, 2.6938000000000004, 2.7136000000000005, 2.7334000000000005, 2.7532, 2.773, 2.7928, 2.8126, 2.8324000000000003, 2.8522000000000003, 2.8720000000000003, 2.8918000000000004, 2.9116000000000004, 2.9314000000000004, 2.9512000000000005, 2.9710000000000005, 2.9908, 3.0106, 3.0304, 3.0502000000000002, 3.0700000000000003, 3.0898000000000003, 3.1096000000000004, 3.1294000000000004, 3.1492000000000004, 3.1690000000000005, 3.1888000000000005, 3.2086000000000006, 3.2284, 3.2482, 3.2680000000000002, 3.2878000000000003, 3.3076000000000003, 3.3274000000000004, 3.3472000000000004, 3.3670000000000004, 3.3868000000000005, 3.4066000000000005, 3.4264000000000006, 3.4462, 3.466, 3.4858000000000002, 3.5056000000000003, 3.5254000000000003, 3.5452000000000004, 3.5650000000000004, 3.5848000000000004, 3.6046000000000005, 3.6244000000000005, 3.6442000000000005, 3.6640000000000006, 3.6838, 3.7036000000000002, 3.7234000000000003, 3.7432000000000003, 3.7630000000000003, 3.7828000000000004, 3.8026000000000004, 3.8224000000000005, 3.8422000000000005, 3.8620000000000005, 3.8818000000000006, 3.9016000000000006, 3.9214, 3.9412000000000003, 3.9610000000000003, 3.9808000000000003, 4.0006, 4.0204, 4.0402000000000005, 4.0600000000000005, 4.0798000000000005, 4.099600000000001, 4.1194, 4.1392, 4.159, 4.1788, 4.1986, 4.2184, 4.2382, 4.258, 4.2778, 4.2976, 4.3174, 4.3372, 4.357, 4.3768, 4.3966, 4.4164, 4.4362, 4.456, 4.4758000000000004, 4.4956, 4.5154, 4.5352, 4.555, 4.5748, 4.5946, 4.6144, 4.6342, 4.654, 4.6738, 4.6936, 4.7134, 4.7332, 4.753, 4.7728, 4.7926, 4.8124, 4.8322, 4.852, 4.8718, 4.8916, 4.9114, 4.9312000000000005, 4.951, 4.9708, 4.9906, 5.0104, 5.0302, 5.05, 5.0698, 5.0896, 5.1094, 5.1292, 5.149, 5.1688, 5.1886, 5.2084, 5.2282, 5.248, 5.2678, 5.2876, 5.3074, 5.3272, 5.347, 5.3668000000000005, 5.3866000000000005, 5.4064, 5.4262, 5.446, 5.4658, 5.4856, 5.5054, 5.5252, 5.545, 5.5648, 5.5846, 5.6044, 5.6242, 5.644, 5.6638, 5.6836, 5.7034, 5.7232, 5.743, 5.7628, 5.7826, 5.8024000000000004, 5.8222000000000005, 5.8420000000000005, 5.8618, 5.8816, 5.9014, 5.9212, 5.941, 5.9608, 5.9806, 6.0004, 6.0202, 6.04, 6.0598, 6.0796, 6.0994, 6.1192, 6.139, 6.1588, 6.1786, 6.1984, 6.2182, 6.238, 6.2578000000000005, 6.2776000000000005, 6.2974000000000006, 6.317200000000001, 6.337, 6.3568, 6.3766, 6.3964, 6.4162, 6.436, 6.4558, 6.4756, 6.4954, 6.5152, 6.535, 6.5548, 6.5746, 6.5944, 6.6142, 6.634, 6.6538, 6.6736, 6.6934000000000005, 6.7132000000000005, 6.7330000000000005, 6.752800000000001, 6.772600000000001, 6.7924, 6.8122, 6.832, 6.8518, 6.8716, 6.8914, 6.9112, 6.931, 6.9508, 6.9706, 6.9904, 7.0102, 7.03, 7.0498, 7.0696, 7.0894, 7.1092, 7.1290000000000004, 7.1488000000000005, 7.1686000000000005, 7.188400000000001, 7.208200000000001, 7.228000000000001, 7.2478, 7.2676, 7.2874, 7.3072, 7.327, 7.3468, 7.3666, 7.3864, 7.4062, 7.426, 7.4458, 7.4656, 7.4854, 7.5052, 7.525, 7.5448, 7.5646, 7.5844000000000005, 7.6042000000000005, 7.6240000000000006, 7.643800000000001, 7.663600000000001, 7.683400000000001, 7.703200000000001, 7.723, 7.7428, 7.7626, 7.7824, 7.8022, 7.822, 7.8418, 7.8616, 7.8814, 7.9012, 7.921, 7.9408, 7.9606, 7.9804, 8.000200000000001, 8.020000000000001, 8.039800000000001, 8.059600000000001, 8.079400000000001, 8.099200000000002, 8.119, 8.1388, 8.1586, 8.1784, 8.1982, 8.218, 8.2378, 8.2576, 8.2774, 8.2972, 8.317, 8.3368, 8.3566, 8.3764, 8.3962, 8.416, 8.4358, 8.4556, 8.4754, 8.4952, 8.515, 8.5348, 8.5546, 8.5744, 8.5942, 8.614, 8.6338, 8.6536, 8.6734, 8.693200000000001, 8.713000000000001, 8.732800000000001, 8.752600000000001, 8.772400000000001, 8.792200000000001, 8.812000000000001, 8.831800000000001, 8.851600000000001, 8.8714, 8.8912, 8.911, 8.9308, 8.9506, 8.9704, 8.9902, 9.01, 9.0298, 9.0496, 9.0694, 9.0892, 9.109, 9.1288, 9.1486, 9.1684, 9.1882, 9.208, 9.2278, 9.2476, 9.2674, 9.2872, 9.307, 9.3268, 9.3466, 9.3664, 9.3862, 9.406, 9.4258, 9.4456, 9.4654, 9.4852, 9.505, 9.5248, 9.5446, 9.564400000000001, 9.584200000000001, 9.604000000000001, 9.623800000000001, 9.643600000000001, 9.663400000000001, 9.683200000000001, 9.703000000000001, 9.722800000000001, 9.742600000000001, 9.762400000000001, 9.7822, 9.802, 9.8218, 9.8416, 9.8614, 9.8812, 9.901, 9.9208, 9.9406, 9.9604, 9.9802, 10.0], "coordinate_type": "point", "coordinate_name": "recoil energy", "map": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.399698834317144, 2.6757041167692246, 2.9389584467645196, 3.1879387364333605, 3.4218464263881017, 3.640438747706453, 3.8438826185759316, 4.032633922322844, 4.207341398232108, 4.368772506786422, 4.517757871618573, 4.655150818029523, 4.781798810972488, 4.898524040066033, 5.006110883169805, 5.105298437153001, 5.196776704242026, 5.281185355360305, 5.359114260149574, 5.4311051842129014, 5.497654216711703, 5.559214614913085, 5.616199844819526, 5.668986665561592, 5.717918155452077, 5.763306613975364, 5.805436300013317, 5.8445659849700355, 5.880931312186183, 5.9147469626578575, 5.9462086327354795, 5.9754948330189075, 6.002768519707652, 6.028178570664022, 6.051861118732537, 6.073940754669365, 6.094531611541286, 6.1137383417757745, 6.131656997266583, 6.148375822121101, 6.163975966816124, 6.178532131732728, 6.192113147285232, 6.204782497152356, 6.216598790465547, 6.227616188210844, 6.2378847885561495, 6.247450975322641, 6.256357733374619, 6.264644934302595, 6.272349595416272, 6.279506114743732, 6.286146484446773, 6.29230048480688, 6.297995860708476, 6.303258482342988, 6.308112491676312, 6.312580436061036, 6.316683390231179, 6.3204410677891305, 6.323871923180462, 6.326993245050581, 6.329821241786351, 6.3323711199649795, 6.334657156360061, 6.336692764090129, 6.338490553437281, 6.340062387811787, 6.3414194352923605, 6.342572216130294, 6.343530646568537, 6.344304079293457, 6.344901340807084, 6.345330765980769, 6.345600230026956, 6.345717178104053, 6.345688652749733, 6.345521319320338, 6.3452214895981225, 6.344795143713659, 6.34424795051771, 6.3435852865251405, 6.342812253542752, 6.341933695083314, 6.34095421165928, 6.339878175041808, 6.338709741563437, 6.337452864536266, 6.33611130585156, 6.334688646821199, 6.333188298316586, 6.3316135102560445, 6.329967380487659, 6.328252863110799, 6.32647277627616, 6.32462980950096, 6.322726530533191, 6.320765391796111, 6.318748736441836, 6.316678804040675, 6.314557735930852, 6.312387580251373, 6.310170296679195, 6.30790776089021, 6.305601768762126, 6.303254040336128, 6.300866223552819, 6.298439897776962, 6.295976577124459, 6.2934777136040365, 6.290944700085308, 6.288378873103965, 6.285781515514199, 6.2831538589977365, 6.280497086438177, 6.27781233416884, 6.275100694101677, 6.272363215744355, 6.269600908112143, 6.2668147415407685, 6.2640056494060605, 6.261174529755742, 6.258322246858472, 6.255449632674856, 6.252557488254865, 6.249646585065797, 6.246717666254715, 6.243771447848973, 6.240808619898294, 6.2378298475615575, 6.234835772141394, 6.231827012069344, 6.228804163844293, 6.225767802926673, 6.2227184845907795, 6.21965674473743, 6.216583100669038, 6.213498051829076, 6.2104020805077695, 6.2072956525157545, 6.204179217827378, 6.201053211195141, 6.197918052736768, 6.1947741484963, 6.191621890980469, 6.188461659671619, 6.185293821518319, 6.18211873140476, 6.178936732599992, 6.175748157187949, 6.17255332647922, 6.169352551405439, 6.166146132897085, 6.162934362245543, 6.159717521450128, 6.156495883550765, 6.15326971294704, 6.150039265704216, 6.14680478984684, 6.143566525640485, 6.14032470586219, 6.137079556060111, 6.133831294802851, 6.1305801339189605, 6.127326278727007, 6.124069928256684, 6.120811275461304, 6.117550507422104, 6.114287805544667, 6.111023345747856, 6.107757298645548, 6.1044898297214845, 6.10122109949755, 6.097951263695735, 6.094680473394073, 6.091408875176782, 6.088136611278882, 6.084863819725484, 6.081590634466014, 6.078317185503532, 6.075043599019406, 6.07176999749346, 6.06849649981985, 6.065223221418809, 6.0619502743444, 6.058677767388495, 6.055405806181095, 6.052134493287127, 6.048863928299894, 6.045594207931272, 6.042325426098806, 6.039057674009821, 6.035791040242641, 6.032525610825078, 6.029261469310236, 6.025998696849778, 6.022737372264733, 6.019477572113928, 6.016219370760174, 6.0129628404342235, 6.0097080512966565, 6.006455071497714, 6.003203967235193, 5.9999548028104535, 5.9967076406826045, 5.9934625415209535, 5.990219564255785, 5.986978766127489, 5.983740202734144, 5.9805039280775985, 5.9772699946080765, 5.97403845326741, 5.970809353530893, 5.967582743447848, 5.964358669680937, 5.961137177544235, 5.9579183110401654, 5.95470211289527, 5.951488624594915, 5.94827788641692, 5.945069937464193, 5.941864815696348, 5.938662557960415, 5.93546320002059, 5.9322667765871255, 5.92907332134435, 5.925882866977873, 5.922695445200971, 5.919511086780211, 5.9163298215603195, 5.913151678488335, 5.909976685637046, 5.906804870227775, 5.903636258652468, 5.900470876495201, 5.897308748553026, 5.8941498988562415, 5.890994350688107, 5.8878421266039656, 5.8846932484498415, 5.881547737380531, 5.878405613877172, 5.875266897764313, 5.872131608226546, 5.8689997638246325, 5.86587138251122, 5.8627464816461075, 5.859625078011108, 5.856507187824489, 5.853392826755032, 5.850282009935706, 5.8471747519769774, 5.844071066979749, 5.840970968547966, 5.8378744698008855, 5.834781583384992, 5.831692321485638, 5.8286066958383485, 5.825524717739826, 5.8224463980586885, 5.819371747245898, 5.816300775344936, 5.81323349200171, 5.810169906474193, 5.80711002764183, 5.804053864014689, 5.801001423742367, 5.79795271462271, 5.79490774411025, 5.7918665193244765, 5.78882904705787, 5.785795333783746, 5.782765385663897, 5.779739208556025, 5.776716808021024, 5.773698189330052, 5.77068335747142, 5.767672317157338, 5.764665072830481, 5.761661628670371, 5.758661988599642, 5.755666156290112, 5.752674135168731, 5.749685928423378, 5.746701539008506, 5.7437209696506635, 5.7407442228538725, 5.73777130090488, 5.734802205878285, 5.7318369396415365, 5.728875503859817, 5.725917900000805, 5.722964129339318, 5.72001419296187, 5.717068091771076, 5.71412582649001, 5.711187397666397, 5.708252805676765, 5.705322050730449, 5.7023951328735425, 5.699472051992726, 5.696552807819022, 5.693637399931456, 5.690725827760643, 5.68781809059227, 5.684914187570522, 5.682014117701412, 5.679117879856035, 5.67622547277377, 5.6733368950653595, 5.670452145215989, 5.6675712215882195, 5.664694122424915, 5.661820845852078, 5.658951389881598, 5.656085752413997, 5.653223931241049, 5.6503659240483834, 5.647511728418015, 5.644661341830811, 5.641814761668913, 5.638971985218107, 5.636133009670129, 5.633297832124924, 5.630466449592865, 5.6276388589969075, 5.624815057174699, 5.62199504088065, 5.619178806787966, 5.6163663514906075, 5.613557671505229, 5.610752763273075, 5.6079516231618225, 5.605154247467393, 5.6023606324157305, 5.5995707741645155, 5.596784668804874, 5.594002312363026, 5.5912237008019146, 5.588448830022778, 5.585677695866724, 5.582910294116222, 5.580146620496607, 5.577386670677528, 5.57463044027437, 5.571877924849648, 5.56912911991437, 5.566384020929362, 5.563642623306588, 5.560904922410418, 5.558170913558873, 5.555440592024863, 5.55271395303737, 5.54999099178263, 5.547271703405273, 5.544556083009456, 5.541844125659953, 5.539135826383238, 5.536431180168533, 5.533730181968844, 5.53103282670197, 5.528339109251492, 5.525649024467736, 5.522962567168735, 5.520279732141136, 5.517600514141129, 5.514924907895323, 5.512252908101624, 5.509584509430087, 5.50691970652375, 5.504258493999447, 5.501600866448624, 5.4989468184381085, 5.496296344510881, 5.493649439186836, 5.4910060969635035, 5.488366312316785, 5.485730079701653, 5.48309739355284, 5.4804682482855265, 5.477842638295993, 5.4752205579622775, 5.472602001644807, 5.469986963687029, 5.4673754384160125, 5.464767420143055, 5.462162903164255, 5.459561881761108, 5.456964350201048, 5.454370302738003, 5.451779733612942, 5.4491926370543915, 5.446609007278967, 5.444028838491865, 5.441452124887369, 5.438878860649328, 5.4363090399516425, 5.433742656958719, 5.431179705825943, 5.428620180700104, 5.4260640757198555, 5.423511385016131, 5.420962102712571, 5.418416222925927, 5.415873739766473, 5.413334647338401, 5.410798939740197, 5.4082666110650335, 5.405737655401135, 5.403212066832137, 5.4006898394374465, 5.398170967292595, 5.3956554444695755, 5.393143265037172, 5.390634423061299, 5.388128912605308, 5.38562672773032, 5.383127862495514, 5.380632310958442, 5.37814006717532, 5.375651125201311, 5.37316547909082, 5.370683122897764, 5.368204050675839, 5.365728256478798, 5.363255734360701, 5.360786478376175, 5.3583204825806545, 5.355857741030647, 5.353398247783942, 5.350941996899876, 5.348488982439535, 5.346039198466, 5.343592639044549, 5.341149298242891, 5.338709170131358, 5.336272248783124, 5.3338385282744, 5.331408002684632, 5.3289806660967, 5.326556512597097, 5.324135536276125, 5.321717731228068, 5.319303091551372, 5.316891611348819, 5.314483284727695, 5.3120781057999595, 5.309676068682402, 5.307277167496804, 5.3048813963700985, 5.302488749434512, 5.300099220827726, 5.29771280469301, 5.295329495179369, 5.292949286441685, 5.290572172640848, 5.288198147943896, 5.285827206524133, 5.2834593425612715, 5.281094550241539, 5.2787328237578155, 5.276374157309746, 5.274018545103849, 5.2716659813536415, 5.269316460279746, 5.26696997610999, 5.264626523079527, 5.262286095430927, 5.259948687414279, 5.257614293287297, 5.255282907315408, 5.252954523771851, 5.2506291369377625, 5.248306741102272, 5.245987330562584, 5.243670899624072, 5.241357442600348, 5.2390469538133555, 5.236739427593438, 5.23443485827943, 5.232133240218714, 5.229834567767313, 5.227538835289943, 5.225246037160101, 5.222956167760116, 5.220669221481225, 5.2183851927236375, 5.216104075896592, 5.213825865418419, 5.211550555716607, 5.209278141227849, 5.207008616398109, 5.204741975682669, 5.20247821354619, 5.200217324462751]} diff --git a/appletree/maps/_nr_spectrum.json b/appletree/maps/_nr_spectrum.json index 6d1f3f2f..dd6de07f 100644 --- a/appletree/maps/_nr_spectrum.json +++ b/appletree/maps/_nr_spectrum.json @@ -1 +1 @@ -{"coordinate_system": [0.0, 0.008674250513574166, 0.017385831342227036, 0.026134011011075906, 0.03491803596549739, 0.04373710290947451, 0.0525904023915049, 0.0614770980395643, 0.07039635304605102, 0.07934727777040364, 0.08832896038443616, 0.09734046973592765, 0.10638086702318948, 0.11544919011693941, 0.12454441909172975, 0.133665530784099, 0.14281147304457437, 0.15198119783528433, 0.16117359618287658, 0.17038753641294246, 0.17962186795964177, 0.1888754358630215, 0.19814706159400924, 0.20743550034431782, 0.2167395089061304, 0.22605781391323224, 0.23538915294109322, 0.24473219422935258, 0.25408558407703297, 0.26344795184215664, 0.27281792781156394, 0.2821941198809936, 0.29157506095507385, 0.3009592928389145, 0.31034532730002373, 0.31973169673269375, 0.32911685573438926, 0.3384992394331302, 0.34787726996055185, 0.3572493782874654, 0.36661397603914203, 0.37596939116195727, 0.385313970819052, 0.39464603396881925, 0.40396393331558184, 0.41326593552299284, 0.42255029241992337, 0.43181524926881804, 0.4410590711715375, 0.45028000925614087, 0.45947622261342774, 0.4686459034139906, 0.47778721961852, 0.486898390005204, 0.49597753962774294, 0.505022785941018, 0.5140322492037932, 0.5230040840667214, 0.5319364393216955, 0.5408273640241414, 0.549674958154086, 0.5584773039937946, 0.5672325560499413, 0.5759387682951296, 0.5845939972543511, 0.5931963148874381, 0.6017438458723628, 0.6102347201467008, 0.618666961166487, 0.6270386653003384, 0.6353479204685935, 0.6435929125954172, 0.6517717214261269, 0.6598824424218406, 0.6679232024518587, 0.6758922031323417, 0.683787665454075, 0.6916076983782674, 0.6993505096733181, 0.7070143105886918, 0.7145974400786342, 0.7220981265908185, 0.7295146301857607, 0.736845261286985, 0.7440884301755678, 0.7512425831671699, 0.7583060502570543, 0.7652772891441487, 0.7721547750929328, 0.7789371434648913, 0.7856229160509068, 0.7922106640079921, 0.7986990298093253, 0.8050867825194014, 0.811372745355052, 0.8175556219023288, 0.8236342735788843, 0.8296075944251897, 0.8354746714593915, 0.8412344758594399, 0.8468860462088508, 0.8524285135114671, 0.8578611613866691, 0.8631833452141051, 0.8683942979083284, 0.8734934385833695, 0.8784802330415387, 0.8833543698490365, 0.8881154194734794, 0.8927630355014605, 0.897296982348325, 0.9017171987034962, 0.9060237072167462, 0.9102164106865437, 0.914295414528494, 0.9182608830687138, 0.9221132251904172, 0.9258527281917908, 0.929479772331229, 0.9329948604862989, 0.9363986822918908, 0.9396920180787702, 0.94287552336351, 0.9459500668561801, 0.9489165789400514, 0.9517762422156, 0.9545301113412471, 0.9571793336367344, 0.9597251794237142, 0.9621691034424912, 0.9645126461890613, 0.9667572147739493, 0.9689044227402475, 0.9709559364429498, 0.9729136613283946, 0.9747793643627848, 0.9765548903487579, 0.9782421913658214, 0.9798433813321221, 0.9813606391928589, 0.9827959975032644, 0.9841516656747114, 0.9854298822617409, 0.9866330856745581, 0.9877635608279232, 0.988823638482599, 0.9898157218507749, 0.9907423301651228, 0.991606009472444, 0.9924091432447222, 0.9931542373685055, 0.9938437884905035, 0.9944804266957321, 0.9950666119485576, 0.9956048022204868, 0.9960974622272872, 0.9965471469265694, 0.996956345780815, 0.997327384702356, 0.9976626380439038, 0.9979644238769665, 0.9982351083721674, 0.9984768766480808, 0.9986918580089603, 0.9988821336204634, 0.9990497888737323, 0.9991968045500048, 0.9993249922909321, 0.9994361367068881, 0.9995319269114, 0.9996140190881634, 0.9996838982621323, 0.999742955526716, 0.9997924964132655, 0.999833765166545, 0.999867890207725, 0.9998958566741145, 0.9999185798569857, 0.9999368769055774, 0.9999514955943983, 0.9999630636934566, 0.99997212587712, 0.9999791544457013, 0.9999845599766313, 0.9999886823890205, 0.9999917907617311, 0.9999941105124707, 0.9999958231418894, 0.9999970770541755, 0.9999979839802485, 0.9999986308038148, 0.9999990855520497, 0.9999994011244926, 0.999999617092682, 0.9999997617711627, 0.9999998566659399, 0.9999999174309635, 0.9999999555504395, 0.9999999787477784, 0.9999999923450269, 1.0], "coordinate_type": "point", "coordinate_name": "cdf", "map": [0.29999999999999993, 0.30391067028671026, 0.30787231838039175, 0.3118856088056944, 0.3159512147497243, 0.32006981817496355, 0.3242421099336622, 0.32846878988372163, 0.33275056700608807, 0.33708815952367716, 0.34148229502184746, 0.34593371057044603, 0.35044315284744365, 0.3550113782641822, 0.35963915309225486, 0.36432725359204, 0.36907646614291045, 0.3738875873751409, 0.3787614243035334, 0.3836987944627864, 0.3887005260446269, 0.3937674580367316, 0.3989004403634571, 0.4041003340284072, 0.40936801125885586, 0.4147043556520548, 0.4201102623234476, 0.42558663805681546, 0.43113440145638116, 0.4367544831008948, 0.44244782569972874, 0.44821538425100704, 0.45405812620179653, 0.4599770316103856, 0.4659730933106787, 0.4720473170787339, 0.4782007218014709, 0.484434339647579, 0.490749216240652, 0.4971464108345809, 0.5036269964912324, 0.5101920602604437, 0.5168427033623639, 0.5235800413721712, 0.5304052044072002, 0.5373193373165059, 0.544323599872901, 0.5514191669674948, 0.5586072288067692, 0.5658889911122232, 0.57326567532262, 0.5807385187988702, 0.5883087750315865, 0.595977713851343, 0.6037466216416763, 0.6116168015548623, 0.6195895737305069, 0.6276662755169848, 0.6358482616957661, 0.6441369047086661, 0.6525335948880585, 0.6610397406900884, 0.6696567689309264, 0.6783861250261017, 0.6872292732329555, 0.6961876968962541, 0.7052628986970056, 0.7144564009045175, 0.7237697456317417, 0.7332044950939481, 0.7427622318707691, 0.7524445591716612, 0.7622531011048259, 0.7721895029496374, 0.7822554314326198, 0.792452575007024, 0.8027826441360474, 0.813247371579746, 0.8238485126856865, 0.8345878456833877, 0.8454671719825996, 0.8564883164754707, 0.8676531278426545, 0.8789634788634062, 0.8904212667297215, 0.9020284133645711, 0.9137868657442819, 0.9256985962251228, 0.9377656028741461, 0.9499899098043424, 0.9623735675141638, 0.974918653231474, 0.9876272712619805, 1.0005015533422101, 1.0135436589970865, 1.0267557759021648, 1.0401401202505942, 1.0536989371248584, 1.067434500873366, 1.0813491154919492, 1.095445115010332, 1.1097248638836414, 1.1241907573890193, 1.1388452220274046, 1.1536907159305532, 1.1687297292733636, 1.1839647846915777, 1.1993984377049267, 1.2150332771457915, 1.2308719255934524, 1.2469170398139995, 1.2631713112059773, 1.2796374662518377, 1.2963182669752786, 1.313216511404545, 1.3303350340417688, 1.3476767063384252, 1.3652444371769894, 1.383041173358871, 1.4010699000987092, 1.4193336415251099, 1.4378354611879118, 1.4565784625720646, 1.475565789618207, 1.4948006272500276, 1.514286201908503, 1.5340257820930991, 1.5540226789100293, 1.5742802466276538, 1.5948018832391262, 1.6155910310323693, 1.6366511771674819, 1.6579858542616763, 1.6795986409818335, 1.701493162644789, 1.7236730918254408, 1.746142148972787, 1.7689041030339883, 1.7919627720865714, 1.8153220239788708, 1.8389857769788207, 1.8629580004312005, 1.8872427154234523, 1.911843995460175, 1.9367659671464137, 1.9620128108798511, 1.9875887615520271, 2.013498109258696, 2.039745200019447, 2.0663344365067005, 2.093270278784211, 2.120557245055194, 2.1481999124202127, 2.1762029176449307, 2.204570957937885, 2.233308791738392, 2.2624212395147256, 2.2919131845727008, 2.3217895738747942, 2.3520554188699467, 2.3827157963341823, 2.4137758492221804, 2.4452407875299538, 2.4771158891687723, 2.5094065008504725, 2.542118038984318, 2.575255990585539, 2.608825914195724, 2.6428334408152065, 2.677284274847608, 2.7121841950566856, 2.747539055535664, 2.7833547866891943, 2.819637396228122, 2.8563929701772106, 2.8936276738960114, 2.9313477531130365, 2.969559534973417, 3.008269429100209, 3.047483928669546, 3.0872096114997967, 3.1274531411549256, 3.168221268062237, 3.2095208306446854, 3.251358756467952, 3.2937420634024672, 3.3366778608005854, 3.3801733506891085, 3.4242358289773414, 3.4688726866809096, 3.5140914111615227, 3.5598995873829002, 3.606304899183069, 3.6533151305632456, 3.700938166993522, 3.7491819967355653, 3.798054712182575, 3.8475645112166834, 3.8977196985840705, 3.9485286872879977, 4.0]} \ No newline at end of file +{"coordinate_system": [0.0, 0.008674250513574166, 0.017385831342227036, 0.026134011011075906, 0.03491803596549739, 0.04373710290947451, 0.0525904023915049, 0.0614770980395643, 0.07039635304605102, 0.07934727777040364, 0.08832896038443616, 0.09734046973592765, 0.10638086702318948, 0.11544919011693941, 0.12454441909172975, 0.133665530784099, 0.14281147304457437, 0.15198119783528433, 0.16117359618287658, 0.17038753641294246, 0.17962186795964177, 0.1888754358630215, 0.19814706159400924, 0.20743550034431782, 0.2167395089061304, 0.22605781391323224, 0.23538915294109322, 0.24473219422935258, 0.25408558407703297, 0.26344795184215664, 0.27281792781156394, 0.2821941198809936, 0.29157506095507385, 0.3009592928389145, 0.31034532730002373, 0.31973169673269375, 0.32911685573438926, 0.3384992394331302, 0.34787726996055185, 0.3572493782874654, 0.36661397603914203, 0.37596939116195727, 0.385313970819052, 0.39464603396881925, 0.40396393331558184, 0.41326593552299284, 0.42255029241992337, 0.43181524926881804, 0.4410590711715375, 0.45028000925614087, 0.45947622261342774, 0.4686459034139906, 0.47778721961852, 0.486898390005204, 0.49597753962774294, 0.505022785941018, 0.5140322492037932, 0.5230040840667214, 0.5319364393216955, 0.5408273640241414, 0.549674958154086, 0.5584773039937946, 0.5672325560499413, 0.5759387682951296, 0.5845939972543511, 0.5931963148874381, 0.6017438458723628, 0.6102347201467008, 0.618666961166487, 0.6270386653003384, 0.6353479204685935, 0.6435929125954172, 0.6517717214261269, 0.6598824424218406, 0.6679232024518587, 0.6758922031323417, 0.683787665454075, 0.6916076983782674, 0.6993505096733181, 0.7070143105886918, 0.7145974400786342, 0.7220981265908185, 0.7295146301857607, 0.736845261286985, 0.7440884301755678, 0.7512425831671699, 0.7583060502570543, 0.7652772891441487, 0.7721547750929328, 0.7789371434648913, 0.7856229160509068, 0.7922106640079921, 0.7986990298093253, 0.8050867825194014, 0.811372745355052, 0.8175556219023288, 0.8236342735788843, 0.8296075944251897, 0.8354746714593915, 0.8412344758594399, 0.8468860462088508, 0.8524285135114671, 0.8578611613866691, 0.8631833452141051, 0.8683942979083284, 0.8734934385833695, 0.8784802330415387, 0.8833543698490365, 0.8881154194734794, 0.8927630355014605, 0.897296982348325, 0.9017171987034962, 0.9060237072167462, 0.9102164106865437, 0.914295414528494, 0.9182608830687138, 0.9221132251904172, 0.9258527281917908, 0.929479772331229, 0.9329948604862989, 0.9363986822918908, 0.9396920180787702, 0.94287552336351, 0.9459500668561801, 0.9489165789400514, 0.9517762422156, 0.9545301113412471, 0.9571793336367344, 0.9597251794237142, 0.9621691034424912, 0.9645126461890613, 0.9667572147739493, 0.9689044227402475, 0.9709559364429498, 0.9729136613283946, 0.9747793643627848, 0.9765548903487579, 0.9782421913658214, 0.9798433813321221, 0.9813606391928589, 0.9827959975032644, 0.9841516656747114, 0.9854298822617409, 0.9866330856745581, 0.9877635608279232, 0.988823638482599, 0.9898157218507749, 0.9907423301651228, 0.991606009472444, 0.9924091432447222, 0.9931542373685055, 0.9938437884905035, 0.9944804266957321, 0.9950666119485576, 0.9956048022204868, 0.9960974622272872, 0.9965471469265694, 0.996956345780815, 0.997327384702356, 0.9976626380439038, 0.9979644238769665, 0.9982351083721674, 0.9984768766480808, 0.9986918580089603, 0.9988821336204634, 0.9990497888737323, 0.9991968045500048, 0.9993249922909321, 0.9994361367068881, 0.9995319269114, 0.9996140190881634, 0.9996838982621323, 0.999742955526716, 0.9997924964132655, 0.999833765166545, 0.999867890207725, 0.9998958566741145, 0.9999185798569857, 0.9999368769055774, 0.9999514955943983, 0.9999630636934566, 0.99997212587712, 0.9999791544457013, 0.9999845599766313, 0.9999886823890205, 0.9999917907617311, 0.9999941105124707, 0.9999958231418894, 0.9999970770541755, 0.9999979839802485, 0.9999986308038148, 0.9999990855520497, 0.9999994011244926, 0.999999617092682, 0.9999997617711627, 0.9999998566659399, 0.9999999174309635, 0.9999999555504395, 0.9999999787477784, 0.9999999923450269, 1.0], "coordinate_type": "point", "coordinate_name": "cdf", "map": [0.29999999999999993, 0.30391067028671026, 0.30787231838039175, 0.3118856088056944, 0.3159512147497243, 0.32006981817496355, 0.3242421099336622, 0.32846878988372163, 0.33275056700608807, 0.33708815952367716, 0.34148229502184746, 0.34593371057044603, 0.35044315284744365, 0.3550113782641822, 0.35963915309225486, 0.36432725359204, 0.36907646614291045, 0.3738875873751409, 0.3787614243035334, 0.3836987944627864, 0.3887005260446269, 0.3937674580367316, 0.3989004403634571, 0.4041003340284072, 0.40936801125885586, 0.4147043556520548, 0.4201102623234476, 0.42558663805681546, 0.43113440145638116, 0.4367544831008948, 0.44244782569972874, 0.44821538425100704, 0.45405812620179653, 0.4599770316103856, 0.4659730933106787, 0.4720473170787339, 0.4782007218014709, 0.484434339647579, 0.490749216240652, 0.4971464108345809, 0.5036269964912324, 0.5101920602604437, 0.5168427033623639, 0.5235800413721712, 0.5304052044072002, 0.5373193373165059, 0.544323599872901, 0.5514191669674948, 0.5586072288067692, 0.5658889911122232, 0.57326567532262, 0.5807385187988702, 0.5883087750315865, 0.595977713851343, 0.6037466216416763, 0.6116168015548623, 0.6195895737305069, 0.6276662755169848, 0.6358482616957661, 0.6441369047086661, 0.6525335948880585, 0.6610397406900884, 0.6696567689309264, 0.6783861250261017, 0.6872292732329555, 0.6961876968962541, 0.7052628986970056, 0.7144564009045175, 0.7237697456317417, 0.7332044950939481, 0.7427622318707691, 0.7524445591716612, 0.7622531011048259, 0.7721895029496374, 0.7822554314326198, 0.792452575007024, 0.8027826441360474, 0.813247371579746, 0.8238485126856865, 0.8345878456833877, 0.8454671719825996, 0.8564883164754707, 0.8676531278426545, 0.8789634788634062, 0.8904212667297215, 0.9020284133645711, 0.9137868657442819, 0.9256985962251228, 0.9377656028741461, 0.9499899098043424, 0.9623735675141638, 0.974918653231474, 0.9876272712619805, 1.0005015533422101, 1.0135436589970865, 1.0267557759021648, 1.0401401202505942, 1.0536989371248584, 1.067434500873366, 1.0813491154919492, 1.095445115010332, 1.1097248638836414, 1.1241907573890193, 1.1388452220274046, 1.1536907159305532, 1.1687297292733636, 1.1839647846915777, 1.1993984377049267, 1.2150332771457915, 1.2308719255934524, 1.2469170398139995, 1.2631713112059773, 1.2796374662518377, 1.2963182669752786, 1.313216511404545, 1.3303350340417688, 1.3476767063384252, 1.3652444371769894, 1.383041173358871, 1.4010699000987092, 1.4193336415251099, 1.4378354611879118, 1.4565784625720646, 1.475565789618207, 1.4948006272500276, 1.514286201908503, 1.5340257820930991, 1.5540226789100293, 1.5742802466276538, 1.5948018832391262, 1.6155910310323693, 1.6366511771674819, 1.6579858542616763, 1.6795986409818335, 1.701493162644789, 1.7236730918254408, 1.746142148972787, 1.7689041030339883, 1.7919627720865714, 1.8153220239788708, 1.8389857769788207, 1.8629580004312005, 1.8872427154234523, 1.911843995460175, 1.9367659671464137, 1.9620128108798511, 1.9875887615520271, 2.013498109258696, 2.039745200019447, 2.0663344365067005, 2.093270278784211, 2.120557245055194, 2.1481999124202127, 2.1762029176449307, 2.204570957937885, 2.233308791738392, 2.2624212395147256, 2.2919131845727008, 2.3217895738747942, 2.3520554188699467, 2.3827157963341823, 2.4137758492221804, 2.4452407875299538, 2.4771158891687723, 2.5094065008504725, 2.542118038984318, 2.575255990585539, 2.608825914195724, 2.6428334408152065, 2.677284274847608, 2.7121841950566856, 2.747539055535664, 2.7833547866891943, 2.819637396228122, 2.8563929701772106, 2.8936276738960114, 2.9313477531130365, 2.969559534973417, 3.008269429100209, 3.047483928669546, 3.0872096114997967, 3.1274531411549256, 3.168221268062237, 3.2095208306446854, 3.251358756467952, 3.2937420634024672, 3.3366778608005854, 3.3801733506891085, 3.4242358289773414, 3.4688726866809096, 3.5140914111615227, 3.5598995873829002, 3.606304899183069, 3.6533151305632456, 3.700938166993522, 3.7491819967355653, 3.798054712182575, 3.8475645112166834, 3.8977196985840705, 3.9485286872879977, 4.0]} diff --git a/appletree/maps/_posrec_reso.json b/appletree/maps/_posrec_reso.json index 764e25a3..be35c5a7 100644 --- a/appletree/maps/_posrec_reso.json +++ b/appletree/maps/_posrec_reso.json @@ -1 +1 @@ -{"coordinate_system": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999], "coordinate_type": "point", "coordinate_name": "num_e", "map": [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]} \ No newline at end of file +{"coordinate_system": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999], "coordinate_type": "point", "coordinate_name": "num_e", "map": [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]} diff --git a/appletree/maps/_s1_bias.json b/appletree/maps/_s1_bias.json index 25ffbd58..ec4651d4 100644 --- a/appletree/maps/_s1_bias.json +++ b/appletree/maps/_s1_bias.json @@ -1 +1 @@ -{"coordinate_system": [0, 1, 2, 3], "coordinate_type": "point", "coordinate_name": "hit", "map": [0, 0, 0, 0]} \ No newline at end of file +{"coordinate_system": [0, 1, 2, 3], "coordinate_type": "point", "coordinate_name": "hit", "map": [0, 0, 0, 0]} diff --git a/appletree/maps/_s1_correction.json b/appletree/maps/_s1_correction.json index d6ddc0e5..f18b49b2 100644 --- a/appletree/maps/_s1_correction.json +++ b/appletree/maps/_s1_correction.json @@ -1 +1 @@ -{"coordinate_lowers": [-70, -70, -140], "coordinate_uppers": [70, 70, 0], "coordinate_type": "regbin", "coordinate_name": ["x", "y", "z"], "map": [[[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]], [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]], [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]], [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]], [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]]]} \ No newline at end of file +{"coordinate_lowers": [-70, -70, -140], "coordinate_uppers": [70, 70, 0], "coordinate_type": "regbin", "coordinate_name": ["x", "y", "z"], "map": [[[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]], [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]], [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]], [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]], [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]]]} diff --git a/appletree/maps/_s1_cut_acc.json b/appletree/maps/_s1_cut_acc.json index 9876ac40..b71eb464 100644 --- a/appletree/maps/_s1_cut_acc.json +++ b/appletree/maps/_s1_cut_acc.json @@ -1 +1 @@ -{"coordinate_system": [0, 50, 100], "coordinate_type": "point", "coordinate_name": "s1_area", "map": [1.0, 1.0, 1.0]} \ No newline at end of file +{"coordinate_system": [0, 50, 100], "coordinate_type": "point", "coordinate_name": "s1_area", "map": [1.0, 1.0, 1.0]} diff --git a/appletree/maps/_s1_smearing.json b/appletree/maps/_s1_smearing.json index 093da9fd..6a683ac4 100644 --- a/appletree/maps/_s1_smearing.json +++ b/appletree/maps/_s1_smearing.json @@ -1 +1 @@ -{"coordinate_system": [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 100.0], "coordinate_type": "point", "coordinate_name": "hit", "map": [0.23094010767585033, 0.2, 0.17888543819998318, 0.16329931618554522, 0.15118578920369088, 0.1414213562373095, 0.13333333333333333, 0.12649110640673517, 0.12060453783110546, 0.11547005383792516, 0.11094003924504584, 0.10690449676496976, 0.10327955589886445, 0.1, 0.09701425001453319, 0.09428090415820635, 0.0917662935482247, 0.08944271909999159, 0.08728715609439697, 0.08528028654224418, 0.08340576562282992, 0.08164965809277261, 0.08, 0.07844645405527362, 0.0769800358919501, 0.07559289460184544, 0.07427813527082075, 0.07302967433402215, 0.07184212081070997, 0.07071067811865475, 0.06963106238227915, 0.06859943405700354, 0.06761234037828133, 0.06666666666666667, 0.06575959492214292, 0.06488856845230502, 0.06405126152203486, 0.06324555320336758, 0.06246950475544243, 0.06172133998483677, 0.06099942813304187, 0.06030226891555273, 0.05962847939999439, 0.05897678246195886, 0.058345996599157825, 0.05773502691896258, 0.05714285714285715, 0.0565685424949238, 0.05601120336112039, 0.05547001962252292, 0.05494422557947561, 0.05443310539518174, 0.05393598899705937, 0.05345224838248488, 0.05298129428260175, 0.05252257314388902, 0.052075564392329556, 0.051639777949432225, 0.0512147519731584, 0.0508000508000762, 0.05039526306789696, 0.05, 0.04961389383568339, 0.04923659639173309, 0.04886777774252209, 0.048507125007266595, 0.04815434123430768, 0.047809144373375745, 0.047471266327754134, 0.047140452079103175, 0.04681645887845223, 0.04649905549752772, 0.04618802153517006, 0.04588314677411235, 0.045584230583855176, 0.04529108136578383, 0.04500351603704096, 0.044721359549995794, 0.044444444444444446, 0.044172610429938614, 0.04390570399587614, 0.043643578047198484, 0.04338609156373124, 0.04313310928137537, 0.04288450139351179, 0.04264014327112209, 0.04239991520025441, 0.04216370213557839, 0.04193139346887673, 0.04170288281141496, 0.04147806778921701, 0.04125684985035174, 0.04103913408340617, 0.040824829046386304, 0.04061384660534477, 0.040406101782088436, 0.04020151261036849, 0.04]} \ No newline at end of file +{"coordinate_system": [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 100.0], "coordinate_type": "point", "coordinate_name": "hit", "map": [0.23094010767585033, 0.2, 0.17888543819998318, 0.16329931618554522, 0.15118578920369088, 0.1414213562373095, 0.13333333333333333, 0.12649110640673517, 0.12060453783110546, 0.11547005383792516, 0.11094003924504584, 0.10690449676496976, 0.10327955589886445, 0.1, 0.09701425001453319, 0.09428090415820635, 0.0917662935482247, 0.08944271909999159, 0.08728715609439697, 0.08528028654224418, 0.08340576562282992, 0.08164965809277261, 0.08, 0.07844645405527362, 0.0769800358919501, 0.07559289460184544, 0.07427813527082075, 0.07302967433402215, 0.07184212081070997, 0.07071067811865475, 0.06963106238227915, 0.06859943405700354, 0.06761234037828133, 0.06666666666666667, 0.06575959492214292, 0.06488856845230502, 0.06405126152203486, 0.06324555320336758, 0.06246950475544243, 0.06172133998483677, 0.06099942813304187, 0.06030226891555273, 0.05962847939999439, 0.05897678246195886, 0.058345996599157825, 0.05773502691896258, 0.05714285714285715, 0.0565685424949238, 0.05601120336112039, 0.05547001962252292, 0.05494422557947561, 0.05443310539518174, 0.05393598899705937, 0.05345224838248488, 0.05298129428260175, 0.05252257314388902, 0.052075564392329556, 0.051639777949432225, 0.0512147519731584, 0.0508000508000762, 0.05039526306789696, 0.05, 0.04961389383568339, 0.04923659639173309, 0.04886777774252209, 0.048507125007266595, 0.04815434123430768, 0.047809144373375745, 0.047471266327754134, 0.047140452079103175, 0.04681645887845223, 0.04649905549752772, 0.04618802153517006, 0.04588314677411235, 0.045584230583855176, 0.04529108136578383, 0.04500351603704096, 0.044721359549995794, 0.044444444444444446, 0.044172610429938614, 0.04390570399587614, 0.043643578047198484, 0.04338609156373124, 0.04313310928137537, 0.04288450139351179, 0.04264014327112209, 0.04239991520025441, 0.04216370213557839, 0.04193139346887673, 0.04170288281141496, 0.04147806778921701, 0.04125684985035174, 0.04103913408340617, 0.040824829046386304, 0.04061384660534477, 0.040406101782088436, 0.04020151261036849, 0.04]} diff --git a/appletree/maps/_s2_bias.json b/appletree/maps/_s2_bias.json index 784775f7..e8bdaae2 100644 --- a/appletree/maps/_s2_bias.json +++ b/appletree/maps/_s2_bias.json @@ -1 +1 @@ -{"coordinate_system": [0, 100, 200, 300], "coordinate_type": "point", "coordinate_name": "hit", "map": [0, 0, 0, 0]} \ No newline at end of file +{"coordinate_system": [0, 100, 200, 300], "coordinate_type": "point", "coordinate_name": "hit", "map": [0, 0, 0, 0]} diff --git a/appletree/maps/_s2_correction.json b/appletree/maps/_s2_correction.json index 90f2304e..2c6ef063 100644 --- a/appletree/maps/_s2_correction.json +++ b/appletree/maps/_s2_correction.json @@ -1 +1 @@ -{"coordinate_lowers": [-70, -70], "coordinate_uppers": [70, 70], "coordinate_type": "regbin", "coordinate_name": ["x", "y"], "map": [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]]} \ No newline at end of file +{"coordinate_lowers": [-70, -70], "coordinate_uppers": [70, 70], "coordinate_type": "regbin", "coordinate_name": ["x", "y"], "map": [[1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0]]} diff --git a/appletree/maps/_s2_cut_acc.json b/appletree/maps/_s2_cut_acc.json index 5a68974b..e6854821 100644 --- a/appletree/maps/_s2_cut_acc.json +++ b/appletree/maps/_s2_cut_acc.json @@ -1 +1 @@ -{"coordinate_system": [0, 500, 1000], "coordinate_type": "point", "coordinate_name": "s2_area", "map": [1.0, 1.0, 1.0]} \ No newline at end of file +{"coordinate_system": [0, 500, 1000], "coordinate_type": "point", "coordinate_name": "s2_area", "map": [1.0, 1.0, 1.0]} diff --git a/appletree/maps/_s2_smearing.json b/appletree/maps/_s2_smearing.json index 8e0c3618..85189954 100644 --- a/appletree/maps/_s2_smearing.json +++ b/appletree/maps/_s2_smearing.json @@ -1 +1 @@ -{"coordinate_system": [200.0, 298.98989898989896, 397.979797979798, 496.969696969697, 595.959595959596, 694.9494949494949, 793.939393939394, 892.929292929293, 991.9191919191919, 1090.909090909091, 1189.8989898989898, 1288.888888888889, 1387.878787878788, 1486.8686868686868, 1585.858585858586, 1684.8484848484848, 1783.8383838383838, 1882.828282828283, 1981.8181818181818, 2080.808080808081, 2179.7979797979797, 2278.787878787879, 2377.777777777778, 2476.7676767676767, 2575.757575757576, 2674.747474747475, 2773.7373737373737, 2872.7272727272725, 2971.717171717172, 3070.7070707070707, 3169.6969696969695, 3268.686868686869, 3367.6767676767677, 3466.6666666666665, 3565.656565656566, 3664.6464646464647, 3763.6363636363635, 3862.626262626263, 3961.6161616161617, 4060.6060606060605, 4159.595959595959, 4258.585858585859, 4357.575757575758, 4456.565656565656, 4555.555555555556, 4654.545454545455, 4753.535353535353, 4852.525252525253, 4951.515151515152, 5050.50505050505, 5149.49494949495, 5248.484848484848, 5347.474747474747, 5446.464646464647, 5545.454545454545, 5644.444444444444, 5743.434343434344, 5842.424242424242, 5941.414141414141, 6040.404040404041, 6139.393939393939, 6238.383838383838, 6337.373737373738, 6436.363636363636, 6535.353535353535, 6634.343434343435, 6733.333333333333, 6832.323232323232, 6931.313131313132, 7030.30303030303, 7129.292929292929, 7228.282828282829, 7327.272727272727, 7426.262626262626, 7525.252525252526, 7624.242424242424, 7723.232323232323, 7822.222222222223, 7921.212121212121, 8020.20202020202, 8119.191919191919, 8218.181818181818, 8317.171717171717, 8416.161616161617, 8515.151515151516, 8614.141414141413, 8713.131313131313, 8812.121212121212, 8911.111111111111, 9010.10101010101, 9109.09090909091, 9208.080808080807, 9307.070707070707, 9406.060606060606, 9505.050505050505, 9604.040404040405, 9703.030303030304, 9802.020202020201, 9901.0101010101, 10000.0], "coordinate_type": "point", "coordinate_name": "hit", "map": [0.04242640687119285, 0.03469948204302269, 0.030076045749379714, 0.026914498767438323, 0.024577790718658368, 0.022760124248649292, 0.021294015931801514, 0.020079029379292207, 0.019050795002414796, 0.018165902124584948, 0.017393869302254315, 0.016712580435934668, 0.016105547065784806, 0.015560191683182803, 0.015066730548687448, 0.014617423327939895, 0.014206055206495972, 0.01382757089073122, 0.013477810510123258, 0.013153315503623565, 0.012851183578557534, 0.012568958723945882, 0.012304546686443938, 0.012056149223305782, 0.011822212393725336, 0.011601385478256713, 0.01139248803753423, 0.011194483270620514, 0.011006456296989467, 0.010827596321680224, 0.010657181888877543, 0.010494568611131443, 0.010339178897569419, 0.010190493307301362, 0.010048043232616616, 0.009911404676842567, 0.009780192938436514, 0.009654058049342964, 0.00953268084431401, 0.009415769560578172, 0.009303056885312739, 0.009194297382852393, 0.009089265245232528, 0.008987752319115905, 0.008889566369846306, 0.008794529549668929, 0.008702477042333016, 0.008613255860565563, 0.008526723776448556, 0.008442748367682173, 0.008361206165182211, 0.008281981889528361, 0.008204967765521397, 0.00813006290557857, 0.008057172753943237, 0.007986208584745025, 0.007917087047851, 0.007849729757221632, 0.007784062917148722, 0.007720016982323151, 0.00765752634817221, 0.007596529068331823, 0.007536966596487606, 0.007478783550139053, 0.00742192749412006, 0.0073663487419523745, 0.007312000173321487, 0.007258837066150972, 0.0072068169419151834, 0.007155899422974315, 0.007106046100842943, 0.007057220414415376, 0.007009387537270477, 0.006962514273266569, 0.00691656895971526, 0.00687152137749243, 0.00682734266750654, 0.006784005252999681, 0.006741482767206008, 0.006699749985936447, 0.0066587827646980395, 0.0066185579799918105, 0.006579053474464912, 0.0065402480056215, 0.0065021211978226285, 0.006464653497328787, 0.006427826130159722, 0.006391621062565254, 0.006356020963918038, 0.006321009171854811, 0.006286569659506871, 0.006252687004673398, 0.006219346360802937, 0.006186533429659025, 0.0061542344355556495, 0.006122436101057089, 0.006091125624044792, 0.006060290656061303, 0.006029919281848053, 0.006]} \ No newline at end of file +{"coordinate_system": [200.0, 298.98989898989896, 397.979797979798, 496.969696969697, 595.959595959596, 694.9494949494949, 793.939393939394, 892.929292929293, 991.9191919191919, 1090.909090909091, 1189.8989898989898, 1288.888888888889, 1387.878787878788, 1486.8686868686868, 1585.858585858586, 1684.8484848484848, 1783.8383838383838, 1882.828282828283, 1981.8181818181818, 2080.808080808081, 2179.7979797979797, 2278.787878787879, 2377.777777777778, 2476.7676767676767, 2575.757575757576, 2674.747474747475, 2773.7373737373737, 2872.7272727272725, 2971.717171717172, 3070.7070707070707, 3169.6969696969695, 3268.686868686869, 3367.6767676767677, 3466.6666666666665, 3565.656565656566, 3664.6464646464647, 3763.6363636363635, 3862.626262626263, 3961.6161616161617, 4060.6060606060605, 4159.595959595959, 4258.585858585859, 4357.575757575758, 4456.565656565656, 4555.555555555556, 4654.545454545455, 4753.535353535353, 4852.525252525253, 4951.515151515152, 5050.50505050505, 5149.49494949495, 5248.484848484848, 5347.474747474747, 5446.464646464647, 5545.454545454545, 5644.444444444444, 5743.434343434344, 5842.424242424242, 5941.414141414141, 6040.404040404041, 6139.393939393939, 6238.383838383838, 6337.373737373738, 6436.363636363636, 6535.353535353535, 6634.343434343435, 6733.333333333333, 6832.323232323232, 6931.313131313132, 7030.30303030303, 7129.292929292929, 7228.282828282829, 7327.272727272727, 7426.262626262626, 7525.252525252526, 7624.242424242424, 7723.232323232323, 7822.222222222223, 7921.212121212121, 8020.20202020202, 8119.191919191919, 8218.181818181818, 8317.171717171717, 8416.161616161617, 8515.151515151516, 8614.141414141413, 8713.131313131313, 8812.121212121212, 8911.111111111111, 9010.10101010101, 9109.09090909091, 9208.080808080807, 9307.070707070707, 9406.060606060606, 9505.050505050505, 9604.040404040405, 9703.030303030304, 9802.020202020201, 9901.0101010101, 10000.0], "coordinate_type": "point", "coordinate_name": "hit", "map": [0.04242640687119285, 0.03469948204302269, 0.030076045749379714, 0.026914498767438323, 0.024577790718658368, 0.022760124248649292, 0.021294015931801514, 0.020079029379292207, 0.019050795002414796, 0.018165902124584948, 0.017393869302254315, 0.016712580435934668, 0.016105547065784806, 0.015560191683182803, 0.015066730548687448, 0.014617423327939895, 0.014206055206495972, 0.01382757089073122, 0.013477810510123258, 0.013153315503623565, 0.012851183578557534, 0.012568958723945882, 0.012304546686443938, 0.012056149223305782, 0.011822212393725336, 0.011601385478256713, 0.01139248803753423, 0.011194483270620514, 0.011006456296989467, 0.010827596321680224, 0.010657181888877543, 0.010494568611131443, 0.010339178897569419, 0.010190493307301362, 0.010048043232616616, 0.009911404676842567, 0.009780192938436514, 0.009654058049342964, 0.00953268084431401, 0.009415769560578172, 0.009303056885312739, 0.009194297382852393, 0.009089265245232528, 0.008987752319115905, 0.008889566369846306, 0.008794529549668929, 0.008702477042333016, 0.008613255860565563, 0.008526723776448556, 0.008442748367682173, 0.008361206165182211, 0.008281981889528361, 0.008204967765521397, 0.00813006290557857, 0.008057172753943237, 0.007986208584745025, 0.007917087047851, 0.007849729757221632, 0.007784062917148722, 0.007720016982323151, 0.00765752634817221, 0.007596529068331823, 0.007536966596487606, 0.007478783550139053, 0.00742192749412006, 0.0073663487419523745, 0.007312000173321487, 0.007258837066150972, 0.0072068169419151834, 0.007155899422974315, 0.007106046100842943, 0.007057220414415376, 0.007009387537270477, 0.006962514273266569, 0.00691656895971526, 0.00687152137749243, 0.00682734266750654, 0.006784005252999681, 0.006741482767206008, 0.006699749985936447, 0.0066587827646980395, 0.0066185579799918105, 0.006579053474464912, 0.0065402480056215, 0.0065021211978226285, 0.006464653497328787, 0.006427826130159722, 0.006391621062565254, 0.006356020963918038, 0.006321009171854811, 0.006286569659506871, 0.006252687004673398, 0.006219346360802937, 0.006186533429659025, 0.0061542344355556495, 0.006122436101057089, 0.006091125624044792, 0.006060290656061303, 0.006029919281848053, 0.006]} diff --git a/appletree/parameter.py b/appletree/parameter.py index 5892cb2e..ff61ba86 100644 --- a/appletree/parameter.py +++ b/appletree/parameter.py @@ -6,39 +6,41 @@ from appletree.randgen import TwoHalfNorm -class Parameter(): +class Parameter: """Parameter handler to update parameters and calculate prior.""" def __init__(self, parameter_config): - """Initialization + """Initialization. :param parameter_config: can be either * str: the json file name where the config is stored. * dict: config dictionary. + """ if isinstance(parameter_config, str): - with open(parameter_config, 'r') as file: + with open(parameter_config, "r") as file: self.par_config = json.load(file) elif isinstance(parameter_config, dict): self.par_config = copy.deepcopy(parameter_config) else: - raise RuntimeError('Parameter configuration should be file name or dictionary') + raise RuntimeError("Parameter configuration should be file name or dictionary") self._parameter_fixed = set() self._parameter_fit = set() self.init_parameter() def init_parameter(self, seed=None): - """Initializing parameters by sampling prior. - If the prior is free, then sampling from the initial guess. + """Initializing parameters by sampling prior. If the prior is free, then sampling from the + initial guess. :param seed: integer, sent to np.random.seed(seed) + """ self._parameter_dict = {par_name: 0 for par_name in self.par_config.keys()} for par_name in self.par_config.keys(): - if self.par_config[par_name]['prior_type'] == 'fixed': + if self.par_config[par_name]["prior_type"] == "fixed": self._parameter_fixed.add(par_name) else: self._parameter_fit.add(par_name) @@ -52,12 +54,14 @@ def init_parameter(self, seed=None): @property def parameter_fit(self): - """Return sorted list of parameters name waiting for fitting""" + """Return sorted list of parameters name waiting for fitting.""" return sorted(self._parameter_fit) def sample_prior(self): """Sampling parameters from prior and set self._parameter_dict. + If the prior is free, then sampling from the initial guess. + """ for par_name in self._parameter_dict: try: @@ -65,95 +69,98 @@ def sample_prior(self): except KeyError: raise RuntimeError(f'Requested parameter "{par_name}" not in given configuration') - args = setting['prior_args'] - prior_type = setting['prior_type'] + args = setting["prior_args"] + prior_type = setting["prior_type"] - if prior_type == 'norm': + if prior_type == "norm": kwargs = { - 'loc': args['mean'], - 'scale': args['std'], + "loc": args["mean"], + "scale": args["std"], } val = np.random.normal(**kwargs) - self._parameter_dict[par_name] = np.clip(val, *setting['allowed_range']) - elif prior_type == 'twohalfnorm': + self._parameter_dict[par_name] = np.clip(val, *setting["allowed_range"]) + elif prior_type == "twohalfnorm": kwargs = { - 'mu': args['mu'], - 'sigma_pos': args['sigma_pos'], - 'sigma_neg': args['sigma_neg'], + "mu": args["mu"], + "sigma_pos": args["sigma_pos"], + "sigma_neg": args["sigma_neg"], } val = TwoHalfNorm.rvs(**kwargs) - self._parameter_dict[par_name] = np.clip(val, *setting['allowed_range']) - elif prior_type == 'uniform': + self._parameter_dict[par_name] = np.clip(val, *setting["allowed_range"]) + elif prior_type == "uniform": kwargs = { - 'low': args['lower'], - 'high': args['upper'], + "low": args["lower"], + "high": args["upper"], } val = np.random.uniform(**kwargs) - self._parameter_dict[par_name] = np.clip(val, *setting['allowed_range']) - elif prior_type == 'free': + self._parameter_dict[par_name] = np.clip(val, *setting["allowed_range"]) + elif prior_type == "free": kwargs = { - 'loc': setting['init_mean'], - 'scale': setting['init_std'], + "loc": setting["init_mean"], + "scale": setting["init_std"], } val = np.random.normal(**kwargs) - self._parameter_dict[par_name] = np.clip(val, *setting['allowed_range']) - elif prior_type == 'fixed': - self._parameter_dict[par_name] = args['val'] + self._parameter_dict[par_name] = np.clip(val, *setting["allowed_range"]) + elif prior_type == "fixed": + self._parameter_dict[par_name] = args["val"] def sample_init(self): - """Samping parameters from initial guess clipped - by the allowed_range and set self._parameter_dict. - """ + """Samping parameters from initial guess clipped by the allowed_range and set + self._parameter_dict.""" for par_name in self._parameter_dict: try: setting = self.par_config[par_name] except KeyError: raise RuntimeError(f'Requested parameter "{par_name}" not in given configuration') - args = setting['prior_args'] - prior_type = setting['prior_type'] + args = setting["prior_args"] + prior_type = setting["prior_type"] - if prior_type == 'fixed': - self._parameter_dict[par_name] = args['val'] + if prior_type == "fixed": + self._parameter_dict[par_name] = args["val"] else: kwargs = { - 'loc': setting['init_mean'], - 'scale': setting['init_std'], + "loc": setting["init_mean"], + "scale": setting["init_std"], } val = np.random.normal(**kwargs) - self._parameter_dict[par_name] = np.clip(val, *setting['allowed_range']) + self._parameter_dict[par_name] = np.clip(val, *setting["allowed_range"]) @property def log_prior(self): - """Return log prior. If any parameter is out of allowed_range return -np.inf.""" + """Return log prior. + + If any parameter is out of allowed_range return -np.inf. + + """ log_prior = 0 for par_name in self._parameter_fit: val = self._parameter_dict[par_name] setting = self.par_config[par_name] - args = setting['prior_args'] - prior_type = setting['prior_type'] + args = setting["prior_args"] + prior_type = setting["prior_type"] - if val < setting['allowed_range'][0] or val > setting['allowed_range'][1]: + if val < setting["allowed_range"][0] or val > setting["allowed_range"][1]: log_prior += -np.inf - elif prior_type == 'norm': - mean = args['mean'] - std = args['std'] - log_prior += - (val - mean)**2 / 2 / std**2 - elif prior_type == 'twohalfnorm': - mu = args['mu'] - sigma_pos = args['sigma_pos'] - sigma_neg = args['sigma_neg'] + elif prior_type == "norm": + mean = args["mean"] + std = args["std"] + log_prior += -((val - mean) ** 2) / 2 / std**2 + elif prior_type == "twohalfnorm": + mu = args["mu"] + sigma_pos = args["sigma_pos"] + sigma_neg = args["sigma_neg"] log_prior += TwoHalfNorm.logpdf( x=val, mu=mu, sigma_pos=sigma_pos, sigma_neg=sigma_neg, ) - elif prior_type == 'free': + elif prior_type == "free": pass - elif prior_type == 'uniform': + elif prior_type == "uniform": pass return log_prior @@ -161,25 +168,26 @@ def log_prior(self): def check_parameter_exist(self, keys, return_not_exist=False): """Check whether the keys exist in parameters. - :param keys: Parameter names. Can be a single str, or a list of str. - :param return_not_exist: If False, function will return a bool if all keys exist. - If True, function will additionally return the list of the not existing keys. + :param keys: Parameter names. Can be a single str, or a list of str. :param + return_not_exist: If False, function will return a bool if all keys exist. If True, + function will additionally return the list of the not existing keys. + """ if isinstance(keys, (set, list)): not_exist = [] for key in keys: if key not in self._parameter_dict: not_exist.append(key) - all_exist = (not_exist == []) + all_exist = not_exist == [] if return_not_exist: return (all_exist, not_exist) else: - return (all_exist) + return all_exist elif isinstance(keys, str): if return_not_exist: return (keys in self._parameter_dict, keys) else: - return (keys in self._parameter_dict) + return keys in self._parameter_dict elif isinstance(keys, dict): return self.check_parameter_exist(list(keys.keys()), return_not_exist) @@ -195,6 +203,7 @@ def set_parameter(self, keys, vals=None): * list: vals must have the same length. * dict: vals will be overwritten as keys.values(). :param vals: Values to be set. + """ all_exist, not_exist = self.check_parameter_exist(keys, return_not_exist=True) assert all_exist, f"{not_exist} not found!" @@ -215,6 +224,7 @@ def get_parameter(self, keys): """Return parameter values. :param keys: Parameter names. Can be a single str, or a list of str. + """ all_exist, not_exist = self.check_parameter_exist(keys, return_not_exist=True) assert all_exist, f"{not_exist} not found!" @@ -222,7 +232,7 @@ def get_parameter(self, keys): return self.__getitem__(keys) def __getitem__(self, keys): - """__getitem__, keys can be str/list/set""" + """__getitem__, keys can be str/list/set.""" if isinstance(keys, (set, list)): return np.array([self._parameter_dict[key] for key in keys]) elif isinstance(keys, str): diff --git a/appletree/parameters/nestv2.json b/appletree/parameters/nestv2.json index 6882eeff..c8b6d420 100644 --- a/appletree/parameters/nestv2.json +++ b/appletree/parameters/nestv2.json @@ -158,4 +158,4 @@ "unit": "1", "doc": "Placeholder for compatibility" } -} \ No newline at end of file +} diff --git a/appletree/plugin.py b/appletree/plugin.py index a999fc34..d9f673a1 100644 --- a/appletree/plugin.py +++ b/appletree/plugin.py @@ -1,5 +1,6 @@ import inspect from copy import deepcopy +from typing import List, Tuple, Optional from immutabledict import immutabledict @@ -10,35 +11,33 @@ @export -class Plugin(): +class Plugin: """The smallest simulation unit.""" # Do not initialize this class because it is base __is_base = True # the plugin's dependency(the arguments of `simulate`) - depends_on = [] + depends_on: List[str] = [] # the plugin can provide(`simulate` will return) - provides = [] + provides: List[str] = [] # relevant parameters, will be fitted in MCMC - parameters = () + parameters: Tuple = () # Set using the takes_config decorator takes_config = immutabledict() - def __init__(self, llh_name: str = None): + def __init__(self, llh_name: Optional[str] = None): """Initialization.""" # llh_name will tell us which map to use self.llh_name = llh_name if not self.depends_on: - raise ValueError('depends_on not provided for ' - f'{self.__class__.__name__}') + raise ValueError("depends_on not provided for " f"{self.__class__.__name__}") if not self.provides: - raise ValueError('provides not provided for ' - f'{self.__class__.__name__}') + raise ValueError("provides not provided for " f"{self.__class__.__name__}") # configs are loaded when a plugin is initialized for config in self.takes_config.values(): @@ -51,7 +50,7 @@ def __init__(self, llh_name: str = None): setattr(self, config.name, deepcopy(config)) def __call__(self, *args, **kwargs): - """Calls self.simulate""" + """Calls self.simulate.""" return self.simulate(*args, **kwargs) def simulate(self, *args, **kwargs): @@ -65,17 +64,19 @@ def simulate(self, *args, **kwargs): self.depends_on. :return: `key` and output simulated variables, ordered by self.provides. `key` will be updated if it's used inside self.simulate to generate random variables. + """ raise NotImplementedError def sanity_check(self): - """Check the consistency between `depends_on`, `provides` and in(out)put of `self.simulate`""" + """Check the consistency between `depends_on`, `provides` and in(out)put of + `self.simulate`""" arguments = inspect.getfullargspec(self.simulate)[0] - if arguments[1] != 'key': + if arguments[1] != "key": mesg = f"First argument of {self.__class__.__name__}" mesg += ".simulate should be 'key'." raise ValueError(mesg) - if arguments[2] != 'parameters': + if arguments[2] != "parameters": mesg = f"Second argument of {self.__class__.__name__}" mesg += ".simulate should be 'parameters'." raise ValueError(mesg) @@ -83,18 +84,17 @@ def sanity_check(self): if arguments[i] != depend: mesg = f"{i}th argument of {self.__class__.__name__}" mesg += f".simulate should be '{depend}'." - mesg += f'Plugin {self.__class__.__name__} is insane, check dependency!' + mesg += f"Plugin {self.__class__.__name__} is insane, check dependency!" raise ValueError(mesg) - @export def add_plugin_extensions(module1, module2, force=False): - """Add plugins of module2 to module1""" + """Add plugins of module2 to module1.""" utils.add_extensions(module1, module2, Plugin, force=force) @export def _add_plugin_extension(module, plugin, force=False): - """Add plugin to module""" + """Add plugin to module.""" utils._add_extension(module, plugin, Plugin, force=force) diff --git a/appletree/plugins/common.py b/appletree/plugins/common.py index c1c0f0a9..ad91fd54 100644 --- a/appletree/plugins/common.py +++ b/appletree/plugins/common.py @@ -3,29 +3,32 @@ from jax import jit from jax import numpy as jnp -import appletree from appletree import randgen from appletree.plugin import Plugin -from appletree.config import Constant, Map +from appletree.config import takes_config, Constant, Map from appletree.utils import exporter export, __all__ = exporter() @export -@appletree.takes_config( - Constant(name='lower_energy', +@takes_config( + Constant( + name="lower_energy", type=float, default=0.01, - help='Energy lower limit simulated in uniformly distribution'), - Constant(name='upper_energy', + help="Energy lower limit simulated in uniformly distribution", + ), + Constant( + name="upper_energy", type=float, - default=20., - help='Energy upper limit simulated in uniformly distribution'), + default=20.0, + help="Energy upper limit simulated in uniformly distribution", + ), ) class UniformEnergySpectra(Plugin): - depends_on = ['batch_size'] - provides = ['energy'] + depends_on = ["batch_size"] + provides = ["energy"] @partial(jit, static_argnums=(0, 3)) def simulate(self, key, parameters, batch_size): @@ -33,38 +36,33 @@ def simulate(self, key, parameters, batch_size): key, self.lower_energy.value, self.upper_energy.value, - shape=(batch_size, ), + shape=(batch_size,), ) return key, energy @export -@appletree.takes_config( - Map(name='energy_spectrum', - default='_nr_spectrum.json', - help='Recoil energy spectrum'), +@takes_config( + Map(name="energy_spectrum", default="_nr_spectrum.json", help="Recoil energy spectrum"), ) class FixedEnergySpectra(Plugin): - depends_on = ['batch_size'] - provides = ['energy'] + depends_on = ["batch_size"] + provides = ["energy"] @partial(jit, static_argnums=(0, 3)) def simulate(self, key, parameters, batch_size): - key, p = randgen.uniform(key, 0, 1., shape=(batch_size, )) + key, p = randgen.uniform(key, 0, 1.0, shape=(batch_size,)) energy = self.energy_spectrum.apply(p) return key, energy @export -@appletree.takes_config( - Constant(name='mono_energy', - type=float, - default=2.82, - help='Mono energy delta function'), +@takes_config( + Constant(name="mono_energy", type=float, default=2.82, help="Mono energy delta function"), ) class MonoEnergySpectra(Plugin): - depends_on = ['batch_size'] - provides = ['energy'] + depends_on = ["batch_size"] + provides = ["energy"] # default energy is Ar37 K shell @@ -75,29 +73,35 @@ def simulate(self, key, parameters, batch_size): @export -@appletree.takes_config( - Constant(name='z_min', +@takes_config( + Constant( + name="z_min", type=float, default=-133.97, - help='Z lower limit simulated in uniformly distribution'), - Constant(name='z_max', + help="Z lower limit simulated in uniformly distribution", + ), + Constant( + name="z_max", type=float, default=-13.35, - help='Z upper limit simulated in uniformly distribution'), - Constant(name='r_max', + help="Z upper limit simulated in uniformly distribution", + ), + Constant( + name="r_max", type=float, - default=60., - help='Radius upper limit simulated in uniformly distribution'), + default=60.0, + help="Radius upper limit simulated in uniformly distribution", + ), ) class PositionSpectra(Plugin): - depends_on = ['batch_size'] - provides = ['x', 'y', 'z'] + depends_on = ["batch_size"] + provides = ["x", "y", "z"] @partial(jit, static_argnums=(0, 3)) def simulate(self, key, parameters, batch_size): - key, z = randgen.uniform(key, self.z_min.value, self.z_max.value, shape=(batch_size, )) - key, r2 = randgen.uniform(key, 0, self.r_max.value**2, shape=(batch_size, )) - key, theta = randgen.uniform(key, 0, 2*jnp.pi, shape=(batch_size, )) + key, z = randgen.uniform(key, self.z_min.value, self.z_max.value, shape=(batch_size,)) + key, r2 = randgen.uniform(key, 0, self.r_max.value**2, shape=(batch_size,)) + key, theta = randgen.uniform(key, 0, 2 * jnp.pi, shape=(batch_size,)) r = jnp.sqrt(r2) x = r * jnp.cos(theta) diff --git a/appletree/plugins/detector.py b/appletree/plugins/detector.py index 0e2224cd..0051744a 100644 --- a/appletree/plugins/detector.py +++ b/appletree/plugins/detector.py @@ -2,26 +2,27 @@ from jax import jit from functools import partial -import appletree from appletree import randgen from appletree.plugin import Plugin -from appletree.config import Map +from appletree.config import takes_config, Map from appletree.utils import exporter export, __all__ = exporter(export_self=False) @export -@appletree.takes_config( - Map(name='s1_correction', - default='_s1_correction.json', - help='S1 light collection efficiency correction'), +@takes_config( + Map( + name="s1_correction", + default="_s1_correction.json", + help="S1 light collection efficiency correction", + ), ) class S1Correction(Plugin): - depends_on = ['rec_x', 'rec_y', 'rec_z'] - provides = ['s1_correction'] + depends_on = ["rec_x", "rec_y", "rec_z"] + provides = ["s1_correction"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, rec_x, rec_y, rec_z): pos = jnp.stack([rec_x, rec_y, rec_z]).T s1_correction = self.s1_correction.apply(pos) @@ -29,16 +30,18 @@ def simulate(self, key, parameters, rec_x, rec_y, rec_z): @export -@appletree.takes_config( - Map(name='s2_correction', - default='_s2_correction.json', - help='S2 light collection efficiency correction'), +@takes_config( + Map( + name="s2_correction", + default="_s2_correction.json", + help="S2 light collection efficiency correction", + ), ) class S2Correction(Plugin): - depends_on = ['rec_x', 'rec_y'] - provides = ['s2_correction'] + depends_on = ["rec_x", "rec_y"] + provides = ["s2_correction"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, rec_x, rec_y): pos = jnp.stack([rec_x, rec_y]).T s2_correction = self.s2_correction.apply(pos) @@ -47,55 +50,55 @@ def simulate(self, key, parameters, rec_x, rec_y): @export class PhotonDetection(Plugin): - depends_on = ['num_photon', 's1_correction'] - provides = ['num_s1_phd'] - parameters = ('g1', 'p_dpe') + depends_on = ["num_photon", "s1_correction"] + provides = ["num_s1_phd"] + parameters = ("g1", "p_dpe") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_photon, s1_correction): - g1_true_no_dpe = jnp.clip(parameters['g1'] * s1_correction / (1. + parameters['p_dpe']), 0, 1.) + g1_true_no_dpe = jnp.clip( + parameters["g1"] * s1_correction / (1.0 + parameters["p_dpe"]), 0, 1.0 + ) key, num_s1_phd = randgen.binomial(key, g1_true_no_dpe, num_photon) return key, num_s1_phd @export class S1PE(Plugin): - depends_on = ['num_s1_phd'] - provides = ['num_s1_pe'] - parameters = ('p_dpe',) + depends_on = ["num_s1_phd"] + provides = ["num_s1_pe"] + parameters = ("p_dpe",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_s1_phd): - key, num_s1_dpe = randgen.binomial(key, parameters['p_dpe'], num_s1_phd) + key, num_s1_dpe = randgen.binomial(key, parameters["p_dpe"], num_s1_phd) num_s1_pe = num_s1_dpe + num_s1_phd return key, num_s1_pe @export -@appletree.takes_config( - Map(name='elife', - default='_elife.json', - help='Electron lifetime correction'), +@takes_config( + Map(name="elife", default="_elife.json", help="Electron lifetime correction"), ) class DriftLoss(Plugin): - depends_on = ['z'] - provides = ['drift_survive_prob'] - parameters = ('drift_velocity', 'elife_sigma') + depends_on = ["z"] + provides = ["drift_survive_prob"] + parameters = ("drift_velocity", "elife_sigma") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, z): - key, p = randgen.uniform(key, 0, 1., shape=jnp.shape(z)) - lifetime = self.elife.apply(p) * (1 + parameters['elife_sigma']) - drift_survive_prob = jnp.exp(- jnp.abs(z) / parameters['drift_velocity'] / lifetime) + key, p = randgen.uniform(key, 0, 1.0, shape=jnp.shape(z)) + lifetime = self.elife.apply(p) * (1 + parameters["elife_sigma"]) + drift_survive_prob = jnp.exp(-jnp.abs(z) / parameters["drift_velocity"] / lifetime) return key, drift_survive_prob @export class ElectronDrifted(Plugin): - depends_on = ['num_electron', 'drift_survive_prob'] - provides = ['num_electron_drifted'] + depends_on = ["num_electron", "drift_survive_prob"] + provides = ["num_electron_drifted"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_electron, drift_survive_prob): key, num_electron_drifted = randgen.binomial(key, drift_survive_prob, num_electron) return key, num_electron_drifted @@ -103,14 +106,14 @@ def simulate(self, key, parameters, num_electron, drift_survive_prob): @export class S2PE(Plugin): - depends_on = ['num_electron_drifted', 's2_correction'] - provides = ['num_s2_pe'] - parameters = ('g2', 'gas_gain') + depends_on = ["num_electron_drifted", "s2_correction"] + provides = ["num_s2_pe"] + parameters = ("g2", "gas_gain") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_electron_drifted, s2_correction): - extraction_eff = parameters['g2'] / parameters['gas_gain'] - g2_true = parameters['g2'] * s2_correction + extraction_eff = parameters["g2"] / parameters["gas_gain"] + g2_true = parameters["g2"] * s2_correction gas_gain_true = g2_true / extraction_eff key, num_electron_extracted = randgen.binomial(key, extraction_eff, num_electron_drifted) diff --git a/appletree/plugins/efficiency.py b/appletree/plugins/efficiency.py index 588dbc29..55a8a248 100644 --- a/appletree/plugins/efficiency.py +++ b/appletree/plugins/efficiency.py @@ -2,9 +2,8 @@ from jax import jit from functools import partial -import appletree from appletree.plugin import Plugin -from appletree.config import SigmaMap +from appletree.config import takes_config, SigmaMap from appletree.utils import exporter export, __all__ = exporter(export_self=False) @@ -12,85 +11,81 @@ @export class S2Threshold(Plugin): - depends_on = ['s2_area'] - provides = ['acc_s2_threshold'] - parameters = ('s2_threshold',) + depends_on = ["s2_area"] + provides = ["acc_s2_threshold"] + parameters = ("s2_threshold",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, s2_area): - return key, jnp.where(s2_area > parameters['s2_threshold'], 1., 0) + return key, jnp.where(s2_area > parameters["s2_threshold"], 1.0, 0) @export -@appletree.takes_config( - SigmaMap(name='s1_eff_3f', - default=[ - '_3fold_recon_eff.json', - '_3fold_recon_eff.json', - '_3fold_recon_eff.json'], - help='3fold S1 reconstruction efficiency'), +@takes_config( + SigmaMap( + name="s1_eff_3f", + default=["_3fold_recon_eff.json", "_3fold_recon_eff.json", "_3fold_recon_eff.json"], + help="3fold S1 reconstruction efficiency", + ), ) class S1ReconEff(Plugin): - depends_on = ['num_s1_phd'] - provides = ['acc_s1_recon_eff'] - parameters = ('s1_eff_3f_sigma',) + depends_on = ["num_s1_phd"] + provides = ["acc_s1_recon_eff"] + parameters = ("s1_eff_3f_sigma",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_s1_phd): - acc_s1_recon_eff = self.s1_eff_3f.apply( - num_s1_phd, parameters) - acc_s1_recon_eff = jnp.clip(acc_s1_recon_eff, 0., 1.) + acc_s1_recon_eff = self.s1_eff_3f.apply(num_s1_phd, parameters) + acc_s1_recon_eff = jnp.clip(acc_s1_recon_eff, 0.0, 1.0) return key, acc_s1_recon_eff @export -@appletree.takes_config( - SigmaMap(name='s1_cut_acc', - default=[ - '_s1_cut_acc.json', - '_s1_cut_acc.json', - '_s1_cut_acc.json'], - help='S1 cut acceptance'), +@takes_config( + SigmaMap( + name="s1_cut_acc", + default=["_s1_cut_acc.json", "_s1_cut_acc.json", "_s1_cut_acc.json"], + help="S1 cut acceptance", + ), ) class S1CutAccept(Plugin): - depends_on = ['s1_area'] - provides = ['cut_acc_s1'] - parameters = ('s1_cut_acc_sigma',) + depends_on = ["s1_area"] + provides = ["cut_acc_s1"] + parameters = ("s1_cut_acc_sigma",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, s1_area): cut_acc_s1 = self.s1_cut_acc.apply(s1_area, parameters) - cut_acc_s1 = jnp.clip(cut_acc_s1, 0., 1.) + cut_acc_s1 = jnp.clip(cut_acc_s1, 0.0, 1.0) return key, cut_acc_s1 @export -@appletree.takes_config( - SigmaMap(name='s2_cut_acc', - default=[ - '_s2_cut_acc.json', - '_s2_cut_acc.json', - '_s2_cut_acc.json'], - help='S2 cut acceptance'), +@takes_config( + SigmaMap( + name="s2_cut_acc", + default=["_s2_cut_acc.json", "_s2_cut_acc.json", "_s2_cut_acc.json"], + help="S2 cut acceptance", + ), ) class S2CutAccept(Plugin): - depends_on = ['s2_area'] - provides = ['cut_acc_s2'] - parameters = ('s2_cut_acc_sigma',) + depends_on = ["s2_area"] + provides = ["cut_acc_s2"] + parameters = ("s2_cut_acc_sigma",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, s2_area): cut_acc_s2 = self.s2_cut_acc.apply(s2_area, parameters) - cut_acc_s2 = jnp.clip(cut_acc_s2, 0., 1.) + cut_acc_s2 = jnp.clip(cut_acc_s2, 0.0, 1.0) return key, cut_acc_s2 @export class Eff(Plugin): - depends_on = ['acc_s2_threshold', 'acc_s1_recon_eff', 'cut_acc_s1', 'cut_acc_s2'] - provides = ['eff'] + depends_on = ["acc_s2_threshold", "acc_s1_recon_eff", "cut_acc_s1", "cut_acc_s2"] + provides = ["eff"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, acc_s2_threshold, acc_s1_recon_eff, cut_acc_s1, cut_acc_s2): eff = acc_s2_threshold * acc_s1_recon_eff * cut_acc_s1 * cut_acc_s2 return key, eff diff --git a/appletree/plugins/er_microphys.py b/appletree/plugins/er_microphys.py index cd5a295d..2ee7ac5c 100644 --- a/appletree/plugins/er_microphys.py +++ b/appletree/plugins/er_microphys.py @@ -11,82 +11,91 @@ @export class Quanta(Plugin): - depends_on = ['energy'] - provides = ['num_quanta'] - parameters = ('w', 'fano',) - - @partial(jit, static_argnums=(0, )) + depends_on = ["energy"] + provides = ["num_quanta"] + parameters = ( + "w", + "fano", + ) + + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy): - num_quanta_mean = energy / parameters['w'] - num_quanta_std = jnp.sqrt(num_quanta_mean * parameters['fano']) + num_quanta_mean = energy / parameters["w"] + num_quanta_std = jnp.sqrt(num_quanta_mean * parameters["fano"]) key, num_quanta = randgen.truncate_normal(key, num_quanta_mean, num_quanta_std, vmin=0) return key, num_quanta.round().astype(int) @export class IonizationER(Plugin): - depends_on = ['num_quanta'] - provides = ['num_ion'] - parameters = ('nex_ni_ratio',) + depends_on = ["num_quanta"] + provides = ["num_ion"] + parameters = ("nex_ni_ratio",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_quanta): - p_ion = 1. / (1. + parameters['nex_ni_ratio']) + p_ion = 1.0 / (1.0 + parameters["nex_ni_ratio"]) key, num_ion = randgen.binomial(key, p_ion, num_quanta) return key, num_ion @export class mTI(Plugin): - depends_on = ['energy'] - provides = ['recomb_mean'] - parameters = ('w', 'nex_ni_ratio', 'py0', 'py1', 'py2', 'py3', 'py4', 'field') + depends_on = ["energy"] + provides = ["recomb_mean"] + parameters = ("w", "nex_ni_ratio", "py0", "py1", "py2", "py3", "py4", "field") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy): - ni = energy / parameters['w'] / (1. + parameters['nex_ni_ratio']) - ti = ni * parameters['py0'] * jnp.exp(- energy / parameters['py1']) * parameters['field']**parameters['py2'] / 4. - fd = 1. / (1. + jnp.exp(- (energy - parameters['py3']) / parameters['py4'])) + ni = energy / parameters["w"] / (1.0 + parameters["nex_ni_ratio"]) + ti = ( + ni + * parameters["py0"] + * jnp.exp(-energy / parameters["py1"]) + * parameters["field"] ** parameters["py2"] + / 4.0 + ) + fd = 1.0 / (1.0 + jnp.exp(-(energy - parameters["py3"]) / parameters["py4"])) r = jnp.where( ti < 1e-2, - ti / 2. - ti * ti / 3., - 1. - jnp.log(1. + ti) / ti, + ti / 2.0 - ti * ti / 3.0, + 1.0 - jnp.log(1.0 + ti) / ti, ) return key, r * fd @export class RecombFluct(Plugin): - depends_on = ['energy'] - provides = ['recomb_std'] - parameters = ('rf0', 'rf1') + depends_on = ["energy"] + provides = ["recomb_std"] + parameters = ("rf0", "rf1") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy): - fd_factor = 1. - jnp.exp(- energy / parameters['rf1']) - recomb_std = jnp.clip(parameters['rf0'] * fd_factor, 0, 1.) + fd_factor = 1.0 - jnp.exp(-energy / parameters["rf1"]) + recomb_std = jnp.clip(parameters["rf0"] * fd_factor, 0, 1.0) return key, recomb_std @export class TrueRecombER(Plugin): - depends_on = ['recomb_mean', 'recomb_std'] - provides = ['recomb'] + depends_on = ["recomb_mean", "recomb_std"] + provides = ["recomb"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, recomb_mean, recomb_std): - key, recomb = randgen.truncate_normal(key, recomb_mean, recomb_std, vmin=0., vmax=1.) + key, recomb = randgen.truncate_normal(key, recomb_mean, recomb_std, vmin=0.0, vmax=1.0) return key, recomb @export class RecombinationER(Plugin): - depends_on = ['num_quanta', 'num_ion', 'recomb'] - provides = ['num_photon', 'num_electron'] + depends_on = ["num_quanta", "num_ion", "recomb"] + provides = ["num_photon", "num_electron"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_quanta, num_ion, recomb): - p_not_recomb = 1. - recomb + p_not_recomb = 1.0 - recomb key, num_electron = randgen.binomial(key, p_not_recomb, num_ion) num_photon = num_quanta - num_electron return key, num_photon, num_electron diff --git a/appletree/plugins/lyqy.py b/appletree/plugins/lyqy.py index 4d1899f5..729d075e 100644 --- a/appletree/plugins/lyqy.py +++ b/appletree/plugins/lyqy.py @@ -2,68 +2,63 @@ from jax import jit from functools import partial -import appletree from appletree import randgen from appletree.plugin import Plugin -from appletree.config import Map +from appletree.config import takes_config, Map from appletree.utils import exporter export, __all__ = exporter(export_self=False) @export -@appletree.takes_config( - Map(name='ly_median', - default='_nr_ly.json', - help='Light yield curve from NESTv2'), +@takes_config( + Map(name="ly_median", default="_nr_ly.json", help="Light yield curve from NESTv2"), ) class LightYield(Plugin): - depends_on = ['energy'] - provides = ['light_yield'] - parameters = ('t_ly',) + depends_on = ["energy"] + provides = ["light_yield"] + parameters = ("t_ly",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy): - light_yield = self.ly_median.apply(energy) * (1. + parameters['t_ly']) + light_yield = self.ly_median.apply(energy) * (1.0 + parameters["t_ly"]) light_yield = jnp.clip(light_yield, 0, jnp.inf) return key, light_yield @export class NumberPhoton(Plugin): - depends_on = ['energy', 'light_yield'] - provides = ['num_photon'] + depends_on = ["energy", "light_yield"] + provides = ["num_photon"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy, light_yield): key, num_photon = randgen.poisson(key, light_yield * energy) return key, num_photon @export -@appletree.takes_config( - Map(name='qy_median', - default='_nr_qy.json', - help='Charge yield curve from NESTv2'), +@takes_config( + Map(name="qy_median", default="_nr_qy.json", help="Charge yield curve from NESTv2"), ) class ChargeYield(Plugin): - depends_on = ['energy'] - provides = ['charge_yield'] - parameters = ('t_qy',) + depends_on = ["energy"] + provides = ["charge_yield"] + parameters = ("t_qy",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy): - charge_yield = self.qy_median.apply(energy) * (1. + parameters['t_qy']) + charge_yield = self.qy_median.apply(energy) * (1.0 + parameters["t_qy"]) charge_yield = jnp.clip(charge_yield, 0, jnp.inf) return key, charge_yield @export class NumberElectron(Plugin): - depends_on = ['energy', 'charge_yield'] - provides = ['num_electron'] + depends_on = ["energy", "charge_yield"] + provides = ["num_electron"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy, charge_yield): key, num_electron = randgen.poisson(key, charge_yield * energy) return key, num_electron diff --git a/appletree/plugins/nestv2.py b/appletree/plugins/nestv2.py index 12b6b068..880bf929 100644 --- a/appletree/plugins/nestv2.py +++ b/appletree/plugins/nestv2.py @@ -2,10 +2,9 @@ from jax import jit from functools import partial -import appletree from appletree import randgen from appletree.plugin import Plugin -from appletree.config import Constant, ConstantSet +from appletree.config import takes_config, Constant, ConstantSet from appletree.utils import exporter export, __all__ = exporter(export_self=False) @@ -19,45 +18,52 @@ @export -@appletree.takes_config( +@takes_config( ConstantSet( - name='energy_twohalfnorm', + name="energy_twohalfnorm", default=[ - ['mu', 'sigma_pos', 'sigma_neg'], + ["mu", "sigma_pos", "sigma_neg"], [[1.0], [0.1], [0.1]], ], - help='Parameterized energy spectrum'), + help="Parameterized energy spectrum", + ), ) class MonoEnergiesSpectra(Plugin): - depends_on = ['batch_size'] - provides = ['energy', 'energy_center'] + depends_on = ["batch_size"] + provides = ["energy", "energy_center"] @partial(jit, static_argnums=(0, 3)) def simulate(self, key, parameters, batch_size): key, energy = randgen.twohalfnorm( key, shape=(batch_size, self.energy_twohalfnorm.set_volume), - **self.energy_twohalfnorm.value) - energy = jnp.clip(energy, a_min=0., a_max=jnp.inf) + **self.energy_twohalfnorm.value + ) + energy = jnp.clip(energy, a_min=0.0, a_max=jnp.inf) energy_center = jnp.broadcast_to( - self.energy_twohalfnorm.value['mu'], jnp.shape(energy)).astype(float) + self.energy_twohalfnorm.value["mu"], jnp.shape(energy) + ).astype(float) return key, energy, energy_center @export -@appletree.takes_config( - Constant(name='clip_lower_energy', +@takes_config( + Constant( + name="clip_lower_energy", type=float, default=0.5, - help='Smallest energy considered in inference'), - Constant(name='clip_upper_energy', + help="Smallest energy considered in inference", + ), + Constant( + name="clip_upper_energy", type=float, default=2.5, - help='Largest energy considered in inference'), + help="Largest energy considered in inference", + ), ) class UniformEnergiesSpectra(Plugin): - depends_on = ['batch_size'] - provides = ['energy'] + depends_on = ["batch_size"] + provides = ["energy"] @partial(jit, static_argnums=(0, 3)) def simulate(self, key, parameters, batch_size): @@ -65,77 +71,76 @@ def simulate(self, key, parameters, batch_size): key, self.clip_lower_energy.value, self.clip_upper_energy.value, - shape=(batch_size, ), + shape=(batch_size,), ) return key, energy @export class TotalQuanta(Plugin): - depends_on = ['energy'] - provides = ['_Nq'] - parameters = ('alpha', 'beta') + depends_on = ["energy"] + provides = ["_Nq"] + parameters = ("alpha", "beta") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy): - _Nq = parameters['alpha'] * energy ** parameters['beta'] + _Nq = parameters["alpha"] * energy ** parameters["beta"] return key, _Nq @export -@appletree.takes_config( - Constant(name='literature_field', - type=float, - default=23.0, - help='Drift field in each literature'), +@takes_config( + Constant( + name="literature_field", type=float, default=23.0, help="Drift field in each literature" + ), ) class ThomasImelBox(Plugin): - depends_on = ['energy'] - provides = ['ThomasImel'] - parameters = ('gamma', 'delta', 'liquid_xe_density') + depends_on = ["energy"] + provides = ["ThomasImel"] + parameters = ("gamma", "delta", "liquid_xe_density") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy): ThomasImel = jnp.ones(shape=jnp.shape(energy)) - ThomasImel *= parameters['gamma'] * self.literature_field.value ** parameters['delta'] - ThomasImel *= (parameters['liquid_xe_density'] / 2.9) ** 0.3 + ThomasImel *= parameters["gamma"] * self.literature_field.value ** parameters["delta"] + ThomasImel *= (parameters["liquid_xe_density"] / 2.9) ** 0.3 return key, ThomasImel @export class QyNR(Plugin): - depends_on = ['energy', 'ThomasImel'] - provides = ['charge_yield'] - parameters = ('epsilon', 'zeta', 'eta') + depends_on = ["energy", "ThomasImel"] + provides = ["charge_yield"] + parameters = ("epsilon", "zeta", "eta") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy, ThomasImel): - charge_yield = 1 / ThomasImel / jnp.sqrt(energy + parameters['epsilon']) - charge_yield *= (1 - 1 / (1 + (energy / parameters['zeta']) ** parameters['eta'])) + charge_yield = 1 / ThomasImel / jnp.sqrt(energy + parameters["epsilon"]) + charge_yield *= 1 - 1 / (1 + (energy / parameters["zeta"]) ** parameters["eta"]) charge_yield = jnp.clip(charge_yield, 0, jnp.inf) return key, charge_yield @export class LyNR(Plugin): - depends_on = ['energy', '_Nq', 'charge_yield'] - provides = ['light_yield'] - parameters = ('theta', 'iota') + depends_on = ["energy", "_Nq", "charge_yield"] + provides = ["light_yield"] + parameters = ("theta", "iota") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy, _Nq, charge_yield): light_yield = _Nq / energy - charge_yield - light_yield *= (1 - 1 / (1 + (energy / parameters['theta']) ** parameters['iota'])) + light_yield *= 1 - 1 / (1 + (energy / parameters["theta"]) ** parameters["iota"]) light_yield = jnp.clip(light_yield, 0, jnp.inf) return key, light_yield @export class MeanNphNe(Plugin): - depends_on = ['light_yield', 'charge_yield', 'energy'] - provides = ['_Nph', '_Ne'] + depends_on = ["light_yield", "charge_yield", "energy"] + provides = ["_Nph", "_Ne"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, light_yield, charge_yield, energy): _Nph = light_yield * energy _Ne = charge_yield * energy @@ -144,37 +149,41 @@ def simulate(self, key, parameters, light_yield, charge_yield, energy): @export class MeanExcitonIon(Plugin): - depends_on = ['ThomasImel', '_Nph', '_Ne'] - provides = ['_Nex', '_Ni', 'nex_ni_ratio', 'alf', 'elecFrac', 'recombProb'] + depends_on = ["ThomasImel", "_Nph", "_Ne"] + provides = ["_Nex", "_Ni", "nex_ni_ratio", "alf", "elecFrac", "recombProb"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, ThomasImel, _Nph, _Ne): - _Nex = (-1. / ThomasImel) * ( - 4. * jnp.exp(_Ne * ThomasImel / 4.) - (_Ne + _Nph) * ThomasImel - 4.) - _Ni = (4. / ThomasImel) * (jnp.exp(_Ne * ThomasImel / 4.) - 1.) + _Nex = (-1.0 / ThomasImel) * ( + 4.0 * jnp.exp(_Ne * ThomasImel / 4.0) - (_Ne + _Nph) * ThomasImel - 4.0 + ) + _Ni = (4.0 / ThomasImel) * (jnp.exp(_Ne * ThomasImel / 4.0) - 1.0) nex_ni_ratio = _Nex / _Ni - alf = 1. / (1. + nex_ni_ratio) + alf = 1.0 / (1.0 + nex_ni_ratio) elecFrac = _Ne / (_Nph + _Ne) - recombProb = 1. - (nex_ni_ratio + 1.) * elecFrac + recombProb = 1.0 - (nex_ni_ratio + 1.0) * elecFrac return key, _Nex, _Ni, nex_ni_ratio, alf, elecFrac, recombProb @export class TrueExcitonIonNR(Plugin): - depends_on = ['_Nph', '_Ne', 'nex_ni_ratio', 'alf'] - provides = ['Ni', 'Nex', 'Nq'] - parameters = ('fano_ni', 'fano_nex') + depends_on = ["_Nph", "_Ne", "nex_ni_ratio", "alf"] + provides = ["Ni", "Nex", "Nq"] + parameters = ("fano_ni", "fano_nex") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, _Nph, _Ne, nex_ni_ratio, alf): Nq_mean = _Nph + _Ne key, Ni = randgen.truncate_normal( - key, Nq_mean * alf, - jnp.sqrt(parameters['fano_ni'] * Nq_mean * alf), vmin=0) + key, Nq_mean * alf, jnp.sqrt(parameters["fano_ni"] * Nq_mean * alf), vmin=0 + ) Ni = Ni.round().astype(int) key, Nex = randgen.truncate_normal( - key, Nq_mean * nex_ni_ratio * alf, - jnp.sqrt(parameters['fano_nex'] * Nq_mean * nex_ni_ratio * alf), vmin=0) + key, + Nq_mean * nex_ni_ratio * alf, + jnp.sqrt(parameters["fano_nex"] * Nq_mean * nex_ni_ratio * alf), + vmin=0, + ) Nex = Nex.round().astype(int) Nq = Nex + Ni return key, Ni, Nex, Nq @@ -182,81 +191,94 @@ def simulate(self, key, parameters, _Nph, _Ne, nex_ni_ratio, alf): @export class OmegaNR(Plugin): - depends_on = ['elecFrac', 'recombProb', 'Ni'] - provides = ['omega', 'Variance'] - parameters = ('A', 'xi', 'omega') + depends_on = ["elecFrac", "recombProb", "Ni"] + provides = ["omega", "Variance"] + parameters = ("A", "xi", "omega") - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, elecFrac, recombProb, Ni): - omega = parameters['A'] * jnp.exp( - -0.5 * (elecFrac - parameters['xi']) ** 2. / (parameters['omega'] ** 2)) - Variance = recombProb * (1. - recombProb) * Ni + omega * omega * Ni * Ni + omega = parameters["A"] * jnp.exp( + -0.5 * (elecFrac - parameters["xi"]) ** 2.0 / (parameters["omega"] ** 2) + ) + Variance = recombProb * (1.0 - recombProb) * Ni + omega * omega * Ni * Ni return key, omega, Variance @export class TruePhotonElectronNR(Plugin): - depends_on = ['recombProb', 'Variance', 'Ni', 'Nq'] - provides = ['num_photon', 'num_electron'] - parameters = ('alpha2',) + depends_on = ["recombProb", "Variance", "Ni", "Nq"] + provides = ["num_photon", "num_electron"] + parameters = ("alpha2",) - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, recombProb, Variance, Ni, Nq): # these parameters will make mean num_electron is just (1. - recombProb) * Ni - widthCorrection = (1. - (2. / jnp.pi) * parameters['alpha2'] ** 2 / (1. + parameters['alpha2'] ** 2)) ** 0.5 - muCorrection = (jnp.sqrt(Variance) / widthCorrection) * (parameters['alpha2'] / (1. + parameters['alpha2'] ** 2) ** 0.5) * 2. * (1. / (2. * jnp.pi) ** 0.5) + widthCorrection = ( + 1.0 - (2.0 / jnp.pi) * parameters["alpha2"] ** 2 / (1.0 + parameters["alpha2"] ** 2) + ) ** 0.5 + muCorrection = ( + (jnp.sqrt(Variance) / widthCorrection) + * (parameters["alpha2"] / (1.0 + parameters["alpha2"] ** 2) ** 0.5) + * 2.0 + * (1.0 / (2.0 * jnp.pi) ** 0.5) + ) key, num_electron = randgen.skewnormal( key, - jnp.full(len(recombProb), parameters['alpha2']), - (1. - recombProb) * Ni - muCorrection, - jnp.sqrt(Variance) / widthCorrection) + jnp.full(len(recombProb), parameters["alpha2"]), + (1.0 - recombProb) * Ni - muCorrection, + jnp.sqrt(Variance) / widthCorrection, + ) num_electron = jnp.clip(num_electron.round().astype(int), 0, jnp.inf) num_photon = jnp.clip(Nq - num_electron, 0, jnp.inf) return key, num_photon, num_electron @export -@appletree.takes_config( - Constant(name='clip_lower_energy', +@takes_config( + Constant( + name="clip_lower_energy", type=float, default=0.5, - help='Smallest energy considered in inference'), - Constant(name='clip_upper_energy', + help="Smallest energy considered in inference", + ), + Constant( + name="clip_upper_energy", type=float, default=2.5, - help='Largest energy considered in inference'), + help="Largest energy considered in inference", + ), ) class MonoEnergiesClipEff(Plugin): - """ - For mono-energy-like yields constrain, - we need to filter out the energies out of range. + """For mono-energy-like yields constrain, we need to filter out the energies out of range. + The method is set their weights to 0. + """ - depends_on = ['energy_center'] - provides = ['eff'] + depends_on = ["energy_center"] + provides = ["eff"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy_center): mask = energy_center >= self.clip_lower_energy.value mask &= energy_center <= self.clip_upper_energy.value - eff = jnp.where(mask, 1., 0.) + eff = jnp.where(mask, 1.0, 0.0) return key, eff @export class BandEnergiesClipEff(Plugin): - """ - For band-like yields constrain, - we only need a placeholder here. + """For band-like yields constrain, we only need a placeholder here. + Because BandEnergySpectra has already selected energy for us. + """ - depends_on = ['energy'] - provides = ['eff'] + depends_on = ["energy"] + provides = ["eff"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, energy): eff = jnp.ones(len(energy)) return key, eff diff --git a/appletree/plugins/reconstruction.py b/appletree/plugins/reconstruction.py index db2b273c..47c6ac0b 100644 --- a/appletree/plugins/reconstruction.py +++ b/appletree/plugins/reconstruction.py @@ -3,9 +3,8 @@ from jax import numpy as jnp -import appletree from appletree import randgen -from appletree.config import Map +from appletree.config import takes_config, Map from appletree.plugin import Plugin from appletree.utils import exporter @@ -13,16 +12,14 @@ @export -@appletree.takes_config( - Map(name='posrec_reso', - default='_posrec_reso.json', - help='Position reconstruction resolution'), +@takes_config( + Map(name="posrec_reso", default="_posrec_reso.json", help="Position reconstruction resolution"), ) class PositionRecon(Plugin): - depends_on = ['x', 'y', 'z', 'num_electron_drifted'] - provides = ['rec_x', 'rec_y', 'rec_z', 'rec_r'] + depends_on = ["x", "y", "z", "num_electron_drifted"] + provides = ["rec_x", "rec_y", "rec_z", "rec_r"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, x, y, z, num_electron_drifted): std = self.posrec_reso.apply(num_electron_drifted) std /= jnp.sqrt(2) @@ -37,55 +34,47 @@ def simulate(self, key, parameters, x, y, z, num_electron_drifted): @export -@appletree.takes_config( - Map(name='s1_bias_3f', - default='_s1_bias.json', - help='3fold S1 reconstruction bias'), - Map(name='s1_smear_3f', - default='_s1_smearing.json', - help='3fold S1 reconstruction smearing'), +@takes_config( + Map(name="s1_bias_3f", default="_s1_bias.json", help="3fold S1 reconstruction bias"), + Map(name="s1_smear_3f", default="_s1_smearing.json", help="3fold S1 reconstruction smearing"), ) class S1(Plugin): - depends_on = ['num_s1_phd', 'num_s1_pe'] - provides = ['s1_area'] + depends_on = ["num_s1_phd", "num_s1_pe"] + provides = ["s1_area"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_s1_phd, num_s1_pe): mean = self.s1_bias_3f.apply(num_s1_phd) std = self.s1_smear_3f.apply(num_s1_phd) key, bias = randgen.normal(key, mean, std) - s1_area = num_s1_pe * (1. + bias) + s1_area = num_s1_pe * (1.0 + bias) return key, s1_area @export -@appletree.takes_config( - Map(name='s2_bias', - default='_s2_bias.json', - help='S2 reconstruction bias'), - Map(name='s2_smear', - default='_s2_smearing.json', - help='S2 reconstruction smearing'), +@takes_config( + Map(name="s2_bias", default="_s2_bias.json", help="S2 reconstruction bias"), + Map(name="s2_smear", default="_s2_smearing.json", help="S2 reconstruction smearing"), ) class S2(Plugin): - depends_on = ['num_s2_pe'] - provides = ['s2_area'] + depends_on = ["num_s2_pe"] + provides = ["s2_area"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, num_s2_pe): mean = self.s2_bias.apply(num_s2_pe) std = self.s2_smear.apply(num_s2_pe) key, bias = randgen.normal(key, mean, std) - s2_area = num_s2_pe * (1. + bias) + s2_area = num_s2_pe * (1.0 + bias) return key, s2_area @export class cS1(Plugin): - depends_on = ['s1_area', 's1_correction'] - provides = ['cs1'] + depends_on = ["s1_area", "s1_correction"] + provides = ["cs1"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, s1_area, s1_correction): cs1 = s1_area / s1_correction return key, cs1 @@ -93,10 +82,10 @@ def simulate(self, key, parameters, s1_area, s1_correction): @export class cS2(Plugin): - depends_on = ['s2_area', 's2_correction', 'drift_survive_prob'] - provides = ['cs2'] + depends_on = ["s2_area", "s2_correction", "drift_survive_prob"] + provides = ["cs2"] - @partial(jit, static_argnums=(0, )) + @partial(jit, static_argnums=(0,)) def simulate(self, key, parameters, s2_area, s2_correction, drift_survive_prob): cs2 = s2_area / s2_correction / drift_survive_prob return key, cs2 diff --git a/appletree/randgen.py b/appletree/randgen.py index 2e0aaad2..bf4acbf1 100644 --- a/appletree/randgen.py +++ b/appletree/randgen.py @@ -16,33 +16,32 @@ INT = np.int32 FLOAT = np.float32 -if os.environ.get('DO_NOT_USE_APPROX_IN_BINOM') is None: +if os.environ.get("DO_NOT_USE_APPROX_IN_BINOM") is None: ALWAYS_USE_NORMAL_APPROX_IN_BINOM = True - print('Using Normal as an approximation of Binomial') + print("Using Normal as an approximation of Binomial") else: ALWAYS_USE_NORMAL_APPROX_IN_BINOM = False - print('Using accurate Binomial, not Normal approximation') + print("Using accurate Binomial, not Normal approximation") @export def get_key(seed=None): """Generate a key for jax.random.""" if seed is None: - seed = int(time()*1e6) + seed = int(time() * 1e6) return random.PRNGKey(seed) @export -@partial(jit, static_argnums=(3, )) +@partial(jit, static_argnums=(3,)) def uniform(key, vmin, vmax, shape=()): """Uniform random sampler. - :param key: seed for random generator. - :param vmin: -like min in uniform distribution. - :param vmax: -like max in uniform distribution. - :param shape: output shape. If not given, output has shape - jnp.broadcast_shapes(jnp.shape(vmin), jnp.shape(vmax)). - :return: an updated seed, random variables. + :param key: seed for random generator. :param vmin: -like min in uniform + distribution. :param vmax: -like max in uniform distribution. :param shape: output + shape. If not given, output has shape jnp.broadcast_shapes(jnp.shape(vmin), + jnp.shape(vmax)). :return: an updated seed, random variables. + """ key, seed = random.split(key) @@ -55,14 +54,14 @@ def uniform(key, vmin, vmax, shape=()): @export -@partial(jit, static_argnums=(2, )) +@partial(jit, static_argnums=(2,)) def poisson(key, lam, shape=()): """Poisson random sampler. - :param key: seed for random generator. - :param lam: -like expectation in poisson distribution. - :param shape: output shape. If not given, output has shape jnp.shape(lam). + :param key: seed for random generator. :param lam: -like expectation in poisson + distribution. :param shape: output shape. If not given, output has shape jnp.shape(lam). :return: an updated seed, random variables. + """ key, seed = random.split(key) @@ -74,16 +73,15 @@ def poisson(key, lam, shape=()): @export -@partial(jit, static_argnums=(3, )) +@partial(jit, static_argnums=(3,)) def normal(key, mean, std, shape=()): """Normal distribution random sampler. - :param key: seed for random generator. - :param mean: -like mean in normal distribution. - :param std: -like std in normal distribution. - :param shape: output shape. If not given, output has shape - jnp.broadcast_shapes(jnp.shape(mean), jnp.shape(std)). + :param key: seed for random generator. :param mean: -like mean in normal + distribution. :param std: -like std in normal distribution. :param shape: output + shape. If not given, output has shape jnp.broadcast_shapes(jnp.shape(mean), jnp.shape(std)). :return: an updated seed, random variables. + """ key, seed = random.split(key) @@ -96,7 +94,7 @@ def normal(key, mean, std, shape=()): @export -@partial(jit, static_argnums=(5, )) +@partial(jit, static_argnums=(5,)) def truncate_normal(key, mean, std, vmin=None, vmax=None, shape=()): """Truncated normal distribution random sampler. @@ -109,6 +107,7 @@ def truncate_normal(key, mean, std, vmin=None, vmax=None, shape=()): By default it's None. vmin and vmax cannot be both None. :param shape: parameter passed to normal(..., shape=shape) :return: an updated seed, random variables. + """ key, rvs = normal(key, mean, std, shape=shape) rvs = jnp.clip(rvs, a_min=vmin, a_max=vmax) @@ -116,7 +115,7 @@ def truncate_normal(key, mean, std, vmin=None, vmax=None, shape=()): @export -@partial(jit, static_argnums=(4, )) +@partial(jit, static_argnums=(4,)) def skewnormal(key, a, loc, scale, shape=()): """Skew-normal distribution random sampler. @@ -132,9 +131,9 @@ def skewnormal(key, a, loc, scale, shape=()): ---------- .. [1] `"A Method to Simulate the Skew Normal Distribution" `_ + """ - shape = shape or jnp.broadcast_shapes( - jnp.shape(a), jnp.shape(loc), jnp.shape(scale)) + shape = shape or jnp.broadcast_shapes(jnp.shape(a), jnp.shape(loc), jnp.shape(scale)) a = jnp.broadcast_to(a, shape).astype(FLOAT) loc = jnp.broadcast_to(loc, shape).astype(FLOAT) scale = jnp.broadcast_to(scale, shape).astype(FLOAT) @@ -143,19 +142,20 @@ def skewnormal(key, a, loc, scale, shape=()): rvs0 = random.normal(seed, shape=shape) key, seed = random.split(key) rvs1 = random.normal(seed, shape=shape) - rvs = (a * jnp.abs(rvs0) + rvs1) / jnp.sqrt(1 + a ** 2) + rvs = (a * jnp.abs(rvs0) + rvs1) / jnp.sqrt(1 + a**2) rvs = rvs * scale + loc return key, rvs.astype(FLOAT) @export -@partial(jit, static_argnums=(2, )) +@partial(jit, static_argnums=(2,)) def bernoulli(key, p, shape=()): """Bernoulli random sampler. - :param key: seed for random generator. - :param p: -like probability in bernoulli distribution. - :param shape: output shape. If not given, output has shape jnp.shape(lam). + + :param key: seed for random generator. :param p: -like probability in bernoulli + distribution. :param shape: output shape. If not given, output has shape jnp.shape(lam). :return: an updated seed, random variables. + """ key, seed = random.split(key) @@ -171,28 +171,29 @@ def bernoulli(key, p, shape=()): def binomial(key, p, n, shape=(), always_use_normal=ALWAYS_USE_NORMAL_APPROX_IN_BINOM): """Binomial random sampler. - :param key: seed for random generator. - :param p: -like probability in binomial distribution. - :param n: -like count in binomial distribution. - :param shape: output shape. If not given, output has shape - jnp.broadcast_shapes(jnp.shape(p), jnp.shape(n)). - :param always_use_normal: If true, then Norm(np, sqrt(npq)) is always used. - Otherwise if np < 5, use the inversion method instead. - :return: an updated seed, random variables. + :param key: seed for random generator. :param p: -like probability in binomial + distribution. :param n: -like count in binomial distribution. :param shape: output + shape. If not given, output has shape jnp.broadcast_shapes(jnp.shape(p), jnp.shape(n)). + :param always_use_normal: If true, then Norm(np, sqrt(npq)) is always used. Otherwise if np + < 5, use the inversion method instead. :return: an updated seed, random variables. + """ + def _binomial_normal_approx_dispatch(seed, p, n): - q = 1. - p + q = 1.0 - p mean = n * p std = jnp.sqrt(n * p * q) - rvs = jnp.clip(random.normal(seed) * std + mean, a_min=0., a_max=n) + rvs = jnp.clip(random.normal(seed) * std + mean, a_min=0.0, a_max=n) return rvs.round().astype(INT) def _binomial_dispatch(seed, p, n): - use_normal_approx = (n * p >= 5.) + use_normal_approx = n * p >= 5.0 return lax.cond( use_normal_approx, - (seed, p, n), lambda x: _binomial_normal_approx_dispatch(*x), - (seed, p, n), lambda x: _binomial_dispatch_numpyro(*x), + (seed, p, n), + lambda x: _binomial_normal_approx_dispatch(*x), + (seed, p, n), + lambda x: _binomial_dispatch_numpyro(*x), ) key, seed = random.split(key) @@ -223,26 +224,24 @@ def uniform_key_vectorized(key): :param key: seed for random generator, with shape (N, 2) :return: random varibles with shape (N, ) """ - sampler = vmap(jax.random.uniform, (0, ), 0) + sampler = vmap(jax.random.uniform, (0,), 0) return sampler(key) class TwoHalfNorm: - """Continuous distribution, two half Normal""" + """Continuous distribution, two half Normal.""" @staticmethod def rvs(mu=0, sigma_pos=1, sigma_neg=1, size=None): + """Get random variables :param mu: float, 'center' value of the distribution :param + sigma_pos: float, Standard deviation of the distribution when variable larger than mu. + + Must be non-negative. :param sigma_neg: float, Standard deviation of the distribution when + variable smaller than mu. Must be non-negative. :param size: int or tuple of ints, Output + shape. :return: random samples + """ - Get random variables - :param mu: float, 'center' value of the distribution - :param sigma_pos: float, - Standard deviation of the distribution when variable larger than mu. Must be non-negative. - :param sigma_neg: float, - Standard deviation of the distribution when variable smaller than mu. Must be non-negative. - :param size: int or tuple of ints, Output shape. - :return: random samples - """ - assert (sigma_pos > 0) and (sigma_neg > 0), 'sigma should be positive' + assert (sigma_pos > 0) and (sigma_neg > 0), "sigma should be positive" pos_half_prob = sigma_pos / (sigma_pos + sigma_neg) use_pos_half = np.random.uniform(size=size) < pos_half_prob @@ -255,29 +254,28 @@ def rvs(mu=0, sigma_pos=1, sigma_neg=1, size=None): @staticmethod def logpdf(x, mu=0, sigma_pos=1, sigma_neg=1): + """Log of the probability density function. + + :param x: array, input variables :param mu: float, 'center' value of the distribution :param + sigma_pos: float, Standard deviation of the distribution when variable larger than mu. Must + be non-negative. :param sigma_neg: float, Standard deviation of the distribution when + variable smaller than mu. Must be non-negative. :param size: int or tuple of ints, Output + shape. :return: log probability density function + """ - Log of the probability density function. - :param x: array, input variables - :param mu: float, 'center' value of the distribution - :param sigma_pos: float, - Standard deviation of the distribution when variable larger than mu. Must be non-negative. - :param sigma_neg: float, - Standard deviation of the distribution when variable smaller than mu. Must be non-negative. - :param size: int or tuple of ints, Output shape. - :return: log probability density function - """ - assert np.all(sigma_pos > 0) and np.all(sigma_neg > 0), 'sigma should be positive' + assert np.all(sigma_pos > 0) and np.all(sigma_neg > 0), "sigma should be positive" norm = 2 / (sigma_pos + sigma_neg) / np.sqrt(2 * np.pi) - logpdf = np.where(x < mu, -(x - mu)**2 / sigma_neg**2 / 2, -(x - mu)**2 / sigma_pos**2 / 2) + logpdf = np.where( + x < mu, -((x - mu) ** 2) / sigma_neg**2 / 2, -((x - mu) ** 2) / sigma_pos**2 / 2 + ) logpdf += np.log(norm) return logpdf class BandTwoHalfNorm: - """ - This is a TwoHalfNorm which quantifies uncertainty in y-axis, - but we need to interpolate from x-axis. - """ + """This is a TwoHalfNorm which quantifies uncertainty in y-axis, but we need to interpolate from + x-axis.""" + def __init__(self, x, y, yerr_upper, yerr_lower): self.x = x self.y = interp1d(x, y, bounds_error=False, fill_value=np.nan) @@ -285,9 +283,10 @@ def __init__(self, x, y, yerr_upper, yerr_lower): self.yerr_lower = interp1d(x, yerr_lower, bounds_error=False, fill_value=np.nan) def logpdf(self, x, y): - """ - We calculate along LLH where y-axis is random variable. + """We calculate along LLH where y-axis is random variable. + We need to interpolate along x-axis to get y-axis's arguments. + """ mu = self.y(x) sigma_pos = self.yerr_upper(x) @@ -295,22 +294,21 @@ def logpdf(self, x, y): _mu = np.where(np.isnan(mu), 0, mu) _sigma_pos = np.where(np.isnan(sigma_pos), 1, sigma_pos) _sigma_neg = np.where(np.isnan(sigma_neg), 1, sigma_neg) - logpdf = TwoHalfNorm.logpdf( - x=y, mu=_mu, sigma_pos=_sigma_pos, sigma_neg=_sigma_neg) + logpdf = TwoHalfNorm.logpdf(x=y, mu=_mu, sigma_pos=_sigma_pos, sigma_neg=_sigma_neg) # If x out of range of self.x, return -np.inf logpdf = np.where(np.isnan(mu), -np.inf, logpdf) return logpdf @export -@partial(jit, static_argnums=(4, )) +@partial(jit, static_argnums=(4,)) def twohalfnorm(key, mu, sigma_pos, sigma_neg, shape=()): """JAX version of TwoHalfNorm.rvs. - :param key: seed for random generator. - :param shape: output shape. If not given, output has shape - jnp.broadcast_shapes(jnp.shape(mean), jnp.shape(std)). - :return: an updated seed, random variables. + :param key: seed for random generator. :param shape: output shape. If not given, output has + shape jnp.broadcast_shapes(jnp.shape(mean), jnp.shape(std)). :return: an updated seed, random + variables. + """ key, seed = random.split(key) @@ -320,7 +318,7 @@ def twohalfnorm(key, mu, sigma_pos, sigma_neg, shape=()): sigma_neg = jnp.broadcast_to(sigma_neg, shape).astype(FLOAT) pos_half_prob = sigma_pos / (sigma_pos + sigma_neg) - use_pos_half = random.uniform(seed, shape, minval=0., maxval=1.) < pos_half_prob + use_pos_half = random.uniform(seed, shape, minval=0.0, maxval=1.0) < pos_half_prob use_neg_half = ~use_pos_half n_sigma = jnp.abs(random.normal(seed, shape=shape)) diff --git a/appletree/share.py b/appletree/share.py index 722a9c02..46582e1c 100644 --- a/appletree/share.py +++ b/appletree/share.py @@ -1,4 +1,5 @@ import json +from typing import Dict, Any, cast class RecordingDict(dict): @@ -26,13 +27,14 @@ def clear(self): _cached_configs = RecordingDict() -_cached_functions = dict() +_cached_functions = cast(Dict[str, Any], dict()) def set_global_config(configs): - """Set new global configuration options + """Set new global configuration options. :param configs: dict, configuration file name or dictionary + """ from appletree.utils import get_file_path diff --git a/appletree/utils.py b/appletree/utils.py index 131cf0df..3ddc8665 100644 --- a/appletree/utils.py +++ b/appletree/utils.py @@ -1,5 +1,4 @@ import os -import re import json from warnings import warn import importlib_resources @@ -18,6 +17,7 @@ NT_AUX_INSTALLED = False try: import ntauxfiles + NT_AUX_INSTALLED = True except ImportError: pass @@ -31,7 +31,7 @@ def exporter(export_self=False): """ all_ = [] if export_self: - all_.append('exporter') + all_.append("exporter") def decorator(obj): all_.append(obj.__name__) @@ -47,25 +47,44 @@ def decorator(obj): def use_xenon_plot_style(): """Set matplotlib plot style.""" params = { - 'font.family': 'serif', - 'font.size': 24, 'axes.titlesize': 24, - 'axes.labelsize': 24, 'axes.linewidth': 2, + "font.family": "serif", + "font.size": 24, + "axes.titlesize": 24, + "axes.labelsize": 24, + "axes.linewidth": 2, # ticks - 'xtick.labelsize': 22, 'ytick.labelsize': 22, 'xtick.major.size': 16, 'xtick.minor.size': 8, - 'ytick.major.size': 16, 'ytick.minor.size': 8, 'xtick.major.width': 2, 'xtick.minor.width': 2, - 'ytick.major.width': 2, 'ytick.minor.width': 2, 'xtick.direction': 'in', 'ytick.direction': 'in', + "xtick.labelsize": 22, + "ytick.labelsize": 22, + "xtick.major.size": 16, + "xtick.minor.size": 8, + "ytick.major.size": 16, + "ytick.minor.size": 8, + "xtick.major.width": 2, + "xtick.minor.width": 2, + "ytick.major.width": 2, + "ytick.minor.width": 2, + "xtick.direction": "in", + "ytick.direction": "in", # markers - 'lines.markersize': 12, 'lines.markeredgewidth': 3, 'errorbar.capsize': 8, 'lines.linewidth': 3, - 'savefig.bbox': 'tight', 'legend.fontsize': 24, - 'backend': 'Agg', 'mathtext.fontset': 'dejavuserif', 'legend.frameon': False, + "lines.markersize": 12, + "lines.markeredgewidth": 3, + "errorbar.capsize": 8, + "lines.linewidth": 3, + "savefig.bbox": "tight", + "legend.fontsize": 24, + "backend": "Agg", + "mathtext.fontset": "dejavuserif", + "legend.frameon": False, # figure - 'figure.facecolor': 'w', - 'figure.figsize': (12, 8), + "figure.facecolor": "w", + "figure.figsize": (12, 8), # pad - 'axes.labelpad': 12, + "axes.labelpad": 12, # ticks - 'xtick.major.pad': 6, 'xtick.minor.pad': 6, - 'ytick.major.pad': 3.5, 'ytick.minor.pad': 3.5, + "xtick.major.pad": 6, + "xtick.minor.pad": 6, + "ytick.major.pad": 3.5, + "ytick.minor.pad": 3.5, # colormap } plt.rcParams.update(params) @@ -73,66 +92,73 @@ def use_xenon_plot_style(): @export def load_data(file_name: str): - """Load data from file. The suffix can be ".csv", ".pkl".""" + """Load data from file. + + The suffix can be ".csv", ".pkl". + + """ file_name = get_file_path(file_name) - fmt = file_name.split('.')[-1] - if fmt == 'csv': + fmt = file_name.split(".")[-1] + if fmt == "csv": data = pd.read_csv(file_name) - elif fmt == 'pkl': + elif fmt == "pkl": data = pd.read_pickle(file_name) else: - raise ValueError(f'unsupported file format {fmt}!') + raise ValueError(f"unsupported file format {fmt}!") return data @export def load_json(file_name: str): """Load data from json file.""" - with open(get_file_path(file_name), 'r') as file: + with open(get_file_path(file_name), "r") as file: data = json.load(file) return data @export def _get_abspath(file_name): - """Get the abspath of the file. Raise FileNotFoundError when not found in any subfolder""" - for sub_dir in ('maps', 'data', 'parameters', 'instructs'): + """Get the abspath of the file. + + Raise FileNotFoundError when not found in any subfolder + + """ + for sub_dir in ("maps", "data", "parameters", "instructs"): p = os.path.join(_package_path(sub_dir), file_name) if os.path.exists(p): return p - raise FileNotFoundError(f'Cannot find {file_name}') + raise FileNotFoundError(f"Cannot find {file_name}") def _package_path(sub_directory): - """Get the abs path of the requested sub folder""" - return importlib_resources.files('appletree') / sub_directory + """Get the abs path of the requested sub folder.""" + return importlib_resources.files("appletree") / sub_directory @export def get_file_path(fname): - """Find the full path to the resource file - Try 5 methods in the following order - - #. fname begin with '/', return absolute path - #. url_base begin with '/', return url_base + name - #. can get file from _get_abspath, return appletree internal file path - #. can be found in local installed ntauxfiles, return ntauxfiles absolute path - #. can be downloaded from MongoDB, download and return cached path + """Find the full path to the resource file Try 5 methods in the following order. + + #. fname begin with '/', return absolute path #. url_base begin with '/', return url_base + name + #. can get file from _get_abspath, return appletree internal file path #. can be found in local + installed ntauxfiles, return ntauxfiles absolute path #. can be downloaded from MongoDB, + download and return cached path + """ # 1. From absolute path # Usually Config.default is a absolute path - if fname.startswith('/'): + if fname.startswith("/"): return fname # 2. From local folder # Use url_base as prefix - if 'url_base' in _cached_configs.keys(): - url_base = _cached_configs['url_base'] + if "url_base" in _cached_configs.keys(): + url_base = _cached_configs["url_base"] - if url_base.startswith('/'): + if url_base.startswith("/"): fpath = os.path.join(url_base, fname) if os.path.exists(fpath): - warn(f'Load {fname} successfully from {fpath}') + warn(f"Load {fname} successfully from {fpath}") return fpath # 3. From appletree internal files @@ -146,13 +172,14 @@ def get_file_path(fname): # You might want to use this, for example if you are a developer if fname in ntauxfiles.list_private_files(): fpath = ntauxfiles.get_abspath(fname) - warn(f'Load {fname} successfully from {fpath}') + warn(f"Load {fname} successfully from {fpath}") return fpath # 5. From MongoDB if not SKIP_MONGO_DB: try: import straxen + # https://straxen.readthedocs.io/en/latest/config_storage.html # downloading-xenonnt-files-from-the-database # noqa @@ -163,32 +190,36 @@ def get_file_path(fname): # FileNotFoundError, ValueErrors can be raised if we # cannot load the requested config fpath = downloader.download_single(fname) - warn(f'Loading {fname} from mongo downloader to {fpath}') + warn(f"Loading {fname} from mongo downloader to {fpath}") return fname # Keep the name and let get_resource do its thing except (FileNotFoundError, ValueError, NameError, AttributeError): - warn(f'Mongo downloader not possible or does not have {fname}') + warn(f"Mongo downloader not possible or does not have {fname}") # raise error when can not find corresponding file - raise RuntimeError(f'Can not find {fname}, please check your file system') + raise RuntimeError(f"Can not find {fname}, please check your file system") @export def timeit(indent=""): """Use timeit as a decorator. + It will print out the running time of the decorated function. + """ + def _timeit(func, indent): name = func.__name__ def _func(*args, **kwargs): - print(indent + f' Function <{name}> starts.') + print(indent + f" Function <{name}> starts.") start = time() res = func(*args, **kwargs) time_ = (time() - start) * 1e3 - print(indent + f' Function <{name}> ends! Time cost = {time_:.2f} msec.') + print(indent + f" Function <{name}> ends! Time cost = {time_:.2f} msec.") return res return _func + if isinstance(indent, str): return lambda func: _timeit(func, indent) else: @@ -197,14 +228,16 @@ def _func(*args, **kwargs): @export def get_platform(): - """Show the platform we are using, either cpu ot gpu""" + """Show the platform we are using, either cpu ot gpu.""" return xla_bridge.get_backend().platform @export def set_gpu_memory_usage(fraction=0.3): """Set GPU memory usage. + See more on https://jax.readthedocs.io/en/latest/gpu_memory_allocation.html + """ if fraction > 1: fraction = 1 @@ -214,31 +247,32 @@ def set_gpu_memory_usage(fraction=0.3): @export -def get_equiprob_bins_2d(data, - n_partitions, - order = (0, 1), - x_clip = (-np.inf, +np.inf), - y_clip = (-np.inf, +np.inf), - which_np = np): +def get_equiprob_bins_2d( + data, + n_partitions, + order=(0, 1), + x_clip=(-np.inf, +np.inf), + y_clip=(-np.inf, +np.inf), + which_np=np, +): """Get 2D equiprobable binning edges. - :param data: array with shape (N, 2). - :param n_partitions: [M1, M2] where M1 M2 are the number of bins on each dimension. - :param x_clip: lower and upper binning edges on the 0th dimension. - Data outside the x_clip will be dropped. - :param y_clip: lower and upper binning edges on the 1st dimension. - Data outside the y_clip will be dropped. - :param which_np: can be numpy or jax.numpy, determining the returned array type. + :param data: array with shape (N, 2). :param n_partitions: [M1, M2] where M1 M2 are the number + of bins on each dimension. :param x_clip: lower and upper binning edges on the 0th dimension. + Data outside the x_clip will be dropped. :param y_clip: lower and upper binning edges on the 1st + dimension. Data outside the y_clip will be dropped. :param which_np: can be numpy or + jax.numpy, determining the returned array type. + """ - mask = (data[:, 0] > x_clip[0]) - mask &= (data[:, 0] < x_clip[1]) - mask &= (data[:, 1] > y_clip[0]) - mask &= (data[:, 1] < y_clip[1]) + mask = data[:, 0] > x_clip[0] + mask &= data[:, 0] < x_clip[1] + mask &= data[:, 1] > y_clip[0] + mask &= data[:, 1] < y_clip[1] x_bins, y_bins = GOFevaluation.utils.get_equiprobable_binning( data[mask], n_partitions, - order = order, + order=order, ) # To be strict, clip the inf(s) x_bins = np.clip(x_bins, *x_clip) @@ -251,16 +285,15 @@ def get_equiprob_bins_2d(data, def plot_irreg_histogram_2d(bins_x, bins_y, hist, **kwargs): """Plot histogram defined by irregular binning. - :param bins_x: array with shape (M1, ) - :param bins_y: array with shape (M1-1, M2) - :param hist: array with shape (M1-1, M2-1) - :param density: boolean. + :param bins_x: array with shape (M1, ) :param bins_y: array with shape (M1-1, M2) :param hist: + array with shape (M1-1, M2-1) :param density: boolean. + """ hist = np.asarray(hist) bins_x = np.asarray(bins_x) bins_y = np.asarray(bins_y) - density = kwargs.get('density', False) + density = kwargs.get("density", False) cmap = mpl.cm.get_cmap("RdBu_r") loc = [] @@ -272,9 +305,9 @@ def plot_irreg_histogram_2d(bins_x, bins_y, hist, **kwargs): for i, _ in enumerate(hist): for j, _ in enumerate(hist[i]): x_lower = bins_x[i] - x_upper = bins_x[i+1] + x_upper = bins_x[i + 1] y_lower = bins_y[i, j] - y_upper = bins_y[i, j+1] + y_upper = bins_y[i, j + 1] loc.append((x_lower, y_lower)) width.append(x_upper - x_lower) @@ -290,26 +323,26 @@ def plot_irreg_histogram_2d(bins_x, bins_y, hist, **kwargs): if density: norm = mpl.colors.Normalize( - vmin=kwargs.get('vmin', np.min(n/area)), - vmax=kwargs.get('vmax', np.max(n/area)), + vmin=kwargs.get("vmin", np.min(n / area)), + vmax=kwargs.get("vmax", np.max(n / area)), clip=False, ) else: norm = mpl.colors.Normalize( - vmin=kwargs.get('vmin', np.min(n)), - vmax=kwargs.get('vmax', np.max(n)), + vmin=kwargs.get("vmin", np.min(n)), + vmax=kwargs.get("vmax", np.max(n)), clip=False, ) ax = plt.subplot() for i, _ in enumerate(loc): - c = n[i]/area[i] if density else n[i] + c = n[i] / area[i] if density else n[i] rec = Rectangle( loc[i], width[i], height[i], facecolor=cmap(norm(c)), - edgecolor='k', + edgecolor="k", ) ax.add_patch(rec) @@ -317,7 +350,7 @@ def plot_irreg_histogram_2d(bins_x, bins_y, hist, **kwargs): fig.colorbar( mpl.cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax, - label=('# events / bin size' if density else '# events'), + label=("# events / bin size" if density else "# events"), ) ax.set_xlim(np.min(bins_x), np.max(bins_x)) @@ -328,45 +361,40 @@ def plot_irreg_histogram_2d(bins_x, bins_y, hist, **kwargs): @export def add_spaces(x): - """Add four spaces to every line in x - This is needed to make html raw blocks in rst format correctly - """ - y = '' + """Add four spaces to every line in x This is needed to make html raw blocks in rst format + correctly.""" + y = "" if isinstance(x, str): - x = x.split('\n') + x = x.split("\n") for q in x: - y += ' ' + q + y += " " + q return y @export -def tree_to_svg(graph_tree, save_as='data_types', view=True): - """ - Where to save this node +def tree_to_svg(graph_tree, save_as="data_types", view=True): + """Where to save this node. + + :param graph_tree: Digraph instance :param save_as: str, file name :param view: bool, Open the + rendered result with the default application. - :param graph_tree: Digraph instance - :param save_as: str, file name - :param view: bool, Open the rendered result with the default application. """ graph_tree.render(save_as, view=view) - with open(f'{save_as}.svg', mode='r') as f: + with open(f"{save_as}.svg", mode="r") as f: svg = add_spaces(f.readlines()[5:]) os.remove(save_as) return svg @export -def add_deps_to_graph_tree(component, - graph_tree, - data_names: list = ['cs1', 'cs2', 'eff'], - _seen = None): - """ - Recursively add nodes to graph base on plugin.deps +def add_deps_to_graph_tree( + component, graph_tree, data_names: list = ["cs1", "cs2", "eff"], _seen=None +): + """Recursively add nodes to graph base on plugin.deps. + + :param context: Context instance :param graph_tree: Digraph instance :param data_names: Data + type name :param _seen: list or None, the seen data_name should not be plot - :param context: Context instance - :param graph_tree: Digraph instance - :param data_names: Data type name - :param _seen: list or None, the seen data_name should not be plot """ if _seen is None: _seen = [] @@ -375,11 +403,10 @@ def add_deps_to_graph_tree(component, continue # Add new one - graph_tree.node(data_name, - style='filled', - href='#' + data_name.replace('_', '-'), - fillcolor='white') - if data_name == 'batch_size': + graph_tree.node( + data_name, style="filled", href="#" + data_name.replace("_", "-"), fillcolor="white" + ) + if data_name == "batch_size": continue dep_plugin = component._plugin_class_registry[data_name] for dep in dep_plugin.depends_on: @@ -395,24 +422,24 @@ def add_deps_to_graph_tree(component, @export -def add_plugins_to_graph_tree(component, - graph_tree, - data_names: list = ['cs1', 'cs2', 'eff'], - _seen = None, - with_data_names=False): - """ - Recursively add nodes to graph base on plugin.deps +def add_plugins_to_graph_tree( + component, + graph_tree, + data_names: list = ["cs1", "cs2", "eff"], + _seen=None, + with_data_names=False, +): + """Recursively add nodes to graph base on plugin.deps. + + :param context: Context instance :param graph_tree: Digraph instance :param data_names: Data + type name :param _seen: list or None, the seen data_name should not be plot :param + with_data_names: bool, whether plot even with messy data_names - :param context: Context instance - :param graph_tree: Digraph instance - :param data_names: Data type name - :param _seen: list or None, the seen data_name should not be plot - :param with_data_names: bool, whether plot even with messy data_names """ if _seen is None: _seen = [] for data_name in data_names: - if data_name == 'batch_size': + if data_name == "batch_size": continue plugin = component._plugin_class_registry[data_name] @@ -421,17 +448,19 @@ def add_plugins_to_graph_tree(component, continue # Add new one - label = f'{plugin_name}' + label = f"{plugin_name}" if with_data_names: label += f"\n{', '.join(plugin.depends_on)}\n{', '.join(plugin.provides)}" - graph_tree.node(plugin_name, - label=label, - style='filled', - href='#' + plugin_name.replace('_', '-'), - fillcolor='white') + graph_tree.node( + plugin_name, + label=label, + style="filled", + href="#" + plugin_name.replace("_", "-"), + fillcolor="white", + ) for dep in plugin.depends_on: - if dep == 'batch_size': + if dep == "batch_size": continue dep_plugin = component._plugin_class_registry[dep] graph_tree.edge(plugin_name, dep_plugin.__name__) @@ -447,28 +476,26 @@ def add_plugins_to_graph_tree(component, @export def add_extensions(module1, module2, base, force=False): - """ - Add subclasses of module2 to module1 + """Add subclasses of module2 to module1. + + When ComponentSim compiles the dependency tree, it will search in the appletree.plugins module + for Plugin(as attributes). When building Likelihood, it will also search for corresponding + Component(s) specified in the instructions(e.g. NRBand). - When ComponentSim compiles the dependency tree, - it will search in the appletree.plugins module for Plugin(as attributes). - When building Likelihood, it will also search for corresponding Component(s) - specified in the instructions(e.g. NRBand). + So we need to assign the attributes before compilation. These plugins are mostly user defined. - So we need to assign the attributes before compilation. - These plugins are mostly user defined. """ # Assign the module2 as attribute of module1 is_exists = module2.__name__ in dir(module1) if is_exists and not force: raise ValueError( - f'{module2.__name__} already existed in {module1.__name__}, ' - f'do not re-register a module with same name', + f"{module2.__name__} already existed in {module1.__name__}, " + f"do not re-register a module with same name", ) else: if is_exists: - print(f'You have forcibly registered {module2.__name__} to {module1.__name__}') - setattr(module1, module2.__name__.split('.')[-1], module2) + print(f"You have forcibly registered {module2.__name__} to {module1.__name__}") + setattr(module1, module2.__name__.split(".")[-1], module2) # Iterate the module2 and assign the single Plugin(s) as attribute(s) for x in dir(module2): @@ -479,35 +506,33 @@ def add_extensions(module1, module2, base, force=False): def _add_extension(module, subclass, base, force=False): - """ - Add subclass to module - Skip the class when it is base class. + """Add subclass to module Skip the class when it is base class. + + It is no allowed to assign a class which has same name to an already assigned class. We do not + allowed class name covering! Please change the name of your class when Error shows itself. - It is no allowed to assign a class which has same name to an already assigned class. - We do not allowed class name covering! - Please change the name of your class when Error shows itself. """ - if getattr(subclass, '_' + subclass.__name__ + '__is_base', False): + if getattr(subclass, "_" + subclass.__name__ + "__is_base", False): return if issubclass(subclass, base) and subclass != base: is_exists = subclass.__name__ in dir(module) if is_exists and not force: raise ValueError( - f'{subclass.__name__} already existed in {module.__name__}, ' - f'do not re-register a {base.__name__} with same name', + f"{subclass.__name__} already existed in {module.__name__}, " + f"do not re-register a {base.__name__} with same name", ) else: if is_exists: - print(f'You have forcibly registered {subclass.__name__} to {module.__name__}') + print(f"You have forcibly registered {subclass.__name__} to {module.__name__}") setattr(module, subclass.__name__, subclass) def integrate_midpoint(x, y): """Calculate the integral using midpoint method. - :param x: 1D array-like - :param y: 1D array-like, with the same length as x. + :param x: 1D array-like :param y: 1D array-like, with the same length as x. + """ _, res = cum_integrate_midpoint(x, y) return res[-1] @@ -516,8 +541,9 @@ def integrate_midpoint(x, y): def cum_integrate_midpoint(x, y): """Calculate the cumulative integral using midpoint method. - :param x: 1D array-like - :param y: 1D array-like, with the same length as x.""" + :param x: 1D array-like :param y: 1D array-like, with the same length as x. + + """ x = np.array(x) y = np.array(y) dx = x[1:] - x[:-1] @@ -530,6 +556,4 @@ def check_unused_configs(): """Check if there are unused configs.""" unused_configs = set(_cached_configs.keys()) - _cached_configs.accessed_keys if unused_configs: - warn( - f"Detected unused configs: {unused_configs}, you might set the configs incorrectly." - ) + warn(f"Detected unused configs: {unused_configs}, you might set the configs incorrectly.") diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index bff5496e..4339e97c 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -2,7 +2,7 @@ commonmark==0.9.1 graphviz==0.20.1 m2r==0.2.1 -mistune==0.8.4 +mistune==0.8.4 nbsphinx==0.8.9 recommonmark==0.7.1 sphinx==5.2.3 diff --git a/docs/source/advance/file.rst b/docs/source/advance/file.rst index 452c2f30..8a98c647 100644 --- a/docs/source/advance/file.rst +++ b/docs/source/advance/file.rst @@ -5,9 +5,11 @@ File system and searching ========================= -Any file name in appletree will be handled by a function `appletree.utils.get_file_path`, which will search the file and return its path +Any file name in appletree will be handled by a function `appletree.utils.get_file_path`, +which will search the file and return its path .. autofunction:: appletree.utils.get_file_path -The last two methods are only used for XENON collabration. In most cases, method 1 and 2 are enough. And in method 2, the function will search the folders +The last two methods are only used for XENON collabration. +In most cases, method 1 and 2 are enough. And in method 2, the function will search the folders maps, data, parameters, configs. diff --git a/docs/source/advance/instruct.rst b/docs/source/advance/instruct.rst index eb9aff8f..06f6259d 100644 --- a/docs/source/advance/instruct.rst +++ b/docs/source/advance/instruct.rst @@ -6,8 +6,9 @@ Instruct file for context ========================= In appletree, we use an instruct json file to initialize `Context`. Some examples can be found in -`instructs folder `_. In the json file, -the dictionary must contain three items: **"configs"**, **"par_config"** and **"likelihoods"**. +`instructs folder `_. +In the json file, the dictionary must contain three items: +**"configs"**, **"par_config"** and **"likelihoods"**. The value of "configs" is a dictionary that overwrites the default plugins' config, like @@ -20,15 +21,20 @@ The value of "configs" is a dictionary that overwrites the default plugins' conf We will discuss more about how appletree deals with them in :ref:`map ` section. -The value of "par_config" should be the file name of parameter file described in :ref:`parameter `. +The value of "par_config" should be the file name of parameter file described +in :ref:`parameter `. -The value of "likelihoods" is a dictionary that gives the definition of likelihood. If the fitting is a single dataset fitting, -the dictionary only has one item; if the fitting is a combined fitting, it could have multiple items. In each item, it must contain +The value of "likelihoods" is a dictionary that gives the definition of likelihood. +If the fitting is a single dataset fitting, +the dictionary only has one item; if the fitting is a combined fitting, it could have +multiple items. In each item, it must contain * **"components"**: all components that define the model. * **"data_file_name"**: data file name, must be .pkl or .csv. -* **"bins_type"**: can be "meshgrid" or "equiprob". For most of the case, we only recommend "equiprob", meaning a equi-probable binning defined by data. +* **"bins_type"**: can be "meshgrid" or "equiprob". * **"bins_on"**: names of variables that the histogram is applied on. + For most of the case, we only recommend "equiprob", + meaning a equi-probable binning defined by data. * **"bins"**: number of bins. * **"x_clip"**: range of the first dimension. * **"y_clip"**: range of the second dimension. @@ -58,6 +64,8 @@ For example, "y_clip": [2e2, 1e4] } -In this likelihood config, the data has two components: ER and AC, where ER component is `ERBand`, and AC component is `AC` with input file "AC_Rn220.pkl". -And the binned Poisson likelihood is defined in the equi-probable binning of cS1-cS2 space, with 15 bins on each dimension. To understand how appletree locates +In this likelihood config, the data has two components: ER and AC, where ER component is `ERBand`, +and AC component is `AC` with input file "AC_Rn220.pkl". +And the binned Poisson likelihood is defined in the equi-probable binning of cS1-cS2 space, +with 15 bins on each dimension. To understand how appletree locates the files and classes, like "data_Rn220.csv" etc., check :ref:`file ` section. diff --git a/docs/source/advance/map.rst b/docs/source/advance/map.rst index 32ab4466..7e63f116 100644 --- a/docs/source/advance/map.rst +++ b/docs/source/advance/map.rst @@ -5,16 +5,19 @@ Register maps and constants to plugins ====================================== -Sometimes, a plugin could depend on some constants and maps, for example the energy range in an energy sampler, or a curve that gives -the energy spectrum. In appletree, we recommend to use `appletree.takes_config` to systematically manage them. +Sometimes, a plugin could depend on some constants and maps, +for example the energy range in an energy sampler, or a curve that gives +the energy spectrum. In appletree, we recommend to use `appletree.takes_config` +to systematically manage them. .. autofunction:: appletree.takes_config -`appletree.takes_config` takes `Config` as arguments, which will be discussed short later, and returns a decorator for the plugin. For example, +`appletree.takes_config` takes `Config` as arguments, which will be discussed short later, +and returns a decorator for the plugin. For example, .. code-block:: python - @appletree.takes_config( + @takes_config( config0, config1, ... @@ -22,7 +25,8 @@ the energy spectrum. In appletree, we recommend to use `appletree.takes_config` class TestPlugin(appletree.plugin): ... -Currently, appletree supports two kinds of configs, `appletree.Constant` and `appletree.Map`. Both inherit from `appletree.Config` +Currently, appletree supports two kinds of configs, `appletree.Constant` and `appletree.Map`. +Both inherit from `appletree.Config` .. autoclass:: appletree.Map :members: @@ -38,7 +42,7 @@ Here is an example of using `Constant` .. code-block:: python - @appletree.takes_config( + @takes_config( Constant( name='a', type=float, @@ -59,7 +63,7 @@ and an example of using `Map` .. code-block:: python - @appletree.takes_config( + @takes_config( Map( name='b', default='test_file.json', @@ -80,7 +84,8 @@ and an example of using `Map` z = y + shift return key, z -As mentioned in :ref:`instruct `, the instruct file for `Context` can overwrite the default value of plugins' config. For example, +As mentioned in :ref:`instruct `, +the instruct file for `Context` can overwrite the default value of plugins' config. For example, .. code-block:: python @@ -92,4 +97,5 @@ As mentioned in :ref:`instruct `, the instruct file for `Context` can over ... } -which changes the value of `a` in `Scale` plugin to 137.036 and json file of `b` in `Shift` Plugin to "alt_test_file.json". +which changes the value of `a` in `Scale` plugin to 137.036 and json file of `b` in `Shift` +Plugin to "alt_test_file.json". diff --git a/docs/source/advance/parameter.rst b/docs/source/advance/parameter.rst index 7e9d73bf..3866d213 100644 --- a/docs/source/advance/parameter.rst +++ b/docs/source/advance/parameter.rst @@ -5,8 +5,8 @@ Parameters in appletree ======================= -In general, all parameters including fixed parameters and fit parameters are handled by `appletree.Parameter`, -which has many useful attributes +In general, all parameters including fixed parameters and fit +parameters are handled by `appletree.Parameter`, which has many useful attributes .. autoclass:: appletree.Parameter :members: @@ -37,9 +37,9 @@ For each `config_of_param`, it should be a dictionary containing the following i * **"prior_args"**: a dictionary like `{arg_name : arg_value}` which goes into prior. * **"allowed_range"**: a list like `[lower_boundary, upper_boundary]`, above which parameters - will be clipped and have `-np.inf` log prior. -* **"init_mean"**: the gaussian mean as the initial guess of the MCMC walkers. The random initialzation of MCMC - will be clipped by "allowed_range". + will be clipped and have `-np.inf` log prior. +* **"init_mean"**: the gaussian mean as the initial guess of the MCMC walkers. + The random initialzation of MCMC will be clipped by "allowed_range". * **"init_std"**: the gaussian std as the initial guess of the MCMC walkers. * **"unit"**: the unit of the parameter, only for documentation purpose. * **"doc"**: the addtional docstring for the parameter. @@ -77,6 +77,7 @@ For example, }, } -All non-fixed parameters are called fit parameters in appletree, and will be the parameters that MCMC samples. -`appletree.Plugin` needs a dictionary of parameters. With the `Parameter` class, it can be simply obtained by -`Parameter.get_all_parameter()`. +All non-fixed parameters are called fit parameters in appletree, +and will be the parameters that MCMC samples. +`appletree.Plugin` needs a dictionary of parameters. With the `Parameter` class, +it can be simply obtained by `Parameter.get_all_parameter()`. diff --git a/docs/source/basics/appletree.plugins.common.rst b/docs/source/basics/appletree.plugins.common.rst index 0556a1cd..c628de85 100644 --- a/docs/source/basics/appletree.plugins.common.rst +++ b/docs/source/basics/appletree.plugins.common.rst @@ -3,7 +3,8 @@ appletree.plugins.common ======================== -In `appletree.plugins.common`, we put some plugins to sample energies and positions from given spectra. +In `appletree.plugins.common`, we put some plugins to sample energies +and positions from given spectra. .. automodule:: appletree.plugins.common :members: diff --git a/docs/source/basics/appletree.plugins.nestv2.rst b/docs/source/basics/appletree.plugins.nestv2.rst index af40c236..75c24cfa 100644 --- a/docs/source/basics/appletree.plugins.nestv2.rst +++ b/docs/source/basics/appletree.plugins.nestv2.rst @@ -3,7 +3,8 @@ appletree.plugins.nestv2 ======================== -In `appletree.plugins.nestv2`, we put some plugins to simulate quanta based on NESTv2. Currently, we only have the nuclear recoil related plugins. +In `appletree.plugins.nestv2`, we put some plugins to simulate quanta based on NESTv2. +Currently, we only have the nuclear recoil related plugins. .. automodule:: appletree.plugins.nestv2 :members: diff --git a/docs/source/basics/general.rst b/docs/source/basics/general.rst index 70e43fb0..0155255c 100644 --- a/docs/source/basics/general.rst +++ b/docs/source/basics/general.rst @@ -4,26 +4,26 @@ How to think in appletree ========================= To understand the structure of appletree, it's always helpful to keep an exemplar problem in mind. -Think about that we wanna do a combined fitting, where multiple sets of calibration data need to -be fit simultaneously. We have some model, i.e. parametrization of the physics and detector responses, -and we have some prior knowledge on the parameters, but we do not know how much the calibration data -favors the parametrization as well as the prior knowledge. Appletree solves this kind of problem in a -Bayesian way, as shown in the following plot +Think about that we wanna do a combined fitting, where multiple sets of calibration data need to +be fit simultaneously. We have some model, i.e. parametrization of the physics and detector +responses, and we have some prior knowledge on the parameters, but we do not know how much +the calibration data favors the parametrization as well as the prior knowledge. +Appletree solves this kind of problem in a Bayesian way, as shown in the following plot. .. image:: ../../figures/workflow.png :width: 600 For given parameters, which can be physics parameters or detector parameters, the models for each -calibration can be compared with the data, to give log likelihood. Then all log likelihoods are summed -up together with log prior as the log posterior. Now we use an affine invariant MCMC ensemble sampler -to sample from this posterior distribution. After sufficient iterations of sampling, we can choose a -point estimator on the parameters as the "best-fit". +calibration can be compared with the data, to give log likelihood. Then all log likelihoods +are summed up together with log prior as the log posterior. Now we use an affine invariant MCMC +ensemble sampler to sample from this posterior distribution. After sufficient iterations of +sampling, we can choose a point estimator on the parameters as the "best-fit". -The idea of appletree is quite simple, but there are several things need special attention. First, the -model is usually very hard to express in an analytical form, thus the model is usually realized by doing -simulations. Second, models can be different to describe different calibration data, e.g. ER model -and NR model etc. Last, the dataset is usually not pure, meaning that it's consist of events from different -mechanism, which could be AC, wall events. +The idea of appletree is quite simple, but there are several things need special attention. +First, the model is usually very hard to express in an analytical form, thus the model is usually +realized by doing simulations. Second, models can be different to describe different calibration +data, e.g. ER model and NR model etc. Last, the dataset is usually not pure, meaning that it's +consist of events from different mechanism, which could be AC, wall events. This exemplar problem helps us understand the structure of appletree. In appletree, there are four important concepts: @@ -31,8 +31,9 @@ important concepts: - **Plugin**: the smallest simulation unit. - **Component**: the ensemble of plugins as a whole simulation. - **Likelihood**: a class that sums up all components and calculates likelihood. - - **Context**: the whole fitting manager that sums all log likelihoods and log prior and runs fitting. + - **Context**: the whole fitting manager that sums all log likelihoods and log prior + and runs fitting. -Think about a Rn220-Ar37 combined fitting. There will be two **likelihoods**, one for Rn220 and one for Ar37. -In Rn220 likelihood, the model is consist of **components** of ER, AC, wall. And **plugins** can be quanta -generation, DPE effect of PMT etc. +Think about a Rn220-Ar37 combined fitting. There will be two **likelihoods**, +one for Rn220 and one for Ar37. In Rn220 likelihood, the model is consist of **components** of ER, +AC, wall. And **plugins** can be quanta generation, DPE effect of PMT etc. diff --git a/docs/source/basics/plugin.rst b/docs/source/basics/plugin.rst index a054161b..e0847e4f 100644 --- a/docs/source/basics/plugin.rst +++ b/docs/source/basics/plugin.rst @@ -3,7 +3,8 @@ Plugin ====== -Plugin is the smallest simulation unit in appletree. All plugins must inherit from the `appletree.Plugin`. +Plugin is the smallest simulation unit in appletree. +All plugins must inherit from the `appletree.Plugin`. .. autoclass:: appletree.Plugin :members: @@ -39,5 +40,5 @@ Here is an example how a plugin works: int(1e6), # this is the batch_size, the only element in self.depends_on ) -Note that whatever `key` or `parameters` will be used in `Plugin.simulate` or not, they must be the first and second arguments, and `key` -is always the first in the returned tuple. +Note that whatever `key` or `parameters` will be used in `Plugin.simulate` or not, +they must be the first and second arguments, and `key` is always the first in the returned tuple. diff --git a/docs/source/conf.py b/docs/source/conf.py index c8e8b4cb..d40307b3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -4,9 +4,9 @@ import appletree as apt -project = 'Appletree' -copyright = '2023, Appletree contributors and the XENON collaboration' -author = 'Zihao Xu, Dacheng Xu' +project = "Appletree" +copyright = "2023, Appletree contributors and the XENON collaboration" +author = "Zihao Xu, Dacheng Xu" release = apt.__version__ version = apt.__version__ @@ -14,23 +14,23 @@ # -- General configuration extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.viewcode', - 'nbsphinx', + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", + "nbsphinx", ] intersphinx_mapping = { - 'python': ('https://docs.python.org/3/', None), - 'sphinx': ('https://www.sphinx-doc.org/en/master/', None), + "python": ("https://docs.python.org/3/", None), + "sphinx": ("https://www.sphinx-doc.org/en/master/", None), } -intersphinx_disabled_domains = ['std'] +intersphinx_disabled_domains = ["std"] -templates_path = ['_templates'] +templates_path = ["_templates"] # -- Options for HTML output -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # -- Options for EPUB output -epub_show_urls = 'footnote' +epub_show_urls = "footnote" diff --git a/docs/source/index.rst b/docs/source/index.rst index ee65a361..ea204887 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -4,8 +4,8 @@ Appletree Github page: https://github.com/XENONnT/appletree Appletree stands for "a high-performance program simulates and fits response of xenon". -It's a software framework of fitting response of liquid xenon detector, based on -`jax `_ and affine invariant MCMC ensemble sampler +It's a software framework of fitting response of liquid xenon detector, based on +`jax `_ and affine invariant MCMC ensemble sampler using `emcee `_. .. toctree:: diff --git a/docs/source/installation.rst b/docs/source/installation.rst index fbd1951e..259e5e5c 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -38,9 +38,11 @@ Option 2: install from source code git clone https://github.com/XENONnT/appletree cd appletree -To install the package and requirements in your environment, replace `pip install appletree[*]` to `python3 -m pip install .[*] --user` in the above `pip` commands. +To install the package and requirements in your environment, replace `pip install appletree[*]` +to `python3 -m pip install .[*] --user` in the above `pip` commands. -To install appletree in editable mode, insert `--editable` argument after `install` in the above `pip install` or `python3 -m pip install` commands. +To install appletree in editable mode, insert `--editable` argument after `install` in the above +`pip install` or `python3 -m pip install` commands. For example, to install in your environment and in editable mode with CUDA Toolkit 12.1 support: diff --git a/notebooks/1. component.ipynb b/notebooks/1. component.ipynb index 170d3399..b4d70dd2 100644 --- a/notebooks/1. component.ipynb +++ b/notebooks/1. component.ipynb @@ -74,14 +74,14 @@ "outputs": [], "source": [ "# The components is associated with bins, so first we load bins\n", - "data = pd.read_csv(get_file_path('data_Rn220.csv'))\n", + "data = pd.read_csv(get_file_path(\"data_Rn220.csv\"))\n", "bins_cs1, bins_cs2 = apt.utils.get_equiprob_bins_2d(\n", - " data[['cs1', 'cs2']].to_numpy(),\n", + " data[[\"cs1\", \"cs2\"]].to_numpy(),\n", " [15, 15],\n", " order=[0, 1],\n", " x_clip=[0, 100],\n", " y_clip=[1e2, 1e4],\n", - " which_np=jnp\n", + " which_np=jnp,\n", ")" ] }, @@ -93,7 +93,7 @@ "outputs": [], "source": [ "# Initialize component\n", - "er = apt.ERBand(bins=[bins_cs1, bins_cs2], bins_type='irreg')" + "er = apt.ERBand(bins=[bins_cs1, bins_cs2], bins_type=\"irreg\")" ] }, { @@ -104,11 +104,8 @@ "outputs": [], "source": [ "# Deduce the workflow(datastructure)\n", - "er.deduce(\n", - " data_names=['cs1', 'cs2'], # 'eff'(efficiency) is always simulated\n", - " func_name='simulate'\n", - ")\n", - "er.rate_name = 'er_rate' # also we have to specify a normalization factor of the component\n", + "er.deduce(data_names=[\"cs1\", \"cs2\"], func_name=\"simulate\") # 'eff'(efficiency) is always simulated\n", + "er.rate_name = \"er_rate\" # also we have to specify a normalization factor of the component\n", "\n", "# Compile ER script\n", "# This is meta-programing because appletree can generate codes dynamically\n", @@ -231,8 +228,8 @@ "outputs": [], "source": [ "# Initialize component, not based on simulation, but the input template\n", - "ac = apt.AC(bins=[bins_cs1, bins_cs2], bins_type='irreg', file_name='AC_Rn220.pkl')\n", - "ac.rate_name = 'ac_rate'\n", + "ac = apt.AC(bins=[bins_cs1, bins_cs2], bins_type=\"irreg\", file_name=\"AC_Rn220.pkl\")\n", + "ac.rate_name = \"ac_rate\"\n", "\n", "# Do not forget to deduce\n", "ac.deduce()\n", @@ -257,7 +254,7 @@ "source": [ "# Of course we have to load parameters(and their priors) in simulation\n", "\n", - "par_manager = apt.Parameter(get_file_path('er.json'))\n", + "par_manager = apt.Parameter(get_file_path(\"er.json\"))\n", "par_manager.sample_init()\n", "parameters = par_manager.get_all_parameter()" ] @@ -308,16 +305,12 @@ "h, be = jnp.histogramdd(\n", " jnp.asarray([cs1, cs2]).T,\n", " bins=(jnp.linspace(0, 100, 101), jnp.logspace(2.5, 4.1, 81)),\n", - " weights=eff\n", + " weights=eff,\n", ")\n", "\n", - "h = mh.Histdd.from_histogram(\n", - " np.array(h), \n", - " be, \n", - " axis_names=['cs1', 'cs2']\n", - ")\n", + "h = mh.Histdd.from_histogram(np.array(h), be, axis_names=[\"cs1\", \"cs2\"])\n", "h.plot(norm=LogNorm())\n", - "plt.yscale('log')\n", + "plt.yscale(\"log\")\n", "plt.show()" ] }, @@ -362,7 +355,7 @@ ], "source": [ "apt.utils.plot_irreg_histogram_2d(bins_cs1, bins_cs2, h, density=False)\n", - "plt.yscale('log')\n", + "plt.yscale(\"log\")\n", "plt.ylim(5e2, 1e4)\n", "plt.show()" ] @@ -396,7 +389,7 @@ ], "source": [ "apt.utils.plot_irreg_histogram_2d(bins_cs1, bins_cs2, h, density=False)\n", - "plt.yscale('log')\n", + "plt.yscale(\"log\")\n", "plt.ylim(5e2, 1e4)\n", "plt.show()" ] diff --git a/notebooks/2. likelihood.ipynb b/notebooks/2. likelihood.ipynb index 15f3c6b8..a5c22ebb 100644 --- a/notebooks/2. likelihood.ipynb +++ b/notebooks/2. likelihood.ipynb @@ -60,12 +60,12 @@ "outputs": [], "source": [ "config = dict(\n", - " data_file_name = get_file_path('data_Rn220.csv'),\n", - " bins_type = 'equiprob',\n", - " bins_on = ['cs1', 'cs2'],\n", - " bins = [15, 15],\n", - " x_clip = [0, 100],\n", - " y_clip = [2e2, 1e4],\n", + " data_file_name=get_file_path(\"data_Rn220.csv\"),\n", + " bins_type=\"equiprob\",\n", + " bins_on=[\"cs1\", \"cs2\"],\n", + " bins=[15, 15],\n", + " x_clip=[0, 100],\n", + " y_clip=[2e2, 1e4],\n", ")\n", "\n", "llh = apt.Likelihood(**config)" @@ -122,8 +122,8 @@ ], "source": [ "# Register components\n", - "llh.register_component(apt.ERBand, 'rn220_er')\n", - "llh.register_component(apt.AC, 'rn220_ac', file_name='AC_Rn220.pkl')\n", + "llh.register_component(apt.ERBand, \"rn220_er\")\n", + "llh.register_component(apt.AC, \"rn220_ac\", file_name=\"AC_Rn220.pkl\")\n", "\n", "# To see all the components\n", "llh.print_likelihood_summary(short=True)" @@ -146,15 +146,15 @@ "source": [ "# Load parameters(and their priors) in simulation. Note: these parameters will be shared among components\n", "\n", - "par_manager = apt.Parameter(get_file_path('er.json'))\n", + "par_manager = apt.Parameter(get_file_path(\"er.json\"))\n", "\n", "par_manager.sample_init()\n", "\n", "parameters = par_manager.get_all_parameter()\n", "\n", "# Have to specify the normalization factor of each component\n", - "parameters['rn220_ac_rate'] = parameters['ac_rate']\n", - "parameters['rn220_er_rate'] = parameters['er_rate']" + "parameters[\"rn220_ac_rate\"] = parameters[\"ac_rate\"]\n", + "parameters[\"rn220_er_rate\"] = parameters[\"er_rate\"]" ] }, { @@ -256,7 +256,7 @@ } ], "source": [ - "print(f'The log (posterior) LLH is {log_llh:.2f} now.')" + "print(f\"The log (posterior) LLH is {log_llh:.2f} now.\")" ] } ], diff --git a/notebooks/3. context.ipynb b/notebooks/3. context.ipynb index 4ba4fb0f..0c0a5cde 100644 --- a/notebooks/3. context.ipynb +++ b/notebooks/3. context.ipynb @@ -62,7 +62,7 @@ "outputs": [], "source": [ "# Load configuration file\n", - "config = get_file_path('rn220.json')\n", + "config = get_file_path(\"rn220.json\")\n", "\n", "# Initialize context\n", "tree = apt.Context(config)" @@ -176,8 +176,8 @@ "for _logp in logp.T:\n", " plt.plot(_logp, lw=0.1)\n", "\n", - "plt.xlabel('iteration')\n", - "plt.ylabel('log posterior')\n", + "plt.xlabel(\"iteration\")\n", + "plt.ylabel(\"log posterior\")\n", "plt.show()" ] }, @@ -196,7 +196,7 @@ "metadata": {}, "outputs": [], "source": [ - "cs1, cs2, eff = tree.get_template('rn220_llh', 'rn220_er')" + "cs1, cs2, eff = tree.get_template(\"rn220_llh\", \"rn220_er\")" ] }, { @@ -218,19 +218,15 @@ ], "source": [ "h, be = jnp.histogramdd(\n", - " jnp.asarray([cs1, cs2]).T, \n", - " bins=(jnp.linspace(0, 100, 101), jnp.logspace(2.5, 4.1, 81)), \n", - " weights=eff\n", + " jnp.asarray([cs1, cs2]).T,\n", + " bins=(jnp.linspace(0, 100, 101), jnp.logspace(2.5, 4.1, 81)),\n", + " weights=eff,\n", ")\n", "\n", - "h = mh.Histdd.from_histogram(\n", - " np.array(h), \n", - " be, \n", - " axis_names=['cs1', 'cs2']\n", - ")\n", + "h = mh.Histdd.from_histogram(np.array(h), be, axis_names=[\"cs1\", \"cs2\"])\n", "h.plot(norm=LogNorm())\n", - "plt.scatter(*tree['rn220_llh'].data.T, color='r', s=2.0)\n", - "plt.yscale('log')\n", + "plt.scatter(*tree[\"rn220_llh\"].data.T, color=\"r\", s=2.0)\n", + "plt.yscale(\"log\")\n", "plt.show()" ] }, @@ -253,10 +249,7 @@ "metadata": {}, "outputs": [], "source": [ - "key, result = tree['rn220_llh']['rn220_er'].simulate(\n", - " key, \n", - " batch_size, parameters\n", - ")" + "key, result = tree[\"rn220_llh\"][\"rn220_er\"].simulate(key, batch_size, parameters)" ] }, { @@ -286,21 +279,21 @@ ], "source": [ "data_sample = np.array(result[:-1]).T\n", - "x_clip = tree['rn220_llh']._config['x_clip']\n", - "y_clip = tree['rn220_llh']._config['y_clip']\n", + "x_clip = tree[\"rn220_llh\"]._config[\"x_clip\"]\n", + "y_clip = tree[\"rn220_llh\"]._config[\"y_clip\"]\n", "\n", "n, bin_edges = GOFevaluation.utils.equiprobable_histogram(\n", - " tree['rn220_llh'].data, \n", - " data_sample, \n", - " tree['rn220_llh']._config['bins'], \n", - " order=[0, 1], \n", - " plot=True, \n", - " nevents_expected=len(tree['rn220_llh'].data), \n", - " plot_xlim=x_clip, \n", - " plot_ylim=y_clip, \n", - " plot_mode='sigma_deviation'\n", + " tree[\"rn220_llh\"].data,\n", + " data_sample,\n", + " tree[\"rn220_llh\"]._config[\"bins\"],\n", + " order=[0, 1],\n", + " plot=True,\n", + " nevents_expected=len(tree[\"rn220_llh\"].data),\n", + " plot_xlim=x_clip,\n", + " plot_ylim=y_clip,\n", + " plot_mode=\"sigma_deviation\",\n", ")\n", - "plt.yscale('log')" + "plt.yscale(\"log\")" ] }, { @@ -318,10 +311,7 @@ "metadata": {}, "outputs": [], "source": [ - "key, h = tree['rn220_llh']['rn220_er'].simulate_hist(\n", - " key, \n", - " batch_size, parameters\n", - ")" + "key, h = tree[\"rn220_llh\"][\"rn220_er\"].simulate_hist(key, batch_size, parameters)" ] }, { @@ -342,8 +332,8 @@ } ], "source": [ - "apt.utils.plot_irreg_histogram_2d(*tree['rn220_llh']['rn220_er'].bins, h, density=False)\n", - "plt.yscale('log')\n", + "apt.utils.plot_irreg_histogram_2d(*tree[\"rn220_llh\"][\"rn220_er\"].bins, h, density=False)\n", + "plt.yscale(\"log\")\n", "\n", "plt.show()" ] diff --git a/notebooks/4. benchmark.ipynb b/notebooks/4. benchmark.ipynb index ec80db76..8509d579 100644 --- a/notebooks/4. benchmark.ipynb +++ b/notebooks/4. benchmark.ipynb @@ -53,7 +53,7 @@ "source": [ "# Load configuration file\n", "# You should change the configuration file for XENONnT\n", - "config = get_file_path('rn220.json')\n", + "config = get_file_path(\"rn220.json\")\n", "\n", "# Initialize context\n", "tree = apt.Context(config)" @@ -157,8 +157,8 @@ "for _logp in logp.T:\n", " plt.plot(_logp, lw=0.1)\n", "\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('Log posterior')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"Log posterior\")\n", "plt.show()" ] }, @@ -197,16 +197,18 @@ ], "source": [ "key = apt.randgen.get_key()\n", - "key, model_hist = tree.likelihoods['rn220_llh'].components['rn220_er'].simulate_hist(key, int(1e6), parameters)\n", - "model_hist += tree.likelihoods['rn220_llh'].components['rn220_ac'].simulate_hist(parameters)\n", - "data_hist = tree.likelihoods['rn220_llh'].data_hist\n", + "key, model_hist = (\n", + " tree.likelihoods[\"rn220_llh\"].components[\"rn220_er\"].simulate_hist(key, int(1e6), parameters)\n", + ")\n", + "model_hist += tree.likelihoods[\"rn220_llh\"].components[\"rn220_ac\"].simulate_hist(parameters)\n", + "data_hist = tree.likelihoods[\"rn220_llh\"].data_hist\n", "\n", - "bins = tree.likelihoods['rn220_llh'].components['rn220_er'].bins\n", + "bins = tree.likelihoods[\"rn220_llh\"].components[\"rn220_er\"].bins\n", "\n", - "apt.plot_irreg_histogram_2d(*bins, (model_hist-data_hist)/jnp.sqrt(data_hist))\n", - "plt.yscale('log')\n", - "plt.xlabel('cS1 [PE]')\n", - "plt.ylabel('cS2 [PE]')\n", + "apt.plot_irreg_histogram_2d(*bins, (model_hist - data_hist) / jnp.sqrt(data_hist))\n", + "plt.yscale(\"log\")\n", + "plt.xlabel(\"cS1 [PE]\")\n", + "plt.ylabel(\"cS2 [PE]\")\n", "plt.show()" ] }, @@ -226,9 +228,10 @@ ], "source": [ "from scipy.stats import chi2\n", - "t = jnp.sum(((model_hist-data_hist)/jnp.sqrt(data_hist))**2)\n", - "p = 1 - chi2.cdf(t, 30*30)\n", - "print(f'p = {p}')" + "\n", + "t = jnp.sum(((model_hist - data_hist) / jnp.sqrt(data_hist)) ** 2)\n", + "p = 1 - chi2.cdf(t, 30 * 30)\n", + "print(f\"p = {p}\")" ] }, { @@ -252,12 +255,16 @@ "from matplotlib.colors import LogNorm\n", "\n", "key = apt.randgen.get_key()\n", - "key, (cs1, cs2, eff) = tree.likelihoods['rn220_llh'].components['rn220_er'].simulate(key, int(1e6), parameters)\n", + "key, (cs1, cs2, eff) = (\n", + " tree.likelihoods[\"rn220_llh\"].components[\"rn220_er\"].simulate(key, int(1e6), parameters)\n", + ")\n", "\n", - "plt.hist2d(cs1, cs2, weights=eff, bins=[np.linspace(0, 100, 100), np.logspace(2, 4, 100)], norm=LogNorm())\n", - "plt.yscale('log')\n", - "plt.xlabel('cS1 [PE]')\n", - "plt.ylabel('cS2 [PE]')\n", + "plt.hist2d(\n", + " cs1, cs2, weights=eff, bins=[np.linspace(0, 100, 100), np.logspace(2, 4, 100)], norm=LogNorm()\n", + ")\n", + "plt.yscale(\"log\")\n", + "plt.xlabel(\"cS1 [PE]\")\n", + "plt.ylabel(\"cS2 [PE]\")\n", "plt.show()" ] } diff --git a/notebooks/5. datastructure.ipynb b/notebooks/5. datastructure.ipynb index a71cb7c4..279ad6f0 100644 --- a/notebooks/5. datastructure.ipynb +++ b/notebooks/5. datastructure.ipynb @@ -53,14 +53,14 @@ "metadata": {}, "outputs": [], "source": [ - "data = pd.read_csv(get_file_path('data_Rn220.csv'))\n", + "data = pd.read_csv(get_file_path(\"data_Rn220.csv\"))\n", "bins_cs1, bins_cs2 = apt.utils.get_equiprob_bins_2d(\n", - " data[['cs1', 'cs2']].to_numpy(),\n", + " data[[\"cs1\", \"cs2\"]].to_numpy(),\n", " [15, 15],\n", " order=[0, 1],\n", " x_clip=[0, 100],\n", " y_clip=[1e2, 1e4],\n", - " which_np=jnp\n", + " which_np=jnp,\n", ")" ] }, @@ -71,7 +71,7 @@ "metadata": {}, "outputs": [], "source": [ - "er = apt.ERBand(bins=[bins_cs1, bins_cs2], bins_type='irreg')" + "er = apt.ERBand(bins=[bins_cs1, bins_cs2], bins_type=\"irreg\")" ] }, { @@ -81,10 +81,7 @@ "metadata": {}, "outputs": [], "source": [ - "er.deduce(\n", - " data_names=['cs1', 'cs2'], \n", - " func_name='er_simulate'\n", - ")" + "er.deduce(data_names=[\"cs1\", \"cs2\"], func_name=\"er_simulate\")" ] }, { @@ -732,10 +729,10 @@ } ], "source": [ - "graph_tree = graphviz.Digraph(format='svg', strict=True)\n", + "graph_tree = graphviz.Digraph(format=\"svg\", strict=True)\n", "_ = apt.add_deps_to_graph_tree(er, graph_tree)\n", - "_ = apt.tree_to_svg(graph_tree, 'er_dtypes')\n", - "display(SVG('er_dtypes.svg'))" + "_ = apt.tree_to_svg(graph_tree, \"er_dtypes\")\n", + "display(SVG(\"er_dtypes.svg\"))" ] }, { @@ -1209,10 +1206,10 @@ } ], "source": [ - "graph_tree = graphviz.Digraph(format='svg', strict=True)\n", + "graph_tree = graphviz.Digraph(format=\"svg\", strict=True)\n", "_ = apt.add_plugins_to_graph_tree(er, graph_tree)\n", - "_ = apt.tree_to_svg(graph_tree, 'er_plugins')\n", - "display(SVG('er_plugins.svg'))" + "_ = apt.tree_to_svg(graph_tree, \"er_plugins\")\n", + "display(SVG(\"er_plugins.svg\"))" ] }, { @@ -1222,14 +1219,14 @@ "metadata": {}, "outputs": [], "source": [ - "data = pd.read_csv(get_file_path('data_Neutron.csv'))\n", + "data = pd.read_csv(get_file_path(\"data_Neutron.csv\"))\n", "bins_num_s1_phd, bins_cs2 = apt.utils.get_equiprob_bins_2d(\n", - " data[['num_s1_phd', 'cs2']].to_numpy(),\n", + " data[[\"num_s1_phd\", \"cs2\"]].to_numpy(),\n", " [8, 10],\n", " order=[0, 1],\n", " x_clip=[1.5, 9.5],\n", " y_clip=[1e2, 1e3],\n", - " which_np=jnp\n", + " which_np=jnp,\n", ")" ] }, @@ -1240,7 +1237,7 @@ "metadata": {}, "outputs": [], "source": [ - "nr = apt.NR(bins=[bins_num_s1_phd, bins_cs2], bins_type='irreg')" + "nr = apt.NR(bins=[bins_num_s1_phd, bins_cs2], bins_type=\"irreg\")" ] }, { @@ -1250,10 +1247,7 @@ "metadata": {}, "outputs": [], "source": [ - "nr.deduce(\n", - " data_names=['num_s1_phd', 'cs2'], \n", - " func_name='nr_simulate'\n", - ")" + "nr.deduce(data_names=[\"num_s1_phd\", \"cs2\"], func_name=\"nr_simulate\")" ] }, { @@ -1838,10 +1832,10 @@ } ], "source": [ - "graph_tree = graphviz.Digraph(format='svg', strict=True)\n", + "graph_tree = graphviz.Digraph(format=\"svg\", strict=True)\n", "_ = apt.add_deps_to_graph_tree(nr, graph_tree)\n", - "_ = apt.tree_to_svg(graph_tree, 'nr_dtypes')\n", - "display(SVG('nr_dtypes.svg'))" + "_ = apt.tree_to_svg(graph_tree, \"nr_dtypes\")\n", + "display(SVG(\"nr_dtypes.svg\"))" ] }, { @@ -2279,10 +2273,10 @@ } ], "source": [ - "graph_tree = graphviz.Digraph(format='svg', strict=True)\n", + "graph_tree = graphviz.Digraph(format=\"svg\", strict=True)\n", "_ = apt.add_plugins_to_graph_tree(nr, graph_tree)\n", - "_ = apt.tree_to_svg(graph_tree, 'nr_plugins')\n", - "display(SVG('nr_plugins.svg'))" + "_ = apt.tree_to_svg(graph_tree, \"nr_plugins\")\n", + "display(SVG(\"nr_plugins.svg\"))" ] } ], diff --git a/notebooks/6. maps.ipynb b/notebooks/6. maps.ipynb index 6d673a7a..52c88ede 100644 --- a/notebooks/6. maps.ipynb +++ b/notebooks/6. maps.ipynb @@ -27,18 +27,18 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_3fold_recon_eff.json'\n", + "file_name = \"./_3fold_recon_eff.json\"\n", "\n", "data = {}\n", "coordinate_system = np.linspace(0, 5, 6)\n", "_map = np.where(coordinate_system >= 3.0, 1.0, 0).tolist()\n", "\n", - "data['coordinate_system'] = coordinate_system.tolist()\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 'hit'\n", - "data['map'] = _map\n", - " \n", - "with open(file_name, 'w') as file:\n", + "data[\"coordinate_system\"] = coordinate_system.tolist()\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"hit\"\n", + "data[\"map\"] = _map\n", + "\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -49,16 +49,16 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_elife.json'\n", + "file_name = \"./_elife.json\"\n", "\n", "data = {}\n", "\n", - "data['coordinate_system'] = [0, 0.5, 1.0]\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 'cdf'\n", - "data['map'] = [1.2e4, 1.2e4, 1.2e4]\n", - " \n", - "with open(file_name, 'w') as file:\n", + "data[\"coordinate_system\"] = [0, 0.5, 1.0]\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"cdf\"\n", + "data[\"map\"] = [1.2e4, 1.2e4, 1.2e4]\n", + "\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -69,16 +69,16 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_s1_bias.json'\n", + "file_name = \"./_s1_bias.json\"\n", "\n", "data = {}\n", "\n", - "data['coordinate_system'] = [0, 1, 2, 3]\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 'hit'\n", - "data['map'] = [0, 0, 0, 0]\n", + "data[\"coordinate_system\"] = [0, 1, 2, 3]\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"hit\"\n", + "data[\"map\"] = [0, 0, 0, 0]\n", "\n", - "with open(file_name, 'w') as file:\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -89,16 +89,16 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_s2_bias.json'\n", + "file_name = \"./_s2_bias.json\"\n", "\n", "data = {}\n", - " \n", - "data['coordinate_system'] = [0, 100, 200, 300]\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 'hit'\n", - "data['map'] = [0, 0, 0, 0]\n", "\n", - "with open(file_name, 'w') as file:\n", + "data[\"coordinate_system\"] = [0, 100, 200, 300]\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"hit\"\n", + "data[\"map\"] = [0, 0, 0, 0]\n", + "\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -109,17 +109,17 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_s1_correction.json'\n", + "file_name = \"./_s1_correction.json\"\n", "\n", "data = {}\n", - " \n", - "data['coordinate_lowers'] = [-70, -70, -140]\n", - "data['coordinate_uppers'] = [70, 70, 0]\n", - "data['coordinate_type'] = 'regbin'\n", - "data['coordinate_name'] = ['x', 'y', 'z']\n", - "data['map'] = np.ones((5, 5, 5)).tolist()\n", - "\n", - "with open(file_name, 'w') as file:\n", + "\n", + "data[\"coordinate_lowers\"] = [-70, -70, -140]\n", + "data[\"coordinate_uppers\"] = [70, 70, 0]\n", + "data[\"coordinate_type\"] = \"regbin\"\n", + "data[\"coordinate_name\"] = [\"x\", \"y\", \"z\"]\n", + "data[\"map\"] = np.ones((5, 5, 5)).tolist()\n", + "\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -130,17 +130,17 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_s2_correction.json'\n", + "file_name = \"./_s2_correction.json\"\n", "\n", "data = {}\n", - " \n", - "data['coordinate_lowers'] = [-70, -70]\n", - "data['coordinate_uppers'] = [70, 70]\n", - "data['coordinate_type'] = 'regbin'\n", - "data['coordinate_name'] = ['x', 'y']\n", - "data['map'] = np.ones((5, 5)).tolist()\n", - "\n", - "with open(file_name, 'w') as file:\n", + "\n", + "data[\"coordinate_lowers\"] = [-70, -70]\n", + "data[\"coordinate_uppers\"] = [70, 70]\n", + "data[\"coordinate_type\"] = \"regbin\"\n", + "data[\"coordinate_name\"] = [\"x\", \"y\"]\n", + "data[\"map\"] = np.ones((5, 5)).tolist()\n", + "\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -151,16 +151,16 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_s1_cut_acc.json'\n", + "file_name = \"./_s1_cut_acc.json\"\n", "\n", "data = {}\n", - " \n", - "data['coordinate_system'] = [0, 50, 100]\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 's1_area'\n", - "data['map'] = [1.0, 1.0, 1.0]\n", "\n", - "with open(file_name, 'w') as file:\n", + "data[\"coordinate_system\"] = [0, 50, 100]\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"s1_area\"\n", + "data[\"map\"] = [1.0, 1.0, 1.0]\n", + "\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -171,16 +171,16 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_s2_cut_acc.json'\n", + "file_name = \"./_s2_cut_acc.json\"\n", "\n", "data = {}\n", - " \n", - "data['coordinate_system'] = [0, 500, 1000]\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 's2_area'\n", - "data['map'] = [1.0, 1.0, 1.0]\n", "\n", - "with open(file_name, 'w') as file:\n", + "data[\"coordinate_system\"] = [0, 500, 1000]\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"s2_area\"\n", + "data[\"map\"] = [1.0, 1.0, 1.0]\n", + "\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -191,18 +191,18 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_s1_smearing.json'\n", + "file_name = \"./_s1_smearing.json\"\n", "\n", "data = {}\n", - " \n", + "\n", "coordinate_system = np.linspace(3, 100, 98)\n", "_map = 0.4 / np.sqrt(coordinate_system)\n", - "data['coordinate_system'] = coordinate_system.tolist()\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 'hit'\n", - "data['map'] = _map.tolist()\n", + "data[\"coordinate_system\"] = coordinate_system.tolist()\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"hit\"\n", + "data[\"map\"] = _map.tolist()\n", "\n", - "with open(file_name, 'w') as file:\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -213,18 +213,18 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_s2_smearing.json'\n", + "file_name = \"./_s2_smearing.json\"\n", "\n", "data = {}\n", - " \n", + "\n", "coordinate_system = np.linspace(2e2, 1e4, 100)\n", "_map = 0.6 / np.sqrt(coordinate_system)\n", - "data['coordinate_system'] = coordinate_system.tolist()\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 'hit'\n", - "data['map'] = _map.tolist()\n", + "data[\"coordinate_system\"] = coordinate_system.tolist()\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"hit\"\n", + "data[\"map\"] = _map.tolist()\n", "\n", - "with open(file_name, 'w') as file:\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] }, @@ -235,17 +235,17 @@ "metadata": {}, "outputs": [], "source": [ - "file_name = './_posrec_reso.json'\n", + "file_name = \"./_posrec_reso.json\"\n", "\n", "data = {}\n", - " \n", + "\n", "coordinate_system = np.arange(1000)\n", - "data['coordinate_system'] = coordinate_system.tolist()\n", - "data['coordinate_type'] = 'point'\n", - "data['coordinate_name'] = 'num_e'\n", - "data['map'] = (np.ones_like(coordinate_system) * 0.1).tolist()\n", + "data[\"coordinate_system\"] = coordinate_system.tolist()\n", + "data[\"coordinate_type\"] = \"point\"\n", + "data[\"coordinate_name\"] = \"num_e\"\n", + "data[\"map\"] = (np.ones_like(coordinate_system) * 0.1).tolist()\n", "\n", - "with open(file_name, 'w') as file:\n", + "with open(file_name, \"w\") as file:\n", " json.dump(data, file)" ] } diff --git a/setup.cfg b/setup.cfg index 853f51d8..56e37415 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,82 +3,23 @@ # Set maximum width of the line to 100 max-line-length = 100 -# docstring-style = SPHINX +# E203 whitespace before ':' +# E402 module level import not at top of file +# F401 imported but unused +# F403 unable to detect undefined names +# W503 line break before binary operator -# Excluding some directories: -exclude = - .git - .github - docs* - notebooks* - *.yml - __pycache__ - .venv - .eggs - *.egg - dist +ignore = E203, W503 -# Some pep8 checks we are not interested in. List of codes ignored: -# C409 Unnecessary list passed to tuple() - rewrite as a tuple literal. -# C819 trailing comma prohibited -# D100 Missing docstring in public module -# D205 1 blank line required between summary line and description -# D400 First line should end with a period -# D401 First line should be in imperative mood -# D403 First word of the first line should be properly capitalized -# DAR101 Missing parameter(s) in Docstring: - min_hits -# DAR201 Missing "Returns" in Docstring: - return -# DAR401 Missing exception(s) in Raises section: -r ValueError -# E128 continuation line under-indented for visual indent -# E226 missing whitespace around arithmetic operator -# E251 unexpected spaces around keyword / parameter equals -# F403 'from .veto_events import *' used; unable to detect undefined names -# F541 f-string is missing placeholders -# I001 isort found an import in the wrong position -# I003 isort expected 1 blank line in imports, found 0 -# I004 isort found an unexpected blank line in imports -# I005 isort found an unexpected missing import -# P101 format string does contain unindexed parameters -# WPS110 Found wrong variable name: result -# WPS111 Found too short name: m < 2 -# WPS211 Found too many arguments: 7 > 5 -# WPS122 Found all unused variables definition: _time_zone_widget -# WPS210 Found too many local variables: 8 > 5 -# WPS218 Found too many assert statements: 6 > 5 -# WPS229 Found too long try body length: 2 > 1 -# WPS231 Found function with too much cognitive complexity: 13 > 12 -# WPS237 Found a too complex f string -# WPS336 Found explicit string concatenation -# WPS300 Found local folder import -# WPS303 Found underscored number: 35_000 -# WPS304 Found partial float -# WPS305 Found `f` string -# WPS306 Found class without a base class: TimeWidgets -# WPS317 Found incorrect multi-line parameters -# WPS318 Found extra indentation -# WPS319 Found bracket in wrong position -# WPS326 Found implicit string concatenation -# WPS331 Found variables that are only used for return: _time_zone_widget -# WPS335 Found incorrect for loop iter type -# WPS420 Found wrong keyword: del -# WPS421 Found wrong function call: print -# WPS432 Found magic number: 2e-05 -# WPS433 Found nested import -# WPS435 Found list multiply -# WPS437 Found protected attribute usage: _plugin_class_registry -# WPS440 Found block variables overlap: * -# WPS503 Found useless returning else statement -# WPS504 Found negated condition -# WPS519 Found implicit sum() call -# WPS602 Found using @staticmethod -# Q000 Remove bad quotes -ignore = C409, C819, D100, D205, D400, D401, D403, DAR101, DAR201, DAR401, E128, E226, E251, F403, F541, I001, I003, I004, I005, P101, WPS110, WPS111, WPS211, WPS122, WPS210, WPS218, WPS229, WPS231, WPS237, WPS237, WPS300, WPS303, WPS304, WPS305, WPS306, WPS317, WPS318, WPS319, WPS326, WPS331, WPS335, WPS336, WPS420, WPS421, WPS432, WPS433, WPS440, WPS435, WPS437, WPS503, WPS504, WPS519, WPS602, Q000 +per-file-ignores = + appletree/*__init__.py: E402, F401, F403 +[docformatter] +in-place = true +blank = true +style = google +wrap-summaries = 100 +wrap-descriptions = 100 -per-file-ignores = - # There are multiple `assert`s in tests, we allow them: - tests/*.py: S101 - appletree/*__init__.py: F401 WPS347 - # Missing docstrings in plugins are allowed since depends_on and provides say everything - appletree/plugins/*: D101 D102 D107 - appletree/components/*: D101 D102 D107 \ No newline at end of file +[doc8] +max-line-length = 100 diff --git a/setup.py b/setup.py index 8cfe11c0..857fd245 100644 --- a/setup.py +++ b/setup.py @@ -4,63 +4,65 @@ def open_requirements(path): with open(path) as f: requires = [ - r.split('/')[-1] if r.startswith('git+') else r - for r in f.read().splitlines() if not r.startswith('-')] + r.split("/")[-1] if r.startswith("git+") else r + for r in f.read().splitlines() + if not r.startswith("-") + ] return requires -requires = open_requirements('requirements.txt') +requires = open_requirements("requirements.txt") -with open('README.md') as file: +with open("README.md") as file: readme = file.read() -with open('HISTORY.md') as file: +with open("HISTORY.md") as file: history = file.read() setuptools.setup( - name='appletree', - version='0.2.3', - description='A high-Performance Program simuLatEs and fiTs REsponse of xEnon.', - author='Appletree contributors, the XENON collaboration', - long_description=readme + '\n\n' + history, - long_description_content_type='text/markdown', - setup_requires=['pytest-runner'], + name="appletree", + version="0.2.3", + description="A high-Performance Program simuLatEs and fiTs REsponse of xEnon.", + author="Appletree contributors, the XENON collaboration", + long_description=readme + "\n\n" + history, + long_description_content_type="text/markdown", + setup_requires=["pytest-runner"], install_requires=requires, - python_requires='>=3.8', + python_requires=">=3.8", extras_require={ - 'cpu': [ + "cpu": [ # pip install appletree[cpu] - 'jax[cpu]', + "jax[cpu]", ], - 'cuda112': [ - # pip install appletree[cuda112] -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html - 'jax[cuda]==0.3.15', + "cuda112": [ + # pip install appletree[cuda112] -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html # noqa: E501 + "jax[cuda]==0.3.15", ], - 'cuda121': [ - # pip install appletree[cuda121] -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html + "cuda121": [ + # pip install appletree[cuda121] -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html # noqa: E501 # according to this commit, jax[cuda12_pip]==0.4.10 is valid for CUDA Toolkit 12.1 - 'jax[cuda12_pip]', + "jax[cuda12_pip]", ], }, packages=setuptools.find_packages(), package_data={ - 'appletree': [ - 'instructs/*', - 'parameters/*', - 'maps/*', - 'data/*', + "appletree": [ + "instructs/*", + "parameters/*", + "maps/*", + "data/*", ], }, url="https://github.com/XENONnT/appletree", classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: English', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Intended Audience :: Science/Research', - 'Programming Language :: Python :: Implementation :: CPython', - 'Topic :: Scientific/Engineering :: Physics', + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Intended Audience :: Science/Research", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Scientific/Engineering :: Physics", ], zip_safe=False, ) diff --git a/tests/test_component.py b/tests/test_component.py index 3701e347..4b04b222 100644 --- a/tests/test_component.py +++ b/tests/test_component.py @@ -6,51 +6,53 @@ # Get parameters -par_instruct_file_name = get_file_path('er.json') +par_instruct_file_name = get_file_path("er.json") par_manager = apt.Parameter(par_instruct_file_name) par_manager.sample_init() parameters = par_manager.get_all_parameter() # Define bins -data_file_name = get_file_path('data_Rn220.csv',) +data_file_name = get_file_path( + "data_Rn220.csv", +) data = pd.read_csv(data_file_name) -data = data[['cs1', 'cs2']].to_numpy() +data = data[["cs1", "cs2"]].to_numpy() bins_cs1, bins_cs2 = apt.utils.get_equiprob_bins_2d( data, [15, 15], - order = [0, 1], - x_clip = [0, 100], - y_clip = [1e2, 1e4], - which_np = jnp, + order=[0, 1], + x_clip=[0, 100], + y_clip=[1e2, 1e4], + which_np=jnp, ) def test_fixed_component(): - """Test ComponentFixed""" + """Test ComponentFixed.""" ac = apt.components.AC( - bins = [bins_cs1, bins_cs2], - bins_type = 'irreg', - file_name = 'AC_Rn220.pkl', + bins=[bins_cs1, bins_cs2], + bins_type="irreg", + file_name="AC_Rn220.pkl", ) - ac.rate_name = 'ac_rate' - ac.deduce(data_names = ('cs1', 'cs2')) + ac.rate_name = "ac_rate" + ac.deduce(data_names=("cs1", "cs2")) ac.simulate_hist(parameters) ac.simulate_weighted_data(parameters) def test_sim_component(): - """Test ComponentSim""" + """Test ComponentSim.""" er = apt.components.ERBand( - bins = [bins_cs1, bins_cs2], - bins_type = 'irreg', + bins=[bins_cs1, bins_cs2], + bins_type="irreg", ) er.deduce( - data_names = ('cs1', 'cs2'), - func_name = 'er_sim', + data_names=("cs1", "cs2"), + func_name="er_sim", ) er.compile() - er.save_code('_temp.json') - er.rate_name = 'er_rate' + er.save_code("_temp.json") + er.rate_name = "er_rate" batch_size = int(1e3) key = apt.randgen.get_key(seed=137) diff --git a/tests/test_context.py b/tests/test_context.py index d847cf25..9d36cb32 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -4,24 +4,24 @@ def test_rn220_context(): - """Test Context of Rn220 combine fitting""" + """Test Context of Rn220 combine fitting.""" _cached_configs.clear() context = apt.ContextRn220() - context.print_context_summary() + context.print_context_summary(short=False) context.fitting(nwalkers=100, iteration=2, batch_size=int(1e4)) - context.dump_post_parameters('_temp.json') + context.dump_post_parameters("_temp.json") - context['rn220_llh']['rn220_er'].new_component() + context["rn220_llh"]["rn220_er"].new_component() check_unused_configs() def test_rn220_ar37_context(): - """Test Context of Rn220 & Ar37 combine fitting""" + """Test Context of Rn220 & Ar37 combine fitting.""" _cached_configs.clear() context = apt.ContextRn220Ar37() - context.print_context_summary() + context.print_context_summary(short=False) batch_size = int(1e4) context.fitting(nwalkers=100, iteration=2, batch_size=batch_size) @@ -32,23 +32,23 @@ def test_rn220_ar37_context(): def test_neutron_context(): - """Test Context of neutron combine fitting""" + """Test Context of neutron combine fitting.""" _cached_configs.clear() - instruct = get_file_path('neutron_low.json') + instruct = get_file_path("neutron_low.json") context = apt.Context(instruct) - context.print_context_summary() + context.print_context_summary(short=False) context.fitting(nwalkers=100, iteration=2, batch_size=int(1e4)) check_unused_configs() def test_literature_context(): - """Test Context of neutron combine fitting""" + """Test Context of neutron combine fitting.""" _cached_configs.clear() - instruct = get_file_path('literature_lyqy.json') + instruct = get_file_path("literature_lyqy.json") context = apt.Context(instruct) - context.print_context_summary() + context.print_context_summary(short=False) batch_size = int(1) context.fitting(nwalkers=100, iteration=2, batch_size=batch_size) diff --git a/tests/test_likelihood.py b/tests/test_likelihood.py index ce11cf49..46a71ba3 100644 --- a/tests/test_likelihood.py +++ b/tests/test_likelihood.py @@ -3,75 +3,75 @@ def test_er_likelihood(): - """Test Likelihood""" + """Test Likelihood.""" instruct = dict( - data_file_name = get_file_path('data_Rn220.csv'), - bins_type = 'equiprob', - bins_on = ['cs1', 'cs2'], - bins = [15, 15], - x_clip = [0, 100], - y_clip = [2e2, 1e4], + data_file_name=get_file_path("data_Rn220.csv"), + bins_type="equiprob", + bins_on=["cs1", "cs2"], + bins=[15, 15], + x_clip=[0, 100], + y_clip=[2e2, 1e4], ) llh = apt.Likelihood(**instruct) - llh.register_component(apt.components.AC, 'rn220_ac', 'AC_Rn220.pkl') - llh.register_component(apt.components.ERBand, 'rn220_er') + llh.register_component(apt.components.AC, "rn220_ac", "AC_Rn220.pkl") + llh.register_component(apt.components.ERBand, "rn220_er") llh.print_likelihood_summary(short=True) # Get parameters - par_instruct_file_name = get_file_path('er.json') + par_instruct_file_name = get_file_path("er.json") par_manager = apt.Parameter(par_instruct_file_name) par_manager.sample_init() parameters = par_manager.get_all_parameter() - parameters['rn220_ac_rate'] = parameters['ac_rate'] - parameters['rn220_er_rate'] = parameters['er_rate'] + parameters["rn220_ac_rate"] = parameters["ac_rate"] + parameters["rn220_er_rate"] = parameters["er_rate"] key = apt.randgen.get_key() llh.get_log_likelihood(key, int(1e6), parameters) def test_nr_likelihood(): - """Test Likelihood""" + """Test Likelihood.""" instruct = dict( - data_file_name = get_file_path('data_Neutron.csv'), - bins_type = 'equiprob', - bins_on = ['num_s1_phd', 'cs2'], - bins = [8, 15], - x_clip = [1.5, 9.5], - y_clip = [1e2, 1e3], + data_file_name=get_file_path("data_Neutron.csv"), + bins_type="equiprob", + bins_on=["num_s1_phd", "cs2"], + bins=[8, 15], + x_clip=[1.5, 9.5], + y_clip=[1e2, 1e3], ) llh = apt.Likelihood(**instruct) - llh.register_component(apt.components.NR, 'neutron_nr') + llh.register_component(apt.components.NR, "neutron_nr") llh.print_likelihood_summary(short=True) # Get parameters - par_instruct_file_name = get_file_path('nr_low.json') + par_instruct_file_name = get_file_path("nr_low.json") par_manager = apt.Parameter(par_instruct_file_name) par_manager.sample_init() parameters = par_manager.get_all_parameter() - parameters['neutron_nr_rate'] = parameters['nr_rate'] + parameters["neutron_nr_rate"] = parameters["nr_rate"] key = apt.randgen.get_key() llh.get_log_likelihood(key, int(1e6), parameters) def test_equiprob_likelihood(): - """Test Likelihood""" + """Test Likelihood.""" try: error_raised = True instruct = dict( - data_file_name = get_file_path('data_Neutron.csv'), - bins_type = 'equiprob', - bins_on = ['num_s1_phd', 'cs2'], - bins = [[1.5, 9.5], [1e2, 1e3]], - x_clip = [1.5, 9.5], - y_clip = [1e2, 1e3], + data_file_name=get_file_path("data_Neutron.csv"), + bins_type="equiprob", + bins_on=["num_s1_phd", "cs2"], + bins=[[1.5, 9.5], [1e2, 1e3]], + x_clip=[1.5, 9.5], + y_clip=[1e2, 1e3], ) - llh = apt.Likelihood(**instruct) + apt.Likelihood(**instruct) error_raised = False except Exception: - print('Error correctly raised when bins are not int in equiprob') + print("Error correctly raised when bins are not int in equiprob") else: if not error_raised: - raise RuntimeError('Should throw error when bins are not int in equiprob') + raise RuntimeError("Should throw error when bins are not int in equiprob")