diff --git a/pycytominer/cyto_utils/DeepProfiler_processing.py b/pycytominer/cyto_utils/DeepProfiler_processing.py new file mode 100644 index 00000000..3bb183c7 --- /dev/null +++ b/pycytominer/cyto_utils/DeepProfiler_processing.py @@ -0,0 +1,274 @@ +""" +Utility function to load and process the output files of a DeepProfiler run. +""" +import os +import pathlib +import numpy as np +import pandas as pd +import warnings + +from pycytominer import aggregate +from pycytominer.cyto_utils import load_npz, infer_cp_features + + +class AggregateDeepProfiler: + """This class holds all functions needed to load and annotate the DeepProfiler (DP) run. + + Attributes + ---------- + + profile_dir : str + file location of the output profiles from DeepProfiler + (e.g. `/project1/outputs/results/features/`) + aggregate_operation : ['median', 'mean'] + method of aggregation + aggregate_on : ['site', 'well', 'plate'] + up to which level to aggregate + filename_delimiter : default = '_' + delimiter for the filenames of the profiles (e.g. B02_4.npz). + file_extension : default = '.npz' + extension of the profile file. + index_df : pandas.DataFrame + load in the index.csv file from DeepProfiler, provided by an input index file. + filenames : list of paths + list of Purepaths that point to the npz files. + aggregated_profiles : pandas.DataFrame + df to hold the metadata and profiles. + file_aggregate : dict + dict that holds the file names and metadata. + Is used to load in the npz files in the correct order and grouping. + + Methods + ------- + annotate_deep() + Given an initialized AggregateDeepProfiler() class, run this function to output + level 3 profiles (aggregated profiles with annotated metadata). + + """ + + def __init__( + self, + index_file, + profile_dir, + aggregate_operation="median", + aggregate_on="well", + filename_delimiter="_", + file_extension=".npz", + ): + """ + __init__ function for this class. + + Arguments + --------- + index_file : str + file location of the index.csv from DP + + See above for all other parameters. + """ + assert aggregate_operation in [ + "median", + "mean", + ], "Input of aggregate_operation is incorrect, it must be either median or mean" + assert aggregate_on in [ + "site", + "well", + "plate", + ], "Input of aggregate_on is incorrect, it must be either site or well or plate" + + self.aggregate_operation = aggregate_operation + self.profile_dir = profile_dir + self.aggregate_on = aggregate_on + self.filename_delimiter = filename_delimiter + self.file_extension = file_extension + if not self.file_extension.startswith("."): + self.file_extension = f".{self.file_extension}" + self.index_df = pd.read_csv(index_file, dtype=str) + + def build_filenames(self): + """ + Create file names indicated by plate, well, and site information + """ + self.filenames = self.index_df.apply( + self.build_filename_from_index, axis="columns" + ) + self.filenames = [ + pathlib.PurePath(f"{self.profile_dir}/{x}") for x in self.filenames + ] + + def build_filename_from_index(self, row): + """ + Builds the name of the profile files + """ + plate = row["Metadata_Plate"] + well = row["Metadata_Well"] + site = row["Metadata_Site"] + + filename = f"{plate}/{well}_{site}{self.file_extension}" + return filename + + def extract_filename_metadata(self, npz_file, delimiter="_"): + """ + Extract metadata (site, well and plate) from the filename. + The input format of the file: path/plate/well_site.npz + + Arguments + --------- + npz_file : str + file path + + delimiter : str + the delimiter used in the naming convention of the files. default = '_' + + Returns + ------- + loc : dict + dict with metadata + """ + base_file = os.path.basename(npz_file).strip(".npz").split(delimiter) + site = base_file[-1] + well = base_file[-2] + plate = str(npz_file).split("/")[-2] + + loc = {"site": site, "well": well, "plate": plate} + return loc + + def setup_aggregate(self): + """ + Sets up the file_aggregate attribute. This is a helper function to aggregate_deep(). + + the file_aggregate dictionary contains the file locations and metadata for each grouping. + If for example we are grouping by well then the keys of self.file_aggregate would be: + plate1/well1, plate1/well2, plate2/well1, etc. + """ + if not hasattr(self, "filenames"): + self.build_filenames() + + self.file_aggregate = {} + for filename in self.filenames: + file_info = self.extract_filename_metadata( + filename, self.filename_delimiter + ) + file_key = file_info[self.aggregate_on] + + if self.aggregate_on == "site": + file_key = ( + f"{file_info['plate']}/{file_info['well']}_{file_info['site']}" + ) + + if self.aggregate_on == "well": + file_key = f"{file_info['plate']}/{file_info['well']}" + + if file_key in self.file_aggregate: + self.file_aggregate[file_key]["files"].append(filename) + else: + self.file_aggregate[file_key] = {} + self.file_aggregate[file_key]["files"] = [filename] + + self.file_aggregate[file_key]["metadata"] = file_info + + def aggregate_deep(self): + """ + Aggregates the profiles into a pandas dataframe. + + For each key in file_aggregate, the profiles are loaded, concatenated and then aggregated. + If files are missing, we throw a warning but continue the code. + """ + if not hasattr(self, "file_aggregate"): + self.setup_aggregate() + + self.aggregated_profiles = [] + self.aggregate_merge_col = f"Metadata_{self.aggregate_on.capitalize()}_Position" + + for metadata_level in self.file_aggregate: + # uses custom load function to create df with metadata and profiles + arr = [load_npz(x) for x in self.file_aggregate[metadata_level]["files"]] + # empty dataframes from missing files are deleted + arr = [x for x in arr if not x.empty] + # if no files were found there is a miss-match between the index and the output files + if not len(arr): + warnings.warn( + f"No files for the key {metadata_level} could be found.\nThis program will continue, but be aware that this might induce errors!" + ) + continue + + df = pd.concat(arr) + + # Prepare inputs for the aggregate function + meta_df = pd.DataFrame( + self.file_aggregate[metadata_level]["metadata"], index=[0] + ).reset_index(drop=True) + meta_df.columns = [ + f"Metadata_{x.capitalize()}" if not x.startswith("Metadata_") else x + for x in meta_df.columns + ] + + if self.aggregate_on == "well": + meta_df = ( + meta_df.drop("Metadata_Site", axis="columns") + .drop_duplicates() + .reset_index(drop=True) + ) + + metadata_cols = [x for x in df if x.startswith("Metadata_")] + profiles = [x for x in df.columns.tolist() if x not in metadata_cols] + df = df.assign(Metadata_Aggregate_On=self.aggregate_on) + df = aggregate.aggregate( + population_df=df, + strata="Metadata_Aggregate_On", + features=profiles, + operation=self.aggregate_operation, + ).reset_index(drop=True) + + df.loc[:, self.aggregate_merge_col] = metadata_level + df = meta_df.merge(df, left_index=True, right_index=True) + self.aggregated_profiles.append(df) + + # Concatenate all of the above created profiles + self.aggregated_profiles = pd.concat( + [x for x in self.aggregated_profiles] + ).reset_index(drop=True) + self.aggregated_profiles.columns = [ + str(x) for x in self.aggregated_profiles.columns + ] + meta_features = infer_cp_features(self.aggregated_profiles, metadata=True) + reindex_profiles = [str(x) for x in profiles] + self.aggregated_profiles = self.aggregated_profiles.reindex( + meta_features + reindex_profiles, axis="columns" + ) + + def annotate_deep( + self, + ): + """ + Main function of this class. Merges the index df and the profiles back into one dataframe. + + Returns + ------- + df_out : pandas.dataframe + dataframe with all metadata and the feature space. + This is the input to any further pycytominer or pycytominer-eval processing + """ + if not hasattr(self, "aggregated_profiles"): + self.aggregate_deep() + + meta_df = self.index_df + meta_df.columns = [ + "Metadata_{}".format(x) if not x.startswith("Metadata_") else x + for x in meta_df.columns + ] + + # prepare for merge with profiles + if self.aggregate_on == "plate": + meta_df = meta_df.drop(["Metadata_Site", "Metadata_Well"], axis="columns") + merge_cols = ["Metadata_Plate"] + + elif self.aggregate_on == "well": + meta_df = meta_df.drop("Metadata_Site", axis="columns") + merge_cols = ["Metadata_Well", "Metadata_Plate"] + + elif self.aggregate_on == "site": + merge_cols = ["Metadata_Well", "Metadata_Plate", "Metadata_Site"] + + meta_df = meta_df.drop_duplicates(subset=merge_cols) + df_out = meta_df.merge(self.aggregated_profiles, on=merge_cols, how="inner") + return df_out diff --git a/pycytominer/cyto_utils/__init__.py b/pycytominer/cyto_utils/__init__.py index 2a6bf019..7bfcabbb 100644 --- a/pycytominer/cyto_utils/__init__.py +++ b/pycytominer/cyto_utils/__init__.py @@ -15,10 +15,7 @@ assert_linking_cols_complete, provide_linking_cols_feature_name_update, ) -from .load import ( - load_profiles, - load_platemap, -) +from .load import load_profiles, load_platemap, load_npz, infer_delim from .features import ( get_blocklist_features, label_compartment, @@ -30,3 +27,4 @@ from .write_gct import write_gct from .modz import modz from .annotate_custom import annotate_cmap, cp_clean +from .DeepProfiler_processing import AggregateDeepProfiler diff --git a/pycytominer/cyto_utils/load.py b/pycytominer/cyto_utils/load.py index 0ab47b9c..dd944da1 100644 --- a/pycytominer/cyto_utils/load.py +++ b/pycytominer/cyto_utils/load.py @@ -1,5 +1,6 @@ import csv import gzip +import numpy as np import pandas as pd @@ -7,10 +8,13 @@ def infer_delim(file): """ Sniff the delimiter in the given file - Arguments: - file - a string indicating file name + Arguments + --------- + file : str + File name - Output: + Return + ------ the delimiter used in the dataframe (typically either tab or commas) """ try: @@ -29,10 +33,13 @@ def load_profiles(profiles): """ Unless a dataframe is provided, load the given profile dataframe from path or string - Arguments: - profiles - location or actual pandas dataframe of profiles + Arguments + --------- + profiles : {str, pandas.DataFrame} + file location or actual pandas dataframe of profiles - Return: + Return + ------ pandas DataFrame of profiles """ if not isinstance(profiles, pd.DataFrame): @@ -48,12 +55,18 @@ def load_platemap(platemap, add_metadata_id=True): """ Unless a dataframe is provided, load the given platemap dataframe from path or string - Arguments: - platemap - location or actual pandas dataframe of platemap file - add_metadata_id - boolean if "Metadata_" should be appended to all platemap columns + Arguments + --------- + platemap : pandas dataframe + location or actual pandas dataframe of platemap file - Return: - pandas DataFrame of profiles + add_metadata_id : bool + boolean if "Metadata_" should be appended to all platemap columns + + Return + ------ + platemap : pandas DataFrame + pandas DataFrame of profiles """ if not isinstance(platemap, pd.DataFrame): try: @@ -68,3 +81,59 @@ def load_platemap(platemap, add_metadata_id=True): for x in platemap.columns ] return platemap + + +def load_npz(npz_file, fallback_feature_prefix="DP"): + """ + Load an npz file storing features and, sometimes, metadata. + + The function will first search the .npz file for a metadata column called + "Metadata_Model". If the field exists, the function uses this entry as the + feature prefix. If it doesn't exist, use the fallback_feature_prefix. + + If the npz file does not exist, this function returns an empty dataframe. + + Arguments + --------- + npz_file : str + file path to the compressed output (typically DeepProfiler output) + fallback_feature_prefix :str + a string to prefix all features [default: "DP"]. + """ + try: + npz = np.load(npz_file, allow_pickle=True) + except FileNotFoundError: + return pd.DataFrame([]) + + files = npz.files + + # Load features + df = pd.DataFrame(npz["features"]) + + # Load metadata + if "metadata" in files: + metadata = npz["metadata"].item() + metadata_df = pd.DataFrame(metadata, index=range(0, df.shape[0]), dtype=str) + metadata_df.columns = [ + f"Metadata_{x}" if not x.startswith("Metadata_") else x for x in metadata_df + ] + + # Determine the appropriate metadata prefix + if "Metadata_Model" in metadata_df.columns: + feature_prefix = metadata_df.Metadata_Model.unique()[0] + else: + feature_prefix = fallback_feature_prefix + else: + feature_prefix = fallback_feature_prefix + + # Append feature prefix + df.columns = [ + f"{feature_prefix}_{x}" if not str(x).startswith(feature_prefix) else x + for x in df + ] + + # Append metadata with features + if "metadata" in files: + df = metadata_df.merge(df, how="outer", left_index=True, right_index=True) + + return df diff --git a/pycytominer/data/DeepProfiler_example_data/Week1_22123_B02_s1.npz b/pycytominer/data/DeepProfiler_example_data/Week1_22123_B02_s1.npz new file mode 100644 index 00000000..83bcf366 Binary files /dev/null and b/pycytominer/data/DeepProfiler_example_data/Week1_22123_B02_s1.npz differ diff --git a/pycytominer/tests/test_cyto_utils/test_DeepProfiler_processing.py b/pycytominer/tests/test_cyto_utils/test_DeepProfiler_processing.py new file mode 100644 index 00000000..8f16f542 --- /dev/null +++ b/pycytominer/tests/test_cyto_utils/test_DeepProfiler_processing.py @@ -0,0 +1,85 @@ +""" +This tests the output from a DeepProfiler run (May 2021) +""" +import os +import random +import pytest +import numpy as np +import pandas as pd +import sys +import numpy.testing as npt + +from pycytominer.cyto_utils.DeepProfiler_processing import AggregateDeepProfiler + + +random.seed(42) +# setting the file locations +example_project_dir = os.path.join( + os.path.dirname(__file__), "..", "test_data", "DeepProfiler_example_data" +) + +profile_dir = os.path.join(example_project_dir, "outputs", "results", "features") + +index_file = os.path.join(example_project_dir, "inputs", "metadata", "test_index.csv") + +# calculating the dataframe for each depth +site_class = AggregateDeepProfiler( + index_file=index_file, + profile_dir=profile_dir, + aggregate_operation="median", + aggregate_on="site", +) +df_site = site_class.annotate_deep() + +well_class = AggregateDeepProfiler( + index_file=index_file, + profile_dir=profile_dir, + aggregate_operation="median", + aggregate_on="well", +) +df_well = well_class.annotate_deep() +# +plate_class = AggregateDeepProfiler( + index_file=index_file, + profile_dir=profile_dir, + aggregate_operation="median", + aggregate_on="plate", +) +df_plate = plate_class.annotate_deep() + + +def test_output_size(): + assert df_site.shape == (36, 6417) + assert df_well.shape == (4, 6416) + assert df_plate.shape == (2, 6417) + + +def test_columns(): + meta_cols = [x for x in df_site.columns if x.startswith("Metadata_")] + assert meta_cols.index("Metadata_Site_Position") + assert len(meta_cols) == 17 + + meta_cols = [x for x in df_well.columns if x.startswith("Metadata_")] + assert meta_cols.index("Metadata_Well_Position") + assert len(meta_cols) == 16 + + meta_cols = [x for x in df_plate.columns if x.startswith("Metadata_")] + assert meta_cols.index("Metadata_Plate_Position") + assert len(meta_cols) == 17 + + for df in [df_site, df_well, df_plate]: + profile_cols = [x for x in df.columns if x.startswith("efficientnet_")] + assert profile_cols.index("efficientnet_6399") + assert len(profile_cols) == 6400 + + +def test_for_nan(): + for df in [df_site, df_well, df_plate]: + assert df.isnull().values.any() + + +def test_exact_values(): + # random value checks + npt.assert_almost_equal(df_plate.efficientnet_4.loc[1], -0.09470577538013458) + npt.assert_almost_equal(df_well.efficientnet_0.loc[3], -0.16986790299415588) + npt.assert_almost_equal(df_site.efficientnet_2.loc[14], -0.14057332277297974) diff --git a/pycytominer/tests/test_cyto_utils/test_load.py b/pycytominer/tests/test_cyto_utils/test_load.py index 3eff2f24..d2159ccd 100644 --- a/pycytominer/tests/test_cyto_utils/test_load.py +++ b/pycytominer/tests/test_cyto_utils/test_load.py @@ -4,7 +4,7 @@ import tempfile import numpy as np import pandas as pd -from pycytominer.cyto_utils import load_profiles, load_platemap +from pycytominer.cyto_utils import load_profiles, load_platemap, load_npz from pycytominer.cyto_utils.load import infer_delim random.seed(123) @@ -12,13 +12,26 @@ # Get temporary directory tmpdir = tempfile.gettempdir() -# Lauch a sqlite connection +# Set file paths for data-to-be-loaded output_data_file = os.path.join(tmpdir, "test_data.csv") output_data_comma_file = os.path.join(tmpdir, "test_data_comma.csv") output_data_gzip_file = "{}.gz".format(output_data_file) output_platemap_file = os.path.join(tmpdir, "test_platemap.csv") output_platemap_comma_file = os.path.join(tmpdir, "test_platemap_comma.csv") output_platemap_file_gzip = "{}.gz".format(output_platemap_file) +output_npz_file = os.path.join(tmpdir, "test_npz.npz") +output_npz_with_model_file = os.path.join(tmpdir, "test_npz_withmodel.npz") +output_npz_without_metadata_file = os.path.join(tmpdir, "test_npz_withoutmetadata.npz") + +# Example .npz file with real data +example_npz_file = os.path.join( + os.path.dirname(__file__), + "..", + "..", + "data", + "DeepProfiler_example_data", + "Week1_22123_B02_s1.npz", +) # Build data to use in tests data_df = pd.concat( @@ -39,6 +52,10 @@ } ).reset_index(drop=True) +npz_metadata_dict = {"Plate": "PlateA", "Well": "A01", "Site": 2} +npz_model_key = {"Model": "cnn"} +npz_feats = data_df.drop("Metadata_Well", axis="columns").values + # Write to temp files data_df.to_csv(output_data_file, sep="\t", index=False) data_df.to_csv(output_data_comma_file, sep=",", index=False) @@ -47,6 +64,17 @@ platemap_df.to_csv(output_platemap_comma_file, sep=",", index=False) platemap_df.to_csv(output_platemap_file_gzip, sep="\t", index=False, compression="gzip") +# Write npz temp files +key_values = {k: npz_metadata_dict[k] for k in npz_metadata_dict.keys()} +npz_metadata_dict.update(npz_model_key) +key_with_model_values = {k: npz_metadata_dict[k] for k in npz_metadata_dict.keys()} + +np.savez_compressed(output_npz_file, features=npz_feats, metadata=key_values) +np.savez_compressed( + output_npz_with_model_file, features=npz_feats, metadata=key_with_model_values +) +np.savez_compressed(output_npz_without_metadata_file, features=npz_feats) + def test_infer_delim(): delim = infer_delim(output_platemap_file) @@ -88,3 +116,42 @@ def test_load_platemap(): platemap_with_annotation = load_platemap(output_platemap_file, add_metadata_id=True) platemap_df.columns = [f"Metadata_{x}" for x in platemap_df.columns] pd.testing.assert_frame_equal(platemap_with_annotation, platemap_df) + + +def test_load_npz(): + npz_df = load_npz(output_npz_file) + npz_custom_prefix_df = load_npz(output_npz_file, fallback_feature_prefix="test") + npz_with_model_df = load_npz(output_npz_with_model_file) + npz_no_meta_df = load_npz(output_npz_without_metadata_file) + real_data_df = load_npz(example_npz_file) + + core_cols = ["Metadata_Plate", "Metadata_Well", "Metadata_Site"] + + assert npz_df.shape == (6, 5) + assert npz_df.columns.tolist() == core_cols + ["DP_0", "DP_1"] + + assert npz_custom_prefix_df.shape == (6, 5) + assert npz_custom_prefix_df.columns.tolist() == core_cols + ["test_0", "test_1"] + + assert npz_with_model_df.shape == (6, 6) + assert npz_with_model_df.columns.tolist() == core_cols + [ + "Metadata_Model", + "cnn_0", + "cnn_1", + ] + + assert npz_no_meta_df.shape == (6, 2) + assert npz_no_meta_df.columns.tolist() == ["DP_0", "DP_1"] + + pd.testing.assert_frame_equal( + npz_df.drop(core_cols, axis="columns"), npz_no_meta_df + ) + + # Check real data + assert real_data_df.shape == (206, 54) + assert all([x in real_data_df.columns for x in core_cols + ["Metadata_Model"]]) + assert len(real_data_df.Metadata_Model.unique()) == 1 + assert real_data_df.Metadata_Model.unique()[0] == "cnn" + assert real_data_df.drop( + core_cols + ["Metadata_Model"], axis="columns" + ).columns.tolist() == [f"cnn_{x}" for x in range(0, 50)] diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/inputs/config/config.json b/pycytominer/tests/test_data/DeepProfiler_example_data/inputs/config/config.json new file mode 100644 index 00000000..5addd68c --- /dev/null +++ b/pycytominer/tests/test_data/DeepProfiler_example_data/inputs/config/config.json @@ -0,0 +1,80 @@ +{ + "dataset": { + "metadata": { + "label_field": "Treatment", + "control_value": "NA@NA" + }, + "images": { + "channels": [ + "DNA", + "RNA", + "ER", + "AGP", + "Mito" + ], + "file_format": "png", + "bits": 8, + "width": 1080, + "height": 1080 + }, + "locations":{ + "mode": "single_cells", + "box_size": 128, + "area_coverage": 0.75, + "mask_objects": false + } + }, + "prepare": { + "illumination_correction": { + "down_scale_factor": 4, + "median_filter_size": 24 + }, + "compression": { + "implement": false, + "scaling_factor": 1.0 + } + }, + "train": { + "partition": { + "targets": [ + "Compound" + ], + "split_field": "Split", + "training_values": ["Training"], + "validation_values": ["Validation"] + }, + "model": { + "name": "efficientnet", + "crop_generator": "repeat_channel_crop_generator", + "metrics": ["accuracy", "top_k"], + "epochs": 100, + "initialization":"ImageNet", + "params": { + "learning_rate": 0.005, + "batch_size": 64, + "conv_blocks": 0, + "feature_dim": 256, + "pooling": "avg" + }, + "lr_schedule": "cosine" + }, + "sampling": { + "factor": 1, + "workers": 4, + "cache_size": 15000 + }, + "validation": { + "frequency": 2, + "top_k": 5, + "batch_size": 32, + "frame": "val", + "sample_first_crops": true + } + }, + "profile": { + "use_pretrained_input_size": 224, + "feature_layer": "avg_pool", + "checkpoint": "None", + "batch_size": 8 + } +} \ No newline at end of file diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/inputs/metadata/test_index.csv b/pycytominer/tests/test_data/DeepProfiler_example_data/inputs/metadata/test_index.csv new file mode 100644 index 00000000..4bb09cc4 --- /dev/null +++ b/pycytominer/tests/test_data/DeepProfiler_example_data/inputs/metadata/test_index.csv @@ -0,0 +1,37 @@ +Metadata_Plate,Metadata_Well,Metadata_Site,Plate_Map_Name,RNA,ER,AGP,Mito,DNA,Treatment_ID,Treatment_Replicate,Treatment,Compound,Concentration,Split +SQ00014812,A01,1,C-7161-01-LM6-022,SQ00014812/r01c01f01p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f01p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f01p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f01p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f01p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A01,2,C-7161-01-LM6-022,SQ00014812/r01c01f02p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f02p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f02p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f02p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f02p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A01,3,C-7161-01-LM6-022,SQ00014812/r01c01f03p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f03p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f03p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f03p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f03p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A01,4,C-7161-01-LM6-022,SQ00014812/r01c01f04p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f04p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f04p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f04p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f04p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A01,5,C-7161-01-LM6-022,SQ00014812/r01c01f05p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f05p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f05p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f05p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f05p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A01,6,C-7161-01-LM6-022,SQ00014812/r01c01f06p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f06p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f06p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f06p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f06p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A01,7,C-7161-01-LM6-022,SQ00014812/r01c01f07p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f07p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f07p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f07p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f07p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A01,8,C-7161-01-LM6-022,SQ00014812/r01c01f08p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f08p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f08p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f08p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f08p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A01,9,C-7161-01-LM6-022,SQ00014812/r01c01f09p01-ch3sk1fk1fl1.png,SQ00014812/r01c01f09p01-ch2sk1fk1fl1.png,SQ00014812/r01c01f09p01-ch4sk1fk1fl1.png,SQ00014812/r01c01f09p01-ch5sk1fk1fl1.png,SQ00014812/r01c01f09p01-ch1sk1fk1fl1.png,0,1,DMSO@NA,DMSO,,Training +SQ00014812,A07,1,C-7161-01-LM6-022,SQ00014812/r01c07f01p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f01p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f01p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f01p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f01p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014812,A07,2,C-7161-01-LM6-022,SQ00014812/r01c07f02p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f02p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f02p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f02p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f02p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014812,A07,3,C-7161-01-LM6-022,SQ00014812/r01c07f03p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f03p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f03p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f03p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f03p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014812,A07,4,C-7161-01-LM6-022,SQ00014812/r01c07f04p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f04p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f04p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f04p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f04p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014812,A07,5,C-7161-01-LM6-022,SQ00014812/r01c07f05p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f05p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f05p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f05p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f05p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014812,A07,6,C-7161-01-LM6-022,SQ00014812/r01c07f06p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f06p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f06p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f06p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f06p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014812,A07,7,C-7161-01-LM6-022,SQ00014812/r01c07f07p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f07p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f07p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f07p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f07p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014812,A07,8,C-7161-01-LM6-022,SQ00014812/r01c07f08p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f08p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f08p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f08p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f08p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014812,A07,9,C-7161-01-LM6-022,SQ00014812/r01c07f09p01-ch3sk1fk1fl1.png,SQ00014812/r01c07f09p01-ch2sk1fk1fl1.png,SQ00014812/r01c07f09p01-ch4sk1fk1fl1.png,SQ00014812/r01c07f09p01-ch5sk1fk1fl1.png,SQ00014812/r01c07f09p01-ch1sk1fk1fl1.png,7060,1,BRD-K74363950-004-01-0@9.99999999999999999,BRD-K74363950-004-01-0,10.000000000000002,Training +SQ00014813,C05,1,C-7161-01-LM6-022,SQ00014813/r03c05f01p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f01p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f01p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f01p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f01p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,C05,2,C-7161-01-LM6-022,SQ00014813/r03c05f02p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f02p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f02p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f02p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f02p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,C05,3,C-7161-01-LM6-022,SQ00014813/r03c05f03p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f03p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f03p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f03p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f03p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,C05,4,C-7161-01-LM6-022,SQ00014813/r03c05f04p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f04p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f04p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f04p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f04p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,C05,5,C-7161-01-LM6-022,SQ00014813/r03c05f05p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f05p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f05p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f05p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f05p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,C05,6,C-7161-01-LM6-022,SQ00014813/r03c05f06p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f06p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f06p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f06p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f06p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,C05,7,C-7161-01-LM6-022,SQ00014813/r03c05f07p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f07p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f07p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f07p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f07p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,C05,8,C-7161-01-LM6-022,SQ00014813/r03c05f08p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f08p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f08p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f08p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f08p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,C05,9,C-7161-01-LM6-022,SQ00014813/r03c05f09p01-ch3sk1fk1fl1.png,SQ00014813/r03c05f09p01-ch2sk1fk1fl1.png,SQ00014813/r03c05f09p01-ch4sk1fk1fl1.png,SQ00014813/r03c05f09p01-ch5sk1fk1fl1.png,SQ00014813/r03c05f09p01-ch1sk1fk1fl1.png,7100,2,BRD-K68103045-001-02-9@0.123456790123076923,BRD-K68103045-001-02-9,0.1234567901230769,Training +SQ00014813,A02,1,C-7161-01-LM6-022,SQ00014813/r01c02f01p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f01p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f01p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f01p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f01p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training +SQ00014813,A02,2,C-7161-01-LM6-022,SQ00014813/r01c02f02p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f02p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f02p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f02p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f02p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training +SQ00014813,A02,3,C-7161-01-LM6-022,SQ00014813/r01c02f03p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f03p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f03p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f03p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f03p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training +SQ00014813,A02,4,C-7161-01-LM6-022,SQ00014813/r01c02f04p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f04p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f04p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f04p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f04p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training +SQ00014813,A02,5,C-7161-01-LM6-022,SQ00014813/r01c02f05p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f05p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f05p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f05p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f05p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training +SQ00014813,A02,6,C-7161-01-LM6-022,SQ00014813/r01c02f06p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f06p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f06p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f06p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f06p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training +SQ00014813,A02,7,C-7161-01-LM6-022,SQ00014813/r01c02f07p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f07p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f07p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f07p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f07p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training +SQ00014813,A02,8,C-7161-01-LM6-022,SQ00014813/r01c02f08p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f08p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f08p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f08p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f08p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training +SQ00014813,A02,9,C-7161-01-LM6-022,SQ00014813/r01c02f09p01-ch3sk1fk1fl1.png,SQ00014813/r01c02f09p01-ch2sk1fk1fl1.png,SQ00014813/r01c02f09p01-ch4sk1fk1fl1.png,SQ00014813/r01c02f09p01-ch5sk1fk1fl1.png,SQ00014813/r01c02f09p01-ch1sk1fk1fl1.png,0,26,DMSO@NA,DMSO,,Training \ No newline at end of file diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_1.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_1.npz new file mode 100644 index 00000000..af1855ab Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_1.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_2.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_2.npz new file mode 100644 index 00000000..63f9fe9b Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_2.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_3.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_3.npz new file mode 100644 index 00000000..4fd278e9 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_3.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_4.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_4.npz new file mode 100644 index 00000000..cf9d2336 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_4.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_5.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_5.npz new file mode 100644 index 00000000..3743be4d Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_5.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_6.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_6.npz new file mode 100644 index 00000000..8ac2793d Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_6.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_7.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_7.npz new file mode 100644 index 00000000..22c1ca67 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_7.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_8.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_8.npz new file mode 100644 index 00000000..05aa5195 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_8.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_9.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_9.npz new file mode 100644 index 00000000..2c54bbaa Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A01_9.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_1.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_1.npz new file mode 100644 index 00000000..fa76328f Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_1.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_2.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_2.npz new file mode 100644 index 00000000..286721ba Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_2.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_3.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_3.npz new file mode 100644 index 00000000..94746449 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_3.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_4.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_4.npz new file mode 100644 index 00000000..cc3ae455 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_4.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_5.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_5.npz new file mode 100644 index 00000000..b65e0761 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_5.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_6.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_6.npz new file mode 100644 index 00000000..e3d23be0 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_6.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_7.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_7.npz new file mode 100644 index 00000000..0adb36d5 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_7.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_8.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_8.npz new file mode 100644 index 00000000..0f977c7e Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_8.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_9.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_9.npz new file mode 100644 index 00000000..dda873e5 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014812/A07_9.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_1.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_1.npz new file mode 100644 index 00000000..9f2d5a3d Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_1.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_2.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_2.npz new file mode 100644 index 00000000..bbcc2d16 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_2.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_3.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_3.npz new file mode 100644 index 00000000..78f0bd82 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_3.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_4.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_4.npz new file mode 100644 index 00000000..e16c2ba3 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_4.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_5.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_5.npz new file mode 100644 index 00000000..2aede192 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_5.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_6.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_6.npz new file mode 100644 index 00000000..215e010b Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_6.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_7.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_7.npz new file mode 100644 index 00000000..1ffe624a Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_7.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_8.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_8.npz new file mode 100644 index 00000000..3d09650c Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_8.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_9.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_9.npz new file mode 100644 index 00000000..f6e4fe4e Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/A02_9.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_1.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_1.npz new file mode 100644 index 00000000..d45dacac Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_1.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_2.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_2.npz new file mode 100644 index 00000000..a32332a7 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_2.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_3.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_3.npz new file mode 100644 index 00000000..52d95af6 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_3.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_4.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_4.npz new file mode 100644 index 00000000..285fa7db Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_4.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_5.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_5.npz new file mode 100644 index 00000000..06f5650f Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_5.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_6.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_6.npz new file mode 100644 index 00000000..d469c81a Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_6.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_7.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_7.npz new file mode 100644 index 00000000..2b57fd5e Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_7.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_8.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_8.npz new file mode 100644 index 00000000..79464249 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_8.npz differ diff --git a/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_9.npz b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_9.npz new file mode 100644 index 00000000..0d27a740 Binary files /dev/null and b/pycytominer/tests/test_data/DeepProfiler_example_data/outputs/results/features/SQ00014813/C05_9.npz differ