# @ ImagePlus imp

from ij import *
from ij import IJ, ImagePlus
from ij.gui import Roi, PointRoi, GenericDialog, Overlay
from ij.plugin import Duplicator
from ij.plugin.frame import RoiManager
from ij.io import FileSaver, Opener
from ij.process import ImageStatistics
from ConfigParser import SafeConfigParser

from java.awt import Color

from datetime import datetime
import subprocess
import shlex
import os
import glob
import csv
import math
import shutil
import time


def error_dialog(title, message):
    """ Creates a dialog box with a message and throws an exception

    Args:
        title::str
            The title at the top of the dialog box
        message::str
            The message within the dialog box and in the exception

    Returns:
        Dialog box with message
    """
    gui = GenericDialog(title)
    gui.addMessage(message)
    gui.hideCancelButton()
    gui.showDialog()
    raise Exception(message)

def adjust_count(input_count, slope, intercept):
	""" Adjusts cell counts based on linear equation

	Args:
		input_count::int
			The number of cells in a given ROI
		slope::float
			The slope of the linear equation to adjust with
		intercept::float
			The intercept of the linear equation to adjust with
			
	Returns:
		Float of number of cells in an ROI
	"""
	
	return (input_count-intercept)/float(slope)

def path_convert(path):
    """ Converts Windows paths to Unix paths

    Args:
        path::str
            The Windows path to convert

    Returns:
        Unix path
    """
    if IJ.isWindows():
        return path.replace("\\", "/")
    else:
        return path
    
def config_setup(event=None):
    """ Opens dialog box and sets up the configuration file for the plugin

    Args:
        None

    Returns:
        None
    """
    if IJ.isWindows() == True:
        plugin_wd = IJ.getDirectory("plugins").replace("\\", "/") + "InVitro_Cellpose/scripts/"
    else:
        plugin_wd = IJ.getDirectory("plugins") + "InVitro_Cellpose/scripts/"

    if not os.path.exists(plugin_wd + 'plugin_config.ini'):
        open(plugin_wd + 'plugin_config.ini', 'w').close()
    
    config = SafeConfigParser()
    config.read(plugin_wd + 'plugin_config.ini')
    
    if config.has_section('default_settings'):
        existing_model_path = config.get('default_settings', 'model_path')
        existing_python_path = config.get('default_settings','python_path')
        existing_logging_bool = config.getboolean('default_settings','logging')
    else:
        config.add_section('default_settings')
        # Get the first model path in the models folder
        model_list = glob.glob(plugin_wd + "models/*.txt")
        if len(model_list) > 0:
            existing_model_path = model_list[0]
            existing_model_path = path_convert(existing_model_path)
        else:
            existing_model_path = ""

        # existing_model_path = plugin_wd + "models/Pass3.txt"
        existing_python_path = ""
        existing_logging_bool = True
    
    config_dialog = GenericDialog("Configure Plugin Defaults")
    config_dialog.addFileField("Model Path", existing_model_path)
    config_dialog.addFileField("Python Path", existing_python_path)
    config_dialog.addCheckbox("Logging", existing_logging_bool)
    config_dialog.showDialog()
    if config_dialog.wasCanceled():
        return
    
    model_path_input = path_convert(config_dialog.getNextString())
    python_path_input = path_convert(config_dialog.getNextString())
    logging_bool_input = str(config_dialog.getNextBoolean())

    config.set('default_settings', 'model_path', model_path_input)
    config.set('default_settings', 'python_path', python_path_input)
    config.set('default_settings', 'logging', logging_bool_input)
    with open(plugin_wd + 'plugin_config.ini', 'w') as configfile:
        config.write(configfile)

    return
    

def run_script():
    # Tile Selection Portion
    # Creates a new ImagePlus
    session_stamp = datetime.now().strftime("%y%m%d%H%M%S")
    imp = IJ.getImage()
    imp_path = imp.getOriginalFileInfo().directory + imp.getOriginalFileInfo().fileName
    print(imp_path)
    stripped_imp = imp.duplicate().getProcessor()  # Creates a copy of the ImagePlus, stripped of any overlays
    stripped_imp = ImagePlus("duplicate", stripped_imp)
    width = imp.getDimensions()[0]
    height = imp.getDimensions()[1]
    
    imp_overlay = imp.getOverlay()
    try:
        number_tiles = imp_overlay.size()
    except:
        number_tiles = 0
        imp_overlay = Overlay()

    print("Overlay: ", imp_overlay)
    print("Tiles: ", number_tiles)

    if number_tiles != 0:
        iterate = imp_overlay.iterator()

    # Checks if points have been selected, displays warning and raises exception if not
    if number_tiles == 0:
        print("Got here")
        warn_dialog = GenericDialog("No Insets Selected")
        warn_dialog.addMessage("No insets have been selected. \nCancel and select insets or continue to automatically identify an ROI.")
        warn_dialog.setOKLabel("Continue")
        warn_dialog.showDialog()
        if warn_dialog.wasCanceled():
            return
        if warn_dialog.wasOKed():
            pass

    # Checks if too many tiles are selected
    if number_tiles >= 6:
        warn_dialog = GenericDialog("Warning")
        warn_dialog.addMessage("There are currently {} tiles selected. \nConfirm the active window is correct. \nAre you sure you want to proceed?".format(number_tiles))
        warn_dialog.setOKLabel("Continue")
        warn_dialog.showDialog()
        if warn_dialog.wasCanceled():
            return
        if warn_dialog.wasOKed():
            pass

    # Plugin path setup
    if IJ.isWindows() == True:
        plugin_wd = IJ.getDirectory("plugins").replace("\\", "/") + "InVitro_Cellpose/scripts/"
    else:
        plugin_wd = IJ.getDirectory("plugins") + "InVitro_Cellpose/scripts/"
    temp_folder = plugin_wd + "temp/"
    log_folder = plugin_wd + "logs/"

    if not os.path.exists(temp_folder):
        os.makedirs(temp_folder)
    if not os.path.exists(log_folder):
        os.makedirs(log_folder)
    
    # Config setup
    if not os.path.exists(plugin_wd + 'plugin_config.ini'):
        config_setup()

    # Parameter Dialog - differs if no tiles selected
    parameter_dialog = GenericDialog("Set Parameters")
    parameter_dialog.addNumericField("Box Size (px)", 272)
    if number_tiles == 0:
        parameter_dialog.addNumericField("Margin Size (px)", 64)
    else:
        parameter_dialog.addNumericField("Expand Edges (px)", 20)
    parameter_dialog.addSlider("Flow Threshold", 0.0, 3.0, 3.0, 0.1)
    parameter_dialog.addSlider("Cell Probability Threshold", -6.0, 6.0, -6.0, 0.1)
    parameter_dialog.addSlider("Left/Top Edge Threshold", 0.0, 1.0, 0.25, 0.05) 
    parameter_dialog.addSlider("Right/Bottom Edge Threshold", 0.0, 1.0, 1.0, 0.05)
    if number_tiles == 0:
        parameter_dialog.addSlider("Percentile Value", 0.0, 100.0, 65.0, 1.0)
    parameter_dialog.addChoice("Plot Option", ["Cell Outlines", "Cell Centroids", "Both Outlines and Centroids"], "Both Outlines and Centroids")
    parameter_dialog.addCheckbox("Plot Insets in Grayscale", False)
    parameter_dialog.addCheckbox("Show Unmarked Image", True)
    if number_tiles == 0:
        parameter_dialog.addCheckbox("Compare Quartiles", False)
    parameter_dialog.addCheckbox("GPU", True)
    parameter_dialog.addButton("Configure Defaults", config_setup)

    parameter_dialog.showDialog() 
    if parameter_dialog.wasCanceled():
        return
    
    config = SafeConfigParser()
    config.read(plugin_wd + 'plugin_config.ini')
    model_path = config.get('default_settings', 'model_path')
    python_path = config.get('default_settings','python_path')
    logging_bool = config.getboolean('default_settings','logging')

    if model_path == "" or python_path == "":
        config_setup()
    
    box_size = parameter_dialog.getNextNumber()
    if number_tiles == 0:
        margin_size = parameter_dialog.getNextNumber()
    else:
        expand = parameter_dialog.getNextNumber()
    flow_threshold = parameter_dialog.getSliders().get(0).getValue() / 10.0
    cellprob_threshold = parameter_dialog.getSliders().get(1).getValue() / 10.0
    lt_edge_threshold = parameter_dialog.getSliders().get(2).getValue() / 20.0
    rb_edge_threshold = parameter_dialog.getSliders().get(3).getValue() / 20.0
    if number_tiles == 0:
        percentile_value = int(parameter_dialog.getSliders().get(4).getValue())
    plot_option = parameter_dialog.getNextChoice()
    grayscale_bool = parameter_dialog.getNextBoolean()
    show_unmarked = parameter_dialog.getNextBoolean()
    if number_tiles == 0:
        compare_quartiles = parameter_dialog.getNextBoolean()
    gpu_bool = parameter_dialog.getNextBoolean()

    print("Grayscale: ", grayscale_bool)

    print(flow_threshold, cellprob_threshold, lt_edge_threshold, rb_edge_threshold)
    
    safe_zone = box_size/2
    
    print("Tile number: ", number_tiles)
    
    i = 1  # Counter
    all_counts = []

    start_time = time.time()

    if number_tiles == 0:
        print(imp)
        cropped_imp = Duplicator().run(stripped_imp)  # Named cropped_imp for consistency -- not cropped this is the temp file passed to the subprocess
        print(cropped_imp)
        output_file = FileSaver(cropped_imp)
        whole_temp_path = temp_folder + session_stamp + "_whole_temp.jpg"
        print(whole_temp_path)
        output_file.saveAsJpeg(whole_temp_path)

        # shell_in = python_path + " " + plugin_wd + "run_invitro_cellpose_heatmap.py " + " --input_image " + whole_temp_path + " --model_path " + str(model_path) + " --box_size " + str(int(box_size)) + " --margin_size " +str(int(margin_size)) + " --flow_threshold " + str(flow_threshold) + " --cellprob_threshold " + str(cellprob_threshold) + " --lt_edge_threshold " + str(lt_edge_threshold) + " --rb_edge_threshold " + str(rb_edge_threshold) + " --percentile " + str(percentile_value) 
        # args = shlex.split(shell_in)

        command = [
            python_path, plugin_wd + "run_invitro_cellpose_heatmap.py",
            "--input_image", whole_temp_path,
            "--model_path", model_path,
            "--box_size", str(int(box_size)),
            "--margin_size", str(int(margin_size)),
            "--flow_threshold", str(flow_threshold),
            "--cellprob_threshold", str(cellprob_threshold),
            "--lt_edge_threshold", str(lt_edge_threshold),
            "--rb_edge_threshold", str(rb_edge_threshold),
            "--percentile", str(percentile_value),
            "--gpu" if gpu_bool else ""
        ]

        command = [arg for arg in command if arg]  # Remove empty strings from the command list
        print(command)

        IJ.showStatus("Identifying cells in whole image. This may take a while...")

        # Calls cell detection algorithm and saves output as string
        try:
            process = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=False,
                                                cwd=plugin_wd)
        except subprocess.CalledProcessError as e:
            raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
                

        inference_time = time.time() - start_time
        print("Inference time: ", inference_time)
        
        # Read CSV file and get the coordinates
        counter = 0
        color_list = [Color.BLUE, Color.RED, Color.YELLOW, Color.MAGENTA, 
                      Color.CYAN, Color.GREEN, Color.ORANGE, Color.BLACK, 
                      Color.WHITE, Color.PINK, Color.GRAY, Color.LIGHT_GRAY]
        
        IJ.showStatus("Plotting results")

        coordinate_path = whole_temp_path.replace(".jpg", "_percentile_coordinates.csv")
        with open(coordinate_path, 'r') as csvfile:
            reader = csv.reader(csvfile)
            next(reader)  # Skip header
            # Skip 3 rows (25, 50, 75 percentiles are not plotted)
            for _ in range(3):
                next(reader)
            for row in reader:
                print(row)
                percentile, x, y = int(row[0]), int(row[1]), int(row[2])
                square_roi = Roi(x, y, box_size, box_size)
                square_roi.setName("%s_percentile_mask" % percentile)
                square_roi.setStrokeColor(color_list[counter])

                # Add the square ROI to the overlay
                imp.setRoi(square_roi)
                imp_overlay.add(square_roi)
                imp.setOverlay(imp_overlay)
                imp.show()

                roi_filename = whole_temp_path.replace(".jpg", "_%s_percentile_mask_rois.zip" % percentile)
                centroids_filename = whole_temp_path.replace(".jpg", "_%s_percentile_rois.csv" % percentile)

                if grayscale_bool == False:
                    inset_imp = Duplicator().run(stripped_imp)
                    inset_imp.setRoi(square_roi)  # Setting cropping boundaries to bounds ROI
                    inset_imp = inset_imp.crop()
                    inset_imp.setTitle("%s_percentile_inset" % percentile)
                else:
                    inset_imp = IJ.openImage(whole_temp_path.replace(".jpg", "_%s_cropped.tif" % percentile))
                    inset_imp.setTitle("%s_percentile_inset" % percentile)

                inset_imp_centroids = inset_imp.duplicate()
                inset_imp_centroids.setTitle("centroids_%s_percentile_inset" % percentile)
                inset_imp_outlines = inset_imp.duplicate()
                inset_imp_outlines.setTitle("outlines_%s_percentile_inset" % percentile)
                
                all_outlines = RoiManager(False)  # Creates RoiManager to store outlines and hides it
                all_outlines.open(roi_filename)

                all_points = RoiManager(False)  # Creates RoiManager to store points and hides it
                for roi in all_outlines.getRoisAsArray():
                    roi.setStrokeColor(color_list[counter])
                    centroid = roi.getContourCentroid()
                    p = PointRoi(centroid[0], centroid[1])
                    p.setPointType(0)
                    p.setStrokeColor(color_list[counter])
                    all_points.add(p, -1)
                all_points.moveRoisToOverlay(inset_imp_centroids)
                all_outlines.moveRoisToOverlay(inset_imp_outlines)

                # If Plot Centroids is selected
                if plot_option == "Cell Centroids" or plot_option == "Both Outlines and Centroids":
                    inset_imp_centroids.show()
                    inset_imp_centroids.getCanvas().zoom100Percent()
                    inset_imp_centroids.getCanvas().setScaleToFit(True)
                    all_points.runCommand("Show All")
                    time.sleep(0.5)

                # If Plot Outlines is selected
                if plot_option == "Cell Outlines" or plot_option == "Both Outlines and Centroids":
                    inset_imp_outlines.show()
                    inset_imp_outlines.getCanvas().zoom100Percent()
                    inset_imp_outlines.getCanvas().setScaleToFit(True)
                    all_outlines.runCommand("Show All")

                # Show unmarked image if selected
                if show_unmarked == True:
                    unmarked_imp = inset_imp.duplicate()
                    unmarked_imp.setTitle("unmarked_%s_percentile_inset" % percentile)
                    unmarked_imp.show()
                    unmarked_imp.getCanvas().zoom100Percent()
                    unmarked_imp.getCanvas().setScaleToFit(True)

                cell_count = all_points.getCount()
                all_counts.append(cell_count)
                IJ.log("Region {} cell count: {}".format(i, cell_count))

                counter += 1
                if counter == len(color_list):
                    counter = 0

                # Logging
                dt_string = datetime.utcnow().strftime("%y%m%d%H%M%S")
                if logging_bool:
                    cropped_imp.setProp("SessionID", session_stamp)
                    cropped_imp.setProp("Inset_WholeImg", imp_path)
                    cropped_imp.setProp("Inset_XY_TopLeft_ofcroppedregion", "%s, %s" % (x, y))  # These x,y coordinates are for the inset cropped region, so expand by margin to get location in whole image
                    cropped_imp.setProp("Inset_Size", box_size + 2*margin_size)
                    cropped_imp.setProp("Auto_Timestamp", dt_string)
                    cropped_imp.setProp("Auto_Count", str(cell_count))
                    log_img = FileSaver(cropped_imp)
                    log_img.saveAsTiff("%s%s_auto_tocellpose_region_%s.tiff" % (log_folder, session_stamp, str(i)))
                    
                    inset_imp_outlines.setProp("SessionID", session_stamp)
                    inset_imp_outlines.setProp("Inset_WholeImg", imp_path)
                    inset_imp_outlines.setProp("Inset_XY_TopLeft", "%s, %s" % (x, y))
                    inset_imp_outlines.setProp("Inset_Size", box_size + 2*margin_size)
                    inset_imp_outlines.setProp("Auto_Timestamp", dt_string)
                    inset_imp_outlines.setProp("Auto_Count", str(cell_count))
                    log_orig = FileSaver(inset_imp_outlines)
                    log_orig.saveAsTiff("%s%s_auto_display_region_%s.tiff" % (log_folder, session_stamp, str(i)))

                    shutil.copy(roi_filename, "%s%s_auto_region_%s_rois.zip" % (log_folder, session_stamp, str(i)))
                    shutil.copy(centroids_filename, "%s%s_auto_region_%s_rois.csv" % (log_folder, session_stamp, str(i)))

                time.sleep(1)

        plot_time = time.time() - start_time
        print("Plotting time: ", plot_time)

        # Open the percentile comparison plot
        if compare_quartiles == True:
            percentile_plot = Opener().openImage(whole_temp_path.replace(".jpg", "_percentile_plot.png"))
            percentile_plot.setTitle("Percentile Comparison Plot")
            percentile_plot.show()
            percentile_plot.getCanvas().zoom100Percent()
            percentile_plot.getCanvas().setScaleToFit(True)


    # TODO: Run multiple ROIs on Cellpose subprocess simultaneously rather than sequentially? - Will this be much faster? 
    if number_tiles != 0:
        while iterate.hasNext():
            IJ.showStatus("Processing region " + str(i) + "/" + str(number_tiles))
        
            p = iterate.next()
        
            # # Check edges are within safe zone
            # Get the centroid coordinates
            x_centroid, y_centroid = p.getContourCentroid()
            
            # Initialize flags for adjustments
            x_adjusted = False
            y_adjusted = False
    
            # For x-coordinate
            if safe_zone < x_centroid < (width - safe_zone):
                x_min = x_centroid - safe_zone
                # Ensure x_min is at least 'expand'
                if x_min < expand:
                    x_min = expand
                    x_adjusted = True
                # Ensure the box doesn't exceed the right edge minus 'expand'
                if x_min + box_size > width - expand:
                    x_min = width - expand - box_size
                    x_adjusted = True
            else:
                if x_centroid < safe_zone:
                    x_min = expand  # Set x_min to 'expand' instead of 0
                    x_adjusted = True
                else:
                    x_min = width - box_size - expand
                    x_adjusted = True
    
            # For y-coordinate
            if safe_zone < y_centroid < (height - safe_zone):
                y_min = y_centroid - safe_zone
                # Ensure y_min is at least 'expand'
                if y_min < expand:
                    y_min = expand
                    y_adjusted = True
                # Ensure the box doesn't exceed the bottom edge minus 'expand'
                if y_min + box_size > height - expand:
                    y_min = height - expand - box_size
                    y_adjusted = True
            else:
                if y_centroid < safe_zone:
                    y_min = expand  # Set y_min to 'expand' instead of 0
                    y_adjusted = True
                else:
                    y_min = height - box_size - expand
                    y_adjusted = True
        
            # Log a message if any adjustments to bounds were made
            if x_adjusted or y_adjusted:
                IJ.log("Selection area was adjusted to stay within edge safe zones defined by 'expand'.")
        
            # For output to Cellpose (dimensions may be different from display img - if expanded)
            cellpose_bounds = Roi(x_min - expand, y_min - expand, box_size + 2*expand, box_size + 2*expand)  # Creating ROI with correct bounds
            cropped_imp = Duplicator().run(stripped_imp)
            cropped_imp.setRoi(cellpose_bounds)  # Setting cropping boundaries to bounds ROI
            cropped_imp = cropped_imp.crop()
            cropped_imp.setTitle("region_%s" % i)
        
            # Crop for display
            original_bounds = Roi(x_min, y_min, box_size, box_size)
            display_imp = Duplicator().run(stripped_imp)
            display_imp.setRoi(original_bounds)  # Setting cropping boundaries to bounds ROI
            display_imp = display_imp.crop()
            display_imp.setTitle("region_%s_inset" % (i))
            unmarked_imp = display_imp.duplicate()
    
            # Saves images as temporary files to be passed into algorithm subprocess
            output_file = FileSaver(cropped_imp)
            output_file.saveAsJpeg(temp_folder + cropped_imp.getTitle() + ".jpg")
            output_filename = (temp_folder + cropped_imp.getTitle() + ".jpg")
            roi_filename = (temp_folder + cropped_imp.getTitle() + "_rois.zip")  # Filename without extension (_rois.zip)
            centroids_filename = (temp_folder + cropped_imp.getTitle() + "_rois.csv")  # Filename without extension (_rois.csv)
            output_filename = '"{}"'.format(output_filename) 
            clahe_filename = (temp_folder + cropped_imp.getTitle() + "_clahe.tif")
    
            print(roi_filename)
           
            print(output_filename)
    
            IJ.showStatus("Identifying cells in region " + str(i) + "/" + str(number_tiles))
    
            shell_in = python_path + " " + plugin_wd + "run_invitro_cellpose.py "  + " --input_image " + output_filename + " --model_path " + str(model_path) + " --flow_threshold " + str(flow_threshold) + " --cellprob_threshold " + str(cellprob_threshold) + " --lt_edge_threshold " + str(lt_edge_threshold) + " --rb_edge_threshold " + str(rb_edge_threshold) + " --expand_size " + str(expand)
            args = shlex.split(shell_in)
            print(args)
    
            # Calls cell detection algorithm and saves output as string
            try:
                process = subprocess.check_output(args, stderr=subprocess.STDOUT, shell=False,
                                                 cwd=plugin_wd)
            except subprocess.CalledProcessError as e:
                raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
           
            print("Plotting region " + str(i))
            print(roi_filename)
    
            IJ.showStatus("Plotting cell locations in region " + str(i) + "/" + str(number_tiles))
    
           # Plotting grayscale inset
            if grayscale_bool == True:
                display_imp = IJ.openImage(clahe_filename)
                crop_bounds = Roi(expand, expand, box_size, box_size)
                display_imp.setRoi(crop_bounds)
                display_imp = display_imp.crop()
                display_imp.setTitle("gray_region_%s_inset" % (i))
    
           # Plotting Outlines and Centroids - requires duplicate imp
            if plot_option == "Both Outlines and Centroids":
                duplicate_outline_imp = Duplicator().run(display_imp)
                duplicate_outline_imp.setTitle("duplicate_region_%s_inset" % (i))
    
            all_points = RoiManager(False)  # Creates RoiManager to store points and hides it
    
            # Plotting Centroids
            if plot_option == "Cell Centroids" or plot_option == "Both Outlines and Centroids":
                with open(centroids_filename, "r") as csvfile:
                    csvreader = csv.reader(csvfile, delimiter=',')
                    next(csvreader) # Skip header
                    for row in csvreader:
                        x = float(row[0])
                        y = float(row[1])
                        p = PointRoi(x, y)
                        p.setPointType(0)
                        all_points.add(p, -1)
    
            # Plotting Outlines
            if plot_option == "Cell Outlines":
                all_points.runCommand("Open", roi_filename)
        
            all_points.moveRoisToOverlay(display_imp)
            display_imp.show()
            display_imp.getCanvas().zoom100Percent()
            display_imp.getCanvas().setScaleToFit(True)
            all_points.runCommand("Show All")
    
            # Plotting outlines for "Both" option
            if plot_option == "Both Outlines and Centroids":
                duplicate_roi_manager = RoiManager(False)
                duplicate_roi_manager.runCommand("Open", roi_filename)
                duplicate_roi_manager.moveRoisToOverlay(duplicate_outline_imp)
                duplicate_outline_imp.show()
                duplicate_outline_imp.getCanvas().zoom100Percent()
                duplicate_outline_imp.getCanvas().setScaleToFit(True)
                duplicate_roi_manager.runCommand("Show All")
    
            # Plot unmarked image if selected
            if show_unmarked == True:
                unmarked_imp.setTitle("region_%s_unmarked" % i)
                unmarked_imp.show()
                unmarked_imp.getCanvas().zoom100Percent()
                unmarked_imp.getCanvas().setScaleToFit(True)
    
    
            cell_count = all_points.getCount()
            all_counts.append(cell_count)
            IJ.log("Region {} cell count: {}".format(i, cell_count))
    
           # Logging
            dt_string = datetime.utcnow().strftime("%y%m%d%H%M%S")
            if logging_bool:
                cropped_imp.setProp("SessionID", session_stamp)
                cropped_imp.setProp("Inset_WholeImg", imp_path)
                cropped_imp.setProp("Inset_XY_TopLeft", "%s, %s" % (x_min, y_min))
                cropped_imp.setProp("Inset_Size", box_size + 2*expand)
                cropped_imp.setProp("Auto_Timestamp", dt_string)
                cropped_imp.setProp("Auto_Count", str(cell_count))
                log_img = FileSaver(cropped_imp)
                log_img.saveAsTiff("%s%s_auto_tocellpose_region_%s.tiff" % (log_folder, session_stamp, str(i)))
                
                display_imp.setProp("SessionID", session_stamp)
                display_imp.setProp("Inset_WholeImg", imp_path)
                display_imp.setProp("Inset_XY_TopLeft", "%s, %s" % (x_min, y_min))
                display_imp.setProp("Inset_Size", box_size + 2*expand)
                display_imp.setProp("Auto_Timestamp", dt_string)
                display_imp.setProp("Auto_Count", str(cell_count))
                log_orig = FileSaver(display_imp)
                log_orig.saveAsTiff("%s%s_auto_display_region_%s.tiff" % (log_folder, session_stamp, str(i)))
        
                shutil.copy(roi_filename, "%s%s_auto_region_%s_rois.zip" % (log_folder, session_stamp, str(i)))
                shutil.copy(centroids_filename, "%s%s_auto_region_%s_rois.csv" % (log_folder, session_stamp, str(i)))
        
                i += 1  # Increment counter


    if logging_bool:
        shutil.copy(imp_path, "%s%s_auto_wholeimg.tiff" % (log_folder, session_stamp))

    # Calculate average and standard deviation
    if len(all_counts) > 1:
        avg_count = sum(all_counts)/float(len(all_counts))
        sum_differences_sq = 0
        for value in all_counts:
            sum_differences_sq += (value - avg_count)**2
            stdev_val = math.sqrt(sum_differences_sq/(len(all_counts)-1.0))
        IJ.log("Average cell count: %.2f" % avg_count)
        IJ.log("Standard deviation (s): %.2f" % stdev_val)
        IJ.log("Session ID: %s \n" % session_stamp)
    else:
        IJ.log("Session ID: %s \n" % session_stamp)

    IJ.showStatus("Cleaning up temporary files")
    # Deleting tile images saved in temp folder
    IJ.showStatus("Cleaning up temporary files")
    temp_files = glob.glob(temp_folder + '*')
#    for f in temp_files:
#        os.remove(f)
    
    # Switch selection back to whole image
    imp.show()
    IJ.selectWindow(imp.getTitle())

    if plot_option == "Cell Centroids" or plot_option == "Both Outlines and Centroids":
        IJ.setTool("point tool")


if __name__ in ['__builtin__', '__main__']:
    run_script()
