Exemplo n.º 1
0
 def test_new_format_new_method(self):
     xy_list = points_string_to_xy_list(("1,2 3,4 5,6"))
     assert xy_list == [(1, 2), (3, 4), (5, 6)]
Exemplo n.º 2
0
 def test_old_format_new_method(self):
     xy_list = points_string_to_xy_list(("points[1,2, 3,4, 5,6] "))
     assert xy_list == [(1, 2), (3, 4), (5, 6)]
Exemplo n.º 3
0
 def test_bbox(self):
     xy_list = points_string_to_xy_list(("points[1,2, 3,4, 5,6] "))
     bbox = xyListToBbox(xy_list)
     assert bbox == (1, 2, 4, 4)
def process_images(conn, script_params):

    file_anns = []
    message = ""
    # Get the images
    images, log_message = script_utils.get_objects(conn, script_params)
    message += log_message
    if not images:
        return None, message
    # Check for line and polyline ROIs and filter images list
    images = [
        image for image in images
        if image.getROICount(["Polyline", "Line"]) > 0
    ]
    if not images:
        message += "No ROI containing line or polyline was found."
        return None, message

    csv_data = []

    for image in images:

        if image.getSizeT() > 1:
            message += "%s ID: %s appears to be a time-lapse Image," \
                " not a kymograph." % (image.getName(), image.getId())
            continue

        roi_service = conn.getRoiService()
        result = roi_service.findByImage(image.getId(), None)

        secs_per_pixel_y = image.getPixelSizeY()
        microns_per_pixel_x = image.getPixelSizeX()
        if secs_per_pixel_y and microns_per_pixel_x:
            microns_per_sec = microns_per_pixel_x / secs_per_pixel_y
        else:
            microns_per_sec = None

        # for each line or polyline, create a row in csv table: y(t), x,
        # dy(dt), dx, x/t (line), x/t (average)
        col_names = "\nt_start (pixels), x_start (pixels), t_end (pixels)," \
            " x_end (pixels), dt (pixels), dx (pixels), x/t, speed(um/sec)," \
            "avg x/t, avg speed(um/sec)"
        table_data = ""
        for roi in result.rois:
            for s in roi.copyShapes():
                if s is None:
                    continue  # seems possible in some situations
                if type(s) == omero.model.LineI:
                    table_data += "\nLine ID: %s" % s.getId().getValue()
                    x1 = s.getX1().getValue()
                    x2 = s.getX2().getValue()
                    y1 = s.getY1().getValue()
                    y2 = s.getY2().getValue()
                    dx = abs(x1 - x2)
                    dy = abs(y1 - y2)
                    dx_per_y = float(dx) / dy
                    speed = ""
                    if microns_per_sec:
                        speed = dx_per_y * microns_per_sec
                    table_data += "\n"
                    table_data += ",".join([
                        str(x)
                        for x in (y1, x1, y2, x2, dy, dx, dx_per_y, speed)
                    ])

                elif type(s) == omero.model.PolylineI:
                    table_data += "\nPolyline ID: %s" % s.getId().getValue()
                    v = s.getPoints().getValue()
                    points = roi_utils.points_string_to_xy_list(v)
                    x_start, y_start = points[0]
                    for i in range(1, len(points)):
                        x1, y1 = points[i - 1]
                        x2, y2 = points[i]
                        dx = abs(x1 - x2)
                        dy = abs(y1 - y2)
                        dx_per_y = float(dx) / dy
                        av_x_per_y = abs(float(x2 - x_start) / (y2 - y_start))
                        speed = ""
                        avg_speed = ""
                        if microns_per_sec:
                            speed = dx_per_y * microns_per_sec
                            avg_speed = av_x_per_y * microns_per_sec
                        table_data += "\n"
                        table_data += ",".join([
                            str(x) for x in (y1, x1, y2, x2, dy, dx, dx_per_y,
                                             speed, av_x_per_y, avg_speed)
                        ])

        # write table data to csv...
        if len(table_data) > 0:
            table_string = "Image ID:, %s," % image.getId()
            table_string += "Name:, %s" % image.getName()
            table_string += "\nsecsPerPixelY: %s" % secs_per_pixel_y
            table_string += '\nmicronsPerPixelX: %s' % microns_per_pixel_x
            table_string += "\n"
            table_string += col_names
            table_string += table_data
            csv_data.append(table_string)

    iids = [str(i.getId()) for i in images]
    to_link_csv = [i.getId() for i in images if i.canAnnotate()]
    csv_file_name = 'kymograph_velocities_%s.csv' % "-".join(iids)
    with open(csv_file_name, 'w') as csv_file:
        csv_file.write("\n \n".join(csv_data))

    file_ann = conn.createFileAnnfromLocalFile(csv_file_name,
                                               mimetype="text/csv")
    fa_message = "Created Line Plot csv (Excel) file"

    links = []
    if len(to_link_csv) == 0:
        fa_message += " but could not attach to images."
    for iid in to_link_csv:
        link = ImageAnnotationLinkI()
        link.parent = ImageI(iid, False)
        link.child = file_ann._obj
        links.append(link)
    if len(links) > 0:
        links = conn.getUpdateService().saveAndReturnArray(links)

    if file_ann:
        file_anns.append(file_ann)

    if not file_anns:
        fa_message = "No Analysis files created. See 'Info' or 'Error'" \
            " for more details"
    elif len(file_anns) > 1:
        fa_message = "Created %s csv (Excel) files" % len(file_anns)
    message += fa_message
    return file_anns, message
Exemplo n.º 5
0
def process_images(conn, script_params):

    line_width = script_params['Line_Width']
    new_kymographs = []
    message = ""

    # Get the images
    images, log_message = script_utils.get_objects(conn, script_params)
    message += log_message
    if not images:
        return None, message

    # Check for line and polyline ROIs and filter images list
    images = [
        image for image in images
        if image.getROICount(["Polyline", "Line"]) > 0
    ]
    if not images:
        message += "No ROI containing line or polyline was found."
        return None, message

    for image in images:
        if image.getSizeT() == 1:
            continue
        new_images = []  # kymographs derived from the current image.
        c_names = []
        colors = []
        for ch in image.getChannels():
            c_names.append(ch.getLabel())
            colors.append(ch.getColor().getRGB())

        size_t = image.getSizeT()
        pixels = image.getPrimaryPixels()

        dataset = image.getParent()
        if dataset is not None and not dataset.canLink():
            dataset = None

        roi_service = conn.getRoiService()
        result = roi_service.findByImage(image.getId(), None)

        # kymograph strategy - Using Line and Polyline ROIs:
        # NB: Use ALL time points unless >1 shape AND 'use_all_timepoints' =
        # False
        # If > 1 shape per time-point (per ROI), pick one!
        # 1 - Single line. Use this shape for all time points
        # 2 - Many lines. Use the first one to fix length. Subsequent lines to
        # update start and direction
        # 3 - Single polyline. Use this shape for all time points
        # 4 - Many polylines. Use the first one to fix length.
        for roi in result.rois:
            lines = {}  # map of theT: line
            polylines = {}  # map of theT: polyline
            for s in roi.copyShapes():
                if s is None:
                    continue
                the_t = unwrap(s.getTheT())
                the_z = unwrap(s.getTheZ())
                z = 0
                t = 0
                if the_t is not None:
                    t = the_t
                if the_z is not None:
                    z = the_z
                # TODO: Add some filter of shapes. E.g. text? / 'lines' only
                # etc.
                if type(s) == omero.model.LineI:
                    x1 = s.getX1().getValue()
                    x2 = s.getX2().getValue()
                    y1 = s.getY1().getValue()
                    y2 = s.getY2().getValue()
                    lines[t] = {
                        'theZ': z,
                        'x1': x1,
                        'y1': y1,
                        'x2': x2,
                        'y2': y2
                    }

                elif type(s) == omero.model.PolylineI:
                    v = s.getPoints().getValue()
                    points = roi_utils.points_string_to_xy_list(v)
                    polylines[t] = {'theZ': z, 'points': points}

            if len(lines) > 0:
                new_img = lines_kymograph(conn, script_params, image, lines,
                                          line_width, dataset)
                new_images.append(new_img)
                lines = []
            elif len(polylines) > 0:
                new_img = polyline_kymograph(conn, script_params, image,
                                             polylines, line_width, dataset)
                new_images.append(new_img)

        # look-up the interval for each time-point
        t_interval = None
        infos = list(pixels.copyPlaneInfo(theC=0, theT=size_t - 1, theZ=0))
        if len(infos) > 0 and infos[0].getDeltaT() is not None:
            duration = infos[0].getDeltaT(units="SECOND").getValue()
            if size_t == 1:
                t_interval = duration
            else:
                t_interval = duration / (size_t - 1)
        elif pixels.timeIncrement is not None:
            t_interval = pixels.timeIncrement
        elif "Time_Increment" in script_params:
            t_interval = script_params["Time_Increment"]

        pixel_size = None
        if pixels.physicalSizeX is not None:
            pixel_size = pixels.physicalSizeX
        elif "Pixel_Size" in script_params:
            pixel_size = script_params['Pixel_Size']

        # Save channel names and colors for each new image
        for img in new_images:
            for i, c in enumerate(img.getChannels()):
                lc = c.getLogicalChannel()
                lc.setName(c_names[i])
                lc.save()
                r, g, b = colors[i]
                # need to reload channels to avoid optimistic lock on update
                c_obj = conn.getQueryService().get("Channel", c.id)
                c_obj.red = omero.rtypes.rint(r)
                c_obj.green = omero.rtypes.rint(g)
                c_obj.blue = omero.rtypes.rint(b)
                c_obj.alpha = omero.rtypes.rint(255)
                conn.getUpdateService().saveObject(c_obj)
            img.resetRDefs()  # reset based on colors above

            # If we know pixel sizes, set them on the new image
            if pixel_size is not None or t_interval is not None:
                px = conn.getQueryService().get("Pixels", img.getPixelsId())
                microm = getattr(omero.model.enums.UnitsLength, "MICROMETER")
                if pixel_size is not None:
                    pixel_size = omero.model.LengthI(pixel_size, microm)
                    px.setPhysicalSizeX(pixel_size)
                if t_interval is not None:
                    t_per_pixel = t_interval / line_width
                    t_per_pixel = omero.model.LengthI(t_per_pixel, microm)
                    px.setPhysicalSizeY(t_per_pixel)
                conn.getUpdateService().saveObject(px)
        new_kymographs.extend(new_images)

    if not new_kymographs:
        message += "No kymograph created. See 'Error' or 'Info' for details."
    else:
        if not dataset:
            link_message = " but could not be attached"
        else:
            link_message = ""

        if len(new_images) == 1:
            message += "New kymograph created%s: %s." \
                % (link_message, new_images[0].getName())
        elif len(new_images) > 1:
            message += "%s new kymographs created%s." \
                % (len(new_images), link_message)

    return new_kymographs, message
Exemplo n.º 6
0
def process_images(conn, script_params):

    line_width = script_params['Line_Width']
    file_anns = []
    message = ""

    # Get the images
    images, log_message = script_utils.get_objects(conn, script_params)
    message += log_message
    if not images:
        return None, message

    # Check for line and polyline ROIs and filter images list
    images = [image for image in images if
              image.getROICount(["Polyline", "Line"]) > 0]
    if not images:
        message += "No ROI containing line or polyline was found."
        return None, message

    for image in images:

        c_names = []
        colors = []
        for ch in image.getChannels():
            c_names.append(ch.getLabel())
            colors.append(ch.getColor().getRGB())

        size_c = image.getSizeC()

        if 'Channels' in script_params:
            script_params['Channels'] = [i-1 for i in
                                         script_params['Channels']]
        else:
            script_params['Channels'] = range(size_c)

        roi_service = conn.getRoiService()
        result = roi_service.findByImage(image.getId(), None)

        lines = []
        polylines = []

        for roi in result.rois:
            roi_id = roi.getId().getValue()
            for s in roi.copyShapes():
                the_t = unwrap(s.getTheT())
                the_z = unwrap(s.getTheZ())
                z = 0
                t = 0
                if the_t is not None:
                    t = the_t
                if the_z is not None:
                    z = the_z
                # TODO: Add some filter of shapes e.g. text? / 'lines' only
                # etc.
                if type(s) == omero.model.LineI:
                    x1 = s.getX1().getValue()
                    x2 = s.getX2().getValue()
                    y1 = s.getY1().getValue()
                    y2 = s.getY2().getValue()
                    lines.append({'id': roi_id, 'theT': t, 'theZ': z,
                                  'x1': x1, 'y1': y1, 'x2': x2, 'y2': y2})

                elif type(s) == omero.model.PolylineI:
                    v = s.getPoints().getValue()
                    points = roi_utils.points_string_to_xy_list(v)
                    polylines.append({'id': roi_id, 'theT': t, 'theZ': z,
                                      'points': points})

        if len(lines) == 0 and len(polylines) == 0:
            continue

        # prepare column headers, including line-id if we are going to output
        # raw data.
        line_id = script_params['Sum_or_Average'] == 'Average, with raw data' \
            and 'Line, ' or ""
        col_header = 'Image_ID, ROI_ID, Z, T, C, %sLine data %s of Line" \
            " Width %s\n' % (line_id, script_params['Sum_or_Average'],
                             script_params['Line_Width'])

        # prepare a csv file to write our data to...
        file_name = "Plot_Profile_%s.csv" % image.getId()
        with open(file_name, 'w') as f:
            f.write(col_header)
            if len(lines) > 0:
                process_lines(conn, script_params, image, lines, line_width, f)
            if len(polylines) > 0:
                process_polylines(
                    conn, script_params, image, polylines, line_width, f)

        file_ann, fa_message = script_utils.create_link_file_annotation(
            conn, file_name, image, output="Line Plot csv (Excel) file",
            mimetype="text/csv", description=None)
        if file_ann:
            file_anns.append(file_ann)

    if not file_anns:
        fa_message = "No Analysis files created. See 'Info' or 'Error' for"\
            " more details"
    elif len(file_anns) > 1:
        fa_message = "Created %s csv (Excel) files" % len(file_anns)
    message += fa_message

    return file_anns, message