From eef40d56ac2659f20a33a009319a822d7756b07e Mon Sep 17 00:00:00 2001 From: David Kelley Date: Wed, 18 Oct 2023 17:05:45 -0700 Subject: [PATCH 01/24] true sqrt --- src/baskerville/dataset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/baskerville/dataset.py b/src/baskerville/dataset.py index a427499..a876d0c 100644 --- a/src/baskerville/dataset.py +++ b/src/baskerville/dataset.py @@ -351,9 +351,9 @@ def untransform_preds(preds, targets_df, unscale=False): preds_unclip = cs - 1 + (preds - cs + 1) ** 2 preds = np.where(preds > cs, preds_unclip, preds) - # ** 0.75 + # sqrt sqrt_mask = np.array([ss.find("_sqrt") != -1 for ss in targets_df.sum_stat]) - preds[:, sqrt_mask] = -1 + (preds[:, sqrt_mask] + 1) ** (4 / 3) + preds[:, sqrt_mask] = -1 + (preds[:, sqrt_mask] + 1) ** 2 # (4 / 3) # scale if unscale: From 153edafc8a11c0faa3fdc055566d9345bbbdcbc4 Mon Sep 17 00:00:00 2001 From: David Kelley Date: Wed, 18 Oct 2023 17:06:32 -0700 Subject: [PATCH 02/24] typo --- src/baskerville/snps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/baskerville/snps.py b/src/baskerville/snps.py index d89a6ab..dc610e9 100644 --- a/src/baskerville/snps.py +++ b/src/baskerville/snps.py @@ -314,7 +314,7 @@ def make_alt_1hot(ref_1hot, snp_seq_pos, ref_allele, alt_allele): dna.hot1_delete(alt_1hot, snp_seq_pos + 1, delete_len) else: print( - "WARNING: Delection first nt does not match: %s %s" + "WARNING: Deletion first nt does not match: %s %s" % (ref_allele, alt_allele), file=sys.stderr, ) From bace4cabf2f85af63b711a1446e6db7002058aa5 Mon Sep 17 00:00:00 2001 From: David Kelley Date: Wed, 18 Oct 2023 17:07:04 -0700 Subject: [PATCH 03/24] subset targets --- src/baskerville/scripts/hound_eval_spec.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/baskerville/scripts/hound_eval_spec.py b/src/baskerville/scripts/hound_eval_spec.py index 43d908c..2e3187b 100755 --- a/src/baskerville/scripts/hound_eval_spec.py +++ b/src/baskerville/scripts/hound_eval_spec.py @@ -45,7 +45,7 @@ def main(): parser.add_option( "-c", dest="class_min", - default=100, + default=80, type="int", help="Minimum target class size to consider [Default: %default]", ) @@ -182,6 +182,7 @@ def main(): # initialize model seqnn_model = seqnn.SeqNN(params_model) seqnn_model.restore(model_file, options.head_i) + seqnn_model.build_slice(targets_df.index) if options.step > 1: seqnn_model.step(options.step) seqnn_model.build_ensemble(options.rc, options.shifts) @@ -202,11 +203,14 @@ def main(): eval_preds.append(yh) y = y.numpy().astype("float16") + y = y[:, :, np.array(targets_df.index)] if options.step > 1: step_i = np.arange(0, eval_data.target_length, options.step) y = y[:, step_i, :] eval_targets.append(y) + gc.collect() + # flatten eval_preds = np.concatenate(eval_preds, axis=0) eval_targets = np.concatenate(eval_targets, axis=0) From 269c23ab0fb0dfcb1774a8680ee8e12d745b08cf Mon Sep 17 00:00:00 2001 From: David Kelley Date: Wed, 18 Oct 2023 17:07:16 -0700 Subject: [PATCH 04/24] single shifts --- src/baskerville/seqnn.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/baskerville/seqnn.py b/src/baskerville/seqnn.py index a00c843..c86ffeb 100644 --- a/src/baskerville/seqnn.py +++ b/src/baskerville/seqnn.py @@ -219,12 +219,13 @@ def build_embed(self, conv_layer_i: int, batch_norm: bool = True): def build_ensemble(self, ensemble_rc: bool = False, ensemble_shifts=[0]): """Build ensemble of models computing on augmented input sequences.""" - if ensemble_rc or len(ensemble_shifts) > 1: + shift_bool = len(ensemble_shifts) > 1 or ensemble_shifts[0] != 0 + if ensemble_rc or shift_bool: # sequence input sequence = tf.keras.Input(shape=(self.seq_length, 4), name="sequence") sequences = [sequence] - if len(ensemble_shifts) > 1: + if shift_bool: # generate shifted sequences sequences = layers.EnsembleShift(ensemble_shifts)(sequences) From c6df4ffc6d71339dc1f05e5fa8dd0982a0861cde Mon Sep 17 00:00:00 2001 From: lruizcalico Date: Wed, 1 Nov 2023 14:50:30 -0700 Subject: [PATCH 05/24] add grad to seqnn, clean up utils --- src/baskerville/helpers/gcs_utils.py | 60 ++- .../helpers/h5_baskerville_utils.py | 114 +++++ src/baskerville/helpers/h5_utils.py | 59 +++ src/baskerville/helpers/utils.py | 20 + src/baskerville/scripts/hound_snp.py | 20 +- src/baskerville/seqnn.py | 404 +++++++++++++++++- 6 files changed, 646 insertions(+), 31 deletions(-) create mode 100644 src/baskerville/helpers/h5_baskerville_utils.py create mode 100644 src/baskerville/helpers/utils.py diff --git a/src/baskerville/helpers/gcs_utils.py b/src/baskerville/helpers/gcs_utils.py index 72a853e..35aad61 100644 --- a/src/baskerville/helpers/gcs_utils.py +++ b/src/baskerville/helpers/gcs_utils.py @@ -64,6 +64,43 @@ def download_from_gcs(gcs_path: str, local_path: str, bytes=True) -> None: storage_client.download_blob_to_file(gcs_path, o) +def download_folder_from_gcs(gcs_dir: str, local_dir: str, bytes=True) -> None: + """ + Downloads a whole folder from GCS + Args: + gcs_dir: string path to GCS folder to download + local_dir: string path to download to + bytes: boolean flag indicating if gcs file contains bytes + + Returns: None + + """ + storage_client = _get_storage_client() + write_mode = "wb" if bytes else "w" + if not is_gcs_path(gcs_dir): + raise ValueError(f"gcs_dir is not a valid GCS path: {gcs_dir}") + bucket_name, gcs_object_prefix = split_gcs_uri(gcs_dir) + # Get the bucket from the client. + bucket = storage_client.bucket(bucket_name) + + # Ensure local folder exists + if not os.path.exists(local_dir): + os.makedirs(local_dir) + # List all blobs with the given prefix (i.e., folder path). + blobs = bucket.list_blobs(prefix=gcs_object_prefix) + # Download each blob. + for blob in blobs: + # Compute the full path to which we'll download the blob. + blob_rel_path = os.path.relpath(blob.name, gcs_object_prefix) + local_blob_path = os.path.join(local_dir, blob_rel_path) + + # Ensure the local directory structure exists + local_blob_dir = os.path.dirname(local_blob_path) + if not os.path.exists(local_blob_dir): + os.makedirs(local_blob_dir) + download_from_gcs(join(gcs_dir, blob_rel_path), local_blob_path, bytes=bytes) + + def sync_dir_to_gcs( local_dir: str, gcs_dir: str, verbose=False, recursive=False ) -> None: @@ -120,7 +157,7 @@ def upload_folder_gcs(local_dir: str, gcs_dir: str) -> None: """ storage_client = _get_storage_client() bucket_name = gcs_dir.split("//")[1].split("/")[0] - gcs_object_prefix = gcs_dir.split("//")[1].split("/")[1] + gcs_object_prefix = "/".join(gcs_dir.split("//")[1].split("/")[1:]) local_prefix = local_dir.split("/")[-1] bucket = storage_client.bucket(bucket_name) for filename in os.listdir(local_dir): @@ -142,7 +179,7 @@ def upload_file_gcs(local_path: str, gcs_path: str, bytes=True) -> None: storage_client = _get_storage_client() bucket_name = gcs_path.split("//")[1].split("/")[0] bucket = storage_client.bucket(bucket_name) - gcs_object_prefix = gcs_path.split("//")[1].split("/")[1] + gcs_object_prefix = "/".join(gcs_path.split("//")[1].split("/")[1:]) filename = local_path.split("/")[-1] blob = bucket.blob(f"{gcs_object_prefix}/{filename}") blob.upload_from_filename(local_path) @@ -207,18 +244,25 @@ def get_filename_in_dir(files_dir: str, recursive: bool = False) -> List[str]: return files -def download_rename_inputs(filepath: str, temp_dir: str) -> str: +def download_rename_inputs(filepath: str, temp_dir: str, is_dir: bool = False) -> str: """ Download file from gcs to local dir Args: filepath: GCS Uri follows the format gs://$BUCKET_NAME/OBJECT_NAME + temp_dir: local dir to download to + is_dir: boolean flag indicating if the filepath is a directory Returns: new filepath in the local machine """ - _, filename = split_gcs_uri(filepath) - if "/" in filename: - filename = filename.split("/")[-1] - download_from_gcs(filepath, f"{temp_dir}/{filename}") - return f"{temp_dir}/{filename}" + if is_dir: + download_folder_from_gcs(filepath, temp_dir) + dir_name = filepath.split("/")[-1] + return temp_dir + else: + _, filename = split_gcs_uri(filepath) + if "/" in filename: + filename = filename.split("/")[-1] + download_from_gcs(filepath, f"{temp_dir}/{filename}") + return f"{temp_dir}/{filename}" def gcs_file_exist(gcs_path: str) -> bool: diff --git a/src/baskerville/helpers/h5_baskerville_utils.py b/src/baskerville/helpers/h5_baskerville_utils.py new file mode 100644 index 0000000..ddbd4b5 --- /dev/null +++ b/src/baskerville/helpers/h5_baskerville_utils.py @@ -0,0 +1,114 @@ +import h5py +import numpy as np +import argparse + + +def collect_h5(file_name, out_dir, num_procs) -> None: + """ + Concatenate all output files together + Args: + file_name: filename containing output (sad.h5) + out_dir: directory containing output files + num_procs: number of processes + Returns: None + """ + # count variants + num_variants = 0 + for pi in range(num_procs): + # open job + job_h5_file = "%s/job%d/%s" % (out_dir, pi, file_name) + job_h5_open = h5py.File(job_h5_file, "r") + num_variants += len(job_h5_open["snp"]) + job_h5_open.close() + + # initialize final h5 + final_h5_file = "%s/%s" % (out_dir, file_name) + final_h5_open = h5py.File(final_h5_file, "w") + + # keep dict for string values + final_strings = {} + + job0_h5_file = "%s/job0/%s" % (out_dir, file_name) + job0_h5_open = h5py.File(job0_h5_file, "r") + for key in job0_h5_open.keys(): + if key in ["percentiles", "target_ids", "target_labels"]: + # copy + final_h5_open.create_dataset(key, data=job0_h5_open[key]) + + elif key[-4:] == "_pct": + values = np.zeros(job0_h5_open[key].shape) + final_h5_open.create_dataset(key, data=values) + + elif job0_h5_open[key].dtype.char == "S": + final_strings[key] = [] + + elif job0_h5_open[key].ndim == 1: + final_h5_open.create_dataset( + key, shape=(num_variants,), dtype=job0_h5_open[key].dtype + ) + + else: + num_targets = job0_h5_open[key].shape[1] + final_h5_open.create_dataset( + key, shape=(num_variants, num_targets), dtype=job0_h5_open[key].dtype + ) + + job0_h5_open.close() + + # set values + vi = 0 + for pi in range(num_procs): + # open job + job_h5_file = "%s/job%d/%s" % (out_dir, pi, file_name) + job_h5_open = h5py.File(job_h5_file, "r") + + # append to final + for key in job_h5_open.keys(): + if key in ["percentiles", "target_ids", "target_labels"]: + # once is enough + pass + + elif key[-4:] == "_pct": + # average + u_k1 = np.array(final_h5_open[key]) + x_k = np.array(job_h5_open[key]) + final_h5_open[key][:] = u_k1 + (x_k - u_k1) / (pi + 1) + + else: + if job_h5_open[key].dtype.char == "S": + final_strings[key] += list(job_h5_open[key]) + else: + job_variants = job_h5_open[key].shape[0] + try: + final_h5_open[key][vi : vi + job_variants] = job_h5_open[key] + except TypeError as e: + raise Exception( + f"{job_h5_file} ${key} has the wrong shape. Remove this file and rerun, {e}" + ) + + vi += job_variants + job_h5_open.close() + + # create final string datasets + for key in final_strings: + final_h5_open.create_dataset(key, data=np.array(final_strings[key], dtype="S")) + + final_h5_open.close() + + +def main(): + parser = argparse.ArgumentParser(description="Process and collect h5 files.") + + parser.add_argument("file_name", type=str, help="Path to the input file.") + parser.add_argument( + "out_dir", type=str, help="Output directory for processed data." + ) + parser.add_argument("num_procs", type=int, help="Number of processes to use.") + + args = parser.parse_args() + + collect_h5(args.file_name, args.out_dir, args.num_procs) + + +if __name__ == "__main__": + main() diff --git a/src/baskerville/helpers/h5_utils.py b/src/baskerville/helpers/h5_utils.py index 11b91b5..c8c3eb6 100644 --- a/src/baskerville/helpers/h5_utils.py +++ b/src/baskerville/helpers/h5_utils.py @@ -87,3 +87,62 @@ def collect_h5(file_name, out_dir, num_procs): final_h5_open.create_dataset(key, data=np.array(final_strings[key], dtype="S")) final_h5_open.close() + + +def collect_h5_borzoi(out_dir, num_procs, sad_stat) -> None: + h5_file = "scores_f0c0.h5" + + # count sequences + num_seqs = 0 + for pi in range(num_procs): + # open job + job_h5_file = "%s/job%d/%s" % (out_dir, pi, h5_file) + job_h5_open = h5py.File(job_h5_file, "r") + num_seqs += job_h5_open[sad_stat].shape[0] + seq_len = job_h5_open[sad_stat].shape[1] + num_targets = job_h5_open[sad_stat].shape[-1] + job_h5_open.close() + + # initialize final h5 + final_h5_file = "%s/%s" % (out_dir, h5_file) + final_h5_open = h5py.File(final_h5_file, "w") + + # keep dict for string values + final_strings = {} + + job0_h5_file = "%s/job0/%s" % (out_dir, h5_file) + job0_h5_open = h5py.File(job0_h5_file, "r") + for key in job0_h5_open.keys(): + key_shape = list(job0_h5_open[key].shape) + key_shape[0] = num_seqs + key_shape = tuple(key_shape) + if job0_h5_open[key].dtype.char == "S": + final_strings[key] = [] + else: + final_h5_open.create_dataset( + key, shape=key_shape, dtype=job0_h5_open[key].dtype + ) + + # set values + si = 0 + for pi in range(num_procs): + # open job + job_h5_file = "%s/job%d/%s" % (out_dir, pi, h5_file) + job_h5_open = h5py.File(job_h5_file, "r") + + # append to final + for key in job_h5_open.keys(): + job_seqs = job_h5_open[key].shape[0] + if job_h5_open[key].dtype.char == "S": + final_strings[key] += list(job_h5_open[key]) + else: + final_h5_open[key][si : si + job_seqs] = job_h5_open[key] + + job_h5_open.close() + si += job_seqs + + # create final string datasets + for key in final_strings: + final_h5_open.create_dataset(key, data=np.array(final_strings[key], dtype="S")) + + final_h5_open.close() diff --git a/src/baskerville/helpers/utils.py b/src/baskerville/helpers/utils.py new file mode 100644 index 0000000..d1549dc --- /dev/null +++ b/src/baskerville/helpers/utils.py @@ -0,0 +1,20 @@ +import pickle + + +def load_extra_options(options_pkl_file, options): + """ + Args: + options_pkl_file: option file + options: existing options from command line + Returns: + options: updated options + """ + options_pkl = open(options_pkl_file, "rb") + new_options = pickle.load(options_pkl) + new_option_attrs = vars(new_options) + # Assuming 'options' is the existing options object + # Update the existing options with the new attributes + for attr_name, attr_value in new_option_attrs.items(): + setattr(options, attr_name, attr_value) + options_pkl.close() + return options diff --git a/src/baskerville/scripts/hound_snp.py b/src/baskerville/scripts/hound_snp.py index f913060..cf31a5d 100755 --- a/src/baskerville/scripts/hound_snp.py +++ b/src/baskerville/scripts/hound_snp.py @@ -25,6 +25,7 @@ upload_folder_gcs, download_rename_inputs, ) +from baskerville.helpers.utils import load_extra_options """ hound_snp.py @@ -211,25 +212,6 @@ def main(): shutil.rmtree(temp_dir) # clean up temp dir -def load_extra_options(options_pkl_file, options): - """ - Args: - options_pkl_file: option file - options: existing options from command line - Returns: - options: updated options - """ - options_pkl = open(options_pkl_file, "rb") - new_options = pickle.load(options_pkl) - new_option_attrs = vars(new_options) - # Assuming 'options' is the existing options object - # Update the existing options with the new attributes - for attr_name, attr_value in new_option_attrs.items(): - setattr(options, attr_name, attr_value) - options_pkl.close() - return options - - ################################################################################ # __main__ ################################################################################ diff --git a/src/baskerville/seqnn.py b/src/baskerville/seqnn.py index a00c843..36377fd 100644 --- a/src/baskerville/seqnn.py +++ b/src/baskerville/seqnn.py @@ -19,7 +19,7 @@ from natsort import natsorted import numpy as np import tensorflow as tf - +import gc from baskerville import blocks from baskerville import layers from baskerville import metrics @@ -219,12 +219,13 @@ def build_embed(self, conv_layer_i: int, batch_norm: bool = True): def build_ensemble(self, ensemble_rc: bool = False, ensemble_shifts=[0]): """Build ensemble of models computing on augmented input sequences.""" - if ensemble_rc or len(ensemble_shifts) > 1: + shift_bool = len(ensemble_shifts) > 1 or ensemble_shifts[0] != 0 + if ensemble_rc or shift_bool: # sequence input sequence = tf.keras.Input(shape=(self.seq_length, 4), name="sequence") sequences = [sequence] - if len(ensemble_shifts) > 1: + if shift_bool: # generate shifted sequences sequences = layers.EnsembleShift(ensemble_shifts)(sequences) @@ -397,6 +398,401 @@ def get_conv_weights(self, conv_layer_i=0): return weights def gradients( + self, + seq_1hot, + head_i=None, + target_slice=None, + pos_slice=None, + pos_mask=None, + pos_slice_denom=None, + pos_mask_denom=None, + chunk_size=None, + batch_size=1, + track_scale=1.0, + track_transform=1.0, + clip_soft=None, + pseudo_count=0.0, + no_transform=False, + use_mean=False, + use_ratio=False, + use_logodds=False, + subtract_avg=True, + input_gate=True, + smooth_grad=False, + n_samples=5, + sample_prob=0.875, + dtype="float16", + ): + """Compute input gradients for sequences (GPU-friendly).""" + + # start time + t0 = time.time() + + # choose model + if self.ensemble is not None: + model = self.ensemble + elif head_i is not None: + model = self.models[head_i] + else: + model = self.model + + # verify tensor shape(s) + seq_1hot = seq_1hot.astype("float32") + target_slice = np.array(target_slice).astype("int32") + pos_slice = np.array(pos_slice).astype("int32") + + # convert constants to tf tensors + track_scale = tf.constant(track_scale, dtype=tf.float32) + track_transform = tf.constant(track_transform, dtype=tf.float32) + if clip_soft is not None: + clip_soft = tf.constant(clip_soft, dtype=tf.float32) + pseudo_count = tf.constant(pseudo_count, dtype=tf.float32) + + if pos_mask is not None: + pos_mask = np.array(pos_mask).astype("float32") + + if use_ratio and pos_slice_denom is not None: + pos_slice_denom = np.array(pos_slice_denom).astype("int32") + + if pos_mask_denom is not None: + pos_mask_denom = np.array(pos_mask_denom).astype("float32") + + if len(seq_1hot.shape) < 3: + seq_1hot = seq_1hot[None, ...] + + if len(target_slice.shape) < 2: + target_slice = target_slice[None, ...] + + if len(pos_slice.shape) < 2: + pos_slice = pos_slice[None, ...] + + if pos_mask is not None and len(pos_mask.shape) < 2: + pos_mask = pos_mask[None, ...] + + if use_ratio and pos_slice_denom is not None and len(pos_slice_denom.shape) < 2: + pos_slice_denom = pos_slice_denom[None, ...] + + if pos_mask_denom is not None and len(pos_mask_denom.shape) < 2: + pos_mask_denom = pos_mask_denom[None, ...] + + # chunk parameters + num_chunks = 1 + if chunk_size is None: + chunk_size = seq_1hot.shape[0] + else: + num_chunks = int(np.ceil(seq_1hot.shape[0] / chunk_size)) + + # loop over chunks + grad_chunks = [] + for ci in range(num_chunks): + # collect chunk + seq_1hot_chunk = seq_1hot[ci * chunk_size : (ci + 1) * chunk_size, ...] + target_slice_chunk = target_slice[ + ci * chunk_size : (ci + 1) * chunk_size, ... + ] + pos_slice_chunk = pos_slice[ci * chunk_size : (ci + 1) * chunk_size, ...] + + pos_mask_chunk = None + if pos_mask is not None: + pos_mask_chunk = pos_mask[ci * chunk_size : (ci + 1) * chunk_size, ...] + + pos_slice_denom_chunk = None + pos_mask_denom_chunk = None + if use_ratio and pos_slice_denom is not None: + pos_slice_denom_chunk = pos_slice_denom[ + ci * chunk_size : (ci + 1) * chunk_size, ... + ] + + if pos_mask_denom is not None: + pos_mask_denom_chunk = pos_mask_denom[ + ci * chunk_size : (ci + 1) * chunk_size, ... + ] + + actual_chunk_size = seq_1hot_chunk.shape[0] + + # sample noisy (discrete) perturbations of the input pattern chunk + if smooth_grad: + seq_1hot_chunk_corrupted = np.repeat( + np.copy(seq_1hot_chunk), n_samples, axis=0 + ) + + for example_ix in range(seq_1hot_chunk.shape[0]): + for sample_ix in range(n_samples): + corrupt_index = np.nonzero( + np.random.rand(seq_1hot_chunk.shape[1]) >= sample_prob + )[0] + + rand_nt_index = np.random.choice( + [0, 1, 2, 3], size=(corrupt_index.shape[0],) + ) + + seq_1hot_chunk_corrupted[ + example_ix * n_samples + sample_ix, corrupt_index, : + ] = 0.0 + seq_1hot_chunk_corrupted[ + example_ix * n_samples + sample_ix, + corrupt_index, + rand_nt_index, + ] = 1.0 + + seq_1hot_chunk = seq_1hot_chunk_corrupted + target_slice_chunk = np.repeat( + np.copy(target_slice_chunk), n_samples, axis=0 + ) + pos_slice_chunk = np.repeat(np.copy(pos_slice_chunk), n_samples, axis=0) + + if pos_mask is not None: + pos_mask_chunk = np.repeat( + np.copy(pos_mask_chunk), n_samples, axis=0 + ) + + if use_ratio and pos_slice_denom is not None: + pos_slice_denom_chunk = np.repeat( + np.copy(pos_slice_denom_chunk), n_samples, axis=0 + ) + + if pos_mask_denom is not None: + pos_mask_denom_chunk = np.repeat( + np.copy(pos_mask_denom_chunk), n_samples, axis=0 + ) + + # convert to tf tensors + seq_1hot_chunk = tf.convert_to_tensor(seq_1hot_chunk, dtype=tf.float32) + target_slice_chunk = tf.convert_to_tensor( + target_slice_chunk, dtype=tf.int32 + ) + pos_slice_chunk = tf.convert_to_tensor(pos_slice_chunk, dtype=tf.int32) + + if pos_mask is not None: + pos_mask_chunk = tf.convert_to_tensor(pos_mask_chunk, dtype=tf.float32) + + if use_ratio and pos_slice_denom is not None: + pos_slice_denom_chunk = tf.convert_to_tensor( + pos_slice_denom_chunk, dtype=tf.int32 + ) + + if pos_mask_denom is not None: + pos_mask_denom_chunk = tf.convert_to_tensor( + pos_mask_denom_chunk, dtype=tf.float32 + ) + + # batching parameters + num_batches = int( + np.ceil( + actual_chunk_size * (n_samples if smooth_grad else 1) / batch_size + ) + ) + + # loop over batches + grad_batches = [] + for bi in range(num_batches): + # collect batch + seq_1hot_batch = seq_1hot_chunk[ + bi * batch_size : (bi + 1) * batch_size, ... + ] + target_slice_batch = target_slice_chunk[ + bi * batch_size : (bi + 1) * batch_size, ... + ] + pos_slice_batch = pos_slice_chunk[ + bi * batch_size : (bi + 1) * batch_size, ... + ] + + pos_mask_batch = None + if pos_mask is not None: + pos_mask_batch = pos_mask_chunk[ + bi * batch_size : (bi + 1) * batch_size, ... + ] + + pos_slice_denom_batch = None + pos_mask_denom_batch = None + if use_ratio and pos_slice_denom is not None: + pos_slice_denom_batch = pos_slice_denom_chunk[ + bi * batch_size : (bi + 1) * batch_size, ... + ] + + if pos_mask_denom is not None: + pos_mask_denom_batch = pos_mask_denom_chunk[ + bi * batch_size : (bi + 1) * batch_size, ... + ] + + grad_batch = ( + self.gradients_func( + model, + seq_1hot_batch, + target_slice_batch, + pos_slice_batch, + pos_mask_batch, + pos_slice_denom_batch, + pos_mask_denom_batch, + track_scale, + track_transform, + clip_soft, + pseudo_count, + no_transform, + use_mean, + use_ratio, + use_logodds, + subtract_avg, + input_gate, + ) + .numpy() + .astype(dtype) + ) + + grad_batches.append(grad_batch) + + # concat gradient batches + grads = np.concatenate(grad_batches, axis=0) + + # aggregate noisy gradient perturbations + if smooth_grad: + grads_smoothed = np.zeros( + (grads.shape[0] // n_samples, grads.shape[1], grads.shape[2]), + dtype="float32", + ) + + for example_ix in range(grads_smoothed.shape[0]): + for sample_ix in range(n_samples): + grads_smoothed[example_ix, ...] += grads[ + example_ix * n_samples + sample_ix, ... + ] + + grads = grads_smoothed / float(n_samples) + grads = grads.astype(dtype) + + grad_chunks.append(grads) + + # collect garbage + gc.collect() + + # concat gradient chunks + grads = np.concatenate(grad_chunks, axis=0) + + # aggregate and broadcast to original input pattern + if input_gate: + grads = np.sum(grads, axis=-1, keepdims=True) * seq_1hot + + print("Completed gradient computation in %ds" % (time.time() - t0)) + + return grads + + @tf.function + def gradients_func( + self, + model, + seq_1hot, + target_slice, + pos_slice, + pos_mask=None, + pos_slice_denom=None, + pos_mask_denom=True, + track_scale=1.0, + track_transform=1.0, + clip_soft=None, + pseudo_count=0.0, + no_transform=False, + use_mean=False, + use_ratio=False, + use_logodds=False, + subtract_avg=True, + input_gate=True, + ): + with tf.GradientTape() as tape: + tape.watch(seq_1hot) + + # predict + preds = tf.gather( + model(seq_1hot, training=False), target_slice, axis=-1, batch_dims=1 + ) + + if not no_transform: + # undo scale + preds = preds / track_scale + + # undo soft_clip + if clip_soft is not None: + preds = tf.where( + preds > clip_soft, (preds - clip_soft) ** 2 + clip_soft, preds + ) + + # undo sqrt + preds = preds ** (1.0 / track_transform) + + # aggregate over tracks (average) + preds = tf.reduce_mean(preds, axis=-1) + + # slice specified positions + preds_slice = tf.gather(preds, pos_slice, axis=-1, batch_dims=1) + if pos_mask is not None: + preds_slice = preds_slice * pos_mask + + # slice denominator positions + if use_ratio and pos_slice_denom is not None: + preds_slice_denom = tf.gather( + preds, pos_slice_denom, axis=-1, batch_dims=1 + ) + if pos_mask_denom is not None: + preds_slice_denom = preds_slice_denom * pos_mask_denom + + # aggregate over positions + if not use_mean: + preds_agg = tf.reduce_sum(preds_slice, axis=-1) + if use_ratio and pos_slice_denom is not None: + preds_agg_denom = tf.reduce_sum(preds_slice_denom, axis=-1) + else: + if pos_mask is not None: + preds_agg = tf.reduce_sum(preds_slice, axis=-1) / tf.reduce_sum( + pos_mask, axis=-1 + ) + else: + preds_agg = tf.reduce_mean(preds_slice, axis=-1) + + if use_ratio and pos_slice_denom is not None: + if pos_mask_denom is not None: + preds_agg_denom = tf.reduce_sum( + preds_slice_denom, axis=-1 + ) / tf.reduce_sum(pos_mask_denom, axis=-1) + else: + preds_agg_denom = tf.reduce_mean(preds_slice_denom, axis=-1) + + # compute final statistic to take gradient of + if no_transform: + score_ratios = preds_agg + elif not use_ratio: + score_ratios = tf.math.log(preds_agg + pseudo_count + 1e-6) + else: + if not use_logodds: + score_ratios = tf.math.log( + (preds_agg + pseudo_count) / (preds_agg_denom + pseudo_count) + + 1e-6 + ) + else: + score_ratios = tf.math.log( + ((preds_agg + pseudo_count) / (preds_agg_denom + pseudo_count)) + / ( + 1.0 + - ( + (preds_agg + pseudo_count) + / (preds_agg_denom + pseudo_count) + ) + ) + + 1e-6 + ) + + # compute gradient + grads = tape.gradient(score_ratios, seq_1hot) + + # zero mean each position + if subtract_avg: + grads = grads - tf.reduce_mean(grads, axis=-1, keepdims=True) + + # multiply by input + if input_gate: + grads = grads * seq_1hot + + return grads + + def gradients_orig( self, seq_1hot, head_i=None, pos_slice=None, batch_size=8, dtype="float16" ): """Compute input gradients for each task. @@ -463,7 +859,7 @@ def gradients( return grads @tf.function - def gradients_func(self, model, seq_1hot, pos_slice): + def gradients_func_orig(self, model, seq_1hot, pos_slice): """Compute input gradients for each task. Args: From 9db59cad5d39e1f0952d3f40c1d7b0b145a34e0a Mon Sep 17 00:00:00 2001 From: David Kelley Date: Thu, 2 Nov 2023 17:04:37 -0700 Subject: [PATCH 06/24] unet block renaming --- src/baskerville/blocks.py | 105 +++++------------------------------- src/baskerville/seqnn.py | 2 +- tests/data/eval/params.json | 10 ++-- tests/data/params.json | 10 ++-- 4 files changed, 25 insertions(+), 102 deletions(-) diff --git a/src/baskerville/blocks.py b/src/baskerville/blocks.py index 1ba7028..3330ea0 100644 --- a/src/baskerville/blocks.py +++ b/src/baskerville/blocks.py @@ -445,7 +445,7 @@ def conv_next( return current -def fpn_unet( +def unet_conv( inputs, unet_repr, activation="relu", @@ -456,6 +456,7 @@ def fpn_unet( bn_momentum=0.99, kernel_size=1, kernel_initializer="he_normal", + upsample_conv=False, ): """Construct a feature pyramid network block. @@ -468,6 +469,7 @@ def fpn_unet( dropout: Dropout rate probability norm_type: Apply batch or layer normalization bn_momentum: BatchNorm momentum + upsample_conv: Conv1D the upsampled input path Returns: [batch_size, seq_length, features] output sequence @@ -499,11 +501,12 @@ def fpn_unet( filters = inputs.shape[-1] # dense - current1 = tf.keras.layers.Dense( - units=filters, - kernel_regularizer=tf.keras.regularizers.l2(l2_scale), - kernel_initializer=kernel_initializer, - )(current1) + if upsample_conv: + current1 = tf.keras.layers.Dense( + units=filters, + kernel_regularizer=tf.keras.regularizers.l2(l2_scale), + kernel_initializer=kernel_initializer, + )(current1) current2 = tf.keras.layers.Dense( units=filters, kernel_regularizer=tf.keras.regularizers.l2(l2_scale), @@ -514,7 +517,6 @@ def fpn_unet( current1 = tf.keras.layers.UpSampling1D(size=stride)(current1) # add - # current2 = layers.Scale(initializer='ones')(current2) current = tf.keras.layers.Add()([current1, current2]) # normalize? @@ -536,83 +538,7 @@ def fpn_unet( return current -def fpn1_unet( - inputs, - unet_repr, - activation="relu", - stride=2, - l2_scale=0, - dropout=0, - norm_type=None, - bn_momentum=0.99, - kernel_size=1, - kernel_initializer="he_normal", -): - """Construct a feature pyramid network block. - - Args: - inputs: [batch_size, seq_length, features] input sequence - kernel_size: Conv1D kernel_size - activation: relu/gelu/etc - stride: UpSample stride - l2_scale: L2 regularization weight. - dropout: Dropout rate probability - norm_type: Apply batch or layer normalization - bn_momentum: BatchNorm momentum - - Returns: - [batch_size, seq_length, features] output sequence - """ - - # variables - current1 = inputs - current2 = unet_repr - - # normalize - if norm_type == "batch-sync": - current1 = tf.keras.layers.BatchNormalization( - momentum=bn_momentum, synchronized=True - )(current1) - elif norm_type == "batch": - current1 = tf.keras.layers.BatchNormalization(momentum=bn_momentum)(current1) - elif norm_type == "layer": - current1 = tf.keras.layers.LayerNormalization()(current1) - - # activate - current1 = layers.activate(current1, activation) - # current2 = layers.activate(current2, activation) - - # dense - current1 = tf.keras.layers.Dense( - units=unet_repr.shape[-1], - kernel_regularizer=tf.keras.regularizers.l2(l2_scale), - kernel_initializer=kernel_initializer, - )(current1) - - # upsample - current1 = tf.keras.layers.UpSampling1D(size=stride)(current1) - - # add - current2 = layers.Scale(initializer="ones")(current2) - current = tf.keras.layers.Add()([current1, current2]) - - # convolution - current = tf.keras.layers.SeparableConv1D( - filters=unet_repr.shape[-1], - kernel_size=kernel_size, - padding="same", - kernel_regularizer=tf.keras.regularizers.l2(l2_scale), - kernel_initializer=kernel_initializer, - )(current) - - # dropout - if dropout > 0: - current = tf.keras.layers.Dropout(dropout)(current) - - return current - - -def upsample_unet( +def unet_concat( inputs, unet_repr, activation="relu", @@ -774,11 +700,6 @@ def tconv_nac( return current -def concat_unet(inputs, unet_repr, **kwargs): - current = tf.keras.layers.Concatenate()([inputs, unet_repr]) - return current - - def conv_block_2d( inputs, filters=128, @@ -2040,7 +1961,6 @@ def final( "center_average": center_average, "concat_dist_2d": concat_dist_2d, "concat_position": concat_position, - "concat_unet": concat_unet, "conv_block": conv_block, "conv_dna": conv_dna, "conv_nac": conv_nac, @@ -2067,10 +1987,9 @@ def final( "tconv_nac": tconv_nac, "transformer": transformer, "transformer_tower": transformer_tower, + "unet_conv": unet_conv, + "unet_concat": unet_concat, "upper_tri": upper_tri, - "fpn_unet": fpn_unet, - "fpn1_unet": fpn1_unet, - "upsample_unet": upsample_unet, "wheeze_excite": wheeze_excite, } diff --git a/src/baskerville/seqnn.py b/src/baskerville/seqnn.py index c86ffeb..bcffaf0 100644 --- a/src/baskerville/seqnn.py +++ b/src/baskerville/seqnn.py @@ -99,7 +99,7 @@ def build_block(self, current, block_params): block_args["reprs"] = self.reprs # U-net helper - if block_name[-5:] == "_unet": + if block_name.startswith("unet_"): # find matching representation unet_repr = None for seq_repr in reversed(self.reprs[:-1]): diff --git a/tests/data/eval/params.json b/tests/data/eval/params.json index 7387223..2decd6f 100644 --- a/tests/data/eval/params.json +++ b/tests/data/eval/params.json @@ -54,12 +54,14 @@ "repeat": 2 }, { - "name": "fpn_unet", - "kernel_size": 3 + "name": "unet_conv", + "kernel_size": 3, + "upsample_conv": true }, { - "name": "fpn_unet", - "kernel_size": 3 + "name": "unet_conv", + "kernel_size": 3, + "upsample_conv": true }, { "name": "Cropping1D", diff --git a/tests/data/params.json b/tests/data/params.json index 24d3d0a..34ac510 100644 --- a/tests/data/params.json +++ b/tests/data/params.json @@ -54,12 +54,14 @@ "repeat": 1 }, { - "name": "fpn_unet", - "kernel_size": 3 + "name": "unet_conv", + "kernel_size": 3, + "upsample_conv": true }, { - "name": "fpn_unet", - "kernel_size": 3 + "name": "unet_conv", + "kernel_size": 3, + "upsample_conv": true }, { "name": "Cropping1D", From 38c874cac76e4d55d707d99c221ce4c4d5e1f579 Mon Sep 17 00:00:00 2001 From: David Kelley Date: Thu, 9 Nov 2023 14:16:07 -0800 Subject: [PATCH 07/24] D2 scores within shift before averaging; compensation shifts --- src/baskerville/snps.py | 160 ++++++++++++++++++++++++++-------------- src/baskerville/vcf.py | 4 + 2 files changed, 108 insertions(+), 56 deletions(-) diff --git a/src/baskerville/snps.py b/src/baskerville/snps.py index dc610e9..7286ebb 100644 --- a/src/baskerville/snps.py +++ b/src/baskerville/snps.py @@ -68,7 +68,10 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): seqnn_model.build_slice(targets_df.index) if sum_length: seqnn_model.build_sad() - seqnn_model.build_ensemble(options.rc, options.shifts) + seqnn_model.build_ensemble(options.rc) + + # shift outside seqnn + num_shifts = len(options.shifts) targets_length = seqnn_model.target_lengths[0] num_targets = seqnn_model.num_targets() @@ -128,7 +131,7 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): # setup output scores_out = initialize_output_h5( - options.out_dir, options.snp_stats, snps, targets_length, targets_strand_df + options.out_dir, options.snp_stats, snps, targets_length, targets_strand_df, num_shifts ) # SNP index @@ -136,46 +139,74 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): for sc in tqdm(snp_clusters): snp_1hot_list = sc.get_1hots(genome_open) + ref_1hot = np.expand_dims(snp_1hot_list[0], axis=0) # predict reference - ref_1hot = np.expand_dims(snp_1hot_list[0], axis=0) - ref_preds = seqnn_model(ref_1hot)[0] + ref_preds = [] + for shift in options.shifts: + ref_1hot_shift = dna.hot1_augment(ref_1hot, shift=shift) + ref_preds_shift = seqnn_model(ref_1hot_shift)[0] - # untransform predictions - if options.targets_file is not None: - if options.untransform_old: - ref_preds = dataset.untransform_preds1(ref_preds, targets_df) - else: - ref_preds = dataset.untransform_preds(ref_preds, targets_df) + # untransform predictions + if options.targets_file is not None: + if options.untransform_old: + ref_preds_shift = dataset.untransform_preds1(ref_preds_shift, targets_df) + else: + ref_preds_shift = dataset.untransform_preds(ref_preds_shift, targets_df) + + # sum strand pairs + if strand_transform is not None: + ref_preds_shift = ref_preds_shift * strand_transform - # sum strand pairs - if strand_transform is not None: - ref_preds = ref_preds * strand_transform + # save shift prediction + ref_preds.append(ref_preds_shift) + ref_preds = np.array(ref_preds) + ai = 0 for alt_1hot in snp_1hot_list[1:]: alt_1hot = np.expand_dims(alt_1hot, axis=0) + # add compensation shifts for indels + indel_size = sc.snps[ai].indel_size() + if indel_size == 0: + alt_shifts = options.shifts + else: + # repeat reference predictions + ref_preds = np.repeat(ref_preds, 2, axis=0) + + # add compensation shifts + alt_shifts = [] + for shift in options.shifts: + alt_shifts.append(shift) + alt_shifts.append(shift - indel_size) + # predict alternate - alt_preds = seqnn_model(alt_1hot)[0] + alt_preds = [] + for shift in alt_shifts: + alt_1hot_shift = dna.hot1_augment(alt_1hot, shift=shift) + alt_preds_shift = seqnn_model(alt_1hot_shift)[0] - # untransform predictions - if options.targets_file is not None: - if options.untransform_old: - alt_preds = dataset.untransform_preds1(alt_preds, targets_df) - else: - alt_preds = dataset.untransform_preds(alt_preds, targets_df) + # untransform predictions + if options.targets_file is not None: + if options.untransform_old: + alt_preds_shift = dataset.untransform_preds1(alt_preds_shift, targets_df) + else: + alt_preds_shift = dataset.untransform_preds(alt_preds_shift, targets_df) - # sum strand pairs - if strand_transform is not None: - alt_preds = alt_preds * strand_transform + # sum strand pairs + if strand_transform is not None: + alt_preds_shift = alt_preds_shift * strand_transform + + # save shift prediction + alt_preds.append(alt_preds_shift) # flip reference and alternate if snps[si].flipped: - rp_snp = alt_preds - ap_snp = ref_preds + rp_snp = np.array(alt_preds) + ap_snp = np.array(ref_preds) else: - rp_snp = ref_preds - ap_snp = alt_preds + rp_snp = np.array(ref_preds) + ap_snp = np.array(alt_preds) # write SNP if sum_length: @@ -222,7 +253,7 @@ def cluster_snps(snps, seq_len: int, center_pct: float): return snp_clusters -def initialize_output_h5(out_dir, snp_stats, snps, targets_length, targets_df): +def initialize_output_h5(out_dir, snp_stats, snps, targets_length, targets_df, num_shifts): """Initialize an output HDF5 file for SAD stats. Args: @@ -230,7 +261,8 @@ def initialize_output_h5(out_dir, snp_stats, snps, targets_length, targets_df): snp_stats [str]: List of SAD stats to compute. snps [SNP]: List of SNPs. targets_length (int): Targets' sequence length - targets_df (pd.DataFrame): Targets AataFrame. + targets_df (pd.DataFrame): Targets DataFrame. + num_shifts (int): Number of shifts. """ num_targets = targets_df.shape[0] @@ -275,7 +307,7 @@ def initialize_output_h5(out_dir, snp_stats, snps, targets_length, targets_df): for snp_stat in snp_stats: if snp_stat in ["REF", "ALT"]: scores_out.create_dataset( - snp_stat, shape=(num_snps, targets_length, num_targets), dtype="float16" + snp_stat, shape=(num_snps, num_shifts, targets_length, num_targets), dtype="float16" ) else: scores_out.create_dataset( @@ -407,7 +439,8 @@ def write_snp(ref_preds_sum, alt_preds_sum, scores_out, si, snp_stats): # compare reference to alternative via mean subtraction if "SAD" in snp_stats: sad = alt_preds_sum - ref_preds_sum - scores_out["SAD"][si, :] = sad.astype("float16") + sad = sad.mean(axis=0) + scores_out["SAD"][si] = sad.astype("float16") def write_snp_len(ref_preds, alt_preds, scores_out, si, snp_stats): @@ -421,7 +454,7 @@ def write_snp_len(ref_preds, alt_preds, scores_out, si, snp_stats): si (int): SNP index. snp_stats [str]: List of SAD stats to compute. """ - seq_length, num_targets = ref_preds.shape + num_shifts, seq_length, num_targets = ref_preds.shape # log/sqrt ref_preds_log = np.log2(ref_preds + 1) @@ -430,12 +463,12 @@ def write_snp_len(ref_preds, alt_preds, scores_out, si, snp_stats): alt_preds_sqrt = np.sqrt(alt_preds) # sum across length - ref_preds_sum = ref_preds.sum(axis=0) - alt_preds_sum = alt_preds.sum(axis=0) - ref_preds_log_sum = ref_preds_log.sum(axis=0) - alt_preds_log_sum = alt_preds_log.sum(axis=0) - ref_preds_sqrt_sum = ref_preds_sqrt.sum(axis=0) - alt_preds_sqrt_sum = alt_preds_sqrt.sum(axis=0) + ref_preds_sum = ref_preds.sum(axis=(0,1)) + alt_preds_sum = alt_preds.sum(axis=(0,1)) + ref_preds_log_sum = ref_preds_log.sum(axis=(0,1)) + alt_preds_log_sum = alt_preds_log.sum(axis=(0,1)) + ref_preds_sqrt_sum = ref_preds_sqrt.sum(axis=(0,1)) + alt_preds_sqrt_sum = alt_preds_sqrt.sum(axis=(0,1)) # difference altref_diff = alt_preds - ref_preds @@ -461,53 +494,65 @@ def write_snp_len(ref_preds, alt_preds, scores_out, si, snp_stats): # compare reference to alternative via max subtraction if "SAX" in snp_stats: - max_i = np.argmax(altref_adiff, axis=0) - sax = altref_diff[max_i, np.arange(num_targets)] + sax = [] + for s in range(num_shifts): + max_i = np.argmax(altref_adiff[s], axis=0) + sax.append(altref_diff[s, max_i, np.arange(num_targets)]) + sax = np.array(sax).mean(axis=0) scores_out["SAX"][si] = sax.astype("float16") # L1 norm of difference vector if "D1" in snp_stats: - sad_d1 = altref_adiff.sum(axis=0) + sad_d1 = altref_adiff.sum(axis=1) sad_d1 = np.clip(sad_d1, np.finfo(np.float16).min, np.finfo(np.float16).max) - scores_out["D1"][si] = sad_d1.astype("float16") + sad_d1 = sad_d1.mean(axis=0) + scores_out["D1"][si] = sad_d1.mean().astype("float16") if "logD1" in snp_stats: - log_d1 = altref_log_adiff.sum(axis=0) + log_d1 = altref_log_adiff.sum(axis=1) log_d1 = np.clip(log_d1, np.finfo(np.float16).min, np.finfo(np.float16).max) + log_d1 = log_d1.mean(axis=0) scores_out["logD1"][si] = log_d1.astype("float16") if "sqrtD1" in snp_stats: - sqrt_d1 = altref_sqrt_adiff.sum(axis=0) + sqrt_d1 = altref_sqrt_adiff.sum(axis=1) sqrt_d1 = np.clip(sqrt_d1, np.finfo(np.float16).min, np.finfo(np.float16).max) + sqrt_d1 = sqrt_d1.mean(axis=0) scores_out["sqrtD1"][si] = sqrt_d1.astype("float16") # L2 norm of difference vector if "D2" in snp_stats: altref_diff2 = np.power(altref_diff, 2) - sad_d2 = np.sqrt(altref_diff2.sum(axis=0)) + sad_d2 = np.sqrt(altref_diff2.sum(axis=1)) sad_d2 = np.clip(sad_d2, np.finfo(np.float16).min, np.finfo(np.float16).max) + sad_d2 = sad_d2.mean(axis=0) scores_out["D2"][si] = sad_d2.astype("float16") if "logD2" in snp_stats: altref_log_diff2 = np.power(altref_log_diff, 2) - log_d2 = np.sqrt(altref_log_diff2.sum(axis=0)) + log_d2 = np.sqrt(altref_log_diff2.sum(axis=1)) log_d2 = np.clip(log_d2, np.finfo(np.float16).min, np.finfo(np.float16).max) + log_d2 = log_d2.mean(axis=0) scores_out["logD2"][si] = log_d2.astype("float16") if "sqrtD2" in snp_stats: altref_sqrt_diff2 = np.power(altref_sqrt_diff, 2) - sqrt_d2 = np.sqrt(altref_sqrt_diff2.sum(axis=0)) + sqrt_d2 = np.sqrt(altref_sqrt_diff2.sum(axis=1)) sqrt_d2 = np.clip(sqrt_d2, np.finfo(np.float16).min, np.finfo(np.float16).max) + sqrt_d2 = sqrt_d2.mean(axis=0) scores_out["sqrtD2"][si] = sqrt_d2.astype("float16") if "JS" in snp_stats: # normalized scores - pseudocounts = np.percentile(ref_preds, 25, axis=0) + pseudocounts = np.percentile(ref_preds, 25, axis=1) ref_preds_norm = ref_preds + pseudocounts - ref_preds_norm /= ref_preds_norm.sum(axis=0) + ref_preds_norm /= ref_preds_norm.sum(axis=1) alt_preds_norm = alt_preds + pseudocounts - alt_preds_norm /= alt_preds_norm.sum(axis=0) + alt_preds_norm /= alt_preds_norm.sum(axis=1) # compare normalized JS - ref_alt_entr = rel_entr(ref_preds_norm, alt_preds_norm).sum(axis=0) - alt_ref_entr = rel_entr(alt_preds_norm, ref_preds_norm).sum(axis=0) - js_dist = (ref_alt_entr + alt_ref_entr) / 2 + js_dist = [] + for s in range(num_shifts): + ref_alt_entr = rel_entr(ref_preds_norm[s], alt_preds_norm[s]).sum(axis=0) + alt_ref_entr = rel_entr(alt_preds_norm[s], ref_preds_norm[s]).sum(axis=0) + js_dist.append((ref_alt_entr + alt_ref_entr) / 2) + js_dist = np.mean(js_dist, axis=0) scores_out["JS"][si] = js_dist.astype("float16") if "logJS" in snp_stats: # normalized scores @@ -518,9 +563,12 @@ def write_snp_len(ref_preds, alt_preds, scores_out, si, snp_stats): alt_preds_log_norm /= alt_preds_log_norm.sum(axis=0) # compare normalized JS - ref_alt_entr = rel_entr(ref_preds_log_norm, alt_preds_log_norm).sum(axis=0) - alt_ref_entr = rel_entr(alt_preds_log_norm, ref_preds_log_norm).sum(axis=0) - log_js_dist = (ref_alt_entr + alt_ref_entr) / 2 + log_js_dist = [] + for s in range(num_shifts): + ref_alt_entr = rel_entr(ref_preds_log_norm[s], alt_preds_log_norm[s]).sum(axis=0) + alt_ref_entr = rel_entr(alt_preds_log_norm[s], ref_preds_log_norm[s]).sum(axis=0) + log_js_dist.append((ref_alt_entr + alt_ref_entr) / 2) + log_js_dist = np.mean(log_js_dist, axis=0) scores_out["logJS"][si] = log_js_dist.astype("float16") # predictions diff --git a/src/baskerville/vcf.py b/src/baskerville/vcf.py index 520be53..7cca40f 100644 --- a/src/baskerville/vcf.py +++ b/src/baskerville/vcf.py @@ -697,6 +697,10 @@ def get_alleles(self): """Return a list of all alleles""" alleles = [self.ref_allele] + self.alt_alleles return alleles + + def indel_size(self): + """Return the size of the indel.""" + return len(self.alt_allele) - len(self.ref_allele) def longest_alt(self): """Return the longest alt allele.""" From bbbb2fd2061b5ebfa8c028cd7f9b407fce887bea Mon Sep 17 00:00:00 2001 From: David Kelley Date: Fri, 10 Nov 2023 14:13:15 -0800 Subject: [PATCH 08/24] black format --- src/baskerville/blocks.py | 21 +++------------- src/baskerville/dataset.py | 2 +- src/baskerville/layers.py | 4 +-- src/baskerville/snps.py | 51 +++++++++++++++++++++++++++----------- src/baskerville/trainer.py | 2 +- src/baskerville/vcf.py | 2 +- tests/test_dna.py | 21 +++------------- 7 files changed, 47 insertions(+), 56 deletions(-) diff --git a/src/baskerville/blocks.py b/src/baskerville/blocks.py index 3330ea0..25f7748 100644 --- a/src/baskerville/blocks.py +++ b/src/baskerville/blocks.py @@ -1772,12 +1772,7 @@ def dense_block( # flatten if flatten: _, seq_len, seq_depth = current.shape - current = tf.keras.layers.Reshape( - ( - 1, - seq_len * seq_depth, - ) - )(current) + current = tf.keras.layers.Reshape((1, seq_len * seq_depth,))(current) # dense current = tf.keras.layers.Dense( @@ -1879,12 +1874,7 @@ def dense_nac( # flatten if flatten: _, seq_len, seq_depth = current.shape - current = tf.keras.layers.Reshape( - ( - 1, - seq_len * seq_depth, - ) - )(current) + current = tf.keras.layers.Reshape((1, seq_len * seq_depth,))(current) # dense current = tf.keras.layers.Dense( @@ -1934,12 +1924,7 @@ def final( # flatten if flatten: _, seq_len, seq_depth = current.shape - current = tf.keras.layers.Reshape( - ( - 1, - seq_len * seq_depth, - ) - )(current) + current = tf.keras.layers.Reshape((1, seq_len * seq_depth,))(current) # dense current = tf.keras.layers.Dense( diff --git a/src/baskerville/dataset.py b/src/baskerville/dataset.py index a876d0c..1498556 100644 --- a/src/baskerville/dataset.py +++ b/src/baskerville/dataset.py @@ -353,7 +353,7 @@ def untransform_preds(preds, targets_df, unscale=False): # sqrt sqrt_mask = np.array([ss.find("_sqrt") != -1 for ss in targets_df.sum_stat]) - preds[:, sqrt_mask] = -1 + (preds[:, sqrt_mask] + 1) ** 2 # (4 / 3) + preds[:, sqrt_mask] = -1 + (preds[:, sqrt_mask] + 1) ** 2 # (4 / 3) # scale if unscale: diff --git a/src/baskerville/layers.py b/src/baskerville/layers.py index acde2e5..db4b5de 100644 --- a/src/baskerville/layers.py +++ b/src/baskerville/layers.py @@ -471,7 +471,7 @@ def call(self, inputs, training=False): # Scale the query by the square-root of key size. if self._scaling: - q *= self._key_size**-0.5 + q *= self._key_size ** -0.5 # [B, H, T', T] content_logits = tf.matmul(q + self._r_w_bias, k, transpose_b=True) @@ -888,7 +888,7 @@ def call(self, inputs): triu_tup = np.triu_indices(seq_len, self.diagonal_offset) triu_index = list(triu_tup[0] + seq_len * triu_tup[1]) - unroll_repr = tf.reshape(inputs, [-1, seq_len**2, output_dim]) + unroll_repr = tf.reshape(inputs, [-1, seq_len ** 2, output_dim]) return tf.gather(unroll_repr, triu_index, axis=1) def get_config(self): diff --git a/src/baskerville/snps.py b/src/baskerville/snps.py index 7286ebb..2603863 100644 --- a/src/baskerville/snps.py +++ b/src/baskerville/snps.py @@ -131,7 +131,12 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): # setup output scores_out = initialize_output_h5( - options.out_dir, options.snp_stats, snps, targets_length, targets_strand_df, num_shifts + options.out_dir, + options.snp_stats, + snps, + targets_length, + targets_strand_df, + num_shifts, ) # SNP index @@ -150,9 +155,13 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): # untransform predictions if options.targets_file is not None: if options.untransform_old: - ref_preds_shift = dataset.untransform_preds1(ref_preds_shift, targets_df) + ref_preds_shift = dataset.untransform_preds1( + ref_preds_shift, targets_df + ) else: - ref_preds_shift = dataset.untransform_preds(ref_preds_shift, targets_df) + ref_preds_shift = dataset.untransform_preds( + ref_preds_shift, targets_df + ) # sum strand pairs if strand_transform is not None: @@ -189,9 +198,13 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): # untransform predictions if options.targets_file is not None: if options.untransform_old: - alt_preds_shift = dataset.untransform_preds1(alt_preds_shift, targets_df) + alt_preds_shift = dataset.untransform_preds1( + alt_preds_shift, targets_df + ) else: - alt_preds_shift = dataset.untransform_preds(alt_preds_shift, targets_df) + alt_preds_shift = dataset.untransform_preds( + alt_preds_shift, targets_df + ) # sum strand pairs if strand_transform is not None: @@ -253,7 +266,9 @@ def cluster_snps(snps, seq_len: int, center_pct: float): return snp_clusters -def initialize_output_h5(out_dir, snp_stats, snps, targets_length, targets_df, num_shifts): +def initialize_output_h5( + out_dir, snp_stats, snps, targets_length, targets_df, num_shifts +): """Initialize an output HDF5 file for SAD stats. Args: @@ -307,7 +322,9 @@ def initialize_output_h5(out_dir, snp_stats, snps, targets_length, targets_df, n for snp_stat in snp_stats: if snp_stat in ["REF", "ALT"]: scores_out.create_dataset( - snp_stat, shape=(num_snps, num_shifts, targets_length, num_targets), dtype="float16" + snp_stat, + shape=(num_snps, num_shifts, targets_length, num_targets), + dtype="float16", ) else: scores_out.create_dataset( @@ -463,12 +480,12 @@ def write_snp_len(ref_preds, alt_preds, scores_out, si, snp_stats): alt_preds_sqrt = np.sqrt(alt_preds) # sum across length - ref_preds_sum = ref_preds.sum(axis=(0,1)) - alt_preds_sum = alt_preds.sum(axis=(0,1)) - ref_preds_log_sum = ref_preds_log.sum(axis=(0,1)) - alt_preds_log_sum = alt_preds_log.sum(axis=(0,1)) - ref_preds_sqrt_sum = ref_preds_sqrt.sum(axis=(0,1)) - alt_preds_sqrt_sum = alt_preds_sqrt.sum(axis=(0,1)) + ref_preds_sum = ref_preds.sum(axis=(0, 1)) + alt_preds_sum = alt_preds.sum(axis=(0, 1)) + ref_preds_log_sum = ref_preds_log.sum(axis=(0, 1)) + alt_preds_log_sum = alt_preds_log.sum(axis=(0, 1)) + ref_preds_sqrt_sum = ref_preds_sqrt.sum(axis=(0, 1)) + alt_preds_sqrt_sum = alt_preds_sqrt.sum(axis=(0, 1)) # difference altref_diff = alt_preds - ref_preds @@ -565,8 +582,12 @@ def write_snp_len(ref_preds, alt_preds, scores_out, si, snp_stats): # compare normalized JS log_js_dist = [] for s in range(num_shifts): - ref_alt_entr = rel_entr(ref_preds_log_norm[s], alt_preds_log_norm[s]).sum(axis=0) - alt_ref_entr = rel_entr(alt_preds_log_norm[s], ref_preds_log_norm[s]).sum(axis=0) + ref_alt_entr = rel_entr(ref_preds_log_norm[s], alt_preds_log_norm[s]).sum( + axis=0 + ) + alt_ref_entr = rel_entr(alt_preds_log_norm[s], ref_preds_log_norm[s]).sum( + axis=0 + ) log_js_dist.append((ref_alt_entr + alt_ref_entr) / 2) log_js_dist = np.mean(log_js_dist, axis=0) scores_out["logJS"][si] = log_js_dist.astype("float16") diff --git a/src/baskerville/trainer.py b/src/baskerville/trainer.py index 5c55f52..ac7aba1 100644 --- a/src/baskerville/trainer.py +++ b/src/baskerville/trainer.py @@ -755,7 +755,7 @@ def make_optimizer(self): def compute_norm(x, axis, keepdims): """Compute L2 norm of a tensor across an axis.""" - return tf.math.reduce_sum(x**2, axis=axis, keepdims=keepdims) ** 0.5 + return tf.math.reduce_sum(x ** 2, axis=axis, keepdims=keepdims) ** 0.5 def unitwise_norm(x): diff --git a/src/baskerville/vcf.py b/src/baskerville/vcf.py index 7cca40f..d455257 100644 --- a/src/baskerville/vcf.py +++ b/src/baskerville/vcf.py @@ -697,7 +697,7 @@ def get_alleles(self): """Return a list of all alleles""" alleles = [self.ref_allele] + self.alt_alleles return alleles - + def indel_size(self): """Return the size of the indel.""" return len(self.alt_allele) - len(self.ref_allele) diff --git a/tests/test_dna.py b/tests/test_dna.py index 8ff5d4b..dcced76 100755 --- a/tests/test_dna.py +++ b/tests/test_dna.py @@ -23,24 +23,9 @@ def test_dna_rc(): ) dna_1hot_cases = [ - ( - "ACGT", - False, - False, - ACGT_ARRAY, - ), - ( - "ACNGT", - False, - False, - ACNGT_FF_ARRAY, - ), - ( - "ACNGT", - True, - False, - ACNGT_TF_ARRAY, - ), + ("ACGT", False, False, ACGT_ARRAY,), + ("ACNGT", False, False, ACNGT_FF_ARRAY,), + ("ACNGT", True, False, ACNGT_TF_ARRAY,), ] From a36eb89b049987547035f6a11817b10c705e8c3e Mon Sep 17 00:00:00 2001 From: lruizcalico Date: Sat, 11 Nov 2023 20:39:18 -0800 Subject: [PATCH 09/24] black format files to pass test --- src/baskerville/blocks.py | 21 ++++++++++++++++++--- src/baskerville/layers.py | 4 ++-- src/baskerville/trainer.py | 2 +- tests/test_dna.py | 21 ++++++++++++++++++--- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/baskerville/blocks.py b/src/baskerville/blocks.py index 25f7748..3330ea0 100644 --- a/src/baskerville/blocks.py +++ b/src/baskerville/blocks.py @@ -1772,7 +1772,12 @@ def dense_block( # flatten if flatten: _, seq_len, seq_depth = current.shape - current = tf.keras.layers.Reshape((1, seq_len * seq_depth,))(current) + current = tf.keras.layers.Reshape( + ( + 1, + seq_len * seq_depth, + ) + )(current) # dense current = tf.keras.layers.Dense( @@ -1874,7 +1879,12 @@ def dense_nac( # flatten if flatten: _, seq_len, seq_depth = current.shape - current = tf.keras.layers.Reshape((1, seq_len * seq_depth,))(current) + current = tf.keras.layers.Reshape( + ( + 1, + seq_len * seq_depth, + ) + )(current) # dense current = tf.keras.layers.Dense( @@ -1924,7 +1934,12 @@ def final( # flatten if flatten: _, seq_len, seq_depth = current.shape - current = tf.keras.layers.Reshape((1, seq_len * seq_depth,))(current) + current = tf.keras.layers.Reshape( + ( + 1, + seq_len * seq_depth, + ) + )(current) # dense current = tf.keras.layers.Dense( diff --git a/src/baskerville/layers.py b/src/baskerville/layers.py index db4b5de..acde2e5 100644 --- a/src/baskerville/layers.py +++ b/src/baskerville/layers.py @@ -471,7 +471,7 @@ def call(self, inputs, training=False): # Scale the query by the square-root of key size. if self._scaling: - q *= self._key_size ** -0.5 + q *= self._key_size**-0.5 # [B, H, T', T] content_logits = tf.matmul(q + self._r_w_bias, k, transpose_b=True) @@ -888,7 +888,7 @@ def call(self, inputs): triu_tup = np.triu_indices(seq_len, self.diagonal_offset) triu_index = list(triu_tup[0] + seq_len * triu_tup[1]) - unroll_repr = tf.reshape(inputs, [-1, seq_len ** 2, output_dim]) + unroll_repr = tf.reshape(inputs, [-1, seq_len**2, output_dim]) return tf.gather(unroll_repr, triu_index, axis=1) def get_config(self): diff --git a/src/baskerville/trainer.py b/src/baskerville/trainer.py index ac7aba1..5c55f52 100644 --- a/src/baskerville/trainer.py +++ b/src/baskerville/trainer.py @@ -755,7 +755,7 @@ def make_optimizer(self): def compute_norm(x, axis, keepdims): """Compute L2 norm of a tensor across an axis.""" - return tf.math.reduce_sum(x ** 2, axis=axis, keepdims=keepdims) ** 0.5 + return tf.math.reduce_sum(x**2, axis=axis, keepdims=keepdims) ** 0.5 def unitwise_norm(x): diff --git a/tests/test_dna.py b/tests/test_dna.py index dcced76..8ff5d4b 100755 --- a/tests/test_dna.py +++ b/tests/test_dna.py @@ -23,9 +23,24 @@ def test_dna_rc(): ) dna_1hot_cases = [ - ("ACGT", False, False, ACGT_ARRAY,), - ("ACNGT", False, False, ACNGT_FF_ARRAY,), - ("ACNGT", True, False, ACNGT_TF_ARRAY,), + ( + "ACGT", + False, + False, + ACGT_ARRAY, + ), + ( + "ACNGT", + False, + False, + ACNGT_FF_ARRAY, + ), + ( + "ACNGT", + True, + False, + ACNGT_TF_ARRAY, + ), ] From 63ed80f94e5a9dc7787fa1253c9f5430d94ff222 Mon Sep 17 00:00:00 2001 From: lruizcalico Date: Mon, 20 Nov 2023 18:30:12 -0800 Subject: [PATCH 10/24] fix pyproject.toml for setuptools update --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4864e56..b98553e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ authors = [ readme = "README.md" requires-python = ">=3.8, <3.11" classifiers = ["License :: OSI Approved :: Apache License"] -dynamic = ["version", "description"] +dynamic = ["version", "description", "dependencies"] [project.optional-dependencies] dev = [ From cb64022ea5bcf50aec03ddefc09a864a5d738023 Mon Sep 17 00:00:00 2001 From: lruizcalico Date: Mon, 11 Dec 2023 10:52:13 -0800 Subject: [PATCH 11/24] add sphinx doc --- .github/workflows/documentation.yml | 38 ++++++++++ src/docs/Makefile | 20 +++++ src/docs/build/.placeholder | 0 src/docs/make.bat | 35 +++++++++ src/docs/source/baskerville.helpers.rst | 19 +++++ src/docs/source/baskerville.rst | 98 +++++++++++++++++++++++++ src/docs/source/baskerville.scripts.rst | 53 +++++++++++++ src/docs/source/conf.py | 38 ++++++++++ src/docs/source/index.rst | 16 ++++ 9 files changed, 317 insertions(+) create mode 100644 .github/workflows/documentation.yml create mode 100644 src/docs/Makefile create mode 100644 src/docs/build/.placeholder create mode 100644 src/docs/make.bat create mode 100644 src/docs/source/baskerville.helpers.rst create mode 100644 src/docs/source/baskerville.rst create mode 100644 src/docs/source/baskerville.scripts.rst create mode 100644 src/docs/source/conf.py create mode 100644 src/docs/source/index.rst diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..bb21740 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,38 @@ +name: Baskerville Docs + +on: + workflow_dispatch: + +defaults: + run: + shell: bash + +permissions: + contents: write +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-python@v3 + + - name: Install dependencies + run: | + cd ${{ github.workspace }}/src/docs + pip install -r requirements.txt + - name: Sphinx build + run: | + cd ${{ github.workspace }}/src/docs/source + rm -f *.rst make.bat + cd ${{ github.workspace }}/src + sphinx-apidoc -F -a -o docs/source baskerville + cd ${{ github.workspace }}/src/docs + make html + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + publish_branch: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ${{ github.workspace }}/src/docs/build/html + force_orphan: true diff --git a/src/docs/Makefile b/src/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/src/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/src/docs/build/.placeholder b/src/docs/build/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/src/docs/make.bat b/src/docs/make.bat new file mode 100644 index 0000000..747ffb7 --- /dev/null +++ b/src/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/src/docs/source/baskerville.helpers.rst b/src/docs/source/baskerville.helpers.rst new file mode 100644 index 0000000..0288778 --- /dev/null +++ b/src/docs/source/baskerville.helpers.rst @@ -0,0 +1,19 @@ +baskerville.helpers Subpackages of helpers for the Baskerville package. +============================================================================== + +Submodules +---------- + +baskerville.helpers.gcs_utils module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.helpers.gcs_utils + :members: + :undoc-members: + :show-inheritance: + +baskerville.helpers.utils module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.helpers.utils + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/src/docs/source/baskerville.rst b/src/docs/source/baskerville.rst new file mode 100644 index 0000000..90776fb --- /dev/null +++ b/src/docs/source/baskerville.rst @@ -0,0 +1,98 @@ +baskerville package +=================== + + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + baskerville.helpers + baskerville.scripts + +Submodules +---------- + +baskerville.bed module +~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: baskerville.bed + :members: + :undoc-members: + :show-inheritance: + +baskerville.blocks module +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: baskerville.blocks + :members: + :undoc-members: + :show-inheritance: + +baskerville.dataset module +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: baskerville.dataset + :members: + :undoc-members: + :show-inheritance: + +baskerville.dna module +~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.dna + :members: + :undoc-members: + :show-inheritance: + + +baskerville.gene module +~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.gene + :members: + :undoc-members: + :show-inheritance: + +baskerville.layers module +~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.layers + :members: + :undoc-members: + :show-inheritance: + +baskerville.metrics module +~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.metrics + :members: + :undoc-members: + :show-inheritance: + +baskerville.seqnn module +~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.seqnn + :members: + :undoc-members: + :show-inheritance: + +baskerville.snps module +~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.snps + :members: + :undoc-members: + :show-inheritance: + +baskerville.trainer module +~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.trainer + :members: + :undoc-members: + :show-inheritance: + +baskerville.vcf module +~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.vcf + :members: + :undoc-members: + :show-inheritance: + + diff --git a/src/docs/source/baskerville.scripts.rst b/src/docs/source/baskerville.scripts.rst new file mode 100644 index 0000000..e554f74 --- /dev/null +++ b/src/docs/source/baskerville.scripts.rst @@ -0,0 +1,53 @@ +baskerville.scripts Subpackages of scripts for the Baskerville project. +============================================================= + +""" +This package contains scripts for the Baskerville project +that are not part of the main codebase. + +""" +Submodules +========== + +baskerville.scripts.hound_eval_spec module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.scripts.hound_eval_spec + :members: + :undoc-members: + :show-inheritance: + +baskerville.scripts.hound_eval module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.scripts.hound_eval + :members: + :undoc-members: + :show-inheritance: + +baskerville.scripts.hound_predbed module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.scripts.hound_predbed + :members: + :undoc-members: + :show-inheritance: + + +baskerville.scripts.hound_snp module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.scripts.hound_snp + :members: + :undoc-members: + :show-inheritance: + +baskerville.scripts.hound_snp_slurm module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.scripts.hound_snp_slurm + :members: + :undoc-members: + :show-inheritance: + +baskerville.scripts.hound_train module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. automodule:: baskerville.scripts.hound_train + :members: + :undoc-members: + :show-inheritance: diff --git a/src/docs/source/conf.py b/src/docs/source/conf.py new file mode 100644 index 0000000..319b105 --- /dev/null +++ b/src/docs/source/conf.py @@ -0,0 +1,38 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +import os +import sys + +# This root should be where docs folder is visible. +sys.path.insert(0, os.path.abspath("../..")) +sys.setrecursionlimit(1500) + +project = "baskerville" +copyright = "2023, David Kelly" +author = "David Kelly" +release = "0.0.1" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", + "sphinx.ext.githubpages", +] + +templates_path = ["_templates"] +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "sphinx_rtd_theme" +html_static_path = ["_static"] diff --git a/src/docs/source/index.rst b/src/docs/source/index.rst new file mode 100644 index 0000000..dc6b601 --- /dev/null +++ b/src/docs/source/index.rst @@ -0,0 +1,16 @@ +Welcome to baskerville's documentation! +======================================= + +.. toctree:: + :maxdepth: 4 + :caption: Contents: + + baskerville + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` From ac813cb370301e279ca82c0f5380b1bdc19ee05a Mon Sep 17 00:00:00 2001 From: lruizcalico Date: Mon, 11 Dec 2023 10:57:51 -0800 Subject: [PATCH 12/24] add sphinx 7.2.6 --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index cb2a2f0..52b40dc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -35,6 +35,7 @@ install_requires = seaborn~=0.12.2 scikit-learn~=1.2.2 scipy~=1.9.1 + sphinx~=7.2.6 statsmodels~=0.13.5 tabulate~=0.8.10 tensorflow==2.13.0 From 318affddfc3e0a9d30364a1bd3fd53094649e7d1 Mon Sep 17 00:00:00 2001 From: lruizcalico Date: Mon, 11 Dec 2023 11:05:06 -0800 Subject: [PATCH 13/24] requirement for sphinx --- src/docs/requirements.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/docs/requirements.txt diff --git a/src/docs/requirements.txt b/src/docs/requirements.txt new file mode 100644 index 0000000..f654e6e --- /dev/null +++ b/src/docs/requirements.txt @@ -0,0 +1,4 @@ +sphinx +sphinx_rtd_theme +python-dotenv +google \ No newline at end of file From d0230e0223f57f9e412c35087d2576423dbfaed8 Mon Sep 17 00:00:00 2001 From: lruizcalico <132386548+lruizcalico@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:14:45 -0800 Subject: [PATCH 14/24] Update setup.cfg --- setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 52b40dc..cb2a2f0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -35,7 +35,6 @@ install_requires = seaborn~=0.12.2 scikit-learn~=1.2.2 scipy~=1.9.1 - sphinx~=7.2.6 statsmodels~=0.13.5 tabulate~=0.8.10 tensorflow==2.13.0 From 28266f4ac1233a56b22a3ae384985bc6efc5b169 Mon Sep 17 00:00:00 2001 From: lruizcalico Date: Mon, 11 Dec 2023 20:46:55 -0800 Subject: [PATCH 15/24] automate gen doc --- .github/workflows/documentation.yml | 19 ++++++++++++++++--- src/baskerville/helpers/__init__.py | 0 src/baskerville/scripts/__init__.py | 0 src/docs/requirements.txt | 23 +++++++++++++++++++++-- src/docs/source/conf.py | 5 +++++ 5 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 src/baskerville/helpers/__init__.py create mode 100644 src/baskerville/scripts/__init__.py diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index bb21740..e91383b 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -2,6 +2,11 @@ name: Baskerville Docs on: workflow_dispatch: + inputs: + python-version: + default: "3.10" + required: false + type: string defaults: run: @@ -11,12 +16,20 @@ permissions: contents: write jobs: docs: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 + strategy: + matrix: + python-version: ["3.10"] steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 - + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + # You can test your matrix by printing the current Python version + - name: Display Python version + run: python -c "import sys; print(sys.version)" - name: Install dependencies run: | cd ${{ github.workspace }}/src/docs diff --git a/src/baskerville/helpers/__init__.py b/src/baskerville/helpers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/baskerville/scripts/__init__.py b/src/baskerville/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/docs/requirements.txt b/src/docs/requirements.txt index f654e6e..8d2f592 100644 --- a/src/docs/requirements.txt +++ b/src/docs/requirements.txt @@ -1,4 +1,23 @@ +h5py~=3.7.0 +intervaltree~=3.1.0 +joblib~=1.1.1 +matplotlib~=3.7.1 +google-cloud-storage~=2.0.0 +natsort~=7.1.1 +networkx~=2.8.4 +numpy +pandas~=1.5.3 +pybigwig~=0.3.18 +pysam~=0.21.0 +pybedtools~=0.9.0 +qnorm~=0.8.1 +seaborn~=0.12.2 +scikit-learn~=1.2.2 +scipy~=1.9.1 sphinx sphinx_rtd_theme -python-dotenv -google \ No newline at end of file +sphinxcontrib-apidoc +statsmodels~=0.13.5 +tensorflow==2.13.0 +tabulate~=0.8.10 +tqdm~=4.65.0 \ No newline at end of file diff --git a/src/docs/source/conf.py b/src/docs/source/conf.py index 319b105..cea225c 100644 --- a/src/docs/source/conf.py +++ b/src/docs/source/conf.py @@ -10,6 +10,10 @@ # This root should be where docs folder is visible. sys.path.insert(0, os.path.abspath("../..")) +sys.path.insert(0, os.path.abspath("../../baskerville")) +sys.path.insert(0, os.path.abspath("../../baskerville/scripts")) +sys.path.insert(0, os.path.abspath("../../bashkerville/helpers")) + sys.setrecursionlimit(1500) project = "baskerville" @@ -25,6 +29,7 @@ "sphinx.ext.viewcode", "sphinx.ext.napoleon", "sphinx.ext.githubpages", + "sphinxcontrib.apidoc", ] templates_path = ["_templates"] From b8835b6806d58337f109e360b9e6e4ab68b31db9 Mon Sep 17 00:00:00 2001 From: lruizcalico Date: Mon, 11 Dec 2023 20:52:50 -0800 Subject: [PATCH 16/24] fix req --- setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 52b40dc..cb2a2f0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -35,7 +35,6 @@ install_requires = seaborn~=0.12.2 scikit-learn~=1.2.2 scipy~=1.9.1 - sphinx~=7.2.6 statsmodels~=0.13.5 tabulate~=0.8.10 tensorflow==2.13.0 From 3a8f20412b1f1d8ad333bb2a4f0c13f304dcdd19 Mon Sep 17 00:00:00 2001 From: lruizcalico <132386548+lruizcalico@users.noreply.github.com> Date: Fri, 15 Dec 2023 13:05:27 -0800 Subject: [PATCH 17/24] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 7c75da7..727cb17 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ Baskerville provides researchers with tools to: --- +### Documentations + +Documentation page: https://calico.github.io/baskerville/index.html + +--- + ### Installation `git clone git@github.com:calico/baskerville.git` From 671c22f4890ae50afb96b32e44c4a959b51c53af Mon Sep 17 00:00:00 2001 From: David Kelley Date: Mon, 18 Dec 2023 15:28:50 -0800 Subject: [PATCH 18/24] left pad bug fix --- src/baskerville/vcf.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/baskerville/vcf.py b/src/baskerville/vcf.py index d455257..66e7b3e 100644 --- a/src/baskerville/vcf.py +++ b/src/baskerville/vcf.py @@ -212,8 +212,8 @@ def snp_seq1(snp, seq_len, genome_open): seq = genome_open.fetch(snp.chr, seq_start - 1, seq_end).upper() # extend to full length - if len(seq) < seq_end - seq_start: - seq += "N" * (seq_end - seq_start - len(seq)) + if len(seq) < seq_len: + seq += "N" * (seq_len - len(seq)) # verify that ref allele matches ref sequence seq_ref = seq[left_len : left_len + len(snp.ref_allele)] @@ -301,16 +301,17 @@ def snps_seq1(snps, seq_len, genome_fasta, return_seqs=False): # extract sequence as BED style if seq_start < 0: - seq = "N" * (-seq_start) + genome_open.fetch(snp.chr, 0, seq_end).upper() + seq = "N" * (1 - seq_start) + genome_open.fetch(snp.chr, 0, seq_end).upper() else: seq = genome_open.fetch(snp.chr, seq_start - 1, seq_end).upper() # extend to full length - if len(seq) < seq_end - seq_start: - seq += "N" * (seq_end - seq_start - len(seq)) + if len(seq) < seq_len: + seq += "N" * (seq_len - len(seq)) # verify that ref allele matches ref sequence seq_ref = seq[left_len : left_len + len(snp.ref_allele)] + ref_found = True if seq_ref != snp.ref_allele: # search for reference allele in alternatives ref_found = False @@ -336,13 +337,13 @@ def snps_seq1(snps, seq_len, genome_fasta, return_seqs=False): ) break - if not ref_found: - print( - "WARNING: %s - reference genome %s does not match any allele; skipping" - % (seq_ref, snp.rsid), - file=sys.stderr, - ) - continue + if not ref_found: + print( + "WARNING: %s - reference genome %s does not match any allele; skipping" + % (seq_ref, snp.rsid), + file=sys.stderr, + ) + break seq_snps.append(snp) From 77d0ee57a3fce2f5532c50fee937b2cb294c74ed Mon Sep 17 00:00:00 2001 From: David Kelley Date: Mon, 18 Dec 2023 15:30:00 -0800 Subject: [PATCH 19/24] minor aesthetic --- src/baskerville/scripts/hound_snp.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/baskerville/scripts/hound_snp.py b/src/baskerville/scripts/hound_snp.py index cf31a5d..626eda3 100755 --- a/src/baskerville/scripts/hound_snp.py +++ b/src/baskerville/scripts/hound_snp.py @@ -15,7 +15,6 @@ # ========================================================================= from optparse import OptionParser import pdb -import pickle import os from baskerville.snps import score_snps import tempfile @@ -51,7 +50,7 @@ def main(): "-f", dest="genome_fasta", default=None, - help="Genome FASTA for sequences [Default: %default]", + help="Genome FASTA [Default: %default]", ) parser.add_option( "-o", @@ -173,6 +172,7 @@ def main(): options.snp_stats = options.snp_stats.split(",") if options.targets_file is None: parser.error("Must provide targets file") + ################################################################# # check if the program is run on GPU, else quit physical_devices = tf.config.list_physical_devices() @@ -185,6 +185,7 @@ def main(): print("Running on CPU") if options.require_gpu: raise SystemExit("Job terminated because it's running on CPU") + ################################################################# # download input files from gcs to a local file if options.gcs: @@ -199,6 +200,7 @@ def main(): options.targets_file = download_rename_inputs( options.targets_file, temp_dir ) + ################################################################# # calculate SAD scores: if options.processes is not None: From 517237b1132c2fe28d79e27e041100e560b7b06b Mon Sep 17 00:00:00 2001 From: David Kelley Date: Mon, 18 Dec 2023 15:30:41 -0800 Subject: [PATCH 20/24] add vcf ism and refactor score computing --- src/baskerville/dataset.py | 31 +++ src/baskerville/scripts/hound_ism_snp.py | 271 +++++++++++++++++++++++ src/baskerville/seqnn.py | 34 ++- src/baskerville/snps.py | 210 ++++++++++++++---- 4 files changed, 504 insertions(+), 42 deletions(-) create mode 100755 src/baskerville/scripts/hound_ism_snp.py diff --git a/src/baskerville/dataset.py b/src/baskerville/dataset.py index 1498556..f061b97 100644 --- a/src/baskerville/dataset.py +++ b/src/baskerville/dataset.py @@ -20,6 +20,7 @@ from natsort import natsorted import numpy as np import pandas as pd +from scipy.sparse import dok_matrix import tensorflow as tf gpu_devices = tf.config.experimental.list_physical_devices("GPU") @@ -310,6 +311,36 @@ def numpy( return targets +def make_strand_transform(targets_df, targets_strand_df): + """Make a sparse matrix to sum strand pairs. + + Args: + targets_df (pd.DataFrame): Targets DataFrame. + targets_strand_df (pd.DataFrame): Targets DataFrame, with strand pairs collapsed. + + Returns: + scipy.sparse.csr_matrix: Sparse matrix to sum strand pairs. + """ + + # initialize sparse matrix + strand_transform = dok_matrix((targets_df.shape[0], targets_strand_df.shape[0])) + + # fill in matrix + ti = 0 + sti = 0 + for _, target in targets_df.iterrows(): + strand_transform[ti, sti] = True + if target.strand_pair == target.name: + sti += 1 + else: + if target.identifier[-1] == "-": + sti += 1 + ti += 1 + strand_transform = strand_transform.tocsr() + + return strand_transform + + def targets_prep_strand(targets_df): """Adjust targets table for merged stranded datasets. diff --git a/src/baskerville/scripts/hound_ism_snp.py b/src/baskerville/scripts/hound_ism_snp.py new file mode 100755 index 0000000..cc43356 --- /dev/null +++ b/src/baskerville/scripts/hound_ism_snp.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python +# Copyright 2017 Calico LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ========================================================================= +from optparse import OptionParser +import json +import os +import pdb +import time + +import h5py +import numpy as np +import pandas as pd + +from baskerville import dataset +from baskerville import dna +from baskerville import seqnn +from baskerville import snps +from baskerville import vcf + +""" +hound_ism_snp.py + +Perform an in silico saturated mutagenesis of the sequences surrounding variants +given in a VCF file. +""" + +################################################################################ +# main +################################################################################ +def main(): + usage = "usage: %prog [options] " + parser = OptionParser(usage) + parser.add_option( + "-d", + dest="mut_down", + default=0, + type="int", + help="Nucleotides downstream of center sequence to mutate [Default: %default]", + ) + parser.add_option( + "-f", + dest="genome_fasta", + default=None, + help="Genome FASTA [Default: %default]", + ) + parser.add_option( + "-l", + dest="mut_len", + default=200, + type="int", + help="Length of centered sequence to mutate [Default: %default]", + ) + parser.add_option( + "-o", + dest="out_dir", + default="ism_snp_out", + help="Output directory [Default: %default]", + ) + parser.add_option( + "--rc", + dest="rc", + default=False, + action="store_true", + help="Ensemble forward and reverse complement predictions [Default: %default]", + ) + parser.add_option( + "--shifts", + dest="shifts", + default="0", + help="Ensemble prediction shifts [Default: %default]", + ) + parser.add_option( + "--stats", + dest="snp_stats", + default="logSUM", + help="Comma-separated list of stats to save. [Default: %default]", + ) + parser.add_option( + "-t", + dest="targets_file", + default=None, + type="str", + help="File specifying target indexes and labels in table format", + ) + parser.add_option( + "-u", + dest="mut_up", + default=0, + type="int", + help="Nucleotides upstream of center sequence to mutate [Default: %default]", + ) + parser.add_option( + "--untransform_old", + dest="untransform_old", + default=False, + action="store_true", + help="Untransform old models [Default: %default]", + ) + (options, args) = parser.parse_args() + + if len(args) != 3: + parser.error("Must provide parameters and model files and VCF") + else: + params_file = args[0] + model_file = args[1] + vcf_file = args[2] + + if not os.path.isdir(options.out_dir): + os.mkdir(options.out_dir) + + options.shifts = [int(shift) for shift in options.shifts.split(",")] + options.snp_stats = [snp_stat for snp_stat in options.snp_stats.split(",")] + + if options.mut_up > 0 or options.mut_down > 0: + options.mut_len = options.mut_up + options.mut_down + else: + assert options.mut_len > 0 + options.mut_up = options.mut_len // 2 + options.mut_down = options.mut_len - options.mut_up + + ################################################################# + # read parameters and targets + + # read model parameters + with open(params_file) as params_open: + params = json.load(params_open) + params_model = params["model"] + + # read targets + if options.targets_file is None: + parser.error("Must provide targets file to clarify stranded datasets") + targets_df = pd.read_csv(options.targets_file, sep="\t", index_col=0) + + # handle strand pairs + if "strand_pair" in targets_df.columns: + # prep strand + targets_strand_df = dataset.targets_prep_strand(targets_df) + + # set strand pairs (using new indexing) + orig_new_index = dict(zip(targets_df.index, np.arange(targets_df.shape[0]))) + targets_strand_pair = np.array( + [orig_new_index[ti] for ti in targets_df.strand_pair] + ) + params_model["strand_pair"] = [targets_strand_pair] + + # construct strand sum transform + strand_transform = dataset.make_strand_transform(targets_df, targets_strand_df) + else: + targets_strand_df = targets_df + strand_transform = None + + ################################################################# + # setup model + + seqnn_model = seqnn.SeqNN(params_model) + seqnn_model.restore(model_file) + seqnn_model.build_slice(targets_df.index) + seqnn_model.build_ensemble(options.rc) + + # shift outside seqnn + num_shifts = len(options.shifts) + targets_length = seqnn_model.target_lengths[0] + num_targets = targets_strand_df.shape[0] + + ################################################################# + # SNP sequence dataset + + # load SNPs + variants = vcf.vcf_snps(vcf_file) + + # get one hot coded input sequences + seqs_1hot, seq_headers, variants, seqs_dna = vcf.snps_seq1( + variants, params_model["seq_length"], options.genome_fasta, return_seqs=True + ) + num_seqs = seqs_1hot.shape[0] + + # determine mutation region limits + seq_mid = params_model["seq_length"] // 2 + mut_start = seq_mid - options.mut_up + mut_end = mut_start + options.mut_len + + ################################################################# + # setup output + + scores_h5_file = "%s/scores.h5" % options.out_dir + if os.path.isfile(scores_h5_file): + os.remove(scores_h5_file) + scores_h5 = h5py.File(scores_h5_file, "w") + scores_h5.create_dataset("label", data=np.array(seq_headers, dtype="S")) + scores_h5.create_dataset("seqs", dtype="bool", shape=(num_seqs, options.mut_len, 4)) + for snp_stat in options.snp_stats: + scores_h5.create_dataset( + snp_stat, dtype="float16", shape=(num_seqs, options.mut_len, 4, num_targets) + ) + + ################################################################# + # predict scores and write output + + for si in range(seqs_1hot.shape[0]): + print("Predicting %d" % si, flush=True) + + # 1-hot encode reference + ref_1hot = np.expand_dims(seqs_1hot[si], axis=0) + + # save sequence + scores_h5['seqs'][si] = ref_1hot[0, mut_start:mut_end].astype('bool') + + # predict reference + ref_preds = [] + for shift in options.shifts: + # shift sequence and predict + ref_1hot_shift = dna.hot1_augment(ref_1hot, shift=shift) + ref_preds_shift = seqnn_model.predict_transform( + ref_1hot_shift, + targets_df, + strand_transform, + options.untransform_old, + ) + ref_preds.append(ref_preds_shift) + ref_preds = np.array(ref_preds) + + # for mutation positions + for mi in range(mut_start, mut_end): + # for each nucleotide + for ni in range(4): + # if non-reference + if ref_1hot[0, mi, ni] == 0: + # copy and modify + alt_1hot = np.copy(ref_1hot) + alt_1hot[0, mi, :] = 0 + alt_1hot[0, mi, ni] = 1 + + # predict alternate + alt_preds = [] + for shift in options.shifts: + # shift sequence and predict + alt_1hot_shift = dna.hot1_augment(alt_1hot, shift=shift) + alt_preds_shift = seqnn_model.predict_transform( + alt_1hot_shift, + targets_df, + strand_transform, + options.untransform_old, + ) + alt_preds.append(alt_preds_shift) + alt_preds = np.array(alt_preds) + + ism_scores = snps.compute_scores(ref_preds, alt_preds, options.snp_stats) + for snp_stat in options.snp_stats: + scores_h5[snp_stat][si, mi-mut_start, ni] = ism_scores[snp_stat] + + # close output HDF5 + scores_h5.close() + + +################################################################################ +# __main__ +################################################################################ +if __name__ == "__main__": + main() diff --git a/src/baskerville/seqnn.py b/src/baskerville/seqnn.py index 716bb7b..4eb4eea 100644 --- a/src/baskerville/seqnn.py +++ b/src/baskerville/seqnn.py @@ -13,14 +13,16 @@ # limitations under the License. # ========================================================================= import pdb +import gc import sys import time from natsort import natsorted import numpy as np import tensorflow as tf -import gc + from baskerville import blocks +from baskerville import dataset from baskerville import layers from baskerville import metrics @@ -967,6 +969,36 @@ def predict( return preds + def predict_transform( + self, + seq_1hot: np.array, + targets_df, + strand_transform: np.array = None, + untransform_old: bool = False, + ): + """Predict a single sequence and transform. + + Args: + seq_1hot (np.array): 1-hot encoded sequence. + targets_df (pd.DataFrame): Targets dataframe. + strand_transform (np.array): Strand merging transform. + untransform_old (bool): Apply old untransform. + """ + # predict + preds = self(seq_1hot)[0] + + # untransform predictions + if untransform_old: + preds = dataset.untransform_preds1(preds, targets_df) + else: + preds = dataset.untransform_preds(preds, targets_df) + + # sum strand pairs + if strand_transform is not None: + preds = preds * strand_transform + + return preds + def restore(self, model_file, head_i=0, trunk=False): """Restore weights from saved model.""" if trunk: diff --git a/src/baskerville/snps.py b/src/baskerville/snps.py index 2603863..f0d0813 100644 --- a/src/baskerville/snps.py +++ b/src/baskerville/snps.py @@ -6,7 +6,6 @@ import numpy as np import pandas as pd import pysam -from scipy.sparse import dok_matrix from scipy.special import rel_entr from tqdm import tqdm @@ -37,6 +36,9 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): params_model = params["model"] # read targets + if options.targets_file is None: + print('Must provide targets file to clarify stranded datasets', file=sys.stderr) + exit(1) targets_df = pd.read_csv(options.targets_file, sep="\t", index_col=0) # handle strand pairs @@ -52,7 +54,7 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): params_model["strand_pair"] = [targets_strand_pair] # construct strand sum transform - strand_transform = make_strand_transform(targets_df, targets_strand_df) + strand_transform = dataset.make_strand_transform(targets_df, targets_strand_df) else: targets_strand_df = targets_df strand_transform = None @@ -72,15 +74,7 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): # shift outside seqnn num_shifts = len(options.shifts) - targets_length = seqnn_model.target_lengths[0] - num_targets = seqnn_model.num_targets() - if options.targets_file is None: - target_ids = ["t%d" % ti for ti in range(num_targets)] - target_labels = [""] * len(target_ids) - targets_strand_df = pd.DataFrame( - {"identifier": target_ids, "description": target_labels} - ) ################################################################# # load SNPs @@ -225,7 +219,10 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): if sum_length: write_snp(rp_snp, ap_snp, scores_out, si, options.snp_stats) else: - write_snp_len(rp_snp, ap_snp, scores_out, si, options.snp_stats) + # write_snp_len(rp_snp, ap_snp, scores_out, si, options.snp_stats) + scores = compute_scores(rp_snp, ap_snp, options.snp_stats) + for snp_stat in options.snp_stats: + scores_out[snp_stat][si] = scores[snp_stat] # update SNP index si += 1 @@ -266,6 +263,167 @@ def cluster_snps(snps, seq_len: int, center_pct: float): return snp_clusters +def compute_scores(ref_preds, alt_preds, snp_stats): + """Compute SNP scores from reference and alternative predictions. + + Args: + ref_preds (np.array): Reference allele predictions. + alt_preds (np.array): Alternative allele predictions. + snp_stats [str]: List of SAD stats to compute. + """ + num_shifts, seq_length, num_targets = ref_preds.shape + + # log/sqrt + ref_preds_log = np.log2(ref_preds + 1) + alt_preds_log = np.log2(alt_preds + 1) + ref_preds_sqrt = np.sqrt(ref_preds) + alt_preds_sqrt = np.sqrt(alt_preds) + + # sum across length + ref_preds_sum = ref_preds.sum(axis=(0, 1)) + alt_preds_sum = alt_preds.sum(axis=(0, 1)) + ref_preds_log_sum = ref_preds_log.sum(axis=(0, 1)) + alt_preds_log_sum = alt_preds_log.sum(axis=(0, 1)) + ref_preds_sqrt_sum = ref_preds_sqrt.sum(axis=(0, 1)) + alt_preds_sqrt_sum = alt_preds_sqrt.sum(axis=(0, 1)) + + # difference + altref_diff = alt_preds - ref_preds + altref_adiff = np.abs(altref_diff) + altref_log_diff = alt_preds_log - ref_preds_log + altref_log_adiff = np.abs(altref_log_diff) + altref_sqrt_diff = alt_preds_sqrt - ref_preds_sqrt + altref_sqrt_adiff = np.abs(altref_sqrt_diff) + + # initialize scores dict + scores = {} + + # compare reference to alternative via sum subtraction + if "SUM" in snp_stats: + sad = alt_preds_sum - ref_preds_sum + sad = np.clip(sad, np.finfo(np.float16).min, np.finfo(np.float16).max) + scores["SUM"] = sad.astype("float16") + if "logSUM" in snp_stats: + log_sad = alt_preds_log_sum - ref_preds_log_sum + log_sad = np.clip(log_sad, np.finfo(np.float16).min, np.finfo(np.float16).max) + scores["logSUM"] = log_sad.astype("float16") + if "sqrtSUM" in snp_stats: + sqrt_sad = alt_preds_sqrt_sum - ref_preds_sqrt_sum + sqrt_sad = np.clip(sqrt_sad, np.finfo(np.float16).min, np.finfo(np.float16).max) + scores["sqrtSUM"] = sqrt_sad.astype("float16") + + # TEMP during name change + if "SAD" in snp_stats: + sad = alt_preds_sum - ref_preds_sum + sad = np.clip(sad, np.finfo(np.float16).min, np.finfo(np.float16).max) + scores["SAD"] = sad.astype("float16") + if "logSAD" in snp_stats: + log_sad = alt_preds_log_sum - ref_preds_log_sum + log_sad = np.clip(log_sad, np.finfo(np.float16).min, np.finfo(np.float16).max) + scores["logSAD"] = log_sad.astype("float16") + if "sqrtSAD" in snp_stats: + sqrt_sad = alt_preds_sqrt_sum - ref_preds_sqrt_sum + sqrt_sad = np.clip(sqrt_sad, np.finfo(np.float16).min, np.finfo(np.float16).max) + scores["sqrtSAD"] = sqrt_sad.astype("sqrtSAD") + + # compare reference to alternative via max subtraction + if "SAX" in snp_stats: + sax = [] + for s in range(num_shifts): + max_i = np.argmax(altref_adiff[s], axis=0) + sax.append(altref_diff[s, max_i, np.arange(num_targets)]) + sax = np.array(sax).mean(axis=0) + scores["SAX"] = sax.astype("float16") + + # L1 norm of difference vector + if "D1" in snp_stats: + sad_d1 = altref_adiff.sum(axis=1) + sad_d1 = np.clip(sad_d1, np.finfo(np.float16).min, np.finfo(np.float16).max) + sad_d1 = sad_d1.mean(axis=0) + scores["D1"] = sad_d1.mean().astype("float16") + if "logD1" in snp_stats: + log_d1 = altref_log_adiff.sum(axis=1) + log_d1 = np.clip(log_d1, np.finfo(np.float16).min, np.finfo(np.float16).max) + log_d1 = log_d1.mean(axis=0) + scores["logD1"] = log_d1.astype("float16") + if "sqrtD1" in snp_stats: + sqrt_d1 = altref_sqrt_adiff.sum(axis=1) + sqrt_d1 = np.clip(sqrt_d1, np.finfo(np.float16).min, np.finfo(np.float16).max) + sqrt_d1 = sqrt_d1.mean(axis=0) + scores["sqrtD1"] = sqrt_d1.astype("float16") + + # L2 norm of difference vector + if "D2" in snp_stats: + altref_diff2 = np.power(altref_diff, 2) + sad_d2 = np.sqrt(altref_diff2.sum(axis=1)) + sad_d2 = np.clip(sad_d2, np.finfo(np.float16).min, np.finfo(np.float16).max) + sad_d2 = sad_d2.mean(axis=0) + scores["D2"] = sad_d2.astype("float16") + if "logD2" in snp_stats: + altref_log_diff2 = np.power(altref_log_diff, 2) + log_d2 = np.sqrt(altref_log_diff2.sum(axis=1)) + log_d2 = np.clip(log_d2, np.finfo(np.float16).min, np.finfo(np.float16).max) + log_d2 = log_d2.mean(axis=0) + scores["logD2"] = log_d2.astype("float16") + if "sqrtD2" in snp_stats: + altref_sqrt_diff2 = np.power(altref_sqrt_diff, 2) + sqrt_d2 = np.sqrt(altref_sqrt_diff2.sum(axis=1)) + sqrt_d2 = np.clip(sqrt_d2, np.finfo(np.float16).min, np.finfo(np.float16).max) + sqrt_d2 = sqrt_d2.mean(axis=0) + scores["sqrtD2"] = sqrt_d2.astype("float16") + + if "JS" in snp_stats: + # normalized scores + pseudocounts = np.percentile(ref_preds, 25, axis=1) + ref_preds_norm = ref_preds + pseudocounts + ref_preds_norm /= ref_preds_norm.sum(axis=1) + alt_preds_norm = alt_preds + pseudocounts + alt_preds_norm /= alt_preds_norm.sum(axis=1) + + # compare normalized JS + js_dist = [] + for s in range(num_shifts): + ref_alt_entr = rel_entr(ref_preds_norm[s], alt_preds_norm[s]).sum(axis=0) + alt_ref_entr = rel_entr(alt_preds_norm[s], ref_preds_norm[s]).sum(axis=0) + js_dist.append((ref_alt_entr + alt_ref_entr) / 2) + js_dist = np.mean(js_dist, axis=0) + scores["JS"] = js_dist.astype("float16") + if "logJS" in snp_stats: + # normalized scores + pseudocounts = np.percentile(ref_preds_log, 25, axis=0) + ref_preds_log_norm = ref_preds_log + pseudocounts + ref_preds_log_norm /= ref_preds_log_norm.sum(axis=0) + alt_preds_log_norm = alt_preds_log + pseudocounts + alt_preds_log_norm /= alt_preds_log_norm.sum(axis=0) + + # compare normalized JS + log_js_dist = [] + for s in range(num_shifts): + ref_alt_entr = rel_entr(ref_preds_log_norm[s], alt_preds_log_norm[s]).sum( + axis=0 + ) + alt_ref_entr = rel_entr(alt_preds_log_norm[s], ref_preds_log_norm[s]).sum( + axis=0 + ) + log_js_dist.append((ref_alt_entr + alt_ref_entr) / 2) + log_js_dist = np.mean(log_js_dist, axis=0) + scores["logJS"] = log_js_dist.astype("float16") + + # predictions + if "REF" in snp_stats: + ref_preds = np.clip( + ref_preds, np.finfo(np.float16).min, np.finfo(np.float16).max + ) + scores["REF"] = ref_preds.astype("float16") + if "ALT" in snp_stats: + alt_preds = np.clip( + alt_preds, np.finfo(np.float16).min, np.finfo(np.float16).max + ) + scores["ALT"] = alt_preds.astype("float16") + + return scores + + def initialize_output_h5( out_dir, snp_stats, snps, targets_length, targets_df, num_shifts ): @@ -382,36 +540,6 @@ def make_alt_1hot(ref_1hot, snp_seq_pos, ref_allele, alt_allele): return alt_1hot -def make_strand_transform(targets_df, targets_strand_df): - """Make a sparse matrix to sum strand pairs. - - Args: - targets_df (pd.DataFrame): Targets DataFrame. - targets_strand_df (pd.DataFrame): Targets DataFrame, with strand pairs collapsed. - - Returns: - scipy.sparse.csr_matrix: Sparse matrix to sum strand pairs. - """ - - # initialize sparse matrix - strand_transform = dok_matrix((targets_df.shape[0], targets_strand_df.shape[0])) - - # fill in matrix - ti = 0 - sti = 0 - for _, target in targets_df.iterrows(): - strand_transform[ti, sti] = True - if target.strand_pair == target.name: - sti += 1 - else: - if target.identifier[-1] == "-": - sti += 1 - ti += 1 - strand_transform = strand_transform.tocsr() - - return strand_transform - - def write_pct(scores_out, snp_stats): """Compute percentile values for each target and write to HDF5. From 0529b9266ecb65db44ffae56ac19203bd1d33e46 Mon Sep 17 00:00:00 2001 From: David Kelley Date: Mon, 18 Dec 2023 15:32:38 -0800 Subject: [PATCH 21/24] snp and ism tests --- tests/data/.gitignore | 2 +- tests/data/hg38_1m.fa.gz | Bin 0 -> 259113 bytes tests/data/hg38_1m.fa.gz.fai | 1 + tests/data/hg38_1m.fa.gz.gzi | Bin 0 -> 264 bytes tests/data/ism/eqtl.vcf | 2 + tests/data/snp/eqtl.vcf | 9 ++ tests/data/snp/eqtl_flip.vcf | 9 ++ tests/data/tiny/hg38/targets_rna.txt | 41 +++++++++ tests/test_eval.py | 0 tests/test_ism.py | 46 ++++++++++ tests/test_snp.py | 125 +++++++++++++++++++++++++++ tests/test_train.py | 0 12 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 tests/data/hg38_1m.fa.gz create mode 100644 tests/data/hg38_1m.fa.gz.fai create mode 100644 tests/data/hg38_1m.fa.gz.gzi create mode 100644 tests/data/ism/eqtl.vcf create mode 100644 tests/data/snp/eqtl.vcf create mode 100644 tests/data/snp/eqtl_flip.vcf create mode 100644 tests/data/tiny/hg38/targets_rna.txt mode change 100644 => 100755 tests/test_eval.py create mode 100755 tests/test_ism.py create mode 100755 tests/test_snp.py mode change 100644 => 100755 tests/test_train.py diff --git a/tests/data/.gitignore b/tests/data/.gitignore index c79104e..26c4af7 100644 --- a/tests/data/.gitignore +++ b/tests/data/.gitignore @@ -1,2 +1,2 @@ -eval/eval_out train?/ +*/*_out/ \ No newline at end of file diff --git a/tests/data/hg38_1m.fa.gz b/tests/data/hg38_1m.fa.gz new file mode 100644 index 0000000000000000000000000000000000000000..f2b9c20cd156fa5a1a3f7fb72de39a9ea8ec11ab GIT binary patch literal 259113 zcmb@M!;&b9f&|;PZQHhO+qP}nwr$(C-KTBa@6JC=t!hypkQq_<(GVa2|Cc{703l%@ zfCQnNT;4Pi={cR34OsR8X9t1~F-YzLq0BGzjX>|&VlTgm4-l)DJ(>Q?sTc`(_m07t zfQawAzbF5nyT8}(_`gT~{_thhK^;bOomyZ7O{dDE~iNn`@^_<`T z{qgYomt*cV$DLa~m;d*}X)%|>Z|}FyaL3ph{`aw;kACI*_H_2L)!x7U{d>LrWO=u5 zKF^nT(`n9s$Jp~T<6ZRmH07=FHNMH5=l7oA|8&{!^YGE%_erns^IMGk_j34TPIuW` zvGq3No$F7RWPGZhcmClX+)-{N_tG~undk4{_Q_8ERUYVT{*_Md4X$P{^ZoJu^y{_H z8}7dc97gIT-vG_(4T0YiKGO-_hkt0^6YkcE|7_Rj`Pb$Do|a$iarAVZcFVqY85_qB zOg;4S{qaS4SiOJ1K*HC**Jw}j%02njlrMCAgW_OwcQ@zVw7Gvf0C(pBoR(}qz&umu z&-46)!oLpu#eM%XlI87!$ZvmtH|YAl$t^JsSR|kNsqXnpFoWmhCftYd-q$n!>bI8Pe#3N~e^>2qcI`X; z`^!5XfPNSLgE<&9>TN4C%79O=wI*lU8-9z^!_RuO(TJ?$y~n@K{NI}Q>`QNGlX5S^93kdx z^w<$-n|MEdKbhT_$O`J&yZqQw@ELdJdbQ6#=PlrLq`*l}o5YX5H2fnQU%e5(hq|x1 z;fk%d+cu9^{A+NwbC34JkE4*yd$*hR)n1-Hi@DJxkQW$2cHw73QZc8KVAlid4b z82e+y=yE^e^XW-g1Q%_D`m&e9?V0<+nfwWN_$drau@Qe)j}<~-?Z4C z-T)2I0OI;!6M;_vJo{!o+ieW)>A`Q05lY5*ZbUAavMt|jG9vqpMaNFR;m~EaJm(D| znQnOR?`do9Yi{UPY{<)Shm_MhQfA;``F#V7E*tdS`FYp||FkPybPLmQ{QB+{w&xB$ z2HXcz=_d4Eu{F3(cUJda^ub*nXvJVsZ+UE`uGeC;YEADL+P8b~C-sg5PInV`_dZN_ zL#G)kNkDFVvo+k2WBxlr zZ$*11thlXI2r%RoTMk^~nR^1gy}(Qjv%zPUfou+svu{YBn}*F5+5~z$wTm>ID z?;CQa%;>X)CMLf4?hKb#JClg@hKO+xpN;SymoeOTIGfi;%qK#)O(LIHIr|U9ygQz8 z{GEnrM)31Hd#7Q(eg1q{?>HciEEA&Pf5_qPY1T-Gdse(RoiYtRJx8=R&M z$<$YP!&`6NiQ_2F09!f*_-TFy~nqGFHI0X+p6PcPBwU zHHI%`*tYG5|1KIr?C(VsaD(lGtVJz&ip-|11fmOcK{If+;9fTeHhfK2Qh@?YaVxHX zz+(LNQb4YRA!6-=o*48KYC&(_CcxP`{>l19k7PsipHSy=XqAzWr35Ty0SZ+^LRFv} zU<aSgd>ANA`U}_OTaun8=9H(7_JD^5hPo(?APkN!$rtVND6T;w;d=Qo% zvO}Dh%jA=+;eL%_6gfE891CL$%|H8=ngnVz%QyN;cu5Oy8X;|U@QdSDaa{woagwWL z=AmD$;E(kpHi9K)OTfW(kHkQQi{+cCr!6*;SdNPxhCp4b(2?Ah_u2auWX0%bTR;C! z3epCf3)ecTLm-H1SV|2|bQhVj+YYtlUC=mI5`Erck(g$%=#-u*BADmfH|Z55Y#_?T z5lU|kcFaxx#_zlzrBgGuO#!3-U_h2Yo+Y-&U(3BfVN<=lB~szOF_D{aeWL;cb30s_ zFDv)hp6EMRw?JGX-Ec5|D`><^etOrv7@959^#ct(tu3hgQ8bo4kCQnp;HM6FSA<%} zHtl-Av!J_>gk*vfaD6Q9-+Vof$y@Uv-#5*UCItltf%uiJoLbLM8=Uas`YiPBfULY2ks&R}PiMT+Q<3 z9n;On-7MN#crs!t`)^K5K7z~YyCu#N;1iCsIeom3=cx((wn%dAEhF}9(G(DqU-`+u zuTl5*aZF8xOsVLfUP$qJUtHZ^S0jt>#@JdRmG*uEP-e$*iYLn?jgh{2!^-%)=A%$<|#axvB9Uu&uZrNt0`4(>^>ZSZ78!2e2y%F!`todb$fc~r0~6ZQsV*?FoSR?zERr^FsBZW0^9MN|`$f;$ zrE)bX(Y(KDDQ%i4I2jg`t6o6TZp=Q1IHU(f>2}_xH!b~HRoDUw9n;v@W#hA9DjD%@ z$~3e*nTWw^RHGkk3XG&%?2&o_z;#Z|8KLGPi0SCdOLq8k)Guj5%iOm71#bQs0N#nw zEf&!o)n+JhFDhXKf7;xvro5JRoZzp^X!qn~yPg3GxXKyWJHuO_umUZ@JS0HzSRUQMdT+UgqJSBknw& z|2$j9=!@?pM`1-f(Yf&#S?3&DZcc$q?amODYL_tV>{u&z$$>^std?QqGGs^5QOBxL z*o;!OLTm#XIs6j*6Tn)u!s{%7;OrV22VGjh42tjYssm+3s~8(~vmfKCMu;mL*yV!O zYz?c|(x*JC-}Ht5z3jwlmqEt*3io8Ie4?xY5u-u<#zSlx3QsS0pGgW$i|iXKGQuVmOk2OX96P0=C7{% zR3;D>6P`l<(0t(aFWgk^y2W;Nvj#_>L#_JeupE!eh^x3*TBh`5Vm1TAn_?-{B7Yk1 z+QTsZjp+5bPabK{*16i+X-`E=7yMLx=%PToMQLat`zzOSE*?;;iVHPO>fFFpc7eWW zT?wVi)~eXzpk3gU)N2h=zY68c7~vTW66L_*-DBuY=2^!8&!rsF{aw(=034QW;_Gkg<5}KP}9#-0a@f+Aqb3wYdRJPJV z9?g-p{8=eCJ256#YN6#FYk6XaM~XKhywE{vmRo)4v*A;PuFCYtd= zUq8;^mN58C>$pSP(7TF_Kt!Y2_I#L@v}sDwfy)OGV0&OIc~nQRJ(&I(ng$lkQq zOt_K%6G!A{B2}tY&(>cC-PMEJIUm1vsVr;&eC=Qf%#Vp2mMMTDH(?Uy-*!&b0PSJ% z?WT;MPB-zn)4+2Ff(#ZJ?$>$8DnjCslSLGbWS9Zh zytKcvvL5UI-QIAa?A5KOSD6m+kF#xT1GZKUEtpLP0tLg9%+O0pJzdw{aK6>R2OXh< z9_!HZQpYhuHckid5}Vt>2OmsKq~%1Cr^6blbu@_u(l%<*6Vo#??4+rNY=N@?AoDsTvWzJ}qgfTBHW zqH?MWHwu+CY=!>Rm)s3-V0mbr$Py`a_8${IZRXL+S=FTW zL`rXcnaYd&(X(S#%t12F;mP>u{*L#SXSBcC7?)B3$KEzOKO6aT*>7;7Nmk0L7+<6K zG8mpHz9_e^s%P1s3^(Ui-7@Nbs1-YOkPlKP(BuE?$PdADx6`CYIfrRjSA0%`0?}k! zRSJSTZpFARF^`7)9iL*~SpehdjU>0Ck<-$@9RdnHC(f@;K9>ssI62riWJb$yKQ%HP1rpt3Xn=iCa9@oh?PgJFh<4{Qi3D!H5Bl_qvXr=*X4 z7t3!YiDcaI(E8hg5!p`K^QEO_&K#+aS9kxu@;Es5LO1Xu)MlRg{5z%Q96BO*Q*2Ff zWEQ-Au!-MW_yJYnC#Pod404^nq?EXFMpyJkUm0bGzts`Z@yM%KJVo1f^LU&s84&p% zUn-y%Q#)AeuX$2$Ca2^hY8n>; z1AcVVN{8)4#@PZR+Ouc^8KuNsE`R@JtUM&#*ghYAwIbCyRj2Jx#NyFEcz>R z18B=tbwW1HU(2RM(8_|y9UBkSR7feS;Wlot^U?JSHki+fQL|vnLBndHjsx24M_qbI zxH$H>rBG<_Lu_Gi?eSnJ4W(v<76^*6+Q{Nm4#8`*yr8wPCj$)9`&lZ^2bEMKX+9Ej+lVfp}>U8I7{|TNhnL`@yJ`Uk=C>q~# zo1#lq_`t=XMY#M-S$foBaocUzvG>fSZhX|A2?nLWJ|(8iLrcAoH={LKnQ>{X zD|u$#BBl1I!(3i!Mh! ze%pT(R!-n(02&2|rUUJjBZ{JzN#>phpRPOj=H4H(3TFHj!@hT!DbQZuyy%@io0(F< zXD6X0M6Ikxv*LMED9b2>$-8k~5V3_l1v?qyd5Og>Izi;PEz|G|{6nuAm)cXYgRI}Mf}w|w+E z4$B+|9{55w)bBrk96&|16}o*joAkxzyn6+-QRbXRSr%D1*DR}Hl|{39dFxF zq0>a;2^5!#Xr^qz@wq|NxIVSmIozeMLrdUy!yJ)XJmfbGR5dwLtSHXRa-rKy_$DJE|pp!1~*yD~cw+SD6 zpjn`&>%xqb;F^1Fe%NLcOf_C^Y-Vr*x}gXRkMc%dI4&q*y|pIT#0h>S?TwCCNPUr! z4@2N0W=pq>NNcX_e1qiLOfkOut@8-5Mm*1I23Ja5sTd4ZP*jU@icgcn2~w0c%w9MT z9H3MUc_XQVF9)i`=8Ddo4MkK>19Q+ZWzaXr(5qB&Z8FgI#uXK+Z+Gn+4Kqb{ItzQS zY7!SPFWaaNR=q&uObYy(CvLaSwzDHx56#Wa0z9;3)%Q7G%ZTRnK5&KYU<^i!yc6f` zOP(Pn<_P2A(+ZjI6iX;4+C2`0LFy@5=zl(kM2yLFw%#`^!bCm4QN(dVt-0A2e?+t1I^kwXRA?B2y z&~fS{cUfEh^<=CX=(4>xiT?#+s^+_!8W-u?79LW1`_4BZlun|4cJfq_ADi0f&qya{ z_j0w9bNtYqk_`An=&7FvTGAP#JQKBuB*1*wjs!v_&$q-AG``@`@YKmY6&a-t+Wd;v zcF;my6Sv!FTTF%b3OV)qQtrgsjEgv4%OwZsI$3fPY{MNjKntagryP_g;vAcXXx6Q_ zgZGWoNLRQdhd34rU40Q^`@9omp-)}~`Ajbs<~nAz1q5>cK3tWzl5F25%+8cKuLy>3 z;{biu!ChMr!Zc#<)<<7Km zvU9`RQ^bp_?-I$&VKDt+3?whpXfg1p3Nu+QC8$U>curCU9(|9|;Klew0OvI_9rV$Z zikxLMX-8McyA78j5|gj2jyTf!_24%ZjRvP3>Cu?*0g=BDhx!UH*c=@&5*8dN9w55* z{GuuX@(LnYUCqOW70LC*o*gGs3xc0v<+ZS!Ehn2)T2k(GKB3d6gXL!~lT4YLOX~zV zv0_bq8=jU=HcGpjdosCraU^0HoGOa>N!8f^^r2|p;eXCjV@)7&2WJU7>%Vf--sN{# zq+F%wv6HZE6cxvOvMaOS|H=LziuIbk-Tiv|eSg-Yn|Y(;dj1o)h(zpu*U9&-gDvGn zp7c{fey@n~4rtwqyH!#zX+pLOk&If7yw=@J-CIO765bW2LRS@+H)d?fo4{erFI7`j zFUtH;Pcg$o`ZXuQ6*W&LqOU#Hsvn5+ zUUYK)K=??jut;lEda%vPjT-Ja)s~XpF3;TBrt7cgXAsJDc`d=5c0x+hJqVMz}qjQkI~wI zPCv5{GzDv$5WR20DmnhV%10*5I$Tm#@+)QeJDm+LVhBwCTs2O8@9TEd`^eP}H0mv? zSq80@X~a-P;z^N#!u1dz7ys_8L>v0)hNUuowUPwy<;|8vZb%wf+g;>HGrP&*Qvyud zv^(pou7}mO^8t(phwAj*#MLSp$A}xAb(|hchYVB6@^n(-QX;CiB)7F=FfmV2UkZu= zOFK4=(Z$m&dtX1y&@Sh)a!AaZj|GOu4@nwntyu|iC>Y0O=E0hVi&3DgU!5EB=qN^YOmIqd z*j1xn@(q5&DOSD9EoAzb6$$~npIcr|N1gG$b2$?=8sZDO$ghozuX)yKO2{@Iq7R(u z!Cpc#`*`ls1H+uGUW+4wM|*Q|zuK`3$M=LgE0I2|>ZhoY#1y>m( ze)WR|-x*!h+34S0U@C7Ff~NnaaY_vpp1fU~t!>L)8vD-#j}u=!v)k*%L6 z+!JnQhAh+`x015|o1uzN0MppWp-1V?xstzKx`yLM6(1U6ynul8!87@M8)VKRf9&ee zZ?<NX5iQ_W6`|SQ4u}yw6XE7b`S_V49QRY%=s3i-3qKSJ4k{CVU;C8a<-J)7R ze?Oog?Dt|%iJ>g}G;(%`>urY#cF@&_jK&IPiTgdecGE{mn4mrx#UB6u&>i4)>;6m_ zZPInLU}*SIP+nhnGf0N+onAwG_SEQ!4`Nbhe~xcOA}7mB_))HFd^w1GJWYd)9>|e zQ1Lwrd;1*HFMLwdB{SoVN+8-fQszF*TGwLSj>kE6c&sag-)!#dbb=VN3$Ex7V#*6< z{-o0kqd4rU;4a;*OlJS{gO0C_uKH~9Z??Fs%TB2=lXN31>{6-yyPOk>_wM%<#0v?r z85<``o2_=Hz0XiCy+E%ulL!=~LP+^4YAspvtuR`jjx)+%_!$Kqm7EsG#{80j?+{n! z?QL9PR!fX5$LHRyYM!|HxwnwU16mSDU1@v}vE5K=BP;gBc){ zD;-bIXbgu0)Y(lWu0mz!EBr1~V&l3xmy4h{gkcMZjQdk#f9>vt?S98?NRzXej6F3m zFk}Skn6r3xlBF~K?XUXPv~cUJ8{g|Mx?@J6cV((aUW@p}_hZ1Po4*Si1c0^+FzI(B zNmM)`r^9@Ppnl#B$>57o&msVWa5;rhMp{P9rpMSO- zBOOh96r-vQNluu!q^wcMaA_xHykmo|!P`w&F&7UxmrCoRfWCfQlXwqA5(;0>oc@#`0e)X}>f(`CK zIfzXJqdm=#xUVb?%;Sq=3Q$$_!6tB{a zUNc!=#Lk(k&JYgJjHTrI6sZ`nC_r%_d1v^^BpPkkS}-erSDmI)LVJtKE5sRbkU=*i zg!MogH_E@l$q5-@mK1{b$&GLvfxV{b(`sxuZ5?${>GMFzxS=$qt;}rcaFg?~ef@+H zY8M&g8y7C*E5Cx#c3&~}R$IFj5MiR zm_aV7Am={wf20=p(5RFV1|+mTF5&`$Em&n6eEu@wa?(=3f@vjq!g8x`3L+}-4NfN4 zNa7BBMn12b!RW;_rsHse5eu)Tr3Tb@YSP-0#dVS5^)Qx~(8p!wejRb2XvqEBXcS!o zH4`}a6ed}5y$D*tkt{3{4N$FYDajv=c0RN_vPM_oPAhWgiC0WR*6-xNV~bUGH-hZA zq_}%w9U-`UNVEm0P16gzgDRJPuza0HA3sVBmO; zEW|W!)kQ={55*8&U7BKT95Xp0)=(xzx2pbGg)*JgoGRf~!6-Loo&=H<&Y$Jp< zE_krB&bon}Vbb@>w!A)LF0Mj{KwSGPAX?cj|s zjVtPyzvO*Qcz^s$NgUXBCF(~yNBLig^}Il0mwzEt z$t7|p{o#Jn&~%~Ad88)c3JTbLG`F}v#o3glah@xZljOCysH@Y&ruS=u{3+)re<3{E zIZa@=B1<;^NG(yj!R%09dzj;_c^{~#`y!|~sDgtP*yP(-zPjrvRi@Y=h}f`olFiG7 z6H~7wLT@_^KC5l|+G-I`mm76&;2oeXf;HzVC(#RP1k4||i~tXSYWbo1TN&Jmx3TJk zB@mKSgk?&Ysy*^KTvyYOk0X)VTto-%(HI)I>EzWgrvZFbYN3TO-WO}|c z!c#lXuwn1X9x>21gUqBz@jq_(lI1vgHoI;#&KSpb77q zZR<=WQUP8f2msSB&JWD$gt;F2*KCxu?2Lo|fjf96oQk&p-W zdIsStwAH}z@$B)It1O!e6-O)E@vuTQ5Mfi z$Z^r$;?mCILv4;##!y$=;bI-^JTf%K{~%{#nk*dvkY>F{d5&xExfGC%IYW60VS3C) zZT8Y3mVjpt)jTqg>q25qHf_KhZM#Rx$djblt;T$qP?)|uYv7>nZG>*S4y3j3mKvXGw2yb6 zNDEV$n3B;*=~3c#p|1T{PwO-GTIB)SqfCXwPfh6UqsdvxRiFBFF52 z8vhT?xpOp<>*r=P^Jw6K`?Y$C^0=j1*PMG-vc?#d`XQ7nA-!myg9-P^I!Vx}_@Zda zm$nD?-E~VOB}y*uHjc=Qs1(>=im@*_gq^vwFZ)Q|J)2k~8t~X;!`Wg^@zSH_8_@gT z?$`x*ssfS0^m*4w0BZ03fDK8x^U07Ec~bI}A_(mH zDdst(Y>+vYDea7EHPn2k5lSRwtuJy}N#EBlzn$_#a*bxwM%=B8x7v| z;Jo+0kN@RzTTdCo>tHvk)Wi(j+tsUDCz~8mg~W1q2Qlh2kwPe`Z-80+mPiNRm=y8n zj%D}Cq$NQPhA9DD2{)NCiJ;DQc8AkLBcnO=*boe;PMjv9376+f2fjbwd|?D%GdGQf z^k$GhnIstM44O1pO}&5=%mFmez5HVxJ*aFllXQq_ymx;xq2}0z>=32K7@4~^Ys3mJ zX-)x8M%{stNu9GSWigmzNNymp4e7ACU-bSsZz+&&E0TN#A~N=e3F*Y{puxwW)fGh7 z9qs!0HvX0!iZAW)3&Aq(<`xUd4HZ%kKhB=YiCOpgGnf;-tl?&1E?osL{? zj0RD$W%3o9Lw2e@ld9v%s^lk+6~m2vPJZdVW@RuOGmXWsJ_QKj+>8nA+HkZJtHhox z6BW##>bxMsc`&Pbi;Lg0F$QThfCQ%kKW#h5S$(8f zDJIA61+bfuL>A1!e|@&t`t*fQyK$(E{_&dDH>-tryDArao8kX9^80p}OYV)xn*S(Rj!+d>lkwo~gSU7VZ_UKk%bP=%se2_?cFQ%e5` zjRw$Y!kf|LmhwyF0;*&Qj^v`F#M3*G?i@)G7%l3co7trDYaGUpX)ZqDK)pOb(LAbz zore$OE0OKJ$wN3o(1R$2>eU@GVsfz*Z4sZc$TKBlQOl_9@XmoCR35*s?G zSh6grz1BMLA{&Z@42}~@(N-O%tbp3yC0d5u_6&AWJiL|kI=fBvL;ZA3jRt`q$KUpP z=rQxMt5L$%{crT?Jt$rYSGkB^g=sV=V~i!x+I)_-GR+l#p;v+=n z*%B@Q|Kr6e3g+KGajTBMhFU{%gCm+ZHct~ z>I~lmhfX$|^gmBs_JXxV2j z^1!~DCsazm7Kg;kdhSx`$#Ct~_rCoRjT)<7^MINafmSZyQL=jZpTX0G}QLL0vNW5xlTiQ;}n&xg`JH@D{WW&XlEs|+Kh95nIYK}B6 zgbWVCTnXreZR*V}{Lf=BpucrrclCIrI+Ppc)!-pV0;<(VZ~^8N8PNB=i-K}&MHaXA z;pO5C;(V4~*xYDbd)8bu*5wfN*7ZqxZ_mU2V9#ZQi6p_^;~!hfOrstWq}lbyP+F&t zbmH~54LqayJpEIQv+r|q`BB0~GQMcC}$~||O#`er6>U!S4SMY0BJ`=aP-!!L_>Yek?#_Qf?^Zd1QHloVBmA4aP zx9^%5RKM3P``*xv%0SYvUp3Dqin&&_uI0njQ|a7j`os`sPda zB3e>6{jPO3Dgmy`NGN$a2;p-O^IZ$-(^Wg^C$dJ(2p_O{o=Zs zZ0`Y*;;LjQ5x&ySCcYj*aQIcG%V(_oC8Z z&HH*V6)z?23P%Pc00ILP)@%8Gti=M!ZmWE?;)! zZv8PNe8{EM`g%O^tAppBUz;W~Z96C9j)sd9qr+A1sLz%jzk``FWpp~(@36 zJ?iM&c<`-*?@z=oKDv&_gqD?NGdUE!4MjHFatF%Y7Npco_JmFre$HpT=2^dx7CAo$prw9ImxzEA zPk50{5rSRat93z+`piFJT&jaV1OSe8r*ILp^Hcn3Z>*0Jxr2vzmik?pB^xONx2y~b zCgI+lq8`MM3GK+MPFBJXZ+pMY&IvO!{y~&mUV&hd`6h2SW$jMPak+qqp3_S&@@no7 zcXH**wL6l>&pwMf^@rG61IIV@)IU~vj{|%kZJ01kF?x9;3ALSNk+y+byN}5<@Kpn%#{_ z=;=cKvH3>Dh>c^8NwrTtpNZq}$^A6=4eP)`I5T^Wlx+XLc63i$Ujb6usfLCz#6JE} zwA6aNZkf~aRNSQ566?c-Ej!L(iGNXF<;5br(mD#r>Bu%fe2b>!n07M)>wx<%60o*0 zfVYb9!k$$R(3X3(xM@iVul?4X+-}`fPhLsmNIWyKZmg%vah0LG-ZP>c&UnasWV(DT z+XYinIMn%;-0)MGZoG}F zOCd$5&t*lXYY+$3I5#_?8-yZ?0E2I0z%%t&UKGepL4Cn=lsNUKSN0j6G|E+B!}g{o zK7+bJ0*2)z~SW&ufKr=(d|zU6GR3 zoi#JDn6$;g46D~me;gQVsf>9xATvkBJCFyb^I9hQKvdi~u8kTvkH4yFWy({}u{zl! zIVHb05l4vmqUsm{hbuAz(I3>aqo7~~3130yO-pq(oqRUao4u#iP>MnZ^gUQ`6orpz zNO@QAbs8giw4_IiHtqeCPT(_nxTx7Y5jfg(A43qL^PgK-_q0y< z^0o~QXEzNH(MuTDJ23p_Bwt5{v-20i&ESX&)~F40j3To-N$zSWzf@_|q`#2R;dA&Z zm(t2#e=<`06m8MDcUeuf&F5zsz&J_5G5NB|2{u51RGJMj%{y3(-`uf)W>XTW&&)4y z$cdjBy2e6-RiTZ9@RZ=OcTn$FcqT_4;tKs2P}GXMD1a|?gmFn`wsb10egTjDwnHwb z-9?p>}hIayGl*i9TS=a_FO?nz(!w`^aPwaH=@I?Z;E79IM z>J;x^ldrkf4zwDDGp$ID-o5fqQI$@AID)L0)Zu}&q@h|4ANkwj2(M;9qFxeNc&4(h zSCws7;7+^Pu1~A>_Jl5xkN==xKk|5NR5gI~V!zWvBGeDH%95pE|MJd0x0*#oQVbdP z!xT&>&Z)!(uPrWpIam@HH4s#|SdV>dlHD!4eB zZJlD38nb@@v0E(p#xC`C1+r^6u{|y(#KCsfEv*HR+~Ou)ocsN`vwq1*UjEU#*hnM9 z-F_KNX3r|&;?*NzPzqE}DSwAT_tOF-f(9K|EiuE3iO;t#t_|nbK%ELyebhEfFq0Rn zE?K*~us`A$4xL$8*e4&kL=AdG%%IE&GyR{82A*#AqFlrS*J0Xi@jK_Uj&7x{Yw@GO z%_f}y(L>IBYoOg|;T>tWTnVK<@B1V}U1F?utdI>$(U}e{M)y&LJwx+J8Y%igu?bf- zH8&YDHvk-{0;45}hxTEK;}#uITZ4oM0EAqs_vC8oXN@IT!Bz?}Q??L`C;sG+mI4Ej zixd&I|9-2@v^=6}qdVYWvJg_nFy_pcco1k%RcR@tloM7A$^gt8i5XaCCgO z;Ez=jNw*QwxmaHrhqna#ewc7!9bKz^>C53m=jc#w29LLc%>BsO?n@!lolRGHxV`aC zwCf3xjCIcqu?oVJ$PFu+-RN}ykHAc-CwFc|4tWcK5pg?T^$NIjdQ6`-N#6;h%9K!& z`!-r51?&Lzzsy&Uz58$CtvjD^Q4A@7o_S>~WNc#NS;~ZrSC@wWj@O4-p`TfrM_U~7rJ@~)};Kd&In#4RNn04d6*YDZP;PU4FVV4eq#}7 z7kE8kDUAy4B(U_}XBUy2E{B=PgN;n^2{X5BY_FOi%j|C$0FA1mc(%38rqP|UUIvG% z&>4o@ic45P23|fAFAli>hAF7o!KW~c4rKbe(1YBOAS0DJ<>yhz9A8y3%-29kXmgFVI?V=ihb-sBO~ zj(bZ2ZwHTdRU`FpN*;bK1ZAwp$nkQrmAk1zt1{AS_9Dxb9l`5W1NL zR85w|I9r$CIbO7MFoBiN^8^YD-DB^}5AA)ow2k;E8IogVTYQ`y&BSfka#IC*O571j zzV^z03J=MOwhP2q{&KV3U!m~tm0Nx{BvU?BUK@nv>34MG;Ey78Q4cTK$dd9%R@Sgk zm@-2h#kedRtsi%BOt@yb8msGS>|{yE4hWfVM$1ueh&(pcPGfMBE{k26POa(`vRoh4 zk~&Z;%bDk%AoDib%=(d<&IJn5<4{xxW!$z=EzjoE7H$`Xt9EEEqpTWn`~l5@Np8A2 zae`>Q?f-2YS<12t)%1oTmQYn1aaWBL@0a5F*Tpa5lPU@x2+r=V0lRyEBt2J@H1`kB z&^d=LxL`6A<0YaOn1L!P$glWr3*qILGg_H%?#Fu+s}S>g1D+7dU!5(?_)9@k#TFLg zCII6PmYfLRt0oCbTN#?y&EAtjROf0NhTtf5KAX-=76|`sh-km>Ay>J;$}*k%k(dtB z{Avg>atzQhcfhkX(UFY}p;K5bU@BSiAYh%9kw|l@Jz=T0&a!N|rcz&#gRJ#KmsKn! ztKm-sdR-*qB$XBLKSm-iqY;^|A1*0QC|C1t@G{LuE-G3!WEPRxJ+Q*pbohNQ4hRBxl(Wy{2PXqt zZbWAb%U$JBe6T;{Ml4YNhY26V>m zrFj{d!I-)<*Kr#cFB{O?KW_d>D)~Mh%WNUNg~xsKoIbw;sHSd9qY6ElGO=#_V@QOd zUH`S4H5J(WO&&@pIoV>xwxH<ihI0}6^vh(Y+td~}DudSp35IF9Ct{5I1fiO-a&JQ0YDfF1X3mL#DS|Hw@OFQ@TH^MvXVgcH zQV`qCh7A|n?F$( z&=0oU6Dk4I5wQ-8tK$1EDY0Q^o+P1c0a9xa3TG|49x-L(!L4*a6ai=eG+mpM4l0y* zWowQ5)9rK9k#56oxWL6<;5XM~KDW5n6A;{zjUqVND?ybOt>{?{axLhItj&;>+946i zK2dxk56A7UynQN4Kimse9OV;4%J`waES~?>#*$h8gI_VvFL`5@sX>VVx2~DExwwH8h(}D!2EJLE#Rz#IB zSxsBibA{mfDCCVbe15|DBFbfR?J_C&mB| zdkI?!{u6>f8-uk04^Ey-hwXo+=y6&?xF39iDt2B7J>3$Fka! z4o@lsH)>8gJhvra(@?pU{jRCVvB|z9*xqZYAjpJ4Hhaw*$0h|34CZMcAuDYzc0$q} zYGeuAIUj!T4AoqQk!zQo@zZfhiLH~qzCDS8>R75`e$(Q4)LcB)d%|dzC1CCzrMZ3# zoO@IE1Ba-XPO^_8QF!YdDQIj}doE*-q-K0kJNUlTWtfh7VrJ=UFH6Y0W8?N$@%uk# zcB75}{{R3ViwFb&00000{{{d;LjnN6O^v--mg7jzZ2RuB!oq`30P`QqO<`|yDZi@v z&y8$DA(7soF*AVV+^RZN({sB%U-#DMzcaP3{(0fgzjNo$U(N=6%g}S`vgf-6yF@#+`>~44u{}Be>{d2&_#EIf-{EI-=e?j!pU>hl$Ips>CewR#jk(uocZWvn zKI5j}a=&{`%h&od`PnVVVeVnB`oib!AM+fidi`$qYOU$BFT3@-U6{j~-Y(q5sAe}T zHu&cZ=X1Or0_MJkysNZxUvFbkFxdI{K6}4E+=+jz(&gK&+Ku9zJDHCqyX5|*34ezD zIs2XX!No{!AAO?@44;+m&q3}m1DBS7^I55nS+>W))2=`H{O-X5^q<|EKOfooeuD|i zi;-X-pTBnPYu$f7zE5D;?^uJ&)|CNq2ny?FpZ^@J?XGcumbZJ}(p`SI=iq#wAD;D& z-i_LK?6`NM=1u)$czgCW*Hi4n-Kf>PZyf&+Ao07=(urH2 z;hr^>_4EyFEWldgj=kMsCWa%kv>g0ihh7>Xj)>)~r`GO1=@)x%4AibapFZmZo!FNg5cB-}cf&tM zLrlK={+&)?SJmU>I{^#(9L)3ZAC~N|U-?fzjNuDs=Gn5p{{GBg-|b(ge&1Ms{r8_A z9B)1Q zyq7bW&p-EH4)D%;{`uqc^})ParMCYV7|{(58-{o+{JNr4GHIL z_pXTmv}ahc>BR5*h0-NP&5?k(Yhyj;4l&v8M^zxmCa?0(T>yWp6QGF@!GNHczM|lq zbA5j!{g1_dEakFnw}Z?W^k-U7Pw zwZnazdwR)E8;T(m4DR#ZL)hHB&5&5;PCBWaNp#W#CC)u$Bi?iIp2816&L+!)#r3Yy zP4**tdwN%)%@C#}@H5Z?0tGJSq}U3<;FBxI(^L>_iL}Q2_}03CnRPHb90@QKJ~XD< z8u7eVcrN&hoMm>xG1+7AN`su&8_upCc!zb`6pW>rYVQtxam521dw*ef-%< z@c#vPZXEh-_s2^LPzJCY$t~=4Nh6dN%slmtriS|_H}qYDk(dFx#ND^I|_yEh%eF=q0I(?umAx(-B z%uXy{IF4C#iPa<+;}}F0Bc6!79|`=VSHeLBB?3rGe2X>c_+-WpO-L-h;zN_DynH$@ zgx`KFSy)e^$@`$l_4ac2id8?PtfYOSy8 zwA%a-gxq@IzGXiJl>PYcJzA{MJ8*V=8-ax|Ak!>RA9nem5L9U*B5m@oAi3Sjo$#iQ z1t9XPK(mX528ol!DyWM@M*x0dn3NB5W<3bwkvK?4AD_4(AjTrm+8*{EY&}8p8iM8B z@QKC+@D1Q-p+t>)I38092seUZD&2rhlKw6Vs zK?@W&2wxF~ONWDg=CDe}zT1R(S{{C-k;JljYi*Jng}YDQm-t>|>xk#FgB}6=xB0bK zB3MUUpx|F%&&U&f^^jisJJ|g&v$?8Y|GY7l{ntH+uvcNSvt?1Kh$>8L| z?X$NR^{C~mi{YIS!`~!ci4!J(+uwb?2Ic4~4I2LfblIfKAhfMAvF$E>FbwLS`D7Cs zz{On;M14764w^`X%-?KWbyn8&3$@*pRFBJ0W6S+& zE35Q=#8=D#oMHe9#8hAfaeShs3BmLy$XD(n2&(W8qH)PyVFmMq$DJ;~2GB*yT4nPC zdt87pJl;D3DltRE{LgZn7I!8WR7WEdCd~x(Xf~%Zl2vAsHj|UoU?g-b+DQ-&I|Y`3 z&w+;qM9u62dzu*wLh2@)Tu)aQ_%RY(Ae`t+oO^%tD$#r1w2N_c$2NmL>{iOcsTw2( z+>J2Gd?>Ct@VdMakGwO&&NIqMn?3;(EvN#(uZgL#Zj3$`0t0>WU>BDceG}rS!fY7- z*kq!E28Ls9elm4w6#(V4IZ-ImKs8D7b)$MxoFOHg2}+5+hZ0y;i3n&Mz=b&l-jaKf zuuK-%Q9VAmVRz+@MUJI`h2-xt^i=dI6|zeb7a&$-bHAyG!z!Z_ntce2Ye^&q75p8O z@`vDMG=6>-M(kT#?to_`+Jb>M@maC!7~;gw4dZ}j_|Q_GA&!7D{Fvr|*F67`XCB^& z=j-KS(bRTIMJGYyz^d!JKswT`?^kyw`1#}^$@AXF)7%SS%o>L!Lcm#d!iL#BXfPcS(BKz+o3sTYC)G%C1M*Y1bE zxQ>me55yKr5NT7t7*fGTOATedfeF+QSvHk{^$dK!lz=)APuSzGjFlkG@i0%yI=ZAJ zH$sMmB*0F6)KQ?9!czTkhz~k`d}r#Vwxgd5wktdj(5mtcuvb6$_zQLp_7*dgC5nEj zV?XCvHU!|>p-24Rw52ta0>gxfOKLz*%Mo1_^Zf{ncLPWk`~L2JJCiC0yVc5AgyzG3 zQ<4luWEnc~vW>8fPI$!sQARKd+#X@lnlGdM{5gptulf?}B>zmTq4F!@@HaB#-@Ku| zm3!Clk!`Y>jHsZd8XGOrL|KOZ}; zU2QgUp~P;FTzu3sa?NL~=L#A|dc1#K^)jR!VD0s^0L4+P2B&(!(r%kM?gNS`<>`=6lc@$UCG=hju9oVrSPlb z!$}CTH)`Te>xBLE&DxWh8!UN6wIc(V5h$YH7#BD^0PBKg5UA9%&b^u;j^2or0p^6z zpz7U#&s_F1_LZpF<5*17vEd$#oSrb+%F>e8_U zcuCf+9&Ta^AC;cR?Jjr|E;FY*|x=5oIq<_5dXAu~DS*q5yLJ z5ewat%|M4_gg{j|yY)IYD!Kl=95pXZNwj~wsw^t({vMj#Obp*trje~O*pUHt+#l@% z(|`R~!|0V@dcOJGe-5x44SS6Z(fKz`ed+F={2+r7fz_$->z_3BjA!l1>6@pX3KTVT zl+8vx`ZI^~@>G5ERMM2P;Wte!@Hmg`J#Z0+k~dR7oXX%oj@(8+e7-w{(W{1UfVwmz zZGC_JNlNph?^wA_y|8ZF>HK6Ds(<%7bg4nY4hzs9TFq8HVY8#~L>Q?Q#HA&;nEqr= z6aDs%8|Eo8xy5Hp$vl;I;co93Dsg0g+a zG0O+XKtKS&5@uI{o;6(VKDZVa6XTb!U1J`8Y3?%$cOws`_D!No$<)P)@o=VI9Y(wPE7pQBD(oC}SlG->kCzHT%BvfsO2Cz>6HFEdzpfd3i(AM}(AUJ0~<9Vg(zm{^>fIH(E)YStNwfMgXh3ej!uXe6HhkSlg&*?Yg%Z8haIH);5s#l z>8#j%>D%qp4oW5uVhEU##PiWp_0ozCxZ2k|X;s04)ciT`Y3Va{5OV5R^a_72>P7;B zV?C-|OVtGzMg3cW(h{RF`GS!^ItCz2Q<8n3gtT)3_KTBMV=#V&28j}(?W6YGtY$K+ z#NBpY@J7^vkHH`gw^9&_tc@AI`|90x%`D;d+s>MdG}Y~KcdbSC3f*e6rbzLBGYPim zKBbFdy_uz7mxJ5M5(&8@Vf3(-=w_i<9`Al*@P69Y+FGYf#qP z)jk&t`Smhui8Ybm6Krivqbh0*WMZ-m9&SohFG=s`vqyf5I=P3}SzcE1;tVwCUfEWt zrv^-Sl54#VR;Ik*?9-9wZ&2OCpk2XMEl=6w9R=8=`uc7W_=nE48+%ws9&O`^qzPU* zO}(sud)S{$vZxFW00aeTb_gkJud|R2;xB-1aDeEED=vVA`w4&|GPD8j?Z|$N!$EF8 z$h)>;)k?Vi*AzleFCT+sEJQdY8+9a4_eSEd7N%O6q=iOh^O5LE>s3<}YFEo5Iq4M- zz>cCX{o5CsQt4}a5`_rSfnnlruxkPQ{@6XKNA}WZS)oi7jD>P4O%`gSXc89E5xbz%S%7V`7W0c#r7VqE={YGcPuSIto6kr$WiH0qdTV3$1r zUx(hFmkt%fuavl6Vdhc>L1jDQ(h&Q*j55eWvjKzaFC2_3Uo>A;j%%1iVleh24+<@=8F2#q zZkUi9VFXw5iqycTa-jr*$p5Ciysur~@ zprh==&yx&4@?a+h3++rP6*tnOeMPeb_ekp$SMOW#YeI|dvM=CrBrQb}>kzKAvqKnI zq-0TMvZF!D6{sbSR-vKBCkU2V7x99?)za>Vh3HWfc9+c(;dYP9(CHBLahkw&11E{M z0i)Q>Bxtf?R~CXgT7G-A-g<^Uit_FBuiTW2zl?SJ`@v;hXeBiyUqv`RuPz5aa&=&(Bx6 zYL$mQQFpAYGwD$*Fu9+IKynB53sgnnA~6`9{G-CPf-0yU)B+F0x1OR7B>Zt0`sV_ z^~>&HwG%~%@BsUgV8~Lc`dk0|tk}35GBwOqp<2D)HdWS@Ch+^BNj_l(luVO)4>pr% zsm)jzzZ$8MC@W$bxq@DTo$^bicvIG7HjQ?N$6iApDx{?P+QZZy!84-@ehBYXAJy7h zDSZK2h2%;v*A31*^in!RNUo04Pr1^~&lC9SvCfKTeMxS~aeJ9~gdvf&!LA|-pk;*P z*6PXgd|Z+XGKDE#W?a7y+?III;6MOMvpyDIB8M)*=XzELH z+f=HAMH%1?=SbHq2)sr;!3ZRGWJLrM3#nDF1)!{^vk3t3Atd2y=Sy?|9x;qJ+f$2}In)|G$OD-gD+BONq-981~3 zqpRGqfHz6F^J?SAX}V^DP|fsB;)dj{sPg5W*kyeo?@fMHw%{|U*8S!8LiR4pW!WQi z={+ExZ)Uv(SKjVOp&t9|lRR%=n3InIa5gXwk>?oR$4Muo>;_C;)*r{AGjeq0g zFZ=XfCqBygGw&bxK&S2t^Gct?0n_Poa9sKXSGiz#AZJTsOGW_fF$-`RtFht2>eQGE z=^rcglzv5&>O{Ll9qj6}oQFvw!)+A05-iY!xSC=Pq~ln8BT|>DGe{b}6rla0!_I}i zAjOqYTuH0To*6AeB=gCY_(sUR$_jz!tMG|Y)W+38EoYQvr;^}}+==D-EW;^D1v)z6 zeKOY_1e#PxAfT%tsdD8$e#JMeVK#MhBNmdz( zX%!eL%M3z<`iAoJC{6ru`Lb3D_dSvv=2~iW{mh-Xe82o;t~Y$}R3hReVKE~?aS{x< zqmDK4zf#Q}GBp{a0M!JF*s!^;4-)YoN#gvMKzP2Q7R32}v%r^NN>rds=ccfqA`U+p zQwunOH%dj&U}#}@MoLPy6@+2li( z<~s3I+cvK&v$R2vy;N-Y9Ozi?qAEK9=@4M}3NOJjo03fmRugM{`UvLpI&1L$t5>%6 z({_4vWxZ9hh-yWRFJeO!Fe@w2@tYbz#Id1)Dw9^cKyH^@#DYT_YOk`XEHUEYC#vs{ z^wtZg>m9BlKka?Q$u zT{evjIQfS5x%eFRP1re7BurbEs;EZ0Oh5axcA9$;7<1}@qaAvBTH@Kew1@a$2|1rF z!Iqa#PbfWGSxLd^3rTbuJyVS>aEfcJq^*`aK#0I^*RqUf0EXjL1@!=9B*w}nR;5hO zZ0NMV38nmK$P{m>_k+r7TNRZFTwSa!vc2u=lrkk#+=6LTNXaDTcN{H0MeJ&EvM*Fb zRiXO0xgDr2FgTjDI1PGnF?vsfY8GqQXnE&_Mmj0T8QI>Qb_NMKH92&9@4~q zQUY?_9=!dx@Az~6?Zx{q@BSX*{O?hJ&-eYD!G?kTef+=v`yT^1|Mi1^{CT|kBVKIG+e(m*uT=wZRk>Nq@#X43Ilfcx7q)kbaS7)|8zRB_2_VBo}DYVE?Em{o4ESN6<)#6n&__Bj{T-ng>+{N z!O(**`yt8CI+>Vmns_}h=CsC2|{FOv;jHQq@T<3+N;tg+4jy`W@psj8tx?{ zcpJ%V`EQvbw9UelbFCF3ZU;^9fw8~DBD^cAw!9w^gZGv-H8xcQfhs3>pul?(l$bx& zHxtthZ=$vWy~oAO5|3Z#!xk96t0PcM{2hLFm4z`ls|Fadq>&zyD+uOfrmac~$E}p5 z7f>C-K4Kb}x$9fP&4E11j__Q^sdc!Q^F`r;#dcRe5vI*S172~@9Y)>fOxW*!WcMe- z{XquWvQ@`=#mjBby+QeR#4R*M8-sP9HRcVlnHYh1q#0yfTY`g|GJT{xx`2{*Zan9@ z^Q3SA`H=|K%c7I$c^`|dmrg)^8Sz_u-Jyht1pXg!`l!e%sZ83F$1aSUa^Cos@ybWS zanE1C``h$1Rz(Tr?`D;i86#KGeBSeLeLQ^2Pl%mPWWL$zR`hPmK{P!rX%#&`=2Je3XHg^lqrn=z&+R!8ZMYALu$A%=8zQbNRz_G2pP1g|mT>DA*6AF$P5`F3o3 zZ)1PZ^=F{R(;@~qb`Jw*ZLg>R#o?9qMwDGmWBNh5WzvbS`|?p>7-4@ab?0q&@>`)2 z7h`!RQNBa|O64IHIKpmmCD-#wqyKdRtFWL-tn2J<97(wO1Vg`JO9>eC@tC*{$$coX zR=QyXcCMwa;ZV*apWiB&aH*7@2ns;~AlTOCB;@y-SXwF_O=|yl?ze13#_@U}lt=50%%GXJ2rn`VWgG;mYLP`$6|O*HPcI{uSiP_~HF+n$|b@%`R=!DtG0o|gw8+k2q_ zNgR{@-Z_o^#8?QLpC&evIBA0@cmki9S zwGc};@=rQgFg!wf(*5oZ_AtTV+}f9ZnR-9VsK$CCrE%M;j-^lgYhLRKp3;_fXg^zu zu@@OxU9^C`@}s+(M1pw+3!T7(s308y`t@QISq!E8%R3D!^6!vb8A! zDU+5-fX#|psQ$F>bL^)P#VT)JW2}2Vp$oeVd-u6(Dp^CY2Az&*>yYS2JMMGSI8vS7 zrgdycv6>%Hl7@{IC#M&vvHff|K89kodt1%j8U=+rKC#h7QL>?Ar8shK?`^)2{&kLF zIMP2WZZ(~(+3D)+n~ZlW6#gqKbA8y&R9CegV+>VA%+1heUl2hC%Q$UZ<4~hzk;QDN zQn?;0{fDH|YI&}tp^b^qNrdLRb>!H=G7GZbeGK%x#*K;bZsq*-09yrin}e=; z`98%cuG4(9a%kU*I`dSQ@*YHM_Cq&;y?5cU7Uj%nYk=Hvn<_#->8V7Gl_Yv2H<85x zxvE2w>1Fp~ubJl)QLe7~v9;|M{$eGnM1#hUg>N-s9xmt!A04j@7Qlr_&fc?YgaVU# z*_B;>36&X{2yr+p!5FG?BO{XMIC;pL-L@l~#N|!&3Zi~aD7h~kbN{o!5p>?A*z+yVxVXl#jCuNmm$Er( zn4mV%)QxUL)&yD;frzHbnh- zH^(z28P^}I=x^5VC^?CR-s^^D6b=A{_)xKKHUF*KYRXp z;(z&U{eJfRAA|mn^Pc}b@%%qOd;W9K|M}VTe^0pn@fl+Br5OTOGA0vC(E^@4N|-!C zS`{Dw;HBo=dKw8Rg=X&Fa1lwy$^wZQ8G{xw%6U{X<&_DMUWzZJU>14J!R7*xG0$yI z9O!x!BPx9YY4O-7`zMUdORiD~xjmKEy$2CWGl+h#p&R>6F1N?H_rbsA%jafO7`O9P zwWv-C9~Du)mHlnjlSr#6n+h=)4nqf=U z<-XQC!w8SWR>;O zdu>8sk02;U{39)(2V^8+@yu^#zF$;x?vD@xZv*hrgP>-LmuYgRtd@^c-FFynHnX{7 z6G5FyqM-(Y&%n7m(Cjs}yu!U}dMRz`8e^xG9sO6WLX)kr?|7*r!SDCs1oe&YQpAzTYZ zsZRj&$p&DN)lNzZzNaSn3Z!ax6IwA$A5MU1{ph!$Snv~P zLjOEBgF=u2?cvXyDv4~Do4J%VWY`m@ACuqT-|B70Ivwr}gc9SfQ&ES!c?V|MOf%SV zQumlwAyGfL(1`Mq%o`<^&|~eQYyk#wU6t%JFX1!00qDF7!X+g8?5&D#5rUoZ!fkC#eg_2a9j`F6hDc1r9-qIv^+xA&DZdKYL8U>I+L7guHl&u0iCbd^|uKI?o z^&X(obX42LCEkDwW4|fnnqp)$WfU<6nD>cP48RlO(lJr7Q(vEyXFUO^nDTk2P+$mI zNWS%#s!;Z?*^^6qz6O!C|BMxmOm$sDe$cTDL+yBX0$gU&EJ;w9yHR@X1{Sgl?@>>d zQ|I$kwFibz3LN$tG;Y7BvjHAm%bqpXJ}xi@aAmpM6a^wzfZ`F!BEOX(mm@L7mxa(XI|1h^=^h48$PO zsI*CEnw(D7_#V4n1O#(bCRWPDD7dN-?o(xkIy)pJ_uzhFeN(ROp+c86mY( zZEBI;u_~8R$soG|7&z~ZQbT^?b{_vqnlowyIl8=fEPSf* zCVZ}N2X+{lHz;JD-XUl;H|z`=Y-zcW(vJHsldcD)q5vNQt~umpHJV}o#(7`DzG8kX z(%}F5*S~ySFK56lV<)dD{C5G{(ve3V5g;k zW#WV?E9Z@@Re_=jxh!>4z{ykp_MZh+4_ztB9Xd7~3FH*v@BG?x>?Hg14WQ#Oep!XcCD=0JYwYZ!_Pr6p6XDXdxfvpFabG&&H#I^5{E>s#Vh+DH;V|n zZ~K7NmWdNV=ROk;)xE|$P%v?pd#Z@IRELpb*i9C;NCEKw)ss7LCAD?X7-54HT7L2~ zmE9LbW030=P#J4XW+PDQ@#aW^>w!?GOpRHqvX6Q}(V;pM;L|ft5KuBGtB_6RYC0ji zb%3-MSOmiL_V3+g{r^O`5Dk)d^~T#;0kp?|y_MX}-$NVEYGNC1<7GG5Y>o*i$kpHt z@YEviRhD7=7Pw_Y2n9{LXI;CWkUN$*N0MW}R(-ItBRp?5$nTF%0ulwwo7Jgem4%cE zxwyGQJLy}*D3p_=RX72R_2*(qLsc@vJjqb49v1_{R9Qk9Pxm8bMMca}J_f?AO4XNj zRqGBo7U37Mon<{JY6){_Q_0#gs_#iQ!kt(oTF2w{h&$s^lIQnK=YBOVcHiEGbXzef zr4_K{kJJYa(HU8xdD0SJJ@5I*!g{%c^~SGFPCd}I8mtTgoMTwt#Vy-n6cE*^saRcO zDIpeodlTwKKAZ<_98slGnriNZ+w)`A#t_E4S8%_Uhc-r78G?ATww`?2XW3w)?lHuN z2`B2AV+mS&!-p#~xX>r*S}MGhOkZt|OJ>$5Hb@GKoG5*}Y&weIww;)3q7hlzB%gsZ zXzv5A?23K)7xttgJX%c>dd#6ViwT3TX{;>q%1zu2M!FE-q|&k`F6xV>Sm{MWsxdgM zHqJsSv`A8~JNxMGB;Ott$}i%=d7`Ee{Gt#p*rto1J56|)E^q>H(TN)qy7K+GYTAe2m*4MYyT^D^!E*Z{XUXxzbu2`)){7a^`?iDs+?j# zr*6A|d7c0wc&fTS{pUvkX&&bAx4imD+Gl-Ed#j^*3dsCZUk`Lq1Jiyute5)jFK!4 zHewo_MBN*lP7JkG!+l~8)LF*b(de@yR6jbT`Hl5`Q1fX#F~>83Nz2P*Ep|&$NGMGyCZg>jlIac=l-0!pW#-^s7QQEohg*rn#zoM~4h#9L zn>g^r{mM-#XfGAbd>@aP`i24VBM5pdw;ko?5=^jI$b!n1a1anDDjW)pIAoV1!HnEG z_bE~vX7fzp3x?T2S^YzU1Xg!PrupEpQB0+^=UP1(6TXyNJOr6I5siq_HaZ|0wDQ`0 zdj0D5k$#i-73KfLYH=W1A!1BP2)2ph2XxSF2f&tp%hPsFf#r|;XFR#src-Ivw zaVIQ$-wU?*e4Q(S(AMW#&a5D(d5TKoBs^4?h({7(919G?<{uVcS3R=OvVKU2y${E= z+PDz%b9k?@3XQ6I(j6o*7@hqr&*C;;`otimYIs4<^_=2v%UMU((m06ec9EF5X*u1J zfsa|aSF-|A{iDZ_T|?a7b}^Mn6!{3iu zPW30_m4sN;*>r}Cv&sH^$1^{jo3|$$Owxd4ZUi|$VW^+9(dOow3Z8q*>V4o9-x8F< z{eHhDiA-5yGQ!-T1cKRG=S{+)+HZ=7PDogh!32uA0q_ zc8RJWGbz>07cFD^0nZz+>FT`drRc`3w1W}v(7I#(+d3Od9osY1-RDI}2#^_TuKh5t z8ji!m2(EN-tPx>YR;-W-Xm9cBC)UtKC>2W~m3VLiY&k5dzcxHJ7$Dv37?gi(E3@1) z;t7%x$^Htio`mvpO8=-o_iyoMuYb8we_X!*Q~cQnpH(;#ddz>yKPvslW1~+G%U3F% z^VLNVqIZ#w`u`19K!Cx__SY*gzy|1nzf2ZYqoqJ%GU1L0cLRnucYXQLN|d8@lbNd0 zxXmpO_BtN4B7(wXcU)|q#z?uY`agcn_y3=f9DRe3gBP)fD!7;8R&j~bMIy+zyG|pak>?T=nE8vE0s{sUs#K)fKaPsTVAgETiGA)7UN|fi-NT**OFYZOa z7WheO9;2ZF3RnsR!F%57Pc*Emv`R9oZ@F*p1nQ%E#oC6*fKg>ao35%{^kdItfAf1e zZT|O2LMmEVvNf7bza0VLK9k(>-9*s6b;*qkW&OhPKr6n0X`QM0h4gvDKXwU?(y1lN zd^eo=c!E>~3sOm%T1%5`v@vMty4l!XS+QFo?2e7b1*lgm4+@mpLQbhjv2H}XtD?3I z?el~YcDX0tgOMo}pjy#Nd^jih)dRe9-7dz;s6b z!x68MW3D9;{lxO+8WMTm%3I*DdKC?K<4H?n=9&@Bd1YhXJh1uLOv-`}mG|4$YtaCIDY8B_HoGHm;)+Y`Hok)JAuBoC{@x&Zig>5x6;i}^6I4wM7Z^bY_w5mIlN(e)0ue8GqSqwn-%fHid zGXf+_{vf7fnrh|lSF)@pvFtl;>M$Z$r4gJ~N${$U5&|l!OLGZ;q)z*-r>hz~u1aTi z0NpY{GU%9pDPf9e#}1i#_ffR@AzzVn;~0JR@}hUZeoDxF4m{dWp?yTmk@u zh3m1DLY`~^$MYZ1q6rmV*jz>UQnLeeUOqE2_f z+JM?Gan|2FX`+>V6ZMgoCw&C_tIf(@GZL39>D0kp=(gXF&O{&>!tZB3C%JWA z`iYTO1;oz;&3}HK3B&=zMQ^`yA0iWC5a-^DB`E;O7E?|gLwRZiyGv__C$7Xt1)u;a z1SOTTNkH#oIPU0ARPJzrTleK?RMM@#jN=x9tNgJk<$;Qr*~YQ!A;w%pHSHP^Qko-h zF|nfoH)VU@w4Fd_QF2rD&%yP6V;%|mH7<{Mj+_4-pTG|)rT zaFC=8j<;kTDA-8QgM3y&mK1cab-z~GX%`u@eC3>~SLeR?JTORWO8fAZYr){xyk>O{ zwE4s$>ac)bP$LOM6j>^t8o6stP-*TAwrbLskdAW64NU9gSImZcLIypL{VRm%T$5(K zVlAH{*X1mga!YAg0XwN*091Gegfcr8oYg2*>lBq~PnoS)?Vhz(T3&Aym<$5L`Qslx z?pC3p-k{4AQPx#QiLU!KQIt`$sK4rUm~`yl*0v)#=%7mR{EeZFIkypEX4_3wk{OTg zjO+&L-X%wB-W+_4KE`DA8@U7USXf@ANOhhba3{HWG?;p{rY&FWjL)PZGT5L;5LFU? zr0HmrYy1%vIvG&rr83(F`j&DYP-ly2Esz=uqWer>(fY$lk>yEB%BHWz;zx;}p8=c> zF?GNuO@jNw=zLhOZ1V*4n*b3AGbjzOSVL?$-_oVJ;$M}^YXyu1$8dgckmBrbSP^>k^B2}UQa_oauQCisC^RO4|g_Llu-ozxYuy$S1>YHrH zg!tVi!vCZ`vMY2fG_@gffN8(dmu##x@5)U@3LM&!A%#5bRC+Yn&pjbv*Y{sz%;lR( z`=Us?Y-!%hsJV8Nj*#g5jP400q`yPV0ZEl|6rk!V5~T8$H9X37qhgCBFw%^Q;!S!Y z$1Y7^iAl_ANs37iDO?%Gc%239s8AN)^HcSml6Wwdc@LpB=UakGA)^w0UheVX6lxpM zU-x6Q8UZwjwNQuQIlMd6WNayz>&$Y{?+VG?V#<@WA@7?jFi?|D+#KL>zLqdy(?H2P z|MBbm{Vk9v(ozbv9jn`|J7_)4V3X}+cOIaF$bg(jtxbUP{t;s{MOh)(2TcipQVN0d zDmwQ^pXm25SES~pYe=g1?|7zfHAAl?*BC~_F|B2EfTu+7`oL2nG+5yZ#)-~zQ%tye z;i0x+Eq}`rx&wkhiU~uW|D5_n929ibSNTv@WKrCP3b?w8)1$GP_DEKw;;#;y2L^%k zJ9R)6ynExBKp#Yb^9!C?>&qWo9iFC~B(w^A$^TffrxOvV`^_e?=6HRfjf zSHY+r(`(pDMbl5j7!hp4U8U3*S^>B&C<0Vei^qUfla7I}M81bKB(MVLPhOVwF}M5n z9i}59=pd`BhH%Q-A#g2?HdIB}Pl|&EZhd1i)0!Y zCBWJZ=P{8tA?c}HsFGBB5v)~GxZ#7k3`1D&gr78h+)yXv4cZ$dt~*uR`UL$C0e&sN z%3GIIz(kFj79d1gQe}Ju-5&`K09|F5oKXR!qN-7N;cVPWg`x`5}*ACU~PrG)jiRb~yNX)<81l-{91%v?PtAc%DVHwFD^0Yhk3&5{x z*T1$Cj78x|(egDpr5@j}ogf8Q?mY+#g*kt}Uhs1LM4-8=#z0p!tWl-qo2aUxZ&Oc8 zo}bqP72eD95-E4pm^h3QfgqG*E52A~3_X1lRzWRi$@{#@!8<|ZhYH5f3t2cKzx~n`23}6IA3cpqSWq57?v2@7g!=mx z@zM_G1S4cFBf*u$naz>>*>sds252sp_}Retc#Yi+op_Hd)#{w z@L#J_po`Y9qf2b+!Q1wJ7a8y1_}wX@Q>;Z)uzvYD&1pTNQ)tv@P$1=U=rXQOj9+L_ za3)3ni})Mu8eG3!ooaz?7X^iMk4XwsVnW3~?DXDZ9cIN2h5An=BVMeyWKT#D3O@-+Q`3Z{f=) zz}SLL0OYmYRx;fIdyrlyJ7=Fvhh}3gxAgl6Z1>bF6AB;{I)Of75p*v1YA<391}3tT z|6VCdNHk9mCL{Ov0c!vkr0kFZB5t_h`5_N4;bRe{NFTLB1h-xZ%q#bRA5avnu@U3e zSM@z@a{YPD2o!|}*8n_G-v_MJSBo{U>jV+I1uA#@V1H;4KTPFJsmkQ1p!gcw+RaM2 zvQs*{nPa8IG(tFQp`?g$;qzH|%Si0{1fY|^u!7LBjga+@7bh^*sN2!FsPt zQePN$8B?P#q`zf4MS|_QN~n|ugLbJ-TT!{G4>M>UN@ajt^FtUjt9b-4wN(io>`Mg=fRXJib}wJ;s13E3EVYj(U?^!kdECMVB$FD`>Y~KyDJ)yu zH$GI!VmU-q9Z5}A6$t5hmnRqU0Z4nl<@%R46X@gfO$PUy^>eJgdS@c4sHeBtz9!mS*}AX|hp^ul8UScOm%q&dvU&N2P_UJu zFuHeH$OsZUI<)mtc^r2MAeKG{G&tOs??1l&9(IhSb<#Cedqvy)?_zeYzjFYY@v7xghzXC z>!S18DMznl$u{A(d1%L|0B6;Gqy_tgDI3m^*jb|8h<7c}H{8xn-*6&YsASj3CGa;D z=v}6j2Tk@bwNa-73tbTq`?lJ+(1x4LrIV=AEHxA^<13q}k4vI@BlT8(bXvcr`6<^@ zAwsIV4}?9jhWJV$P95w7KbU~9#i0;T_LWH;M5$*&iIeE-TX<<{Xj=hC3dtkL`-zRE z#p60aft!T3p|9gw9l(22@+S8ia4LE%H+Zxfc2y!(VAN5h<6p>h=BWo{fVREL>|jQl z=q?}Mzc{FPwCKt$ZKA>x@n!03_F7Y9%IV_P;ZH2&Og=IXbf&Opu(_#%1L{b&HC`xP zhIf#`H9tG{v14&J;qC?OI($*FjI31X!JTafPOKx>4TA!>ThiwRm~Y

_F~8q!%k5 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

@%lJ4mDEArjc!@IaTY3?GOFn&Hm3O?r+)KW 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 h001A02m}BC000301^_}s0stET0{{R300000000kzW(WWP literal 0 HcmV?d00001 diff --git a/tests/data/hg38_1m.fa.gz.fai b/tests/data/hg38_1m.fa.gz.fai new file mode 100644 index 0000000..935da38 --- /dev/null +++ b/tests/data/hg38_1m.fa.gz.fai @@ -0,0 +1 @@ +chr1 1000000 6 50 51 diff --git a/tests/data/hg38_1m.fa.gz.gzi b/tests/data/hg38_1m.fa.gz.gzi new file mode 100644 index 0000000000000000000000000000000000000000..1a8a1d4aafc011455112e8ebc67f6fef62fe9bf0 GIT binary patch literal 264 zcmWe&fPjfkP{w}<9W(*T|HlYsEV={b|78L*zI}x9|1g6Y^1pF{`4gu>`Cqxfe53nN{ugdAKUEvz i4u;P>VE)+(DE|{Ln7{ofl>d 0).all() diff --git a/tests/test_snp.py b/tests/test_snp.py new file mode 100755 index 0000000..68a0a9b --- /dev/null +++ b/tests/test_snp.py @@ -0,0 +1,125 @@ +import subprocess + +import h5py +import numpy as np +import pandas as pd + +from baskerville.dataset import targets_prep_strand + +stat_keys = ["logSUM", "logD2"] +fasta_file = "tests/data/hg38_1m.fa.gz" +targets_file = "tests/data/tiny/hg38/targets.txt" +params_file = "tests/data/eval/params.json" +model_file = "tests/data/eval/model.h5" +snp_out_dir = "tests/data/snp/eqtl_out" + + +def test_snp(): + cmd = [ + "src/baskerville/scripts/hound_snp.py", + "-f", + fasta_file, + "-o", + snp_out_dir, + "--stats", + ",".join(stat_keys), + "-t", + targets_file, + params_file, + model_file, + "tests/data/snp/eqtl.vcf", + ] + print(" ".join(cmd)) + subprocess.run(cmd, check=True) + + scores_file = "tests/data/snp/eqtl_out/scores.h5" + with h5py.File(scores_file, "r") as scores_h5: + for sk in stat_keys: + score = scores_h5[sk][:] + score_var = score.var(axis=0, dtype="float32") + + # verify shapes + assert score.shape == (8, 47) + + # verify not NaN + assert not np.isnan(score).any() + + # verify variance + assert (score_var > 0).all() + + +def test_flip(): + # score SNPs + flip_out_dir = "tests/data/snp/flip_out" + cmd = [ + "src/baskerville/scripts/hound_snp.py", + "-f", + fasta_file, + "-o", + flip_out_dir, + "--stats", + ",".join(stat_keys), + "-t", + targets_file, + params_file, + model_file, + "tests/data/snp/eqtl_flip.vcf", + ] + print(" ".join(cmd)) + subprocess.run(cmd, check=True) + + scores_file = f"{snp_out_dir}/scores.h5" + with h5py.File(scores_file, "r") as scores_h5: + score_sum = scores_h5["logSUM"][:] + score_d2 = scores_h5["logD2"][:] + + scores_flip_file = f"{flip_out_dir}/scores.h5" + with h5py.File(scores_flip_file, "r") as scores_h5: + score_sum_flip = scores_h5["logSUM"][:] + score_d2_flip = scores_h5["logD2"][:] + + assert np.allclose(score_sum, -score_sum_flip) + assert np.allclose(score_d2, score_d2_flip) + + +def test_slice(): + # slice targets + targets_df = pd.read_csv(targets_file, sep="\t", index_col=0) + rna_mask = np.array([desc.startswith("RNA") for desc in targets_df.description]) + targets_rna_df = targets_df[rna_mask] + targets_rna_file = targets_file.replace(".txt", "_rna.txt") + targets_rna_df.to_csv(targets_rna_file, sep="\t") + + # score SNPs + slice_out_dir = "tests/data/snp/slice_out" + cmd = [ + "src/baskerville/scripts/hound_snp.py", + "-f", + fasta_file, + "-o", + slice_out_dir, + "--stats", + ",".join(stat_keys), + "-t", + targets_rna_file, + params_file, + model_file, + "tests/data/snp/eqtl.vcf", + ] + print(" ".join(cmd)) + subprocess.run(cmd, check=True) + + # stranded mask + targets_strand_df = targets_prep_strand(targets_df) + rna_strand_mask = np.array( + [desc.startswith("RNA") for desc in targets_strand_df.description] + ) + + # verify all close + for sk in stat_keys: + with h5py.File(f"{snp_out_dir}/scores.h5", "r") as scores_h5: + score_full = scores_h5[sk][:].astype("float32") + score_full = score_full[..., rna_strand_mask] + with h5py.File(f"{slice_out_dir}/scores.h5", "r") as scores_h5: + score_slice = scores_h5[sk][:].astype("float32") + assert np.allclose(score_full, score_slice) diff --git a/tests/test_train.py b/tests/test_train.py old mode 100644 new mode 100755 From 7b3fc9fdc00ca7db53891225129617083c298bdb Mon Sep 17 00:00:00 2001 From: David Kelley Date: Mon, 18 Dec 2023 16:12:28 -0800 Subject: [PATCH 22/24] ism bed --- src/baskerville/scripts/hound_ism_bed.py | 304 +++++++++++++++++++++++ src/baskerville/scripts/hound_ism_snp.py | 6 +- tests/data/ism/seqs.bed | 2 + tests/data/ism/{eqtl.vcf => snp.vcf} | 0 tests/test_ism.py | 45 +++- 5 files changed, 347 insertions(+), 10 deletions(-) create mode 100755 src/baskerville/scripts/hound_ism_bed.py create mode 100644 tests/data/ism/seqs.bed rename tests/data/ism/{eqtl.vcf => snp.vcf} (100%) diff --git a/src/baskerville/scripts/hound_ism_bed.py b/src/baskerville/scripts/hound_ism_bed.py new file mode 100755 index 0000000..faf62b4 --- /dev/null +++ b/src/baskerville/scripts/hound_ism_bed.py @@ -0,0 +1,304 @@ +#!/usr/bin/env python +# Copyright 2017 Calico LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ========================================================================= +from optparse import OptionParser + +import gc +import json +import os +import pickle +from queue import Queue +import sys +from threading import Thread + +import h5py +import numpy as np +import pandas as pd +import tensorflow as tf + + +from baskerville import bed +from baskerville import dataset +from baskerville import dna +from baskerville import seqnn +from baskerville import snps + +""" +hound_ism_bed.py + +Perform an in silico saturation mutagenesis of sequences in a BED file. +""" + + +################################################################################ +# main +################################################################################ +def main(): + usage = "usage: %prog [options] " + parser = OptionParser(usage) + parser.add_option( + "-d", + dest="mut_down", + default=0, + type="int", + help="Nucleotides downstream of center sequence to mutate [Default: %default]", + ) + parser.add_option( + "-f", + dest="genome_fasta", + default=None, + help="Genome FASTA for sequences [Default: %default]", + ) + parser.add_option( + "-l", + dest="mut_len", + default=0, + type="int", + help="Length of center sequence to mutate [Default: %default]", + ) + parser.add_option( + "-o", + dest="out_dir", + default="sat_mut", + help="Output directory [Default: %default]", + ) + parser.add_option( + "-p", + dest="processes", + default=None, + type="int", + help="Number of processes, passed by multi script", + ) + parser.add_option( + "--rc", + dest="rc", + default=False, + action="store_true", + help="Ensemble forward and reverse complement predictions [Default: %default]", + ) + parser.add_option( + "--shifts", + dest="shifts", + default="0", + help="Ensemble prediction shifts [Default: %default]", + ) + parser.add_option( + "--stats", + dest="snp_stats", + default="logSUM", + help="Comma-separated list of stats to save. [Default: %default]", + ) + parser.add_option( + "-t", + dest="targets_file", + default=None, + type="str", + help="File specifying target indexes and labels in table format", + ) + parser.add_option( + "-u", + dest="mut_up", + default=0, + type="int", + help="Nucleotides upstream of center sequence to mutate [Default: %default]", + ) + parser.add_option( + "--untransform_old", + dest="untransform_old", + default=False, + action="store_true", + help="Untransform old models [Default: %default]", + ) + (options, args) = parser.parse_args() + + if len(args) == 3: + # single worker + params_file = args[0] + model_file = args[1] + bed_file = args[2] + else: + parser.error("Must provide parameter and model files and BED file") + + if not os.path.isdir(options.out_dir): + os.mkdir(options.out_dir) + + options.shifts = [int(shift) for shift in options.shifts.split(",")] + options.snp_stats = [snp_stat for snp_stat in options.snp_stats.split(",")] + + if options.mut_up > 0 or options.mut_down > 0: + options.mut_len = options.mut_up + options.mut_down + else: + assert options.mut_len > 0 + options.mut_up = options.mut_len // 2 + options.mut_down = options.mut_len - options.mut_up + + ################################################################# + # read parameters and targets + + # read model parameters + with open(params_file) as params_open: + params = json.load(params_open) + params_model = params["model"] + + # read targets + if options.targets_file is None: + parser.error("Must provide targets file to clarify stranded datasets") + targets_df = pd.read_csv(options.targets_file, sep="\t", index_col=0) + + # handle strand pairs + if "strand_pair" in targets_df.columns: + # prep strand + targets_strand_df = dataset.targets_prep_strand(targets_df) + + # set strand pairs (using new indexing) + orig_new_index = dict(zip(targets_df.index, np.arange(targets_df.shape[0]))) + targets_strand_pair = np.array( + [orig_new_index[ti] for ti in targets_df.strand_pair] + ) + params_model["strand_pair"] = [targets_strand_pair] + + # construct strand sum transform + strand_transform = dataset.make_strand_transform(targets_df, targets_strand_df) + else: + targets_strand_df = targets_df + strand_transform = None + num_targets = targets_strand_df.shape[0] + + ################################################################# + # setup model + + seqnn_model = seqnn.SeqNN(params_model) + seqnn_model.restore(model_file) + seqnn_model.build_slice(targets_df.index) + seqnn_model.build_ensemble(options.rc) + + ################################################################# + # sequence dataset + + # read sequences from BED + seqs_dna, seqs_coords = bed.make_bed_seqs( + bed_file, options.genome_fasta, params_model["seq_length"], stranded=True + ) + num_seqs = len(seqs_dna) + + # determine mutation region limits + seq_mid = params_model["seq_length"] // 2 + mut_start = seq_mid - options.mut_up + mut_end = mut_start + options.mut_len + + ################################################################# + # setup output + + scores_h5_file = "%s/scores.h5" % options.out_dir + if os.path.isfile(scores_h5_file): + os.remove(scores_h5_file) + scores_h5 = h5py.File(scores_h5_file, "w") + scores_h5.create_dataset("seqs", dtype="bool", shape=(num_seqs, options.mut_len, 4)) + for snp_stat in options.snp_stats: + scores_h5.create_dataset( + snp_stat, dtype="float16", shape=(num_seqs, options.mut_len, 4, num_targets) + ) + + # store mutagenesis sequence coordinates + scores_chr = [] + scores_start = [] + scores_end = [] + scores_strand = [] + for seq_chr, seq_start, seq_end, seq_strand in seqs_coords: + scores_chr.append(seq_chr) + scores_strand.append(seq_strand) + if seq_strand == "+": + score_start = seq_start + mut_start + score_end = score_start + options.mut_len + else: + score_end = seq_end - mut_start + score_start = score_end - options.mut_len + scores_start.append(score_start) + scores_end.append(score_end) + + scores_h5.create_dataset("chr", data=np.array(scores_chr, dtype="S")) + scores_h5.create_dataset("start", data=np.array(scores_start)) + scores_h5.create_dataset("end", data=np.array(scores_end)) + scores_h5.create_dataset("strand", data=np.array(scores_strand, dtype="S")) + + ################################################################# + # predict scores, write output + + for si, seq_dna in enumerate(seqs_dna): + print("Predicting %d" % si, flush=True) + + # 1 hot code DNA + ref_1hot = dna.dna_1hot(seq_dna) + ref_1hot = np.expand_dims(ref_1hot, axis=0) + + # save sequence + scores_h5["seqs"][si] = ref_1hot[0, mut_start:mut_end].astype("bool") + + # predict reference + ref_preds = [] + for shift in options.shifts: + # shift sequence and predict + ref_1hot_shift = dna.hot1_augment(ref_1hot, shift=shift) + ref_preds_shift = seqnn_model.predict_transform( + ref_1hot_shift, + targets_df, + strand_transform, + options.untransform_old, + ) + ref_preds.append(ref_preds_shift) + ref_preds = np.array(ref_preds) + + # for mutation positions + for mi in range(mut_start, mut_end): + # for each nucleotide + for ni in range(4): + # if non-reference + if ref_1hot[0, mi, ni] == 0: + # copy and modify + alt_1hot = np.copy(ref_1hot) + alt_1hot[0, mi, :] = 0 + alt_1hot[0, mi, ni] = 1 + + # predict alternate + alt_preds = [] + for shift in options.shifts: + # shift sequence and predict + alt_1hot_shift = dna.hot1_augment(alt_1hot, shift=shift) + alt_preds_shift = seqnn_model.predict_transform( + alt_1hot_shift, + targets_df, + strand_transform, + options.untransform_old, + ) + alt_preds.append(alt_preds_shift) + alt_preds = np.array(alt_preds) + + ism_scores = snps.compute_scores( + ref_preds, alt_preds, options.snp_stats + ) + for snp_stat in options.snp_stats: + scores_h5[snp_stat][si, mi - mut_start, ni] = ism_scores[ + snp_stat + ] + + # close output HDF5 + scores_h5.close() + + +################################################################################ +# __main__ +################################################################################ +if __name__ == "__main__": + main() diff --git a/src/baskerville/scripts/hound_ism_snp.py b/src/baskerville/scripts/hound_ism_snp.py index cc43356..b98a02d 100755 --- a/src/baskerville/scripts/hound_ism_snp.py +++ b/src/baskerville/scripts/hound_ism_snp.py @@ -160,6 +160,7 @@ def main(): else: targets_strand_df = targets_df strand_transform = None + num_targets = targets_strand_df.shape[0] ################################################################# # setup model @@ -169,11 +170,6 @@ def main(): seqnn_model.build_slice(targets_df.index) seqnn_model.build_ensemble(options.rc) - # shift outside seqnn - num_shifts = len(options.shifts) - targets_length = seqnn_model.target_lengths[0] - num_targets = targets_strand_df.shape[0] - ################################################################# # SNP sequence dataset diff --git a/tests/data/ism/seqs.bed b/tests/data/ism/seqs.bed new file mode 100644 index 0000000..f78e9c8 --- /dev/null +++ b/tests/data/ism/seqs.bed @@ -0,0 +1,2 @@ +chr1 487600 487601 +chr1 959300 959301 diff --git a/tests/data/ism/eqtl.vcf b/tests/data/ism/snp.vcf similarity index 100% rename from tests/data/ism/eqtl.vcf rename to tests/data/ism/snp.vcf diff --git a/tests/test_ism.py b/tests/test_ism.py index 9cd1fe9..d0b23ea 100755 --- a/tests/test_ism.py +++ b/tests/test_ism.py @@ -9,9 +9,10 @@ targets_file = "tests/data/tiny/hg38/targets.txt" params_file = "tests/data/eval/params.json" model_file = "tests/data/eval/model.h5" -ism_out_dir = "tests/data/ism/eqtl_out" +snp_out_dir = "tests/data/ism/snp_out" +bed_out_dir = "tests/data/ism/bed_out" -def test_vcf(): +def test_snp(): cmd = [ "src/baskerville/scripts/hound_ism_snp.py", "-f", @@ -19,19 +20,19 @@ def test_vcf(): "-l", "6", "-o", - ism_out_dir, + snp_out_dir, "--stats", ",".join(stat_keys), "-t", targets_file, params_file, model_file, - "tests/data/ism/eqtl.vcf", + "tests/data/ism/snp.vcf", ] print(" ".join(cmd)) subprocess.run(cmd, check=True) - with h5py.File(f"{ism_out_dir}/scores.h5", "r") as scores_h5: + with h5py.File(f"{snp_out_dir}/scores.h5", "r") as scores_h5: for sk in stat_keys: score = scores_h5[sk][:] score_var = score.var(axis=2, dtype="float32") @@ -44,3 +45,37 @@ def test_vcf(): # verify variance assert (score_var > 0).all() + +def test_bed(): + cmd = [ + "src/baskerville/scripts/hound_ism_bed.py", + "-f", + fasta_file, + "-l", + "6", + "-o", + bed_out_dir, + "--stats", + ",".join(stat_keys), + "-t", + targets_file, + params_file, + model_file, + "tests/data/ism/seqs.bed", + ] + print(" ".join(cmd)) + subprocess.run(cmd, check=True) + + with h5py.File(f"{bed_out_dir}/scores.h5", "r") as scores_h5: + for sk in stat_keys: + score = scores_h5[sk][:] + score_var = score.var(axis=2, dtype="float32") + + # verify shape + assert score.shape == (2, 6, 4, 47) + + # verify not NaN + assert not np.isnan(score).any() + + # verify variance + assert (score_var > 0).all() \ No newline at end of file From ca640bad81683120968a09e15bc3b50fb2ad3611 Mon Sep 17 00:00:00 2001 From: David Kelley Date: Mon, 18 Dec 2023 16:13:36 -0800 Subject: [PATCH 23/24] black cleanup --- src/baskerville/scripts/hound_ism_snp.py | 13 +++++++++---- src/baskerville/scripts/hound_snp.py | 4 ++-- src/baskerville/seqnn.py | 12 ++++++------ src/baskerville/snps.py | 2 +- tests/test_ism.py | 4 +++- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/baskerville/scripts/hound_ism_snp.py b/src/baskerville/scripts/hound_ism_snp.py index b98a02d..52332d5 100755 --- a/src/baskerville/scripts/hound_ism_snp.py +++ b/src/baskerville/scripts/hound_ism_snp.py @@ -36,6 +36,7 @@ given in a VCF file. """ + ################################################################################ # main ################################################################################ @@ -211,7 +212,7 @@ def main(): ref_1hot = np.expand_dims(seqs_1hot[si], axis=0) # save sequence - scores_h5['seqs'][si] = ref_1hot[0, mut_start:mut_end].astype('bool') + scores_h5["seqs"][si] = ref_1hot[0, mut_start:mut_end].astype("bool") # predict reference ref_preds = [] @@ -250,11 +251,15 @@ def main(): options.untransform_old, ) alt_preds.append(alt_preds_shift) - alt_preds = np.array(alt_preds) + alt_preds = np.array(alt_preds) - ism_scores = snps.compute_scores(ref_preds, alt_preds, options.snp_stats) + ism_scores = snps.compute_scores( + ref_preds, alt_preds, options.snp_stats + ) for snp_stat in options.snp_stats: - scores_h5[snp_stat][si, mi-mut_start, ni] = ism_scores[snp_stat] + scores_h5[snp_stat][si, mi - mut_start, ni] = ism_scores[ + snp_stat + ] # close output HDF5 scores_h5.close() diff --git a/src/baskerville/scripts/hound_snp.py b/src/baskerville/scripts/hound_snp.py index 626eda3..f29bf75 100755 --- a/src/baskerville/scripts/hound_snp.py +++ b/src/baskerville/scripts/hound_snp.py @@ -185,7 +185,7 @@ def main(): print("Running on CPU") if options.require_gpu: raise SystemExit("Job terminated because it's running on CPU") - + ################################################################# # download input files from gcs to a local file if options.gcs: @@ -200,7 +200,7 @@ def main(): options.targets_file = download_rename_inputs( options.targets_file, temp_dir ) - + ################################################################# # calculate SAD scores: if options.processes is not None: diff --git a/src/baskerville/seqnn.py b/src/baskerville/seqnn.py index 4eb4eea..48aa300 100644 --- a/src/baskerville/seqnn.py +++ b/src/baskerville/seqnn.py @@ -970,14 +970,14 @@ def predict( return preds def predict_transform( - self, - seq_1hot: np.array, + self, + seq_1hot: np.array, targets_df, strand_transform: np.array = None, untransform_old: bool = False, ): """Predict a single sequence and transform. - + Args: seq_1hot (np.array): 1-hot encoded sequence. targets_df (pd.DataFrame): Targets dataframe. @@ -986,19 +986,19 @@ def predict_transform( """ # predict preds = self(seq_1hot)[0] - + # untransform predictions if untransform_old: preds = dataset.untransform_preds1(preds, targets_df) else: preds = dataset.untransform_preds(preds, targets_df) - + # sum strand pairs if strand_transform is not None: preds = preds * strand_transform return preds - + def restore(self, model_file, head_i=0, trunk=False): """Restore weights from saved model.""" if trunk: diff --git a/src/baskerville/snps.py b/src/baskerville/snps.py index f0d0813..6ecc4b4 100644 --- a/src/baskerville/snps.py +++ b/src/baskerville/snps.py @@ -37,7 +37,7 @@ def score_snps(params_file, model_file, vcf_file, worker_index, options): # read targets if options.targets_file is None: - print('Must provide targets file to clarify stranded datasets', file=sys.stderr) + print("Must provide targets file to clarify stranded datasets", file=sys.stderr) exit(1) targets_df = pd.read_csv(options.targets_file, sep="\t", index_col=0) diff --git a/tests/test_ism.py b/tests/test_ism.py index d0b23ea..4a93e3d 100755 --- a/tests/test_ism.py +++ b/tests/test_ism.py @@ -12,6 +12,7 @@ snp_out_dir = "tests/data/ism/snp_out" bed_out_dir = "tests/data/ism/bed_out" + def test_snp(): cmd = [ "src/baskerville/scripts/hound_ism_snp.py", @@ -46,6 +47,7 @@ def test_snp(): # verify variance assert (score_var > 0).all() + def test_bed(): cmd = [ "src/baskerville/scripts/hound_ism_bed.py", @@ -78,4 +80,4 @@ def test_bed(): assert not np.isnan(score).any() # verify variance - assert (score_var > 0).all() \ No newline at end of file + assert (score_var > 0).all() From 929993d018c94e46ea1542e67f69d2a0b77d90f6 Mon Sep 17 00:00:00 2001 From: David Kelley Date: Tue, 19 Dec 2023 13:09:51 -0800 Subject: [PATCH 24/24] minor asethetics --- src/baskerville/scripts/hound_eval_spec.py | 3 --- src/baskerville/scripts/hound_ism_bed.py | 10 ---------- src/baskerville/scripts/hound_ism_snp.py | 5 ----- src/baskerville/scripts/hound_snp.py | 3 --- 4 files changed, 21 deletions(-) diff --git a/src/baskerville/scripts/hound_eval_spec.py b/src/baskerville/scripts/hound_eval_spec.py index 2e3187b..bdfde3a 100755 --- a/src/baskerville/scripts/hound_eval_spec.py +++ b/src/baskerville/scripts/hound_eval_spec.py @@ -36,9 +36,6 @@ """ -################################################################################ -# main -################################################################################ def main(): usage = "usage: %prog [options] " parser = OptionParser(usage) diff --git a/src/baskerville/scripts/hound_ism_bed.py b/src/baskerville/scripts/hound_ism_bed.py index faf62b4..7449c18 100755 --- a/src/baskerville/scripts/hound_ism_bed.py +++ b/src/baskerville/scripts/hound_ism_bed.py @@ -15,19 +15,12 @@ # ========================================================================= from optparse import OptionParser -import gc import json import os -import pickle -from queue import Queue -import sys -from threading import Thread import h5py import numpy as np import pandas as pd -import tensorflow as tf - from baskerville import bed from baskerville import dataset @@ -42,9 +35,6 @@ """ -################################################################################ -# main -################################################################################ def main(): usage = "usage: %prog [options] " parser = OptionParser(usage) diff --git a/src/baskerville/scripts/hound_ism_snp.py b/src/baskerville/scripts/hound_ism_snp.py index 52332d5..12b8ba5 100755 --- a/src/baskerville/scripts/hound_ism_snp.py +++ b/src/baskerville/scripts/hound_ism_snp.py @@ -16,8 +16,6 @@ from optparse import OptionParser import json import os -import pdb -import time import h5py import numpy as np @@ -37,9 +35,6 @@ """ -################################################################################ -# main -################################################################################ def main(): usage = "usage: %prog [options] " parser = OptionParser(usage) diff --git a/src/baskerville/scripts/hound_snp.py b/src/baskerville/scripts/hound_snp.py index f29bf75..1ccad45 100755 --- a/src/baskerville/scripts/hound_snp.py +++ b/src/baskerville/scripts/hound_snp.py @@ -33,9 +33,6 @@ """ -################################################################################ -# main -################################################################################ def main(): usage = "usage: %prog [options] " parser = OptionParser(usage)