# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # BIAFlows
#
# ## Nuclei Tracking 2D+t
#
# ### Fiji-workflow
#
# The workflow treats the time-dimension as z-dimension and does a 3D-segmentation of the objects. The resulting object slices are then reduced to a center point.

# +
from getpass import getpass 

publicKey = getpass("Please enter the public key: ")
privateKey = getpass("Please enter the private key: ")

argv = ['--cytomine_public_key', publicKey, 
 '--cytomine_host',  'biaflows.neubias.org',
 '--cytomine_private_key',  privateKey,
 '--cytomine_id_project',  '1695226', 
 '--cytomine_id_software', '11244427',
 '--ij_gauss_radius',  '3',
 '--ij_threshold',  '60',
 '--ij_open_radius', '7']
# -

# Import CytomineJob and Job and update the status information. Set the problem class to particle-tracking (PrtTrk).

# +
import sys
from subprocess import call

from cytomine.models import Job
from neubiaswg5.helpers import NeubiasJob, prepare_data, upload_data, upload_metrics
from neubiaswg5 import CLASS_PRTTRK

jobID=-666
with NeubiasJob.from_cli(argv) as nj:
    nj.job.update(status=Job.RUNNING, progress=0, statusComment="Initialisation...")
    jobID = nj.job.id
    
problem_cls = CLASS_PRTTRK
# -

# #### Create local directories and download images
#
# Create the local working directories in a subfolder jobID of the user's home folder.
#
# - in: input images
# - out: output images
# - ground_truth: ground truth images
# - tmp: temporary path

in_images, gt_images, in_path, gt_path, out_path, tmp_path = prepare_data(problem_cls, nj, is_2d=False, **nj.flags)

# Check the downloaded input and ground-truth images. In this case there is only one time-series as input image and one time-series as ground-truth image.

print(in_path)
# !ls -alh $in_path
print(gt_path)
# !ls -alh $gt_path

# #### Call the image analysis workflow 

# +
nj.job.update(progress=25, statusComment="Launching workflow...")
command = "/usr/bin/xvfb-run ./ImageJ-linux64 -macro macro.ijm \"input={}, output={}, gauss_rad={}, threshold={}, open_rad={}\" -batch".format(in_path, out_path, nj.parameters.ij_gauss_radius, nj.parameters.ij_threshold, nj.parameters.ij_open_radius)

return_code = call(command, shell=True, cwd="./fiji")  # waits for the subprocess to return

if return_code != 0:
    err_desc = "Failed to execute the ImageJ macro (return code: {})".format(return_code)
    nj.job.update(progress=50, statusComment=err_desc)
    raise ValueError(err_desc)
nj.job.update(progress=30, statusComment="Workflow finished...")
# -

# #### Visualize the result of the workflow

# +
macro = '\
open("'+in_path + '/' + str(in_images[0].object.id)+'.tif"); \n\
cellsStackID = getImageID(); \n\
run("Duplicate...", " "); \n\
cellsTitle = getTitle(); \n\
selectImage(cellsStackID); \n\
close(); \n\
open("'+out_path + '/' + str(in_images[0].object.id)+'.tif"); \n\
tracesStackID = getImageID(); \n\
run("Z Project...", "projection=[Max Intensity]"); \n\
run("3-3-2 RGB"); \n\
run("Maximum...", "radius=4"); \n\
run("8-bit"); \n\
tracesTitle = getTitle(); \n\
run("Merge Channels...", "c2="+tracesTitle+" c4="+cellsTitle+" create"); \n\
selectImage(tracesStackID); \n\
close(); \n\
overlayID = getImageID(); \n\
run("Capture Image"); \n\
selectImage(overlayID); \n\
close(); \n\
resultTitle=getTitle(); \n\
saveAs("jpeg", "'+tmp_path+'/'+str(in_images[0].object.id)+'"); \n\
close(); \n\
run("Quit"); \n\
'

file = open(tmp_path + "/visualize_tracks.ijm", "w") 
 
file.write(macro) 
file.close() 

print(macro)

# +
command = "/usr/bin/xvfb-run ./ImageJ-linux64 -macro "+tmp_path + "/visualize_tracks.ijm -batch"

return_code = call(command, shell=True, cwd="./fiji")  # waits for the subprocess to return

if return_code > 1:
    err_desc = "Failed to execute the ImageJ macro (return code: {})".format(return_code)
    nj.job.update(progress=50, statusComment=err_desc)
    raise ValueError(err_desc)
# -

from IPython.display import Image
Image(filename = tmp_path+'/'+str(in_images[0].object.id)+'.jpg')

# #### Calculate metrics

# +
from neubiaswg5.metrics import computemetrics_batch
from cytomine.models import Property
import os
os.chdir("/home/jovyan/neubiaswg5-utilities/neubiaswg5/metrics")
import re
import shutil
import sys
import subprocess 
from sklearn.metrics import f1_score
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import confusion_matrix
import numpy as np
from scipy import ndimage
import tifffile as tiff
from scipy.spatial import cKDTree
from neubiaswg5 import *
from neubiaswg5 import CLASS_LNDDET
from img_to_xml import *
from img_to_seq import *
from skl2obj import *
from netmets_obj import netmets_obj
from node_sorter import swc_node_sorter
from node_sorter import findchildren

os.chdir("/home/jovyan/")

def computemetrics(infile, reffile, problemclass, tmpfolder, verbose=True, **extra_params):
    outputs = _computemetrics(infile, reffile, problemclass, tmpfolder, **extra_params)
    return outputs


def get_image_metadata(tiff):
    import xml.etree.ElementTree as ET
    return list(list(ET.fromstring(tiff.ome_metadata))[0])[0].attrib


def get_dimensions(tiff, time=False):
    array = tiff.asarray()
    T, Z = 1, 1
    if array.ndim > 2:
        metadata = get_image_metadata(tiff)
        Y, X = int(metadata['SizeY']), int(metadata['SizeX'])
        if array.ndim > 3 or time:
            T = int(metadata['SizeT'])
        if array.ndim > 3 or not time:
            Z = int(metadata['SizeZ'])
    else:
        Y, X = array.shape
    return T, Z, Y, X


def _computemetrics(infile, reffile, problemclass, tmpfolder, **extra_params):
    # Remove all xml and txt (temporary) files in tmpfolder
    filelist = [ f for f in os.listdir(tmpfolder) if (f.endswith(".xml") or f.endswith(".txt")) ]
    for f in filelist:
        os.remove(os.path.join(tmpfolder, f))

    # Remove all (temporary) subdirectories in tmpfolder
    for subdir in next(os.walk(tmpfolder))[1]:
        shutil.rmtree(os.path.join(tmpfolder, subdir), ignore_errors=True)

    metrics_dict = {}
    params_dict = {}
    

    # Read metadata from reference image (OME-TIFF)
    img = tiff.TiffFile(reffile)
    T, Z, Y, X = get_dimensions(img, time=False)

    # Convert non null pixels coordinates to track files
    ref_xml_fname = os.path.join(tmpfolder, "reftracks.xml")
    tracks_to_xml(ref_xml_fname, img_to_tracks(reffile,X,Y,Z,T), True)
    in_xml_fname = os.path.join(tmpfolder, "intracks.xml")
    tracks_to_xml(in_xml_fname, img_to_tracks(infile,X,Y,Z,T), True)
    res_fname = in_xml_fname + ".score.txt"

    # Call tracking metric code
    gating_dist = extra_params.get("gating_dist", 5)
    # the fourth parameter represents the gating distance
    os.system('java -jar /home/jovyan/neubiaswg5-utilities/bin/TrackingPerformance.jar -r ' + ref_xml_fname + ' -c ' + in_xml_fname + ' -o ' + res_fname + ' ' + str(gating_dist))

    # Parse the output file created automatically in tmpfolder
    with open(res_fname, "r") as f:
        bchmetrics = [line.split(':')[0].strip() for line in f.readlines()]

    metric_names = [
        "PD", "NPSA", "FNPSB", "NRT", "NCT",
        "JST", "NPT", "NMT", "NST", "NRD",
        "NCD", "JSD", "NPD", "NMD", "NSD"
    ]
    metrics_dict.update({name: value for name, value in zip(metric_names, bchmetrics)})
    params_dict["GATING_DIST"] = gating_dist

    return metrics_dict, params_dict

nj.job.update(progress=80, statusComment="Computing and uploading metrics...")
outfiles, reffiles = zip(*[
    (os.path.join(out_path, "{}.tif".format(image.object.id)),
     os.path.join(gt_path, "{}.tif".format(image.object.id)))
    for image in in_images
])

for infile, reffile in zip(outfiles, reffiles):
    metrics = computemetrics(infile, reffile, problem_cls, tmp_path, {})
# -

path = tmp_path+'/'+"intracks.xml.score.txt"
print(path)
with open(path) as file:
    for line in file:
        print(line)

print("test")



StarcoderdataJupyterScriptsDedupFiltered