Exemple #1
0
def create_bookmark_file(df, output_path=None, default_text=None):
    """
    Create a NeuTu bookmark file from a set of points.

    Args:
        df:
            DataFrame with columns ['x', 'y', 'z'], and optionally 'body' and 'text'

        output_path:
            If given, the bookmark file will be written to the given path.

        default_text:
            Optional. If provided, any rows without a 'text' entry will be given this text.

    Returns:
        dict, the contents of a bookmarks file.
        (Typically, you'll just ignore the output and use the output_path argument instead.)
    """
    df = df.copy()
    if df.index.name == 'body':
        df['body'] = df.index

    assert set(df.columns) >= {*'xyz'}, "Input must contain columns for x,y,z"

    df['location'] = df[[*'xyz']].apply(list, axis=1)
    if 'body' in df.columns:
        df['body ID'] = df['body']

    if default_text:
        if 'text' in df.columns:
            blank_rows = df.eval('text.isnull() or text == ""')
            df.loc[blank_rows, 'text'] = default_text
        else:
            df['text'] = default_text

    cols = {'location', 'body ID', 'text'} & {*df.columns}
    data = df[cols].to_dict('records')

    # Does any of this metadata actually matter?
    metadata = {
        "description": "bookmarks",
        "date": datetime.datetime.now().strftime("%d-%B-%Y %H:%M"),
        "username": getpass.getuser(),
        "computer": os.uname().nodename,
        "session path": os.getcwd(),
        "coordinate system": "dvid",
        "software": __name__,
        "software version": "0",
        "software revision": "0",
        "file version": 1,
    }

    contents = {"metadata": metadata, "data": data}

    if output_path:
        dump_json(contents, output_path, unsplit_int_lists=True)

    return contents
Exemple #2
0
def create_precomputed_segment_properties(names, bucket_name, bucket_path, localdir=None):
    """
    Write the "segment properties" for a neuroglancer precomputed volume,
    i.e. the segment names.
    """
    if not bucket_name.startswith('gs://'):
        bucket_name = 'gs://' + bucket_name

    if localdir is None:
        localdir = bucket_path.split('/')[-1]

    os.makedirs(f"{localdir}/segment_properties", exist_ok=True)

    props = {
        "@type": "neuroglancer_segment_properties",
        "inline": {
            "ids": [],
            "properties": [
                {
                    "id": "source",
                    "type": "label",
                    "values": []
                }
            ]
        }
    }

    for label, name in names.items():
        props["inline"]["ids"].append(str(label))
        props["inline"]["properties"][0]["values"].append(name)

    dump_json(props, f"{localdir}/segment_properties/info", unsplit_int_lists=True)

    subprocess.run(f"gsutil cp {bucket_name}/{bucket_path}/info {localdir}/info", shell=True)
    with open(f"{localdir}/info", 'r') as f:
        info = json.load(f)

    info["segment_properties"] = "segment_properties"
    dump_json(info, f"{localdir}/info", unsplit_int_lists=True)

    subprocess.run(f"gsutil cp {localdir}/info {bucket_name}/{bucket_path}/info", shell=True)
    subprocess.run(f"gsutil cp -R {localdir}/segment_properties {bucket_name}/{bucket_path}/segment_properties", shell=True)
Exemple #3
0
def create_precomputed_ngmeshes(vol, vol_fullres_box, names, bucket_name, bucket_path, localdir=None, decimation=0.01):
    """
    Create meshes for the given labelvolume and upload them to a google bucket in
    neuroglancer legacy mesh format (i.e. what flyem calls "ngmesh" format).
    """
    from vol2mesh import Mesh
    if not bucket_name.startswith('gs://'):
        bucket_name = 'gs://' + bucket_name

    if localdir is None:
        localdir = bucket_path.split('/')[-1]

    os.makedirs(f"{localdir}/mesh", exist_ok=True)
    dump_json({"@type": "neuroglancer_legacy_mesh"}, f"{localdir}/mesh/info")

    logger.info("Generating meshes")
    meshes = Mesh.from_label_volume(vol, vol_fullres_box, smoothing_rounds=2)

    logger.info("Simplifying meshes")
    for mesh in meshes.values():
        mesh.simplify(decimation)

    logger.info("Serializing meshes")
    for label, mesh in meshes.items():
        name = names.get(label, str(label))
        mesh.serialize(f"{localdir}/mesh/{name}.ngmesh")
        dump_json({"fragments": [f"{name}.ngmesh"]}, f"{localdir}/mesh/{label}:0")

    subprocess.run(f"gsutil cp {bucket_name}/{bucket_path}/info {localdir}/info", shell=True)
    with open(f"{localdir}/info", 'r') as f:
        info = json.load(f)

    info["mesh"] = "mesh"
    dump_json(info, f"{localdir}/info", unsplit_int_lists=True)

    logger.info("Uploading")
    subprocess.run(f"gsutil cp {localdir}/info {bucket_name}/{bucket_path}/info", shell=True)
    subprocess.run(f"gsutil cp -R {localdir}/mesh {bucket_name}/{bucket_path}/mesh", shell=True)
Exemple #4
0
def edges_to_assignment(df,
                        gray_source,
                        seg_source,
                        sv_as_body=False,
                        output_path=None,
                        shuffle=False,
                        description=""):
    if isinstance(df, str):
        df = pd.read_csv(df)

    assert isinstance(df, pd.DataFrame)

    dupes = df.duplicated(['sv_a', 'sv_b']).sum()
    if dupes:
        print(f"Dropping {dupes} duplicate tasks!")
        df = df.drop_duplicates(['sv_a', 'sv_b'])
        print(f"Writing {len(df)} tasks")

    if shuffle:
        print("Shuffling task order")
        df = df.sample(frac=1)

    tasks = []
    for row in df.itertuples():

        body_a, body_b = row.body_a, row.body_b
        box_a = [[row.body_box_x0_a, row.body_box_y0_a, row.body_box_z0_a],
                 [row.body_box_x1_a, row.body_box_y1_a, row.body_box_z1_a]]
        box_b = [[row.body_box_x0_b, row.body_box_y0_b, row.body_box_z0_b],
                 [row.body_box_x1_b, row.body_box_y1_b, row.body_box_z1_b]]
        box_a = np.asarray(box_a)
        box_b = np.asarray(box_b)

        sv_box_a = [[row.sv_box_x0_a, row.sv_box_y0_a, row.sv_box_z0_a],
                    [row.sv_box_x1_a, row.sv_box_y1_a, row.sv_box_z1_a]]
        sv_box_b = [[row.sv_box_x0_b, row.sv_box_y0_b, row.sv_box_z0_b],
                    [row.sv_box_x1_b, row.sv_box_y1_b, row.sv_box_z1_b]]

        sv_box_a = np.asarray(sv_box_a)
        sv_box_b = np.asarray(sv_box_b)

        if sv_as_body:
            # If presenting the task as if the supervoxels were the body,
            # then overwrite the body items with the supervoxel info instead.
            body_a, body_b = row.sv_a, row.sv_b
            box_a, box_b = sv_box_a, sv_box_b

        edge_info = {}
        for col in df.columns:
            if 'box' not in col:
                edge_info[col] = getattr(row, col)

        task = {
            "task type": "body merge",
            "supervoxel ID 1": row.sv_a,
            "supervoxel ID 2": row.sv_b,
            "supervoxel point 1": [row.xa, row.ya, row.za],
            "supervoxel point 2": [row.xb, row.yb, row.zb],
            "body point 1": [row.xa, row.ya, row.za],
            "body point 2": [row.xb, row.yb, row.zb],
            "default body ID 1": body_a,
            "default body ID 2": body_b,
            "edge_info": edge_info
        }

        # Only add the bounding box keys if the box is legit
        # (Apparently the export contains NaNs sometimes and I'm not sure why...)
        if not np.isnan(box_a).any():
            box_a = box_a.astype(int).tolist()
            task["default bounding box 1"] = {
                "minvoxel": box_a[0],
                "maxvoxel": box_a[1]
            }

        if not np.isnan(box_b).any():
            box_b = box_b.astype(int).tolist()
            task["default bounding box 2"] = {
                "minvoxel": box_b[0],
                "maxvoxel": box_b[1]
            }

        tasks.append(task)

    assignment = {
        "file type": "Neu3 task list",
        "file version": 1,
        "grayscale source": gray_source,
        "segmentation source": seg_source,
        "task list": tasks
    }

    if description:
        assignment["task set description"] = description

    assignment = convert_nans(assignment)
    if output_path:
        dump_json(assignment, output_path, unsplit_int_lists=True)

    return assignment