diff --git a/active_plugins/rundeepprofiler.py b/active_plugins/rundeepprofiler.py new file mode 100644 index 0000000..e2ead16 --- /dev/null +++ b/active_plugins/rundeepprofiler.py @@ -0,0 +1,453 @@ +################################# +# +# Imports from useful Python libraries +# +################################# +import random +import os +import shutil +import subprocess +import csv +import numpy as np +import logging + +from cellprofiler_core.module import Module +from cellprofiler_core.setting.subscriber import LabelSubscriber +from cellprofiler_core.setting.text import Text, Filename, Directory +from cellprofiler.modules import _help +from cellprofiler_core.preferences import ABSOLUTE_FOLDER_NAME +from cellprofiler_core.preferences import DEFAULT_INPUT_FOLDER_NAME +from cellprofiler_core.preferences import DEFAULT_INPUT_SUBFOLDER_NAME +from cellprofiler_core.preferences import DEFAULT_OUTPUT_FOLDER_NAME +from cellprofiler_core.preferences import DEFAULT_OUTPUT_SUBFOLDER_NAME +from cellprofiler_core.constants.module import ( + IO_FOLDER_CHOICE_HELP_TEXT, + IO_WITH_METADATA_HELP_TEXT, +) +from cellprofiler_core.setting import ( + Measurement, + Binary, +) +from cellprofiler_core.setting.subscriber import ( + ImageListSubscriber, +) +from cellprofiler_core.constants.measurement import COLTYPE_FLOAT, C_LOCATION + +LOGGER = logging.getLogger(__name__) + +C_MEASUREMENT = "DeepProfiler" + +################################# +# +# Imports from CellProfiler +# +################################## + +dp_doi = "https://doi.org/10.1101/2022.08.12.503783" +__doc__ = """\ +RunDeepProfiler +=================== + +**RunDeepProfiler** - uses a pre trained CNN model on Cell Painting data to extract features from crops of single-cells using DeepProfiler software subprocess. + +This module will take a configuration file provided by the user to run DeepProfiler in the background. +It will run only after the user install DeepProfiler in their machine and provide the path. + +It depends on having an object previously identified by other modules such as IdentifyPrimaryObjects or RunCellpose to provide as Object_Location_Centers. + + +| + +============ ============ =============== +Supports 2D? Supports 3D? Respects masks? +============ ============ =============== +YES NO NO +============ ============ =============== + +See also +^^^^^^^^ + +What do I need as input? +^^^^^^^^^^^^^^^^^^^^^^^^ + +- Objects: provide which object will be used as a center. +- ExperimentName: enter a name for this experiment. +- Define output directory: where to save the output features. +- Define DeepProfiler directory: where DeepProfiler is located in your computer. +- Path to the model: where the model/weight is located. +- Define metadata Plate, Well, and Site: what are the metadata information (from load_csv or Metadata input module) that has those metadata 3 informations. + +What do I get as output? +^^^^^^^^^^^^^^^^^^^^^^^^ + +About 600 features will be saved inside the output > experiment_name > features > metadata_plate > Well > Site.csv + +For more on how to process those features, check pycytominer functionalities. + +Measurements made by this module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Describe the measurements made by this module. Typically, measurements +are described in the following format: + +**DP**: + +- *EfficientNet_*: the outputs are one file for each site analyzed containing the single-cell features. + +Technical notes +^^^^^^^^^^^^^^^ + +DeepProfiler requires tensorflow-2.5.3 to run. + +References +^^^^^^^^^^ + +DeepProfiler + +- Learning representations for image-based profiling of perturbations Nikita Moshkov, Michael Bornholdt, Santiago Benoit, Matthew Smith, Claire McQuin, + Allen Goodman, Rebecca A. Senft, Yu Han, Mehrtash Babadi, Peter Horvath, Beth A. Cimini, Anne E. Carpenter, Shantanu Singh, Juan C. Caicedo. bioRxiv 2022.08.12.503783 + {dp_doi} +- DeepProfiler GitHub repository: https://github.com/cytomining/DeepProfiler +- DeepProfiler handbook: https://cytomining.github.io/DeepProfiler-handbook/ +""" + + +class RunDeepProfiler(Module): + module_name = "RunDeepProfiler" + category = "Measurement" + variable_revision_number = 1 + doi = {"Please cite DeepProfiler:": 'https://doi.org/10.1101/2022.08.12.503783'} + + def create_settings(self): + self.images_list = ImageListSubscriber( + "Select images to measure", + [], + doc="""Select the grayscale images whose intensity you want to measure.""", + ) + + self.input_object_name = LabelSubscriber( + text="Provide nuclei object name", + doc="Choose the name of the nuclei object to be used as a center.", + ) + + self.assay = Text( + "Name this experiment.", + "FeaturesDeepProfiler", + doc="""\ +Enter a name for your experiment. This will be used to create a folder inside the output folder""", + ) + + self.metadata_plate = Measurement( + "Select the Metadata_Plate", + lambda: "Image", + "", + doc="""\ +Select a measurement made on the image. The value of the +measurement is used for the operand for all of the pixels of the +other operand's image.""", + ) + + self.metadata_well = Measurement( + "Select the Metadata_Well", + lambda: "Image", + "", + doc="""\ +Select a measurement made on the image. The value of the +measurement is used for the operand for all of the pixels of the +other operand's image.""", + ) + + self.metadata_site = Measurement( + "Select the Metadata_Site", + lambda: "Image", + "", + doc="""\ +Select a measurement made on the image. The value of the +measurement is used for the operand for all of the pixels of the +other operand's image.""", + ) + + self.directory = Directory( + "Output folder", + dir_choices=[ + ABSOLUTE_FOLDER_NAME, + DEFAULT_OUTPUT_FOLDER_NAME, + DEFAULT_OUTPUT_SUBFOLDER_NAME, + DEFAULT_INPUT_FOLDER_NAME, + DEFAULT_INPUT_SUBFOLDER_NAME, + ], + doc="""\ +This setting lets you choose the folder for the output files. {folder_choice} + +{metadata_help} +""".format( + folder_choice=IO_FOLDER_CHOICE_HELP_TEXT, + metadata_help=IO_WITH_METADATA_HELP_TEXT, + ), + ) + self.directory.dir_choice = DEFAULT_OUTPUT_FOLDER_NAME + + self.model_directory = Directory( + "Model directory", allow_metadata=False, doc="""\ + Where the model is located. + +{IO_FOLDER_CHOICE_HELP_TEXT} +""".format(**{ + "IO_FOLDER_CHOICE_HELP_TEXT": _help.IO_FOLDER_CHOICE_HELP_TEXT + })) + + def set_directory_fn_executable(path): + dir_choice, custom_path = self.model_directory.get_parts_from_path(path) + self.model_directory.join_parts(dir_choice, custom_path) + + self.model_filename = Filename( + "Model file", "Cell_Painting_CNN_v1.hdf5", doc="Select your DeepProfiler model. ", + get_directory_fn=self.model_directory.get_absolute_path, + set_directory_fn=set_directory_fn_executable, + browse_msg="Choose executable file" + ) + + self.config_directory = Directory( + "Configuration directory", allow_metadata=False, doc="""\ +Select the folder containing the DeepProfiler configuration file. + +{IO_FOLDER_CHOICE_HELP_TEXT} +""".format(**{ + "IO_FOLDER_CHOICE_HELP_TEXT": _help.IO_FOLDER_CHOICE_HELP_TEXT + })) + + self.save_features = Binary( + "Write outputs to final objects table?", + True, + doc="""\ +Select "*{YES}*" to save the features generated by DeepProfiler into your final output object table. + +Note that if you select No, the outputs will be located in the output directory selected by you.""".format( + **{"YES": "Yes"} + ), + ) + + def set_directory_config_executable(path): + dir_choice, custom_path = self.config_directory.get_parts_from_path(path) + self.config_directory.join_parts(dir_choice, custom_path) + + self.config_filename = Filename( + "Configuration file", "profiling.json", doc="Select your configuration file.", + get_directory_fn=self.config_directory.get_absolute_path, + set_directory_fn=set_directory_config_executable, + browse_msg="Choose executable file" + ) + + self.app_directory = Directory( + "DeepProfiler directory", doc="""\ +Select the folder containing the DeepProfiler repository that you cloned to your computer. + +{fcht} +""".format( + fcht=IO_FOLDER_CHOICE_HELP_TEXT + ), + ) + + + def settings(self): + return [self.images_list, self.input_object_name, self.assay, + self.metadata_plate, self.metadata_well, self.metadata_site, + self.save_features, self.directory, self.app_directory, + self.model_directory, self.model_filename, + self.config_directory, self.config_filename] + # + # CellProfiler calls "run" on each image set in your pipeline. + # + def run(self, workspace): + + if self.show_window: + workspace.display_data.col_labels = ( + "Object", + "Feature", + "Mean", + "Median", + "STD", + ) + workspace.display_data.statistics = self.statistics = [] + # + # Get directories + # + try: + self.out_directory = self.directory.get_absolute_path() + model_dir = self.model_directory.get_absolute_path() + config_dir = self.config_directory.get_absolute_path() + deep_directory = self.app_directory.get_absolute_path() + + # + # Create folders using deepprofiler setup + # + executable = os.path.join(f"{deep_directory}","deepprofiler") + cmd_setup = f"python {executable} --root={self.out_directory} setup" + result = subprocess.run(cmd_setup.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + if result.returncode!=0: + msg = f"The call to DeepProfiler ({cmd_setup}) returned an error; you should try to solve this outside of CellProfiler. DeepProfiler output was as follows: \n {result.stdout}" + raise RuntimeError(msg) + + # + # Copy model and config to the folders deepprofiler expects + # + local_output = os.path.join(f"{self.out_directory}","outputs",f"{self.assay.value}","checkpoint") + os.makedirs(local_output, exist_ok=True) + local_input = os.path.join(f"{self.out_directory}","inputs","config") + os.makedirs(local_input, exist_ok=True) + shutil.copy(os.path.join(f"{model_dir}",f"{self.model_filename.value}"), local_output) + shutil.copy(os.path.join(f"{config_dir}",f"{self.config_filename.value}"), local_input) + + # + # Locations file + # creates a location file for each site with the nuclei_center + # + # Get the measurements object + self.measurements = workspace.measurements + # Get inputs + x_obj = self.measurements.get_current_measurement(self.input_object_name.value, "Location_Center_X") + y_obj = self.measurements.get_current_measurement(self.input_object_name.value, "Location_Center_Y") + self.well = self.measurements.get_current_image_measurement(self.metadata_well.value) + self.site = self.measurements.get_current_image_measurement(self.metadata_site.value) + # Create plate directory and location file + loc_dir = os.path.join(f"{self.out_directory}","inputs","locations",f"{self.metadata_plate.value}") + loc_file = f"{self.well}-{self.site}-Nuclei.csv" + os.makedirs(loc_dir, exist_ok=True) + # Create the actual file + header = 'Nuclei_Location_Center_X', 'Nuclei_Location_Center_Y' + csvpath = os.path.join(loc_dir, loc_file) + with open(csvpath, 'w', newline='', encoding='utf-8') as fpointer: + writer = csv.writer(fpointer) + writer.writerow(header) + for i in range(len(x_obj)): + writer.writerow((x_obj[i], y_obj[i])) + # + # Create the index/metadata file + # + header_files = ["Metadata_Plate", "Metadata_Well", "Metadata_Site"] + filename_list = [self.metadata_plate.value, self.well, self.site] + for img in self.images_list.value: + pathname = self.measurements.get_current_image_measurement(f"PathName_{img}") + filename = self.measurements.get_current_image_measurement(f"FileName_{img}") + filename_list.append(os.path.join(f"{pathname}",f"{filename}")) + header_files.extend(self.images_list.value) + index_dir = os.path.join(f"{self.out_directory}","inputs","metadata") + os.makedirs(index_dir, exist_ok=True) + index_file = f"index_{str(random.randint(100000, 999999))}.csv" + indexpath = os.path.join(index_dir, index_file) + with open(indexpath, 'w', newline='', encoding='utf-8') as fpointer: + writer = csv.writer(fpointer) + writer.writerow(header_files) + writer.writerow((filename_list)) + + # + # RUN! + # + cmd_run = f"python {executable} --root={self.out_directory} --config {self.config_filename.value} --metadata {index_file} --exp {self.assay.value} profile" + result = subprocess.run(cmd_run.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + if result.returncode!=0: + msg = f"The call to DeepProfiler ({cmd_run}) returned an error; you should try to solve this outside of CellProfiler. DeepProfiler output was as follows: \n {result.stdout}" + raise RuntimeError(msg) + finally: + # + # Get the outputs to save and/or display on window + # + self.columns_names, self.features = self.get_measurements_deepprofiler() + object_name = self.input_object_name.value + for i in range(len(self.columns_names)): + if self.show_window and len(self.features[i]) > 0: + self.statistics.append( + ( + object_name, + self.columns_names[i], + np.round(np.mean(self.features[i]), 3), + np.round(np.median(self.features[i]), 3), + np.round(np.std(self.features[i]), 3), + ) + ) + self.measurements.add_measurement( + object_name, + self.columns_names[i], + self.features[i], + ) + # + # Delete files after run in inputs folder + # + want_delete = True + input_dir = os.path.join(f"{self.out_directory}","inputs") + if workspace.pipeline.test_mode: + want_delete = False + if want_delete and self.save_features.value: + try: + for subdir, dirs, files in os.walk(input_dir): + for file in files: + os.remove(os.path.join(input_dir, file)) + os.removedirs(input_dir) + except: + LOGGER.error("Unable to delete temporary directory, files may be in use by another program.") + LOGGER.error("Temp folder is subfolder {input_dir} in your Default Output Folder.\nYou may need to remove it manually.") + else: + LOGGER.error(f"Did not remove temporary input folder at {input_dir}") + + def record_measurements(self, object_name, feature_name_list, results): + for i in range(len(feature_name_list)): + if self.show_window and len(results[i]) > 0: + self.statistics.append( + ( + object_name, + feature_name_list[i], + np.round(np.mean(results[i]), 3), + np.round(np.median(results[i]), 3), + np.round(np.std(results[i]), 3), + ) + ) + self.measurements.add_measurement( + object_name, + feature_name_list[i], + results[i], + ) + return + + def get_measurements_deepprofiler(self): + feat_dir = os.path.join(f"{self.out_directory}","outputs",f"{self.assay.value}","features", f"{self.metadata_plate.value}", f"{self.well}") + feat_file = f"{self.site}.npz" + features = os.path.join(f"{feat_dir}", f"{feat_file}") + self.file = np.load(features, allow_pickle=True) + columns_names = ["DeepProfiler_"+str(x+1) for x in range(0, len(self.file["features"][0]+1))] + return columns_names, self.file["features"].transpose() + + def get_measurement_columns(self, pipeline): + input_object_name = self.input_object_name.value + columns = [] + # This shouldn't be hardcode for DeepProfiler only = 672 columns. Change that! + for feature in range(0, 672): + columns.append( + ( + input_object_name, + "%s_%s" % (C_MEASUREMENT, feature+1), + COLTYPE_FLOAT, + ) + ) + return columns + + def get_categories(self, pipeline, object_name): + if object_name == self.input_object_name: + return [C_MEASUREMENT] + else: + return [] + + def get_measurements(self, pipeline, object_name, category): + if category == C_MEASUREMENT and object_name == self.input_object_name: + return self.get_measurement_columns(pipeline) + return [] + + def display(self, workspace, figure): + figure.set_subplots((1, 1)) + figure.subplot_table( + 0, + 0, + workspace.display_data.statistics, + col_labels=workspace.display_data.col_labels, + title="Per-object means. Get the per-object results on the output object's table", + ) + \ No newline at end of file diff --git a/documentation/CP-plugins-documentation/RunDeepProfiler.md b/documentation/CP-plugins-documentation/RunDeepProfiler.md new file mode 100644 index 0000000..c6def54 --- /dev/null +++ b/documentation/CP-plugins-documentation/RunDeepProfiler.md @@ -0,0 +1,65 @@ +# RunDeepProfiler + +## How to use RunDeepProfiler + +### Windows + +1. Follow the instructions to install CellProfiler from source: [Installing plugins with dependencies, using CellProfiler from source](using_plugins.md); + +2. Clone DeepProfiler repository: + +``` +git clone https://github.com/broadinstitute/DeepProfiler.git +``` + +4. Install DeepProfiler + +``` +cd DeepProfiler / +pip install -e . +``` + +5. Install dependencies by running: + +```bash +cd CellProfiler-plugins +pip install -e .[deepprofiler] +``` + +## Run Example + +1. Use the folder with images and files available on CellProfiler-plugins > test > test_deepprofiler [link here](https://github.com/CellProfiler/CellProfiler-plugins/pull/182/commits/62874b4a28a370cea069662d3804a68b651130ec) as an example to run the test pipeline test_deepprofiler.cppipe + +2. Don't forget to select the config, model, and DeepProfiler directories to your local paths. + + +## Using GPU + +If you want to use a GPU to run the model (this is recommended for speed), you'll need a compatible version of Tensorflow and a supported GPU. +General instructions are available at this [link](https://www.tensorflow.org/guide/gpu). + +1. Your GPU should be visible in Device Manager under Display Adaptors. +If your GPU isn't there, you likely need to install drivers. +[Here](https://www.nvidia.com/Download/Find.aspx) is where you can find NVIDIA GPU drivers if you need to install them. + + +2. To test whether the GPU is configured correctly: + * Run `python` on the command line (i.e., in Command Prompt or Terminal) to start an interactive session + * Then run the following + ``` + import tensorflow as tf + tf.test.is_gpu_available( + cuda_only=False, min_cuda_compute_capability=None +) + ``` + * If this returns `True`, you're all set + * If this returns `False`, you likely need to install/reinstall torch. See [here](https://www.tensorflow.org/guide/gpu) for your exact command. + * Exit the session with `exit()` then install tensorflow if necessary. + + +**NOTE**: You might get a warning like this: +``` +W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'cudart64_110.dll'; dlerror: cudart64_110.dll not found +2022-05-26 20:24:21.906286: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine. +``` +If you don't have a GPU, this is not a problem. If you do, your configuration is incorrect and you need to try reinstalling drivers and the correct version of CUDA for your system. \ No newline at end of file diff --git a/documentation/CP-plugins-documentation/supported_plugins.md b/documentation/CP-plugins-documentation/supported_plugins.md index 5ccdda9..0a74e3f 100644 --- a/documentation/CP-plugins-documentation/supported_plugins.md +++ b/documentation/CP-plugins-documentation/supported_plugins.md @@ -24,4 +24,5 @@ Those plugins that do have extra documentation contain links below. | RunImageJScript | RunImageJScript allows you to run any supported ImageJ script directly within CellProfiler. It is significantly more performant than RunImageJMacro, and is also less likely to leave behind temporary files. | Yes | XXXXX | | RunOmnipose | RunOmnipose allows you to run Omnipose within CellProfiler. Omnipose is a general image segmentation tool that builds on Cellpose. | Yes | `omnipose` | | RunStarDist | RunStarDist allows you to run StarDist within CellProfiler. StarDist is a machine-learning algorithm for object detection with star-convex shapes making it best suited for nuclei or round-ish cells. You can use pre-trained StarDist models or your custom model with this plugin. You can use a GPU with this module to dramatically increase your speed/efficiency. RunStarDist is generally faster than RunCellpose. | Yes | `stardist` | +| [RunDeepProfiler](RunDeepProfiler.md) | RunDeepProfiler allows you to run DeepProfiler within CellProfiler. DeepProfiler can measure features from single-cells using pre-trained CNN. | Yes | `deepprofiler` | | VarianceTransform | This module allows you to calculate the variance of an image, using a determined window size. It also has the option to find the optimal window size from a predetermined range to obtain the maximum variance of an image. | No | | \ No newline at end of file diff --git a/documentation/CP-plugins-documentation/using_plugins.md b/documentation/CP-plugins-documentation/using_plugins.md index 9c05ecd..a7782e0 100644 --- a/documentation/CP-plugins-documentation/using_plugins.md +++ b/documentation/CP-plugins-documentation/using_plugins.md @@ -20,6 +20,8 @@ See [Installing plugins with dependencies, using CellProfiler from source](#inst The second option allows you to use pre-built CellProfiler, but plugin installation is more complex. See [Installing plugins with dependencies, using pre-built CellProfiler](#installing-plugins-with-dependencies-using-pre-built-cellprofiler). +If using RunDeepProfiler, check for alternative installation instructions in [RunDeepProfiler](RunDeepProfiler.md). + ### Installing plugins without dependencies 1. **Install CellProfiler.** diff --git a/setup.py b/setup.py index 03d583a..339df2c 100644 --- a/setup.py +++ b/setup.py @@ -20,6 +20,11 @@ "stardist" ] +deepprofiler_deps = [ + "numpy==1.23.0", + "inflect==6.0.0" +] + imagejscript_deps = [ "pyimagej" ] @@ -32,6 +37,7 @@ "cellpose": cellpose_deps, "omnipose": omnipose_deps, "stardist": stardist_deps, + "deepprofiler":deepprofiler_deps, "imagejscript": imagejscript_deps, } ) diff --git a/tests/test_deepprofiler/config/profiling.json b/tests/test_deepprofiler/config/profiling.json new file mode 100644 index 0000000..2fd3079 --- /dev/null +++ b/tests/test_deepprofiler/config/profiling.json @@ -0,0 +1,77 @@ +{ + "dataset": { + "metadata": { + "label_field": "Metadata_Plate", + "control_value": "X" + }, + "images": { + "channels": [ + "DNA", + "RNA", + "ER", + "AGP", + "Mito" + ], + "file_format": "tif", + "bits": 16, + "width": 1224, + "height": 904 + }, + "locations":{ + "mode": "single_cells", + "area_coverage": 0.75, + "box_size": 128, + "mask_objects": false + } + }, + "prepare": { + "illumination_correction": { + "down_scale_factor": 4, + "median_filter_size": 24 + }, + "compression": { + "implement": false, + "scaling_factor": 1.0 + } + }, + "train": { + "partition": { + "targets": [ + "Metadata_Plate" + ], + "split_field": "Split", + "training": [0], + "validation": [1] + }, + "model": { + "name": "efficientnet", + "crop_generator": "sampled_crop_generator", + "augmentations": true, + "metrics": ["accuracy", "top_k", "average_class_precision"], + "epochs": 3, + "initialization":"ImageNet", + "params": { + "label_smoothing":0.0, + "learning_rate": 0.005, + "batch_size": 32, + "conv_blocks": 0 + } + }, + "sampling": { + "factor": 1, + "workers": 1 + }, + "validation": { + "frequency": 1, + "top_k": 5, + "batch_size": 32, + "frame": "val", + "sample_first_crops": true + } + }, + "profile": { + "feature_layer": "block6a_activation", + "checkpoint": "Cell_Painting_CNN_v1.hdf5", + "batch_size": 32 + } +} diff --git a/tests/test_deepprofiler/images/B2_01_1_1_DAPI_001.tif b/tests/test_deepprofiler/images/B2_01_1_1_DAPI_001.tif new file mode 100644 index 0000000..4956f80 Binary files /dev/null and b/tests/test_deepprofiler/images/B2_01_1_1_DAPI_001.tif differ diff --git a/tests/test_deepprofiler/images/B2_01_1_3_DAPI_001.tif b/tests/test_deepprofiler/images/B2_01_1_3_DAPI_001.tif new file mode 100644 index 0000000..178376b Binary files /dev/null and b/tests/test_deepprofiler/images/B2_01_1_3_DAPI_001.tif differ diff --git a/tests/test_deepprofiler/images/B2_01_2_1_GFP_001.tif b/tests/test_deepprofiler/images/B2_01_2_1_GFP_001.tif new file mode 100644 index 0000000..f50321c Binary files /dev/null and b/tests/test_deepprofiler/images/B2_01_2_1_GFP_001.tif differ diff --git a/tests/test_deepprofiler/images/B2_01_2_3_GFP_001.tif b/tests/test_deepprofiler/images/B2_01_2_3_GFP_001.tif new file mode 100644 index 0000000..7be9fd8 Binary files /dev/null and b/tests/test_deepprofiler/images/B2_01_2_3_GFP_001.tif differ diff --git a/tests/test_deepprofiler/images/B2_01_3_1_Propidium Iodide_001.tif b/tests/test_deepprofiler/images/B2_01_3_1_Propidium Iodide_001.tif new file mode 100644 index 0000000..319a81d Binary files /dev/null and b/tests/test_deepprofiler/images/B2_01_3_1_Propidium Iodide_001.tif differ diff --git a/tests/test_deepprofiler/images/B2_01_3_3_Propidium Iodide_001.tif b/tests/test_deepprofiler/images/B2_01_3_3_Propidium Iodide_001.tif new file mode 100644 index 0000000..7821cb1 Binary files /dev/null and b/tests/test_deepprofiler/images/B2_01_3_3_Propidium Iodide_001.tif differ diff --git a/tests/test_deepprofiler/images/B2_01_4_1_CY5_001.tif b/tests/test_deepprofiler/images/B2_01_4_1_CY5_001.tif new file mode 100644 index 0000000..eee76f5 Binary files /dev/null and b/tests/test_deepprofiler/images/B2_01_4_1_CY5_001.tif differ diff --git a/tests/test_deepprofiler/images/B2_01_4_3_CY5_001.tif b/tests/test_deepprofiler/images/B2_01_4_3_CY5_001.tif new file mode 100644 index 0000000..4c2e98f Binary files /dev/null and b/tests/test_deepprofiler/images/B2_01_4_3_CY5_001.tif differ diff --git a/tests/test_deepprofiler/images/G11_01_1_49_DAPI_001.tif b/tests/test_deepprofiler/images/G11_01_1_49_DAPI_001.tif new file mode 100644 index 0000000..870da41 Binary files /dev/null and b/tests/test_deepprofiler/images/G11_01_1_49_DAPI_001.tif differ diff --git a/tests/test_deepprofiler/images/G11_01_2_49_GFP_001.tif b/tests/test_deepprofiler/images/G11_01_2_49_GFP_001.tif new file mode 100644 index 0000000..59ef1f9 Binary files /dev/null and b/tests/test_deepprofiler/images/G11_01_2_49_GFP_001.tif differ diff --git a/tests/test_deepprofiler/images/G11_01_3_49_Propidium Iodide_001.tif b/tests/test_deepprofiler/images/G11_01_3_49_Propidium Iodide_001.tif new file mode 100644 index 0000000..22c14b4 Binary files /dev/null and b/tests/test_deepprofiler/images/G11_01_3_49_Propidium Iodide_001.tif differ diff --git a/tests/test_deepprofiler/images/G11_01_4_49_CY5_001.tif b/tests/test_deepprofiler/images/G11_01_4_49_CY5_001.tif new file mode 100644 index 0000000..338d9b2 Binary files /dev/null and b/tests/test_deepprofiler/images/G11_01_4_49_CY5_001.tif differ diff --git a/tests/test_deepprofiler/model/Cell_Painting_CNN_v1.hdf5 b/tests/test_deepprofiler/model/Cell_Painting_CNN_v1.hdf5 new file mode 100644 index 0000000..06693f2 Binary files /dev/null and b/tests/test_deepprofiler/model/Cell_Painting_CNN_v1.hdf5 differ diff --git a/tests/test_deepprofiler/test_deepprofiler.cppipe b/tests/test_deepprofiler/test_deepprofiler.cppipe new file mode 100644 index 0000000..78a9b47 --- /dev/null +++ b/tests/test_deepprofiler/test_deepprofiler.cppipe @@ -0,0 +1,128 @@ +CellProfiler Pipeline: http://www.cellprofiler.org +Version:5 +DateRevision:425 +GitHash: +ModuleCount:6 +HasImagePlaneDetails:False + +Images:[module_num:1|svn_version:'Unknown'|variable_revision_number:2|show_window:False|notes:['To begin creating your project, use the Images module to compile a list of files and/or folders that you want to analyze. You can also specify a set of rules to include only the desired files in your selected folders.']|batch_state:array([], dtype=uint8)|enabled:True|wants_pause:False] + : + Filter images?:Images only + Select the rule criteria:and (extension does isimage) (directory doesnot containregexp "[\\\\/]\\.") + +Metadata:[module_num:2|svn_version:'Unknown'|variable_revision_number:6|show_window:False|notes:['The Metadata module optionally allows you to extract information describing your images (i.e, metadata) which will be stored along with your measurements. This information can be contained in the file name and/or location, or in an external file.']|batch_state:array([], dtype=uint8)|enabled:True|wants_pause:False] + Extract metadata?:Yes + Metadata data type:Text + Metadata types:{} + Extraction method count:1 + Metadata extraction method:Extract from file/folder names + Metadata source:File name + Regular expression to extract from file name:^(?P.*)_.*_.*_(?P.*)_(?P.*)_001.tif + Regular expression to extract from folder name:(?P[0-9]{4}_[0-9]{2}_[0-9]{2})$ + Extract metadata from:All images + Select the filtering criteria:and (file does contain "") + Metadata file location:Elsewhere...| + Match file and image metadata:[] + Use case insensitive matching?:No + Metadata file name:None + Does cached metadata exist?:No + +NamesAndTypes:[module_num:3|svn_version:'Unknown'|variable_revision_number:8|show_window:False|notes:['The NamesAndTypes module allows you to assign a meaningful name to each image by which other modules will refer to it.']|batch_state:array([], dtype=uint8)|enabled:True|wants_pause:False] + Assign a name to:Images matching rules + Select the image type:Grayscale image + Name to assign these images:DNA + Match metadata:[] + Image set matching method:Order + Set intensity range from:Image metadata + Assignments count:5 + Single images count:0 + Maximum intensity:255.0 + Process as 3D?:No + Relative pixel spacing in X:1.0 + Relative pixel spacing in Y:1.0 + Relative pixel spacing in Z:1.0 + Select the rule criteria:and (file does contain "DAPI") + Name to assign these images:DNA + Name to assign these objects:Cell + Select the image type:Grayscale image + Set intensity range from:Image metadata + Maximum intensity:255.0 + Select the rule criteria:and (file does contain "GFP") + Name to assign these images:ER + Name to assign these objects:Nucleus + Select the image type:Grayscale image + Set intensity range from:Image metadata + Maximum intensity:255.0 + Select the rule criteria:and (file does contain "Propidium") + Name to assign these images:AGP + Name to assign these objects:Cytoplasm + Select the image type:Grayscale image + Set intensity range from:Image metadata + Maximum intensity:255.0 + Select the rule criteria:and (file does contain "CY5") + Name to assign these images:Mito + Name to assign these objects:Speckle + Select the image type:Grayscale image + Set intensity range from:Image metadata + Maximum intensity:255.0 + Select the rule criteria:and (file does contain "CY5") + Name to assign these images:RNA + Name to assign these objects:Object1 + Select the image type:Grayscale image + Set intensity range from:Image metadata + Maximum intensity:255.0 + +Groups:[module_num:4|svn_version:'Unknown'|variable_revision_number:2|show_window:False|notes:['The Groups module optionally allows you to split your list of images into image subsets (groups) which will be processed independently of each other. Examples of groupings include screening batches, microtiter plates, time-lapse movies, etc.']|batch_state:array([], dtype=uint8)|enabled:True|wants_pause:False] + Do you want to group your images?:No + grouping metadata count:1 + Metadata category:None + +IdentifyPrimaryObjects:[module_num:5|svn_version:'Unknown'|variable_revision_number:15|show_window:False|notes:[]|batch_state:array([], dtype=uint8)|enabled:True|wants_pause:False] + Select the input image:DNA + Name the primary objects to be identified:IdentifyPrimaryObjects + Typical diameter of objects, in pixel units (Min,Max):30,200 + Discard objects outside the diameter range?:Yes + Discard objects touching the border of the image?:Yes + Method to distinguish clumped objects:Intensity + Method to draw dividing lines between clumped objects:Intensity + Size of smoothing filter:10 + Suppress local maxima that are closer than this minimum allowed distance:7.0 + Speed up by using lower-resolution image to find local maxima?:Yes + Fill holes in identified objects?:After both thresholding and declumping + Automatically calculate size of smoothing filter for declumping?:Yes + Automatically calculate minimum allowed distance between local maxima?:Yes + Handling of objects if excessive number of objects identified:Continue + Maximum number of objects:500 + Use advanced settings?:Yes + Threshold setting version:12 + Threshold strategy:Global + Thresholding method:Otsu + Threshold smoothing scale:1.3488 + Threshold correction factor:1.0 + Lower and upper bounds on threshold:0.0,1.0 + Manual threshold:0.0 + Select the measurement to threshold with:None + Two-class or three-class thresholding?:Three classes + Log transform before thresholding?:No + Assign pixels in the middle intensity class to the foreground or the background?:Background + Size of adaptive window:50 + Lower outlier fraction:0.05 + Upper outlier fraction:0.05 + Averaging method:Mean + Variance method:Standard deviation + # of deviations:2.0 + Thresholding method:Minimum Cross-Entropy + +RunDeepProfiler:[module_num:6|svn_version:'Unknown'|variable_revision_number:1|show_window:False|notes:[]|batch_state:array([], dtype=uint8)|enabled:True|wants_pause:False] + Select images to measure:AGP, DNA, ER, Mito, RNA + Input nuclei object name:IdentifyPrimaryObjects + Name this experiment.:FeaturesDeepProfiler + Output file location:Elsewhere...|C:\\Users\\fossa\\Desktop\\deepprofiler\\example\\run + DeepProfiler directory:Elsewhere...|C:\Users\fossa\DeepProfiler + Model directory:Elsewhere...|C:\Users\fossa\Desktop\deepprofiler\example + Model file:Cell_Painting_CNN_v1.hdf5 + Select Metadata_Plate:Metadata_Frame + Select Metadata_Well:Metadata_Well + Select Metadata_Site:Metadata_Site + Config directory:Elsewhere...|C:\\Users\\fossa\\Desktop\\deepprofiler\\example + Model file:profiling.json