Пример #1
0
    def testEditSingleC(self, targetName, greyscale, tmpdir):
        sizec = 1
        # 1 channel so should default to greyscale model
        expected_greyscale = ((greyscale is None) or greyscale)
        self.create_image(sizec=sizec)
        rd = self.get_render_def(sizec=sizec, greyscale=greyscale)
        rdfile = tmpdir.join('render-test-editsinglec.json')
        # Should work with json and yaml, but yaml is an optional dependency
        rdfile.write(json.dumps(rd))
        target = getattr(self, targetName)
        self.args += ["edit", target, str(rdfile)]
        self.cli.invoke(self.args, strict=True)

        iids = self.get_target_imageids(target)
        print 'Got %d images' % len(iids)
        gw = BlitzGateway(client_obj=self.client)
        for iid in iids:
            # Get the updated object
            img = gw.getObject('Image', iid)
            # Note: calling _prepareRE below does NOT suffice!
            img._prepareRenderingEngine()  # Call *before* getChannels
            # Passing noRE to getChannels below also prevents leaking
            # the RenderingEngine but then Nones are returned later.
            channels = img.getChannels()
            assert len(channels) == sizec
            for c in xrange(len(channels)):
                self.assert_channel_rdef(channels[c], rd['channels'][c + 1])
            self.assert_image_rmodel(img, expected_greyscale)
            img._closeRE()
        assert not gw._assert_unregistered("testEditSingleC")
Пример #2
0
    def testEdit(self, targetName, tmpdir):
        sizec = 4
        greyscale = None
        # 4 channels so should default to colour model
        expected_greyscale = False
        self.create_image(sizec=sizec)
        rd = self.get_render_def(sizec=sizec, greyscale=greyscale)
        rdfile = tmpdir.join('render-test-edit.json')
        # Should work with json and yaml, but yaml is an optional dependency
        rdfile.write(json.dumps(rd))
        target = getattr(self, targetName)
        self.args += ["edit", target, str(rdfile)]
        self.cli.invoke(self.args, strict=True)

        iids = self.get_target_imageids(target)
        print 'Got %d images' % len(iids)
        gw = BlitzGateway(client_obj=self.client)
        for iid in iids:
            # Get the updated object
            img = gw.getObject('Image', iid)
            channels = img.getChannels()
            assert len(channels) == sizec
            for c in xrange(len(channels)):
                self.assert_channel_rdef(channels[c], rd['channels'][c + 1])
            self.assert_image_rmodel(img, expected_greyscale)
            img._closeRE()
        assert not gw._assert_unregistered("testEdit")
Пример #3
0
 def info(self, args):
     client = self.ctx.conn(args)
     gateway = BlitzGateway(client_obj=client)
     first = True
     for img in self.render_images(gateway, args.object, batch=1):
         ro = RenderObject(img)
         try:
             if args.style == 'plain':
                 self.ctx.out(ro)
             else:
                 if not first:
                     self.ctx.die(
                         103,
                         "Output styles not supported for multiple images")
                 self.ctx.out(pydict_text_io.dump(ro.to_dict(), args.style))
                 first = False
         finally:
             ro.close()
     gateway._assert_unregistered("info")
Пример #4
0
    def edit(self, args):
        client = self.ctx.conn(args)
        gateway = BlitzGateway(client_obj=client)
        newchannels = {}
        data = pydict_text_io.load(
            args.channels, session=client.getSession())
        if 'channels' not in data:
            self.ctx.die(104, "ERROR: No channels found in %s" % args.channels)

        for chindex, chdict in data['channels'].iteritems():
            try:
                cindex = int(chindex)
            except Exception as e:
                self.ctx.err('ERROR: %s' % e)
                self.ctx.die(
                    105, "Invalid channel index: %s" % chindex)

            try:
                cobj = ChannelObject(chdict)
                if (cobj.min is None) != (cobj.max is None):
                    raise Exception('Both or neither of min and max required')
                newchannels[cindex] = cobj
                print '%d:%s' % (cindex, cobj)
            except Exception as e:
                self.ctx.err('ERROR: %s' % e)
                self.ctx.die(
                    105, "Invalid channel description: %s" % chdict)

        try:
            greyscale = data['greyscale']
        except KeyError:
            greyscale = None

        namedict = {}
        cindices = []
        rangelist = []
        colourlist = []
        for (i, c) in newchannels.iteritems():
            if c.label:
                namedict[i] = c.label
            if not c.active:
                continue
            cindices.append(i)
            rangelist.append([c.min, c.max])
            colourlist.append(c.color)

        iids = []
        for img in self.render_images(gateway, args.object, batch=1):
            iids.append(img.id)
            try:
                img.setActiveChannels(
                    cindices, windows=rangelist, colors=colourlist, noRE=True)
                if greyscale is not None:
                    if greyscale:
                        img.setGreyscaleRenderingModel()
                    else:
                        img.setColorRenderingModel()

                img.saveDefaults()
                self.ctx.dbg(
                    "Updated rendering settings for Image:%s" % img.id)
                if not args.skipthumbs:
                    self._generate_thumbs([img])

                if args.copy:
                    # Edit first image only, copy to rest
                    # Don't close source image until outer
                    # loop is done.
                    self._copy_single(gateway,
                                      img, args.object,
                                      args.skipthumbs)
                    break
            finally:
                img._closeRE()

        if namedict:
            self._update_channel_names(gateway, iids, namedict)

        gateway._assert_unregistered("edit")
Пример #5
0
 def copy(self, args):
     client = self.ctx.conn(args)
     gateway = BlitzGateway(client_obj=client)
     self._copy(gateway, args.object, args.target, args.skipthumbs)
     gateway._assert_unregistered("copy")
Пример #6
0
class TestRender(CLITest):

    def setup_method(self, method):
        super(TestRender, self).setup_method(method)
        self.cli.register("render", RenderControl, "TEST")
        self.args += ["render"]

    def create_image(self, sizec=4):
        self.gw = BlitzGateway(client_obj=self.client)
        self.plates = []
        for plate in self.import_plates(fields=2, sizeC=sizec, screens=1):
            self.plates.append(self.gw.getObject("Plate", plate.id.val))
        # Now pick the first Image
        self.imgobj = list(self.plates[0].listChildren())[0].getImage(index=0)
        self.idonly = "%s" % self.imgobj.id
        self.imageid = "Image:%s" % self.imgobj.id
        self.plateid = "Plate:%s" % self.plates[0].id
        self.screenid = "Screen:%s" % self.plates[0].getParent().id
        # And another one as the source for copies
        self.source = list(self.plates[0].listChildren())[0].getImage(index=1)
        self.source = "Image:%s" % self.source.id
        # And for all the images, pre-load a thumbnail
        for p in self.plates:
            for w in p.listChildren():
                for i in range(w.countWellSample()):
                    img = w.getImage(index=i)
                    img.getThumbnail(
                        size=(96,), direct=False)
                    img._closeRE()
        self.imgobj._closeRE()
        assert not self.gw._assert_unregistered("create_image")

    def get_target_imageids(self, target):
        if target in (self.idonly, self.imageid):
            return [self.idonly]
        if target == self.plateid:
            imgs = []
            for w in self.plates[0].listChildren():
                imgs.extend([w.getImage(0).id, w.getImage(1).id])
            return imgs
        if target == self.screenid:
            imgs = []
            for s in self.plates:
                for w in self.plates[0].listChildren():
                    imgs.extend([w.getImage(0).id, w.getImage(1).id])
            return imgs
        raise Exception('Unknown target: %s' % target)

    def get_render_def(self, sizec=4, greyscale=None):
        channels = {}
        channels[1] = {
            'label': self.uuid(),
            'color': '123456',
            'min': 11,
            'max': 22,
        }
        channels[2] = {
            'label': self.uuid(),
            'color': '789ABC',
            'min': 33,
            'max': 44,
        }
        channels[3] = {
            'label': self.uuid(),
            'color': 'DEF012',
            'min': 55,
            'max': 66,
        }
        channels[4] = {
            'label': self.uuid(),
            'color': '345678',
            'min': 77,
            'max': 88,
        }

        for k in xrange(sizec, 4):
            del channels[k + 1]
        d = {'channels': channels}

        if greyscale is not None:
            d['greyscale'] = greyscale
        return d

    def assert_channel_rdef(self, channel, rdef):
        assert channel.getLabel() == rdef['label']
        assert channel.getColor().getHtml() == rdef['color']
        assert channel.getWindowStart() == rdef['min']
        assert channel.getWindowEnd() == rdef['max']

    def assert_image_rmodel(self, img, greyscale):
        assert img.isGreyscaleRenderingModel() == greyscale

    # rendering tests
    # ========================================================================

    @pytest.mark.parametrize('targetName', sorted(SUPPORTED.keys()))
    def testNonExistingImage(self, targetName, tmpdir):
        target = SUPPORTED[targetName]
        self.args += ["info", target]
        with pytest.raises(NonZeroReturnCode):
            self.cli.invoke(self.args, strict=True)

    @pytest.mark.parametrize('targetName', sorted(SUPPORTED.keys()))
    def testInfo(self, targetName, tmpdir):
        self.create_image()
        target = getattr(self, targetName)
        self.args += ["info", target]
        self.cli.invoke(self.args, strict=True)

    @pytest.mark.parametrize('style', ['json', 'yaml'])
    def testInfoStyle(self, style):
        self.create_image()
        target = self.imageid
        self.args += ["info", target]
        self.args += ['--style', style]
        self.cli.invoke(self.args, strict=True)

    @pytest.mark.parametrize('targetName', sorted(SUPPORTED.keys()))
    def testCopy(self, targetName, tmpdir):
        self.create_image()
        target = getattr(self, targetName)
        self.args += ["copy", self.source, target]
        self.cli.invoke(self.args, strict=True)

    @pytest.mark.parametrize('targetName', sorted(SUPPORTED.keys()))
    @pytest.mark.broken(
        reason=('https://trello.com/c/lyyGuRow/'
                '657-incorrect-logical-channels-in-clitest-importplates'))
    @pytest.mark.xfail(
        reason=('https://trello.com/c/lyyGuRow/'
                '657-incorrect-logical-channels-in-clitest-importplates'))
    def testEdit(self, targetName, tmpdir):
        sizec = 4
        greyscale = None
        # 4 channels so should default to colour model
        expected_greyscale = False
        self.create_image(sizec=sizec)
        rd = self.get_render_def(sizec=sizec, greyscale=greyscale)
        rdfile = tmpdir.join('render-test-edit.json')
        # Should work with json and yaml, but yaml is an optional dependency
        rdfile.write(json.dumps(rd))
        target = getattr(self, targetName)
        self.args += ["edit", target, str(rdfile)]
        self.cli.invoke(self.args, strict=True)

        iids = self.get_target_imageids(target)
        print 'Got %d images' % len(iids)
        gw = BlitzGateway(client_obj=self.client)
        for iid in iids:
            # Get the updated object
            img = gw.getObject('Image', iid)
            channels = img.getChannels()
            assert len(channels) == sizec
            for c in xrange(len(channels)):
                self.assert_channel_rdef(channels[c], rd['channels'][c + 1])
            self.assert_image_rmodel(img, expected_greyscale)
            img._closeRE()
        assert not gw._assert_unregistered("testEdit")

    # Once testEdit is no longer broken testEditSingleC could be merged into
    # it with sizec and greyscale parameters
    @pytest.mark.parametrize('targetName', sorted(SUPPORTED.keys()))
    @pytest.mark.parametrize('greyscale', [None, True, False])
    def testEditSingleC(self, targetName, greyscale, tmpdir):
        sizec = 1
        # 1 channel so should default to greyscale model
        expected_greyscale = ((greyscale is None) or greyscale)
        self.create_image(sizec=sizec)
        rd = self.get_render_def(sizec=sizec, greyscale=greyscale)
        rdfile = tmpdir.join('render-test-editsinglec.json')
        # Should work with json and yaml, but yaml is an optional dependency
        rdfile.write(json.dumps(rd))
        target = getattr(self, targetName)
        self.args += ["edit", target, str(rdfile)]
        self.cli.invoke(self.args, strict=True)

        iids = self.get_target_imageids(target)
        print 'Got %d images' % len(iids)
        gw = BlitzGateway(client_obj=self.client)
        for iid in iids:
            # Get the updated object
            img = gw.getObject('Image', iid)
            # Note: calling _prepareRE below does NOT suffice!
            img._prepareRenderingEngine()  # Call *before* getChannels
            # Passing noRE to getChannels below also prevents leaking
            # the RenderingEngine but then Nones are returned later.
            channels = img.getChannels()
            assert len(channels) == sizec
            for c in xrange(len(channels)):
                self.assert_channel_rdef(channels[c], rd['channels'][c + 1])
            self.assert_image_rmodel(img, expected_greyscale)
            img._closeRE()
        assert not gw._assert_unregistered("testEditSingleC")