Example #1
0
def load_raw_slide_to_cache(slide_id, resource):
    # Get the data for this slide
    sr = get_slide_ref(slide_id)
    if sr is not None:
        sr.get_local_copy(resource)
    else:
        print('Slide %s not found' % (slide_id, ))
Example #2
0
def api_get_slide_random_patch(task_id, slide_id, width):
    db = get_db()

    # Find out which machine the slide is currently being served from
    # Get the tiff image from which to sample the region of interest
    sr = get_slide_ref(slide_id)

    # Get the identifiers for the slide
    # TODO: what to do with project here?
    (project, specimen, block, slide_name, slide_ext) = sr.get_id_tuple()

    # Are we de this slide to a different node?
    del_url = find_delegate_for_slide(slide_id)

    # If local, call the method directly
    rawbytes = None
    if del_url is None:
        rawbytes = get_random_patch(project, specimen, block, 'raw',
                                    slide_name, slide_ext, 0, width,
                                    'png').data
    else:
        url = '%s/dzi/random_patch/%s/%s/%s/raw/%s.%s/%d/%d.png' % (
            del_url, project, specimen, block, slide_name, slide_ext, 0, width)
        pr = sr.get_project_ref()
        post_data = urllib.urlencode(
            {'project_data': json.dumps(pr.get_dict())})
        rawbytes = urllib2.urlopen(url, post_data).read()

    # Send the patch
    resp = make_response(rawbytes)
    resp.mimetype = 'image/png'
    return resp
Example #3
0
def export_annot_vtk(task, slide_id, out_file):
    """ Export annotations on a slide to VTK file """

    # Find the annotation in the database
    db = get_db()
    rc = db.execute('SELECT json FROM annot WHERE slide_id=? AND task_id=?',
                    (slide_id, task)).fetchone()

    if rc is not None:
        # Get the annotation
        data = json.loads(rc['json'])

        # Get the raw slide dimensions
        sr = get_slide_ref(slide_id)
        dims = get_slide_raw_dims(sr)
        if dims is None:
            sys.exit("Missing slide dimensions information")

        # Get the set of points
        pts = annot_sample_path_curves(data, 5000)

        # Join all the point arrays
        all_pts = [item for sublist in pts for item in sublist]

        # Length of each polyline segment
        plen = [len(sublist) for sublist in pts]

        # Write a VTK file based on points
        out_file.write("# vtk DataFile Version 4.2\n")
        out_file.write("vtk output\n")
        out_file.write("ASCII\n")
        out_file.write("DATASET POLYDATA\n")
        out_file.write("POINTS %d float\n" % len(all_pts))

        # Write all the points
        for p in all_pts:
            out_file.write('%f %f %f\n' % (p[0], p[1], 0.0))

        out_file.write("LINES %d %d\n" % (len(pts), len(pts) + sum(plen)))

        idx = 0
        for q in pts:
            out_file.write(
                '%d %s\n' %
                (len(q), ' '.join([str(x) for x in range(idx, idx + len(q))])))
            idx = idx + len(q)
Example #4
0
def api_slide_job_status(task_id, slide_id, jobid):
    db = get_db()
    sr = get_slide_ref(slide_id)
    (project, specimen, block, slide_name, slide_ext) = sr.get_id_tuple()

    # Are we de this slide to a different node?
    del_url = find_delegate_for_slide(slide_id)

    # If local, call the method directly
    if del_url is None:
        return dzi_job_status(project, slide_name, jobid)
    else:
        url = '%s/dzi/job/%s/%s/%s/status' % (
                del_url, project, slide_name, jobid)
        pr = sr.get_project_ref()
        post_data = urllib.urlencode({'project_data': json.dumps(pr.get_dict())})
        return urllib2.urlopen(url, post_data).read()
Example #5
0
def generate_sample_patch(slide_id, sample_id, rect, dims=(512, 512), level=0):

    # Find out which machine the slide is currently being served from
    # Get the tiff image from which to sample the region of interest
    db = get_db()
    sr = get_slide_ref(slide_id)

    # Get the identifiers for the slide
    # TODO: what to do with project here?
    (project, specimen, block, slide_name, slide_ext) = sr.get_id_tuple()

    # Are we de this slide to a different node?
    del_url = find_delegate_for_slide(slide_id)

    # Compute the parameters
    ctr_x = int((rect[0] + rect[2]) / 2.0 + 0.5)
    ctr_y = int((rect[1] + rect[3]) / 2.0 + 0.5)
    (w, h) = dims
    x = ctr_x - ((w - int(w / 2.0)) - 1)
    y = ctr_y - ((h - int(h / 2.0)) - 1)

    # If local, call the method directly
    rawbytes = None
    if del_url is None:
        rawbytes = get_patch(project, specimen, block, 'raw', slide_name,
                             slide_ext, level, ctr_x, ctr_y, w, h, 'png').data
    else:
        url = '%s/dzi/patch/%s/%s/%s/raw/%s.%s/%d/%d_%d_%d_%d.png' % (
            del_url, project, specimen, block, slide_name, slide_ext, level,
            ctr_x, ctr_y, w, h)
        pr = sr.get_project_ref()
        post_data = urllib.urlencode(
            {'project_data': json.dumps(pr.get_dict())})
        rawbytes = urllib2.urlopen(url, post_data).read()

    # Save as PNG
    with open(get_sample_patch_filename(sample_id), 'wb') as f:
        f.write(rawbytes)

    # Record that patch has been written
    db.execute('UPDATE training_sample SET have_patch=1 where id=?',
               (sample_id, ))
    db.commit()
Example #6
0
def update_slide_derived_data(slide_id, check_hash=True):
    # Get the slide reference
    sr = get_slide_ref(slide_id)

    # Get the remote thumbnail file
    f_thumb = sr.get_local_copy("thumb", check_hash=check_hash)

    # Get the local thumbnail
    thumb_dir = os.path.join(current_app.instance_path, 'thumb')
    thumb_fn = os.path.join(thumb_dir, "thumb%08d.png" % (slide_id, ))

    # If the thumb has been downloaded successfully, derive a HTML-usable thumb
    if f_thumb is not None:
        x = Image.open(f_thumb)
        m = max(x.size[0] / 256., x.size[1] / 192.)
        x = x.resize(map(int, (x.size[0] / m, x.size[1] / m)))

        if not os.path.exists(thumb_dir):
            os.makedirs(thumb_dir)
        x.save(thumb_fn)
Example #7
0
def get_sample_custom_png(id, level, w, h):

    # Get the slide reference
    db = get_db()
    sample = db.execute('SELECT * FROM training_sample WHERE id=?',
                        (id, )).fetchone()
    slide_id = sample['slide']
    sr = get_slide_ref(slide_id)

    # Get the identifiers for the slide
    # TODO: what to do with project name here
    (project, specimen, block, slide_name, slide_ext) = sr.get_id_tuple()

    # Are we delegating this slide to a different node?
    del_url = find_delegate_for_slide(slide_id)

    # Compute the parameters
    ctr_x = int((sample['x0'] + sample['x1']) / 2.0 + 0.5)
    ctr_y = int((sample['y0'] + sample['y1']) / 2.0 + 0.5)
    x = ctr_x - ((w - int(w / 2.0)) - 1)
    y = ctr_y - ((h - int(h / 2.0)) - 1)

    # If local, call the method directly
    rawbytes = None
    if del_url is None:
        rawbytes = get_patch(project, specimen, block, 'raw', slide_name,
                             slide_ext, level, ctr_x, ctr_y, w, h, 'png').data
    else:
        url = '%s/dzi/patch/%s/%s/%s/raw/%s.%s/%d/%d_%d_%d_%d.png' % (
            del_url, project, specimen, block, slide_name, slide_ext, level,
            ctr_x, ctr_y, w, h)
        pr = sr.get_project_ref()
        post_data = urllib.urlencode(
            {'project_data': json.dumps(pr.get_dict())})
        rawbytes = urllib2.urlopen(url, post_data).read()

    resp = make_response(rawbytes)
    resp.mimetype = 'image/%s' % format
    return resp
Example #8
0
def get_affine_matrix_by_slideid(slide_id, mode, resolution='raw'):

    sr = get_slide_ref(slide_id)
    return get_affine_matrix(sr, mode, resolution)
Example #9
0
def extract_svg(task, slide_id, stroke_width, strip_width, font_size,
                font_color):

    # The return value
    svg = None

    # Find the annotation in the database
    db = get_db()
    rc = db.execute('SELECT json FROM annot WHERE slide_id=? AND task_id=?',
                    (slide_id, task)).fetchone()

    if rc is not None:
        # Get the annotation
        data = json.loads(rc['json'])

        # Get the raw slide dimensions
        sr = get_slide_ref(slide_id)
        dims = get_slide_raw_dims(sr)
        if dims is None:
            raise ValueError("Missing slide dimensions information")

        # Start writing svg
        svg = svgwrite.Drawing(size=(dims[0], dims[1]))

        # Write the paths
        if 'children' in data[0][1]:
            for x in data[0][1]['children']:

                # Handle paths
                if not check_annot_child(x):
                    print('Bad element:', x)
                    continue
                try:
                    if x[0] == 'Path':
                        seg = x[1]['segments']
                        if len(seg) < 1 or seg[0][0][0] is None or seg[0][0][
                                1] is None:
                            continue

                        # Default mode is to draw curves
                        if strip_width is None or strip_width == 0:

                            # List of commands for SVG path
                            cmd = []

                            # Record the initial positioning
                            cmd.append('M%f,%f' % (seg[0][0][0], seg[0][0][1]))

                            # Record the control points
                            for i in range(1, len(seg)):
                                # Get the handles from the control point
                                P1 = seg[i - 1][0]
                                P2 = seg[i][0]
                                D = [P2[0] - P1[0], P2[1] - P1[1]]
                                V1 = seg[i - 1][2]
                                V2 = seg[i][1]
                                cmd.append('c%f,%f %f,%f %f,%f' %
                                           (V1[0], V1[1], D[0] + V2[0],
                                            D[1] + V2[1], D[0], D[1]))

                            # Add the path to the SVG
                            svg.add(
                                svg.path(d=''.join(cmd),
                                         stroke="#000",
                                         fill="none",
                                         stroke_width=stroke_width))

                        # Alternative mode is to draw parallel strips
                        else:

                            # Record the control points
                            for i in range(1, len(seg)):
                                # Get the handles from the control point
                                P1 = seg[i - 1][0]
                                P2 = seg[i][0]

                                D = [P2[0] - P1[0], P2[1] - P1[1]]
                                V1 = seg[i - 1][2]
                                V2 = seg[i][1]

                                # Get the tangent vectors
                                nV1 = math.sqrt(V1[0] * V1[0] + V1[1] * V1[1])
                                nV2 = math.sqrt(V2[0] * V2[0] + V2[1] * V2[1])

                                T1 = [x / nV1 for x in V1] if nV1 > 0 else V1
                                T2 = [x / nV2 for x in V2] if nV2 > 0 else V2

                                Q2 = [
                                    P2[0] + strip_width * T2[1],
                                    P2[1] - strip_width * T2[0]
                                ]
                                Q1 = [
                                    P1[0] - strip_width * T1[1],
                                    P1[1] + strip_width * T1[0]
                                ]
                                DQ = [Q1[0] - Q2[0], Q1[1] - Q2[1]]

                                R2 = [
                                    P2[0] - strip_width * T2[1],
                                    P2[1] + strip_width * T2[0]
                                ]
                                R1 = [
                                    P1[0] + strip_width * T1[1],
                                    P1[1] - strip_width * T1[0]
                                ]
                                DR = [R1[0] - R2[0], R1[1] - R2[1]]

                                # Draw the path (part curve, part line)
                                svg.add(
                                    svg.path(
                                        d="M%f,%f c%f,%f %f,%f %f,%f L%f,%f c%f,%f %f,%f, %f,%f L%f,%f"
                                        % (P1[0], P1[1], V1[0], V1[1],
                                           D[0] + V2[0], D[1] + V2[1], D[0],
                                           D[1], Q2[0], Q2[1], V2[0], V2[1],
                                           DQ[0] + V1[0], DQ[1] + V1[1], DQ[0],
                                           DQ[1], P1[0], P1[1]),
                                        stroke="none",
                                        fill="#ddd",
                                        stroke_width=0))

                                # Draw the path (part curve, part line)
                                svg.add(
                                    svg.path(
                                        d="M%f,%f c%f,%f %f,%f %f,%f L%f,%f c%f,%f %f,%f, %f,%f L%f,%f"
                                        % (P1[0], P1[1], V1[0], V1[1],
                                           D[0] + V2[0], D[1] + V2[1], D[0],
                                           D[1], R2[0], R2[1], V2[0], V2[1],
                                           DR[0] + V1[0], DR[1] + V1[1], DR[0],
                                           DR[1], P1[0], P1[1]),
                                        stroke="none",
                                        fill="#aaa",
                                        stroke_width=0))

                                #svg.add(svg.path(
                                #    d="M%f,%f c%f,%f %f,%f %f,%f L%f,%f L%f,%f L%f,%f" % (
                                #        P1[0],P1[1],
                                #        V1[0],V1[1],D[0]+V2[0],D[1]+V2[1],D[0],D[1],
                                #        P2[0]+strip_width*T2[1],P2[1]-strip_width*T2[0],
                                #        P1[0]-strip_width*T1[1],P1[1]+strip_width*T1[0],
                                #        P1[0],P1[1]), stroke="#000", fill="#ddd", stroke_width=48))

                    elif x[0] == 'PointText':

                        tpos = x[1]['matrix'][4:6]
                        text = x[1]['content']
                        svg.add(
                            svg.text(text,
                                     insert=tpos,
                                     fill=font_color,
                                     stroke=font_color,
                                     font_size=font_size))

                        # ["PointText",
                        #  {"applyMatrix": false, "matrix": [1, 0, 0, 1, 1416.62777, 2090.96831], "content": "CA2",
                        #  "fontWeight": "bold", "fontSize": 44, "leading": 52.8, "justification": "center"}]

                except TypeError:
                    raise ValueError("Unreadable path %s in slide %d task %d" %
                                     (x, slide_id, task))

    return svg