예제 #1
0
    def check_overwrite(self, workspace):
        """Make sure it's ok to overwrite any existing files before starting run
        
        workspace - workspace with all image sets already populated
        
        returns True if ok to proceed, False if user cancels
        """
        if self.wants_overwrite_without_warning:
            return True

        files_to_check = []
        metadata_groups = self.get_metadata_groups(workspace)
        for metadata_group in metadata_groups:
            image_number = metadata_group.image_numbers[0]
            files_to_check.append(
                self.make_image_file_name(workspace, image_number))

        files_to_overwrite = filter(os.path.isfile, files_to_check)
        if len(files_to_overwrite) > 0:
            if get_headless():
                logger.error(
                    "ExportToACC is configured to refrain from overwriting files and the following file(s) already exist: %s"
                    % ", ".join(files_to_overwrite))
                return False
            msg = "Overwrite the following file(s)?\n" +\
                "\n".join(files_to_overwrite)
            import wx
            result = wx.MessageBox(
                msg,
                caption="ExportToACC: Overwrite existing files",
                style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
            if result != wx.YES:
                return False

        return True
예제 #2
0
def show_warning(title, message, get_preference, set_preference):
    """Show a silenceable warning message to the user

    title - title for the dialog box

    message - message to be displayed

    get_preference - function that gets a user preference: do you want to
                     show this warning?

    set_preference - function that sets the user preference if they choose
                     not to see the warning again.

    The message is printed to the console if headless.
    """
    from cellprofiler_core.preferences import get_headless

    if get_headless():
        print(message)
        return

    if not get_preference():
        return

    import wx

    if wx.GetApp() is None:
        print(message)
        return

    with wx.Dialog(None, title=title) as dlg:
        dlg.Sizer = sizer = wx.BoxSizer(wx.VERTICAL)
        subsizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(subsizer, 0, wx.EXPAND | wx.ALL, 5)
        subsizer.Add(
            wx.StaticBitmap(
                dlg,
                wx.ID_ANY,
                wx.ArtProvider.GetBitmap(wx.ART_INFORMATION,
                                         wx.ART_CMN_DIALOG),
            ),
            0,
            wx.ALIGN_LEFT | wx.ALIGN_TOP | wx.RIGHT,
            5,
        )
        text = wx.StaticText(dlg, wx.ID_ANY, message)
        subsizer.Add(text, 0, wx.ALIGN_LEFT | wx.ALIGN_TOP | wx.ALL, 5)
        dont_show = wx.CheckBox(dlg, label="Don't show this message again.")
        sizer.Add(dont_show, 0, wx.ALIGN_LEFT | wx.ALL, 5)
        buttons_sizer = wx.StdDialogButtonSizer()
        buttons_sizer.AddButton(wx.Button(dlg, wx.ID_OK))
        buttons_sizer.Realize()
        sizer.Add(buttons_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
        dlg.Fit()
        dlg.ShowModal()
        if dont_show.GetValue():
            set_preference(False)
예제 #3
0
    def prepare_run(self, workspace):
        """Invoke the image_set_list pickling mechanism and save the pipeline"""

        pipeline = workspace.pipeline
        image_set_list = workspace.image_set_list

        if pipeline.test_mode or self.from_old_matlab:
            return True
        if self.batch_mode.value:
            self.enter_batch_mode(workspace)
            return True
        else:
            path = self.save_pipeline(workspace)
            if not cpprefs.get_headless():
                import wx

                wx.MessageBox(
                    "CreateBatchFiles saved pipeline to %s" % path,
                    caption="CreateBatchFiles: Batch file saved",
                    style=wx.OK | wx.ICON_INFORMATION,
                )
            return False
예제 #4
0
    def run(self, workspace):
        """Run the module. Add the measurements. """

        statistics_dict = {}
        ratio_dict = {}
        for channel in self.channels:
            provider = workspace.image_set.get_image_provider(
                channel.cpimage_name.value)
            assert isinstance(provider, OmeroImageProvider)

            name = provider.get_name()
            omero_image_name = provider.get_omero_image_name()
            omero_image_id = provider.get_image_id()
            pixels_id = provider.get_pixels_id()
            z = provider.get_z()
            c = provider.get_c()
            t = provider.get_t()

            header = []
            row = []
            ratio = []
            m = workspace.measurements
            measurements = ()
            if self.omero_object == MS_DATASET:
                measurements += (
                    (M_DATASET_NAME, self.dataset_name, 3.0),
                    (M_DATASET_ID, self.omero_object_id.value, 1.0),
                )
            elif self.omero_object == MS_PLATE:
                # CellProfiler starts counting image sets from 1
                well = self.wells[workspace.measurements.image_set_number - 1]
                well_row = well.getRow().getValue()
                well_column = well.getColumn().getValue()
                well_id = well.getId().getValue()
                measurements += (
                    (M_PLATE_NAME, self.plate_name, 3.0),
                    (M_PLATE_ID, self.omero_object_id.value, 1.0),
                    (M_WELL_ROW, well_row, 1.0),
                    (M_WELL_COLUMN, well_column, 1.0),
                    (M_WELL_ID, well_id, 3.0),
                )
            measurements += (
                (M_IMAGE_NAME, omero_image_name, 3.0),
                (M_IMAGE_ID, omero_image_id, 1.0),
                (M_PIXELS_ID, pixels_id, 1.0),
                (M_Z, z, 0.5),
                (M_C, c, 0.5),
                (M_T, t, 0.5),
            )
            for tag, value, r in measurements:
                m.add_image_measurement("_".join((tag, name)), value)
                header.append(tag)
                row.append(value)
                ratio.append(r)
            statistics = [header, row]
            ratio = [x / sum(ratio) for x in ratio]
            statistics_dict[channel.channel_number.value] = statistics
            ratio_dict[channel.channel_number.value] = ratio

        workspace.display_data.statistics = statistics_dict
        workspace.display_data.ratio = ratio_dict

        if cpp.get_headless():  # headless mode
            for channel in self.channels:
                image_name, channel_number = (
                    channel.cpimage_name.value,
                    channel.channel_number.value,
                )
                print("--- image name: %s\tchannel: %s" %
                      (image_name, channel_number))
                (header,
                 row) = workspace.display_data.statistics[channel_number]
                for i in range(0, len(header)):
                    print("\t%s: %s" % (header[i], row[i]))
예제 #5
0
    def prepare_run(self, workspace):
        """Set up omero image providers inside the image_set_list"""
        pipeline = workspace.pipeline
        image_set_list = workspace.image_set_list
        if pipeline.in_batch_mode():
            # TODO: Rewrite the OmeroImageProvider such that it can be used in batch mode
            # e.g., omero session keys could be used to attach to existing sessions to
            # keep OmeroImageProviders from creating a new session every time an image should be loaded
            return False

        if cpp.get_headless():
            print(
                "OmeroLoadImages running in headless mode: image directory parameter will be used as omero object id"
            )
            self.omero_object_id.set_value(
                int(cpp.get_default_image_directory()))
            print("omero object id = %d" % self.omero_object_id.value)
            print("omero object type = %s" % self.omero_object.value)

        self.create_omero_gateway()
        if self.omero_object == MS_IMAGE:
            omero_image_list = [
                self.omero_gateway.getImage(self.omero_object_id.value)
            ]
        elif self.omero_object == MS_DATASET:
            # Get dataset without leaves(=images&pixels)
            dataset = self.omero_gateway.getDataset(self.omero_object_id.value,
                                                    False)
            self.dataset_name = dataset.getName().getValue()
            omero_image_list = self.get_images_from_dataset(
                self.omero_object_id.value)
        elif self.omero_object == MS_PLATE:
            self.wells = self.get_wells_from_plate(self.omero_object_id.value)
            self.plate_name = self.wells[0].getPlate().getName().getValue()
            omero_image_list = []
            for well in self.wells:
                for wellsample in well.iterateWellSamples():
                    omero_image_list.append(wellsample.getImage())

        # get names and pixels from omero images
        pixels_list = []
        for omero_image in omero_image_list:
            image_id = omero_image.getId().getValue()
            pixels_list += self.omero_gateway.getPixelsFromImage(image_id)

        # add images to image sets
        image_set_count = len(pixels_list)
        for i in range(0, image_set_count):
            image_set = image_set_list.get_image_set(i)
            pixels = pixels_list[i]
            pixels_id = pixels.getId().getValue()
            sizeZ = pixels.getSizeZ().getValue()
            sizeC = pixels.getSizeC().getValue()
            sizeT = pixels.getSizeT().getValue()
            for channel in self.channels:
                for z in range(0, sizeZ):
                    for t in range(0, sizeT):
                        c = int(channel.channel_number.value)
                        self.save_image_set_info(
                            image_set,
                            channel.cpimage_name.value,
                            P_OMERO,
                            V_OMERO,
                            self.omero_gateway,
                            pixels_id,
                            z,
                            c,
                            t,
                        )
        return True
예제 #6
0
    def merge_files(destination, sources, force_headless=False):
        is_headless = force_headless or get_headless()
        if not is_headless:
            import wx
        if len(sources) == 0:
            return
        if not is_headless:
            progress = wx.ProgressDialog(
                "Writing " + destination,
                "Loading " + sources[0],
                maximum=len(sources) * 4 + 1,
                style=wx.PD_CAN_ABORT
                | wx.PD_APP_MODAL
                | wx.PD_ELAPSED_TIME
                | wx.PD_REMAINING_TIME,
            )
        count = 0
        try:
            pipeline = cpp.Pipeline()
            has_error = [False]

            def callback(caller, event):
                if isinstance(event, cpp.event.LoadException):
                    has_error = True
                    wx.MessageBox(
                        message="Could not load %s: %s" %
                        (sources[0], event.error),
                        caption="Failed to load %s" % sources[0],
                    )
                    has_error[0] = True

            pipeline.add_listener(callback)

            pipeline.load(sources[0])
            if has_error[0]:
                return
            if destination.lower().endswith(".h5"):
                mdest = cpmeas.Measurements(filename=destination,
                                            multithread=False)
                h5_dest = True
            else:
                mdest = cpmeas.Measurements(multithread=False)
                h5_dest = False
            for source in sources:
                if not is_headless:
                    count += 1
                    keep_going, skip = progress.Update(count,
                                                       "Loading " + source)
                    if not keep_going:
                        return
                if h5py.is_hdf5(source):
                    msource = cpmeas.Measurements(filename=source,
                                                  mode="r",
                                                  multithread=False)
                else:
                    msource = cpmeas.load_measurements(source)
                dest_image_numbers = mdest.get_image_numbers()
                source_image_numbers = msource.get_image_numbers()
                if len(dest_image_numbers) == 0 or len(
                        source_image_numbers) == 0:
                    offset_source_image_numbers = source_image_numbers
                else:
                    offset_source_image_numbers = (
                        np.max(dest_image_numbers) -
                        np.min(source_image_numbers) + source_image_numbers +
                        1)
                for object_name in msource.get_object_names():
                    if object_name in mdest.get_object_names():
                        destfeatures = mdest.get_feature_names(object_name)
                    else:
                        destfeatures = []
                    for feature in msource.get_feature_names(object_name):
                        if object_name == cpmeas.EXPERIMENT:
                            if not mdest.has_feature(object_name, feature):
                                src_value = msource.get_experiment_measurement(
                                    feature)
                                mdest.add_experiment_measurement(
                                    feature, src_value)
                            continue
                        src_values = msource.get_measurement(
                            object_name,
                            feature,
                            image_set_number=source_image_numbers)
                        mdest[object_name, feature,
                              offset_source_image_numbers] = src_values
                    destset = set(destfeatures)
            if not is_headless:
                keep_going, skip = progress.Update(count + 1,
                                                   "Saving to " + destination)
                if not keep_going:
                    return
            if not h5_dest:
                pipeline.save_measurements(destination, mdest)
        finally:
            if not is_headless:
                progress.Destroy()
예제 #7
0
    def run(self, workspace):
        default_output_directory = get_default_output_directory()
        tag = "runimagejmacro_" + str(random.randint(100000, 999999))
        tempdir = os.path.join(default_output_directory, tag)
        os.makedirs(tempdir, exist_ok=True)
        try:
            for image_group in self.image_groups_in:
                image = workspace.image_set.get_image(
                    image_group.image_name.value)
                image_pixels = image.pixel_data
                skimage.io.imsave(
                    os.path.join(tempdir, image_group.output_filename.value),
                    image_pixels)

            if self.executable_file.value[-4:] == ".app":
                executable = os.path.join(
                    default_output_directory,
                    self.executable_directory.value.split("|")[1],
                    self.executable_file.value, "Contents/MacOS/ImageJ-macosx")
            else:
                executable = os.path.join(
                    default_output_directory,
                    self.executable_directory.value.split("|")[1],
                    self.executable_file.value)
            cmd = [
                executable, "--headless", "console", "--run",
                os.path.join(default_output_directory,
                             self.macro_directory.value.split("|")[1],
                             self.macro_file.value)
            ]

            cmd += [self.stringify_metadata(tempdir)]

            result = subprocess.run(cmd,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT,
                                    text=True)
            for image_group in self.image_groups_out:
                if not os.path.exists(
                        os.path.join(tempdir,
                                     image_group.input_filename.value)):
                    # Cleanup the error logs for display, we want to remove less-useful lines to keep it succinct.
                    reject = ('console:', 'Java Hot', 'at org', 'at java',
                              '[WARNING]', '\t')
                    # ImageJ tends to report the same few lines over and over, so we'll use a dict as an ordered set.
                    err = {}
                    for line in result.stdout.splitlines():
                        if len(line.strip()) > 0 and not line.startswith(
                                reject):
                            err[line] = None
                    if len(err) > 1:
                        # Error appears when file loading fails, but can also show up if the macro failed to generate
                        # an output image. We remove this if it wasn't the only error, as it can be confusing.
                        err.pop('Unsupported format or not found', None)
                    err = "\n".join(err.keys())
                    msg = f"CellProfiler couldn't find the output expected from the ImageJ Macro," \
                          f"\n File {image_group.input_filename.value} was missing."
                    if err:
                        msg += f"\n\nImageJ logs contained the following: \n{err}"
                    raise FileNotFoundError("Missing file", msg)
                image_pixels = skimage.io.imread(
                    os.path.join(tempdir, image_group.input_filename.value))
                workspace.image_set.add(image_group.image_name.value,
                                        Image(image_pixels, convert=False))
        finally:
            want_delete = True
            # Optionally clean up temp directory regardless of macro success
            if workspace.pipeline.test_mode and self.debug_mode:
                want_delete = False
                if not get_headless():
                    import wx
                    message = f"Debugging was enabled.\nTemporary folder was not deleted automatically" \
                              f"\n\nTemporary subfolder is {os.path.split(tempdir)[-1]} in your Default Output Folder\n\nDo you want to delete it now?"
                    with wx.Dialog(None,
                                   title="RunImageJMacro Debug Mode") as dlg:
                        text_sizer = dlg.CreateTextSizer(message)
                        sizer = wx.BoxSizer(wx.VERTICAL)
                        dlg.SetSizer(sizer)
                        button_sizer = dlg.CreateStdDialogButtonSizer(
                            flags=wx.YES | wx.NO)
                        open_temp_folder_button = wx.Button(
                            dlg, -1, "Open temporary folder")
                        button_sizer.Insert(0, open_temp_folder_button)

                        def on_open_temp_folder(event):
                            import sys
                            if sys.platform == "win32":
                                os.startfile(tempdir)
                            else:
                                import subprocess
                                subprocess.call([
                                    "open",
                                    tempdir,
                                ])

                        open_temp_folder_button.Bind(wx.EVT_BUTTON,
                                                     on_open_temp_folder)
                        sizer.Add(text_sizer, 0, wx.EXPAND | wx.ALL, 10)
                        sizer.Add(button_sizer, 0, wx.EXPAND | wx.ALL, 10)
                        dlg.SetEscapeId(wx.ID_NO)
                        dlg.SetAffirmativeId(wx.ID_YES)
                        dlg.Fit()
                        dlg.CenterOnParent()
                        if dlg.ShowModal() == wx.ID_YES:
                            want_delete = True
            if want_delete:
                try:
                    for subdir, dirs, files in os.walk(tempdir):
                        for file in files:
                            os.remove(os.path.join(tempdir, file))
                    os.removedirs(tempdir)
                except:
                    logging.error(
                        "Unable to delete temporary directory, files may be in use by another program."
                    )
                    logging.error(
                        "Temp folder is subfolder {tempdir} in your Default Output Folder.\nYou may need to remove it manually."
                    )
            else:
                logging.error(
                    f"Debugging was enabled.\nDid not remove temporary folder at {tempdir}"
                )

        pixel_data = []
        image_names = []

        if self.show_window:
            for x in itertools.chain(self.image_groups_in,
                                     self.image_groups_out):
                pixel_data.append(
                    workspace.image_set.get_image(
                        x.image_name.value).pixel_data)
                image_names.append(x.image_name.value)

        workspace.display_data.pixel_data = pixel_data
        workspace.display_data.display_names = image_names
        workspace.display_data.dimensions = workspace.image_set.get_image(
            self.image_groups_out[0].image_name.value).dimensions