From 1a30aaa788b152797ae60fcdcf7d7164b0513839 Mon Sep 17 00:00:00 2001 From: Robert James Date: Wed, 20 Dec 2023 14:06:36 +1100 Subject: [PATCH 1/7] Access LZ template stuff (will be stored on GitLab). --- flamedisx/__init__.py | 4 +++ flamedisx/lz/__init__.py | 1 + flamedisx/lz/data.py | 59 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 flamedisx/lz/__init__.py create mode 100644 flamedisx/lz/data.py diff --git a/flamedisx/__init__.py b/flamedisx/__init__.py index f632b6d2e..fd6bf3c6b 100644 --- a/flamedisx/__init__.py +++ b/flamedisx/__init__.py @@ -37,6 +37,10 @@ # Access through fd.lux.xxx from . import lux +# LZ data access +# Access through fd.lz.xxx +from . import lz + # Custom TFP files # Access through fd.tfp_files.xxx from . import tfp_files diff --git a/flamedisx/lz/__init__.py b/flamedisx/lz/__init__.py new file mode 100644 index 000000000..df22d8bbb --- /dev/null +++ b/flamedisx/lz/__init__.py @@ -0,0 +1 @@ +from .data import * diff --git a/flamedisx/lz/data.py b/flamedisx/lz/data.py new file mode 100644 index 000000000..7d4d22cfe --- /dev/null +++ b/flamedisx/lz/data.py @@ -0,0 +1,59 @@ +"""Tools to get private LZ data +""" +import getpass +import os +import os.path +import random +import string + +import flamedisx as fd +export, __all__ = fd.exporter() + + +# Path to the root folder of the private LZ data repository, if you have already cloned it +PATH = 'lz_private_data' + + +def ensure_token(token=None): + """Requests for token if token is not already available.""" + if token is None: + print(" - Create a token with 'read repository' permissions at " + "https://gitlab.com/-/profile/personal_access_tokens\n" + " - Save or write it down somewhere \n" + " - Type it in the prompt above\n\n" + "'Repository not found' means you didn't give the token" + " the correct permissions.\n" + "'Authentication failed' means you mistyped your username or the" + " token.\n") + # We could prompt for username/password instead, but then the password + # would be printed in plaintext if there is any problem during cloning. + user = input('Gitlab username:') + token = getpass.getpass('GitLab token: ') + return user, token + + +def ensure_repo(repo_name, repo_path, user=None, token=None): + """Clones private repository (prompting for credentials) if we do not have it""" + if not os.path.exists(repo_path): + print("Private data requested, we must clone repository folder.") + user, token = ensure_token() + temp_folder = ''.join(random.choices(string.ascii_lowercase, k=8)) + fd.run_command(f'git clone https://{user}:{token}' + f'@gitlab.com/{repo_name} {temp_folder}') + fd.run_command(f'mv {temp_folder}/{repo_path} .') + fd.run_command(f'rm -r -f {temp_folder}') + + +@export +def clone_lz_repo(): + ensure_repo('luxzeplin/stats/LZFlameFit.git', PATH) + import os + print(os.getcwd()) + + +@export +def get_lz_file(data_file_name): + """Return information from file in lz_private_data/... + """ + ensure_repo('luxzeplin/stats/LZFlameFit.git', PATH) + return fd.get_resource(f'{PATH}/{data_file_name}') From e67ebbcf31a3d713b73bca51cc50dda8239d3632 Mon Sep 17 00:00:00 2001 From: Robert James Date: Wed, 20 Dec 2023 14:35:52 +1100 Subject: [PATCH 2/7] PEP8 fixes. --- flamedisx/lz/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flamedisx/lz/data.py b/flamedisx/lz/data.py index 7d4d22cfe..cea9b269b 100644 --- a/flamedisx/lz/data.py +++ b/flamedisx/lz/data.py @@ -39,7 +39,7 @@ def ensure_repo(repo_name, repo_path, user=None, token=None): user, token = ensure_token() temp_folder = ''.join(random.choices(string.ascii_lowercase, k=8)) fd.run_command(f'git clone https://{user}:{token}' - f'@gitlab.com/{repo_name} {temp_folder}') + f'@gitlab.com/{repo_name} {temp_folder}') fd.run_command(f'mv {temp_folder}/{repo_path} .') fd.run_command(f'rm -r -f {temp_folder}') From 70125f77b34afb745bfb26e2c8b4f0873e4d343c Mon Sep 17 00:00:00 2001 From: Robert James Date: Wed, 20 Dec 2023 16:42:39 +1100 Subject: [PATCH 3/7] Remove debug lines. --- flamedisx/lz/data.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/flamedisx/lz/data.py b/flamedisx/lz/data.py index cea9b269b..1eaf3623c 100644 --- a/flamedisx/lz/data.py +++ b/flamedisx/lz/data.py @@ -47,8 +47,6 @@ def ensure_repo(repo_name, repo_path, user=None, token=None): @export def clone_lz_repo(): ensure_repo('luxzeplin/stats/LZFlameFit.git', PATH) - import os - print(os.getcwd()) @export From a12beeb2b227f6c101ba3e35bc1698307dfb0bb0 Mon Sep 17 00:00:00 2001 From: Robert James Date: Thu, 11 Jan 2024 00:05:40 +1100 Subject: [PATCH 4/7] Add discovery stuff (bit rough for now). --- flamedisx/non_asymptotic_inference.py | 45 ++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/flamedisx/non_asymptotic_inference.py b/flamedisx/non_asymptotic_inference.py index bcec10578..388750172 100644 --- a/flamedisx/non_asymptotic_inference.py +++ b/flamedisx/non_asymptotic_inference.py @@ -211,7 +211,8 @@ def run_routine(self, mus_test=None, save_fits=False, observed_test_stats=None, generate_B_toys=False, simulate_dict_B=None, toy_data_B=None, constraint_extra_args_B=None, - toy_batch=0): + toy_batch=0, + discovery=False): """If observed_data is passed, evaluate observed test statistics. Otherwise, obtain test statistic distributions (for both S+B and B-only). @@ -315,7 +316,8 @@ def run_routine(self, mus_test=None, save_fits=False, # Case where we want test statistic distributions else: self.toy_test_statistic_dist(test_stat_dists_SB, test_stat_dists_B, - mu_test, signal_source, likelihood, save_fits=save_fits) + mu_test, signal_source, likelihood, + save_fits=save_fits, discovery=discovery) if observed_data is not None: observed_test_stats_collection[signal_source] = observed_test_stats @@ -366,7 +368,8 @@ def sample_data_constraints(self, mu_test, signal_source_name, likelihood): return simulate_dict, toy_data, constraint_extra_args def toy_test_statistic_dist(self, test_stat_dists_SB, test_stat_dists_B, - mu_test, signal_source_name, likelihood, save_fits=False): + mu_test, signal_source_name, likelihood, + save_fits=False, discovery=False): """Internal function to get test statistic distribution. """ ts_values_SB = [] @@ -396,7 +399,10 @@ def toy_test_statistic_dist(self, test_stat_dists_SB, test_stat_dists_B, if value < 0.1: guess_dict_SB[key] = 0.1 # Evaluate test statistic - ts_result_SB = test_statistic_SB(mu_test, signal_source_name, guess_dict_SB) + if discovery: + ts_result_SB = test_statistic_SB(0., signal_source_name, guess_dict_SB) + else: + ts_result_SB = test_statistic_SB(mu_test, signal_source_name, guess_dict_SB) # Save test statistic, and possibly fits ts_values_SB.append(ts_result_SB[0]) if save_fits: @@ -424,7 +430,10 @@ def toy_test_statistic_dist(self, test_stat_dists_SB, test_stat_dists_B, # Create test statistic test_statistic_B = self.test_statistic(likelihood) # Evaluate test statistic - ts_result_B = test_statistic_B(mu_test, signal_source_name, guess_dict_B) + if discovery: + ts_result_B = test_statistic_B(0., signal_source_name, guess_dict_B) + else: + ts_result_B = test_statistic_B(mu_test, signal_source_name, guess_dict_B) # Save test statistic, and possibly fits ts_values_B.append(ts_result_B[0]) if save_fits: @@ -667,3 +676,29 @@ def get_bands(self, conf_level=0.1, quantiles=[0, 1, -1, 2, -2], bands[signal_source] = these_bands return bands + + def get_bands_discovery(self, quantiles=[0, 1, -1]): + """ + """ + bands = dict() + + # Loop over signal sources + for signal_source in self.signal_source_names: + # Get test statistic distribitions + test_stat_dists_SB = self.test_stat_dists_SB[signal_source] + test_stat_dists_B = self.test_stat_dists_B[signal_source] + + assert len(test_stat_dists_SB.ts_dists.keys()) == 1, 'Currently only support a single signal strength' + + these_p_vals = (100. - stats.percentileofscore(list(test_stat_dists_B.ts_dists.values())[0], + list(test_stat_dists_SB.ts_dists.values())[0], + kind='weak')) / 100. + these_p_vals = these_p_vals[these_p_vals > 0.] + these_disco_sigs = stats.norm.ppf(1. - these_p_vals) + + these_bands = dict() + for quantile in quantiles: + these_bands[quantile] = np.quantile(np.sort(these_disco_sigs), stats.norm.cdf(quantile)) + bands[signal_source] = these_bands + + return bands From 630b5a01b972cd1696ebbab6666773c0a8707625 Mon Sep 17 00:00:00 2001 From: Robert James Date: Fri, 2 Feb 2024 16:29:12 +1100 Subject: [PATCH 5/7] Update access method for LZ private data. --- flamedisx/lz/data.py | 57 ++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/flamedisx/lz/data.py b/flamedisx/lz/data.py index 1eaf3623c..5152c8875 100644 --- a/flamedisx/lz/data.py +++ b/flamedisx/lz/data.py @@ -5,6 +5,7 @@ import os.path import random import string +import sys import flamedisx as fd export, __all__ = fd.exporter() @@ -32,26 +33,46 @@ def ensure_token(token=None): return user, token -def ensure_repo(repo_name, repo_path, user=None, token=None): - """Clones private repository (prompting for credentials) if we do not have it""" - if not os.path.exists(repo_path): - print("Private data requested, we must clone repository folder.") - user, token = ensure_token() - temp_folder = ''.join(random.choices(string.ascii_lowercase, k=8)) - fd.run_command(f'git clone https://{user}:{token}' - f'@gitlab.com/{repo_name} {temp_folder}') - fd.run_command(f'mv {temp_folder}/{repo_path} .') - fd.run_command(f'rm -r -f {temp_folder}') +def clone_repo(repo_name, repo_path, user=None, token=None): + """Clones private repository (prompting for credentials)""" + fd.run_command(f'rm -r -f {repo_path}') + user, token = ensure_token() + temp_folder = ''.join(random.choices(string.ascii_lowercase, k=8)) + fd.run_command(f'git clone https://{user}:{token}' + f'@gitlab.com/{repo_name} {temp_folder}') + fd.run_command(f'mv {temp_folder}/{repo_path} .') + fd.run_command(f'rm -r -f {temp_folder}') @export -def clone_lz_repo(): - ensure_repo('luxzeplin/stats/LZFlameFit.git', PATH) +def lz_setup(mode='tensors', run='sr1', lz_private_data_dir=None): + """Update the system path to include necessary LZ private data files + """ + if lz_private_data_dir is not None: + if os.path.isdir(f'{lz_private_data_dir}/{mode}/{run}'): + sys.path.append(f'{lz_private_data_dir}/{mode}/{run}') + print(f'Successfully found mode {mode} and run {run} in ' + \ + f'directory {lz_private_data_dir}') + return + else: + print(f'Error finding mode {mode} and run {run} in directory {lz_private_data_dir}') + print('Seeing if LZ private data directory already exists') -@export -def get_lz_file(data_file_name): - """Return information from file in lz_private_data/... - """ - ensure_repo('luxzeplin/stats/LZFlameFit.git', PATH) - return fd.get_resource(f'{PATH}/{data_file_name}') + if os.path.isdir(f'lz_private_data/{mode}/{run}'): + sys.path.append(f'lz_private_data/{mode}/{run}') + print(f'Successfully found mode {mode} and run {run} in directory lz_private_data') + return + else: + print(f'Mode {mode} and run {run} not found in any existing directory') + + print('Cloning repo, requires LZ GitLab access token') + + clone_repo('luxzeplin/stats/LZFlameFit.git', PATH) + + if os.path.isdir(f'lz_private_data/{mode}/{run}'): + sys.path.append(f'lz_private_data/{mode}/{run}') + print(f'Successfully found mode {mode} and run {run} in cloned directory') + else: + raise RuntimeError(f'Either the cloning failed, or could not find ' + \ + f'mode {mode} and run {run} in cloned directory') From 2cbb37d8ace1b5b47fdd5a075dbffd8f32c7dafc Mon Sep 17 00:00:00 2001 From: Robert James Date: Fri, 2 Feb 2024 18:07:02 +1100 Subject: [PATCH 6/7] Let's make this simpler. --- flamedisx/lz/data.py | 68 ++++---------------------------------------- 1 file changed, 6 insertions(+), 62 deletions(-) diff --git a/flamedisx/lz/data.py b/flamedisx/lz/data.py index 5152c8875..137a16837 100644 --- a/flamedisx/lz/data.py +++ b/flamedisx/lz/data.py @@ -1,78 +1,22 @@ """Tools to get private LZ data """ -import getpass import os import os.path -import random -import string import sys import flamedisx as fd export, __all__ = fd.exporter() -# Path to the root folder of the private LZ data repository, if you have already cloned it -PATH = 'lz_private_data' - - -def ensure_token(token=None): - """Requests for token if token is not already available.""" - if token is None: - print(" - Create a token with 'read repository' permissions at " - "https://gitlab.com/-/profile/personal_access_tokens\n" - " - Save or write it down somewhere \n" - " - Type it in the prompt above\n\n" - "'Repository not found' means you didn't give the token" - " the correct permissions.\n" - "'Authentication failed' means you mistyped your username or the" - " token.\n") - # We could prompt for username/password instead, but then the password - # would be printed in plaintext if there is any problem during cloning. - user = input('Gitlab username:') - token = getpass.getpass('GitLab token: ') - return user, token - - -def clone_repo(repo_name, repo_path, user=None, token=None): - """Clones private repository (prompting for credentials)""" - fd.run_command(f'rm -r -f {repo_path}') - user, token = ensure_token() - temp_folder = ''.join(random.choices(string.ascii_lowercase, k=8)) - fd.run_command(f'git clone https://{user}:{token}' - f'@gitlab.com/{repo_name} {temp_folder}') - fd.run_command(f'mv {temp_folder}/{repo_path} .') - fd.run_command(f'rm -r -f {temp_folder}') - - @export def lz_setup(mode='tensors', run='sr1', lz_private_data_dir=None): """Update the system path to include necessary LZ private data files """ - if lz_private_data_dir is not None: - if os.path.isdir(f'{lz_private_data_dir}/{mode}/{run}'): - sys.path.append(f'{lz_private_data_dir}/{mode}/{run}') - print(f'Successfully found mode {mode} and run {run} in ' + \ - f'directory {lz_private_data_dir}') - return - else: - print(f'Error finding mode {mode} and run {run} in directory {lz_private_data_dir}') - - print('Seeing if LZ private data directory already exists') - - if os.path.isdir(f'lz_private_data/{mode}/{run}'): - sys.path.append(f'lz_private_data/{mode}/{run}') - print(f'Successfully found mode {mode} and run {run} in directory lz_private_data') - return - else: - print(f'Mode {mode} and run {run} not found in any existing directory') - - print('Cloning repo, requires LZ GitLab access token') - - clone_repo('luxzeplin/stats/LZFlameFit.git', PATH) + assert lz_private_data_dir is not None, 'Must specifcy a private data directory!' - if os.path.isdir(f'lz_private_data/{mode}/{run}'): - sys.path.append(f'lz_private_data/{mode}/{run}') - print(f'Successfully found mode {mode} and run {run} in cloned directory') + if os.path.isdir(f'{lz_private_data_dir}/{mode}/{run}'): + sys.path.append(f'{lz_private_data_dir}/{mode}/{run}') + print(f'Successfully found mode {mode} and run {run} in ' + \ + f'directory {lz_private_data_dir}') else: - raise RuntimeError(f'Either the cloning failed, or could not find ' + \ - f'mode {mode} and run {run} in cloned directory') + raise RuntimeError(f'Error finding mode {mode} and run {run} in directory {lz_private_data_dir}') From 3a713a1a63709254fc843e70cb382aba58cb4818 Mon Sep 17 00:00:00 2001 From: Robert James Date: Mon, 5 Feb 2024 20:24:08 +1100 Subject: [PATCH 7/7] Don't need any of this actually. --- flamedisx/__init__.py | 4 ---- flamedisx/lz/__init__.py | 1 - flamedisx/lz/data.py | 22 ---------------------- 3 files changed, 27 deletions(-) delete mode 100644 flamedisx/lz/__init__.py delete mode 100644 flamedisx/lz/data.py diff --git a/flamedisx/__init__.py b/flamedisx/__init__.py index fd6bf3c6b..f632b6d2e 100644 --- a/flamedisx/__init__.py +++ b/flamedisx/__init__.py @@ -37,10 +37,6 @@ # Access through fd.lux.xxx from . import lux -# LZ data access -# Access through fd.lz.xxx -from . import lz - # Custom TFP files # Access through fd.tfp_files.xxx from . import tfp_files diff --git a/flamedisx/lz/__init__.py b/flamedisx/lz/__init__.py deleted file mode 100644 index df22d8bbb..000000000 --- a/flamedisx/lz/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .data import * diff --git a/flamedisx/lz/data.py b/flamedisx/lz/data.py deleted file mode 100644 index 137a16837..000000000 --- a/flamedisx/lz/data.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Tools to get private LZ data -""" -import os -import os.path -import sys - -import flamedisx as fd -export, __all__ = fd.exporter() - - -@export -def lz_setup(mode='tensors', run='sr1', lz_private_data_dir=None): - """Update the system path to include necessary LZ private data files - """ - assert lz_private_data_dir is not None, 'Must specifcy a private data directory!' - - if os.path.isdir(f'{lz_private_data_dir}/{mode}/{run}'): - sys.path.append(f'{lz_private_data_dir}/{mode}/{run}') - print(f'Successfully found mode {mode} and run {run} in ' + \ - f'directory {lz_private_data_dir}') - else: - raise RuntimeError(f'Error finding mode {mode} and run {run} in directory {lz_private_data_dir}')