Пример #1
0
def perform_manual_qc(imp, rois, important_channel=1):
    """given cell rois generated by automatic methods, allow user to delete/add/redraw as appropriate"""
    for ch in range(imp.getNChannels()):
        imp.setC(ch + 1)
        sat_frac = 0.99 if (ch + 1) == important_channel else 0.01
        IJ.run(imp, "Enhance Contrast", "saturated={}".format(sat_frac))

    imp.setC(important_channel)
    IJ.setTool("freehand")
    proceed = False
    roim = RoiManager()
    roim.runCommand("Show all with labels")
    for roi in rois:
        roim.addRoi(roi)
    auto_rois_only = rois
    while not proceed:
        dialog = NonBlockingGenericDialog("Perform manual segmentation")
        dialog.setOKLabel("Proceed to next image...")
        dialog.addMessage("Perform manual correction of segmentation: ")
        dialog.addMessage(
            "Draw around cells and add to the region of interest manager (Ctrl+T). "
        )
        dialog.addMessage("Delete and redraw cells as appropriate. ")
        dialog.addMessage(
            "Then press \"proceed to next image\" when all cells have been added. "
        )
        dialog.showDialog()
        if dialog.wasCanceled():
            print("Manual segmentation canceled")
            return auto_rois_only
        elif dialog.wasOKed():
            if roim.getCount() == 0:
                rois = []
                confirm_dialog = GenericDialog("Continue?")
                confirm_dialog.addMessage(
                    "No rois selected in this FOV. Are you sure you want to proceed?"
                )
                confirm_dialog.setOKLabel("Yes, proceed")
                confirm_dialog.setCancelLabel("No, not yet")
                confirm_dialog.showDialog()
                if confirm_dialog.wasOKed():
                    proceed = True
            else:
                rois = roim.getRoisAsArray()
                proceed = True
    roim.reset()
    roim.close()
    for ch in range(imp.getNChannels()):
        imp.setC(ch + 1)
        IJ.run(imp, "Enhance Contrast", "saturated={}".format(0.35))
    imp.setC(important_channel)
    return rois
Пример #2
0
def save_etc(imp, info, output_folder):
	"""handle saving output, final labelling and UI of what to do next"""
	dialog = GenericDialog("Marksl1 cell shape prescreen");
	dialog.addChoice("Vessel type: ", 
						info.get_vessel_types(), 
						info.get_vessel_type());
	dialog.addStringField("Channel 1 label: ", info.get_ch1_label());
	dialog.addStringField("Channel 2 label: ", info.get_ch2_label());
	dialog.addStringField("Experiment identifier: ", info.get_experiment_id());
	dialog.addStringField("Embryo identifier: ", info.get_embryo_id());
	dialog.setOKLabel("Save preprocessing");
	dialog.showDialog();
	info.set_vessel_type(dialog.getNextChoice());
	info.set_ch1_label(dialog.getNextString());
	info.set_ch2_label(dialog.getNextString());
	info.set_experiment_id(dialog.getNextString());
	info.set_embryo_id(dialog.getNextString());
	if dialog.wasCanceled():
		return "stop";
	if dialog.wasOKed():
		exsting_files = os.listdir(output_folder);
		r = re.compile(".*" + info.get_embryo_id() + " " + info.get_vessel_type() + ".*")
		fns = filter(r.match, exsting_files)
		numbers = list((int(s) for fn in fns for s in re.findall(r'\b\d+$', os.path.splitext(fn)[0])));
		append_digit = (max(numbers) + 1) if numbers else 1;
		ch1str = (info.get_ch1_label() + " ") if info.get_ch1_label() else "";
		ch2str = (info.get_ch2_label() + " ") if info.get_ch2_label() else "";
		expstr = (info.get_experiment_id() + " ") if info.get_experiment_id() else "";
		file_name = ("Cropped " + ch1str + ch2str + expstr + 
					"e" + str(info.get_embryo_id()) + " " + 
					info.get_vessel_type() + " " + 
					str(append_digit));
		FileSaver(imp).saveAsTiff(os.path.join(output_folder, (file_name + ".tif")));
		info.save_info_to_json(os.path.join(output_folder, (file_name + ".json")));
		continueDialog = YesNoCancelDialog(WM.getCurrentWindow(), 
											"Continue?", 
											"Continue with same input image or a new input image?", 
											"New image...", 
											"Same image");
		if continueDialog.cancelPressed():
			return "stop";
		if continueDialog.yesPressed():
			return "continue_newimage";
		return "continue_sameimage";
	return "stop";
Пример #3
0
def get_image(info, default_path, used_files):
	"""handle getting image from file"""
	check_for_file_overlap_OK = False;
	while not check_for_file_overlap_OK:
		info.set_input_file_path(file_location_chooser(default_path));
		if info.get_input_file_path() in used_files:
			dlg = GenericDialog("Image already used...");
			dlg.addMessage("This image has already been used in this analysis run.  \n " + 
					"Continue with this image, or choose a new one?");
			dlg.setOKLabel("Continue");
			dlg.setCancelLabel("Choose again...");
			dlg.showDialog();
			check_for_file_overlap_OK = False if dlg.wasCanceled() else True;
		else:
			check_for_file_overlap_OK = True;
	import_opts, info = choose_series(info.get_input_file_path(), info)

	imps = bf.openImagePlus(import_opts);
	imp = imps[0];
	
	try:
		memory_usage = IJ.currentMemory()/IJ.maxMemory();
		print("memory usage = " +str(memory_usage));
		# arbitrary limit...
		if memory_usage > 0.95: 
			IJ.run(imp, "8-bit", "");
			print("WARNING - IMAGE CONVERTED TO 8 BIT TO CONSERVE MEMORY!");
		info.set_metadata_file_path(os.path.splitext(info.get_input_file_path())[0] + ".txt");
		metadata = import_iq3_metadata(info.get_metadata_file_path());
		IJ.run(imp, "Properties...", "channels=" + str(int(metadata['n_channels'])) + 
										" slices=" + str(int(metadata['z_pixels'])) + 
										" frames=1 unit=" + str(metadata['x_unit']) + 
										" pixel_width=" + str(metadata['x_physical_size']) + 
										" pixel_height=" + str(metadata['y_physical_size']) + 
										" voxel_depth=" + str(metadata['z_extent']/metadata['z_pixels']));
		info.set_xy_pixel_size_um(metadata['x_physical_size']);
		info.set_z_plane_spacing_um(metadata['z_extent']/metadata['z_pixels']);
		info = parse_info_from_filename(info);
	except e as Exception:
		print(e.message);
	finally:
		if imp is not None:
			imp.close();
	return imp, info;
def main():
    # define here which membrane indices will be used in the analysis, with last index the "control" index
    membrane_indices = [-1, 0, 1, 3]

    # for now, work with frontmost open image...
    imp = IJ.getImage()
    im_title = imp.getTitle()
    settings = MembraneEvolutionAnalysisSettings(
        membrane_indices=membrane_indices)
    settings.loadPersistedSettings()

    timestamp = datetime.strftime(datetime.now(), '%Y-%m-%d %H-%M-%S')
    DirectoryChooser.setDefaultDirectory((settings.output_path))
    dc = DirectoryChooser('Select the root folder for saving output')
    output_root = dc.getDirectory()
    if output_root is None:
        raise IOError('no output path chosen')
    settings.output_path = output_root

    # get calibration
    cal = imp.getCalibration()
    if cal.getTimeUnit() == "sec":
        cal.setTimeUnit('s')

    # pop up a dialog prompting for selection of zero time point, frame interval, and time step for analysis
    time_steps_not_ok = True
    while time_steps_not_ok:
        dialog = NonBlockingGenericDialog("Determine time parameters...")
        dialog.addNumericField("0 timepoint frame (1-index): ",
                               settings.zero_timepoint_frame, 0)
        dialog.addNumericField("Acquisition time step (s): ",
                               cal.frameInterval,
                               2)  # assume stored in seconds
        dialog.addNumericField(
            "Time step for analysis (s): ",
            cal.frameInterval * settings.analysis_frame_step, 2)
        dialog.showDialog()

        if dialog.wasCanceled():
            return

        zero_f = dialog.getNextNumber()
        acq_t_step = dialog.getNextNumber()
        analysis_t_step = dialog.getNextNumber()
        if acq_t_step != 0 and analysis_t_step != 0:
            analysis_frame_step = analysis_t_step / acq_t_step

            if round(analysis_frame_step) == analysis_frame_step:
                time_steps_not_ok = False
                settings.zero_timepoint_frame = zero_f
                settings.analysis_frame_step = analysis_frame_step
        if time_steps_not_ok:
            warning_dlg = GenericDialog("Error!")
            warning_dlg.addMessage(
                "Analysis time step must be an integer multiple of acquisition time steps, and neither should be zero!!"
            )
            warning_dlg.setOKLabel("Try again...")
            warning_dlg.showDialog()

            if warning_dlg.wasCanceled():
                return

    start_frame = int(((zero_f - 1) % analysis_frame_step) + 1)
    end_frame = int(imp.getNFrames() -
                    (imp.getNFrames() - zero_f) % analysis_frame_step)
    frames = [
        f + 1
        for f in range(start_frame - 1, end_frame, int(analysis_frame_step))
    ]
    print("frames = " + str(frames))
    imp.killRoi()
    analysis_imp = SubstackMaker().makeSubstack(
        imp,
        str(start_frame) + "-" + str(end_frame) + "-" +
        str(int(analysis_frame_step)))
    imp.changes = False
    imp.close()
    analysis_imp.show()
    drawn_membranes = [
        TimepointsMembranes(input_image_title=im_title,
                            time_point_s=(t - 1) * acq_t_step) for t in frames
    ]
    membranes_listener = UpdateRoiImageListener(drawn_membranes)
    analysis_imp.addImageListener(membranes_listener)

    # now attach roi listener to store all 0th membranes after showing a waitforuserdialog to prompt continuation
    IJ.setTool("freeline")
    for membrane_idx in membrane_indices:
        #		if membrane_idx>50:
        #			IJ.setTool("line");
        analysis_imp.killRoi()
        membranes_listener.resetLastFrame()
        membranes_listener.setCurrentMembraneIndex(membrane_idx)
        analysis_imp.setZ(1)
        continue_dlg = WaitForUserDialog(
            "Continue?", "Click OK once all the " + str(membrane_idx) +
            "-index membranes have been drawn")
        continue_dlg.show()
        membranes_listener.imageUpdated(analysis_imp)
        drawn_membranes = membranes_listener.getDrawnMembraneTimepointsList()
        json_path = os.path.join(output_root,
                                 "Membranes " + timestamp + ".json")
        f = open(json_path, 'w+')
        try:
            json.dump(drawn_membranes, f, default=encode_membrane)
        finally:
            f.close()
        # save csv containing mebrane measurements for current membrane index
        csv_path = os.path.join(
            output_root, ("Membrane measurements " + timestamp + ".csv"))
        if membrane_idx == membrane_indices[0]:
            try:
                f = open(csv_path, 'wb')
                writer = csv.writer(f)
                writer.writerow([
                    "Membrane index", ("Time point, " + cal.getTimeUnit()),
                    ("Membrane length, " + cal.getUnit()),
                    ("Euclidean length, " + cal.getUnit()),
                    "Membrane sinuoisty"
                ])
            finally:
                f.close()
        try:
            f = open(csv_path, 'ab')
            writer = csv.writer(f)
            for mems in drawn_membranes:
                mem = mems.getMembrane(membrane_idx)
                if mem is not None:
                    writer.writerow([
                        membrane_idx, mems.time_point_s,
                        mem.getPathLength() * cal.pixelWidth,
                        mem.getEuclidean() * cal.pixelWidth,
                        mem.getSinuosity()
                    ])
        finally:
            f.close()

    settings.persistSettings()
    settings.save_settings()
    print("Finished getting all membranes with indices " +
          str(membrane_indices))
    analysis_imp.close()
Пример #5
0
class Colortags:
'''
This class handles persistence of the name of different color channels.
It instantiates a GUI window to capture and show the color names in use.
Other classes such as ColorMerger needs this to determine the color of the channel being processed.
'''
	def __init__(self):

		self.window = None
		self.tags = {}
		self.prefkeys = ["{0}.{1}".format(SUBKEY, name) for name in COLORS]
		self.userprefs = Prefs()
		self.load()
		while not self.tags:
			self.edit("Please set at least one colortag.\n\n")


	def load(self):
		'''
		Tries to load IBPlib colortags from IJ prefs.
		'''
		for i in range(7):
			storedtags = self.userprefs.getString(".{0}".format(self.prefkeys[i]), "")
			if not storedtags:
				continue
			trimmedtagslist = [t.strip() for t in storedtags.split(",")]
			self.tags.update({i:trimmedtagslist})


	def edit(self, msg=""):
		'''
		Opens the color tags dialog to update color tags
		'''
		self.window = GenericDialog("ColorMerger - Edit color tags")
		self.window.addMessage("{0}Separate tags with a comma.\nBlank values will be ignored.".format(msg))
		for i in range(7):
			try:
				self.window.addStringField(COLORS[i], ", ".join(self.tags[i]), 30)
			except KeyError:
				self.window.addStringField(COLORS[i], "", 30)
		self.window.setOKLabel("Save")
		self.window.showDialog()
		if self.window.wasOKed():
			self.__savetags()
			self.load()


	def __validate(self):

		fields = self.window.getStringFields()
		newvalues = {}
		for i in range(len(fields)):
			txt = fields[i].getText()
			newvalues.update({i: txt.strip()})
		return newvalues


	def __savetags(self):

		newvalues = self.__validate()
		for i, tags in newvalues.items():
			key = self.prefkeys[i]
			self.userprefs.set(key, tags)
			self.userprefs.savePreferences()