def setUp(self):
     context = zmq.Context.instance()
     self.notify_addr = "inproc://" + uuid.uuid4().hex
     self.socket_addr = "inproc://" + uuid.uuid4().hex
     self.kill_pub = context.socket(zmq.PUB)
     self.kill_pub.bind(self.notify_addr)
     self.server = KnimeBridgeServer(context, self.socket_addr,
                                     self.notify_addr, NOTIFY_STOP)
     self.server.start()
     self.session_id = uuid.uuid4().hex
     self.socket = context.socket(zmq.REQ)
     self.socket.connect(self.socket_addr)
示例#2
0
 def setUp(self):
     context = zmq.Context.instance()
     self.notify_addr = "inproc://" + uuid.uuid4().hex
     self.socket_addr = "inproc://" + uuid.uuid4().hex
     self.kill_pub = context.socket(zmq.PUB)
     self.kill_pub.bind(self.notify_addr)
     self.server = KnimeBridgeServer(context, self.socket_addr, self.notify_addr, NOTIFY_STOP)
     self.server.start()
     self.session_id = uuid.uuid4().hex
     self.socket = context.socket(zmq.REQ)
     self.socket.connect(self.socket_addr)
示例#3
0
def main():
    #
    # For OS/X set up the UI elements that users expect from
    # an app.
    #
    if sys.platform == "darwin":
        import os.path

        icon_path = pkg_resources.resource_filename(
            "cellprofiler", os.path.join("data", "icons", "CellProfiler.png"))
        os.environ["APP_NAME_%d" % os.getpid()] = "CellProfilerWorker"
        os.environ["APP_ICON_%d" % os.getpid()] = icon_path

    # Start the JVM
    from cellprofiler_core.utilities.java import start_java, stop_java

    start_java()

    deadman_start_socket = the_zmq_context.socket(zmq.PAIR)
    deadman_start_socket.bind(DEADMAN_START_ADDR)

    # Start the deadman switch thread.
    start_daemon_thread(target=exit_on_stdin_close, name="exit_on_stdin_close")
    deadman_start_socket.recv()
    deadman_start_socket.close()

    from cellprofiler.knime_bridge import KnimeBridgeServer

    with Worker(work_announce_address) as worker:
        worker_thread = threading.Thread(target=worker.run,
                                         name="WorkerThread")
        worker_thread.setDaemon(True)
        worker_thread.start()
        with KnimeBridgeServer(the_zmq_context, knime_bridge_address,
                               NOTIFY_ADDR, NOTIFY_STOP):
            worker_thread.join()

    #
    # Shutdown - need to handle some global cleanup here
    #
    try:
        stop_java()
    except:
        logging.warning("Failed to stop the JVM", exc_info=True)
示例#4
0
def main():
    #
    # For OS/X set up the UI elements that users expect from
    # an app.
    #
    if sys.platform == "darwin":
        from cellprofiler.icons import get_builtin_images_path

        icon_path = os.path.join(get_builtin_images_path(), "artwork/CellProfilerIcon.png")
        os.environ["APP_NAME_%d" % os.getpid()] = "CellProfilerWorker"
        os.environ["APP_ICON_%d" % os.getpid()] = icon_path

    # Start the JVM
    from cellprofiler.utilities.cpjvm import cp_start_vm, cp_stop_vm
    cp_start_vm()

    deadman_start_socket = the_zmq_context.socket(zmq.PAIR)
    deadman_start_socket.bind(DEADMAN_START_ADDR)

    # Start the deadman switch thread.
    start_daemon_thread(target=exit_on_stdin_close,
                        name="exit_on_stdin_close")
    deadman_start_socket.recv()
    deadman_start_socket.close()

    from cellprofiler.knime_bridge import KnimeBridgeServer
    with AnalysisWorker(work_announce_address) as worker:
        worker_thread = threading.Thread(target=worker.run,
                                         name="WorkerThread")
        worker_thread.setDaemon(True)
        worker_thread.start()
        with KnimeBridgeServer(the_zmq_context,
                               knime_bridge_address,
                               NOTIFY_ADDR, NOTIFY_STOP):
            worker_thread.join()

    #
    # Shutdown - need to handle some global cleanup here
    #
    try:
        cp_stop_vm()
    except:
        logger.warn("Failed to stop the JVM", exc_info=1)
class TestKnimeBridge(unittest.TestCase):
    def setUp(self):
        context = zmq.Context.instance()
        self.notify_addr = "inproc://" + uuid.uuid4().hex
        self.socket_addr = "inproc://" + uuid.uuid4().hex
        self.kill_pub = context.socket(zmq.PUB)
        self.kill_pub.bind(self.notify_addr)
        self.server = KnimeBridgeServer(context, self.socket_addr,
                                        self.notify_addr, NOTIFY_STOP)
        self.server.start()
        self.session_id = uuid.uuid4().hex
        self.socket = context.socket(zmq.REQ)
        self.socket.connect(self.socket_addr)

    def tearDown(self):
        self.kill_pub.send(NOTIFY_STOP)
        self.server.join()
        self.kill_pub.close()
        self.socket.close()

    def test_01_01_do_nothing(self):
        # test KB thread lifecycle
        pass

    def test_01_02_connect(self):
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(CONNECT_REQ_1)
        ]
        self.socket.send_multipart(message)
        reply = self.socket.recv_multipart()
        self.assertEqual(reply.pop(0), self.session_id)
        self.assertEqual(reply.pop(0), "")
        self.assertEqual(reply.pop(0), CONNECT_REPLY_1)

    def test_02_01_pipeline_info(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.add_imagecb()
        load_images.images[0].channels[0].image_name.value = "Foo"
        load_images.images[1].channels[0].image_name.value = "Bar"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(PIPELINE_INFO_REQ_1),
            zmq.Frame(pipeline_txt.getvalue())
        ]
        self.socket.send_multipart(message)
        message = self.socket.recv_multipart()
        self.assertEqual(message.pop(0), self.session_id)
        self.assertEqual(message.pop(0), "")
        self.assertEqual(message.pop(0), PIPELINE_INFO_REPLY_1)
        body = json.loads(message.pop(0))
        self.assertEqual(len(body), 3)
        channels, type_names, measurements = body
        self.assertTrue("Foo" in channels)
        self.assertTrue("Bar" in channels)
        self.assertTrue("dizzy" in measurements)
        found_location = False
        found_object_number = False
        for feature, idx in measurements['dizzy']:
            if feature == "Location_Center_X":
                self.assertEqual('java.lang.Double', type_names[idx])
                found_location = True
            elif feature == "Number_Object_Number":
                self.assertEqual('java.lang.Integer', type_names[idx])
                found_object_number = True
        self.assertTrue(found_location)
        self.assertTrue(found_object_number)

    def test_02_02_bad_pipeline(self):
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(PIPELINE_INFO_REQ_1),
            zmq.Frame("Freckles is a good dog but a bad pipeline")
        ]
        self.socket.send_multipart(message)
        message = self.socket.recv_multipart()
        self.assertEqual(message.pop(0), self.session_id)
        self.assertEqual(message.pop(0), "")
        self.assertEqual(message.pop(0), PIPELINE_EXCEPTION_1)

    def test_02_03_clean_pipeline(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.add_imagecb()
        load_images.images[0].channels[0].image_name.value = "Foo"
        load_images.images[1].channels[0].image_name.value = "Bar"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        pipeline.add_module(identify)
        saveimages = SaveImages()
        saveimages.module_num = 3
        saveimages.image_name.value = "Foo"
        pipeline.add_module(saveimages)
        measureobjectsizeshape = MeasureObjectSizeShape()
        measureobjectsizeshape.module_num = 4
        measureobjectsizeshape.object_groups[0].name.value = "dizzy"
        pipeline.add_module(measureobjectsizeshape)
        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)
        module_names = json.dumps([SaveImages.module_name])
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(CLEAN_PIPELINE_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(module_names)
        ]
        self.socket.send_multipart(message)
        message = self.socket.recv_multipart()
        self.assertEqual(message.pop(0), self.session_id)
        self.assertEqual(message.pop(0), "")
        self.assertEqual(message.pop(0), CLEAN_PIPELINE_REPLY_1)
        pipeline_txt = message.pop(0)
        pipeline = cpp.Pipeline()
        pipeline.loadtxt(StringIO(pipeline_txt))
        self.assertEqual(len(pipeline.modules()), 3)
        self.assertIsInstance(pipeline.modules()[0], LoadImages)
        self.assertIsInstance(pipeline.modules()[1], IdentifyPrimaryObjects)
        self.assertIsInstance(pipeline.modules()[2], MeasureObjectSizeShape)

    def test_03_01_run_something(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.use_advanced.value = True
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((11, 17))
        image[2:-2, 2:-2] = 1

        image_metadata = [[
            "Foo",
            [["Y", image.shape[0], image.strides[0] / 8],
             ["X", image.shape[1], image.strides[1] / 8]]
        ]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)
        ]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), RUN_REPLY_1)
        metadata = json.loads(response.pop(0))
        data = response.pop(0)
        measurements = self.decode_measurements(metadata, data)
        self.assertEqual(measurements[cpmeas.IMAGE]["Count_dizzy"][0], 1)
        self.assertEqual(measurements["dizzy"]["Location_Center_Y"][0], 5)

    def test_03_02_bad_cellprofiler(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((11, 17))
        image[2:-2, 2:-2] = 1

        # Get the strides wrong (I broke it accidentally this way before...)
        image_metadata = [[
            "Foo",
            [["Y", image.shape[0], image.strides[0]],
             ["X", image.shape[1], image.strides[1]]]
        ]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)
        ]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), CELLPROFILER_EXCEPTION_1)

    def test_03_03_run_missing_measurement(self):
        # Regression test of knime-bridge issue #6
        #
        # Missing measurement causes exception
        #
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.use_advanced.value = True
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        flag_module = FlagImage()
        flag_module.module_num = 3
        flag = flag_module.flags[0]
        flag.wants_skip.value = True
        criterion = flag.measurement_settings[0]
        criterion.source_choice.value = S_IMAGE
        criterion.measurement.value = "Count_dizzy"
        criterion.wants_minimum.value = True
        criterion.minimum_value.value = 1000
        pipeline.add_module(flag_module)

        measureobjectsizeshape = MeasureObjectSizeShape()
        measureobjectsizeshape.module_num = 4
        measureobjectsizeshape.object_groups[0].name.value = "dizzy"
        pipeline.add_module(measureobjectsizeshape)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((11, 17))
        image[2:-2, 2:-2] = 1

        image_metadata = [[
            "Foo",
            [["Y", image.shape[0], image.strides[0] / 8],
             ["X", image.shape[1], image.strides[1] / 8]]
        ]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)
        ]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), RUN_REPLY_1)
        metadata = json.loads(response.pop(0))
        data = response.pop(0)
        measurements = self.decode_measurements(metadata, data)
        self.assertEqual(measurements[cpmeas.IMAGE]["Count_dizzy"][0], 1)
        self.assertEqual(measurements["dizzy"]["Location_Center_Y"][0], 5)
        self.assertEqual(len(measurements["dizzy"]["AreaShape_Area"]), 0)

    def test_04_01_run_group(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.use_advanced.value = True
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((2, 11, 17))
        image[0, 2:-2, 2:-2] = 1
        image[1, 2:-2, 2:7] = 1
        image[1, 2:-2, 10:-2] = 1

        image_metadata = [[
            "Foo",
            [["Z", image.shape[0], image.strides[0] / 8],
             ["Y", image.shape[1], image.strides[1] / 8],
             ["X", image.shape[2], image.strides[2] / 8]]
        ]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_GROUP_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)
        ]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), RUN_REPLY_1)
        metadata = json.loads(response.pop(0))
        data = response.pop(0)
        measurements = self.decode_measurements(metadata, data)
        self.assertEqual(len(measurements[cpmeas.IMAGE][cpmeas.IMAGE_NUMBER]),
                         2)
        self.assertEqual(measurements[cpmeas.IMAGE]["Count_dizzy"][0], 1)
        self.assertEqual(measurements[cpmeas.IMAGE]["Count_dizzy"][1], 2)
        self.assertEqual(measurements["dizzy"]["Location_Center_Y"][0], 5)

    def test_04_02_bad_cellprofiler(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((11, 17))
        image[2:-2, 2:-2] = 1

        # Get the strides wrong (I broke it accidentally this way before...)
        # And there's more wrong in this one.
        image_metadata = [[
            "Foo",
            [["Y", image.shape[0], image.strides[0]],
             ["X", image.shape[1], image.strides[1]]]
        ]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_GROUP_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)
        ]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), CELLPROFILER_EXCEPTION_1)

    def decode_measurements(self, metadata, data):
        offset = 0
        ddata = {}
        self.assertEqual(len(metadata), 4)
        for object_name, md in metadata[0]:
            items = {}
            ddata[object_name] = items
            for feature, count in md:
                next_offset = offset + count * 8
                items[feature] = np.frombuffer(data[offset:next_offset],
                                               np.float64)
                offset = next_offset
        for object_name, md in metadata[1]:
            if object_name not in ddata:
                items = {}
                ddata[object_name] = items
            else:
                items = ddata[object_name]
            for feature, count in md:
                next_offset = offset + count * 4
                items[feature] = np.frombuffer(data[offset:next_offset],
                                               np.float32)
                offset = next_offset
        for object_name, md in metadata[2]:
            if object_name not in ddata:
                items = {}
                ddata[object_name] = items
            else:
                items = ddata[object_name]
            for feature, count in md:
                next_offset = offset + count * 4
                items[feature] = np.frombuffer(data[offset:next_offset],
                                               np.int32)
                offset = next_offset
        return ddata
class TestKnimeBridge(unittest.TestCase):
    def setUp(self):
        context = zmq.Context.instance()
        self.notify_addr = "inproc://" + uuid.uuid4().hex
        self.socket_addr = "inproc://" + uuid.uuid4().hex
        self.kill_pub = context.socket(zmq.PUB)
        self.kill_pub.bind(self.notify_addr)
        self.server = KnimeBridgeServer(
                context, self.socket_addr, self.notify_addr, NOTIFY_STOP)
        self.server.start()
        self.session_id = uuid.uuid4().hex
        self.socket = context.socket(zmq.REQ)
        self.socket.connect(self.socket_addr)

    def tearDown(self):
        self.kill_pub.send(NOTIFY_STOP)
        self.server.join()
        self.kill_pub.close()
        self.socket.close()

    def test_01_01_do_nothing(self):
        # test KB thread lifecycle
        pass

    def test_01_02_connect(self):
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(CONNECT_REQ_1)]
        self.socket.send_multipart(message)
        reply = self.socket.recv_multipart()
        self.assertEqual(reply.pop(0), self.session_id)
        self.assertEqual(reply.pop(0), "")
        self.assertEqual(reply.pop(0), CONNECT_REPLY_1)

    def test_02_01_pipeline_info(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.add_imagecb()
        load_images.images[0].channels[0].image_name.value = "Foo"
        load_images.images[1].channels[0].image_name.value = "Bar"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)
        message = [zmq.Frame(self.session_id),
                   zmq.Frame(),
                   zmq.Frame(PIPELINE_INFO_REQ_1),
                   zmq.Frame(pipeline_txt.getvalue())]
        self.socket.send_multipart(message)
        message = self.socket.recv_multipart()
        self.assertEqual(message.pop(0), self.session_id)
        self.assertEqual(message.pop(0), "")
        self.assertEqual(message.pop(0), PIPELINE_INFO_REPLY_1)
        body = json.loads(message.pop(0))
        self.assertEqual(len(body), 3)
        channels, type_names, measurements = body
        self.assertTrue("Foo" in channels)
        self.assertTrue("Bar" in channels)
        self.assertTrue("dizzy" in measurements)
        found_location = False
        found_object_number = False
        for feature, idx in measurements['dizzy']:
            if feature == "Location_Center_X":
                self.assertEqual('java.lang.Double', type_names[idx])
                found_location = True
            elif feature == "Number_Object_Number":
                self.assertEqual('java.lang.Integer', type_names[idx])
                found_object_number = True
        self.assertTrue(found_location)
        self.assertTrue(found_object_number)

    def test_02_02_bad_pipeline(self):
        message = [zmq.Frame(self.session_id),
                   zmq.Frame(),
                   zmq.Frame(PIPELINE_INFO_REQ_1),
                   zmq.Frame("Freckles is a good dog but a bad pipeline")]
        self.socket.send_multipart(message)
        message = self.socket.recv_multipart()
        self.assertEqual(message.pop(0), self.session_id)
        self.assertEqual(message.pop(0), "")
        self.assertEqual(message.pop(0), PIPELINE_EXCEPTION_1)

    def test_02_03_clean_pipeline(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.add_imagecb()
        load_images.images[0].channels[0].image_name.value = "Foo"
        load_images.images[1].channels[0].image_name.value = "Bar"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        pipeline.add_module(identify)
        saveimages = SaveImages()
        saveimages.module_num = 3
        saveimages.image_name.value = "Foo"
        pipeline.add_module(saveimages)
        measureobjectsizeshape = MeasureObjectSizeShape()
        measureobjectsizeshape.module_num = 4
        measureobjectsizeshape.object_groups[0].name.value = "dizzy"
        pipeline.add_module(measureobjectsizeshape)
        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)
        module_names = json.dumps([SaveImages.module_name])
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(CLEAN_PIPELINE_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(module_names)]
        self.socket.send_multipart(message)
        message = self.socket.recv_multipart()
        self.assertEqual(message.pop(0), self.session_id)
        self.assertEqual(message.pop(0), "")
        self.assertEqual(message.pop(0), CLEAN_PIPELINE_REPLY_1)
        pipeline_txt = message.pop(0)
        pipeline = cpp.Pipeline()
        pipeline.loadtxt(StringIO(pipeline_txt))
        self.assertEqual(len(pipeline.modules()), 3)
        self.assertIsInstance(pipeline.modules()[0], LoadImages)
        self.assertIsInstance(pipeline.modules()[1], IdentifyPrimaryObjects)
        self.assertIsInstance(pipeline.modules()[2], MeasureObjectSizeShape)

    def test_03_01_run_something(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.use_advanced.value = True
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((11, 17))
        image[2:-2, 2:-2] = 1

        image_metadata = [
            ["Foo",
             [["Y", image.shape[0], image.strides[0] / 8],
              ["X", image.shape[1], image.strides[1] / 8]]]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), RUN_REPLY_1)
        metadata = json.loads(response.pop(0))
        data = response.pop(0)
        measurements = self.decode_measurements(metadata, data)
        self.assertEqual(measurements[cpmeas.IMAGE]["Count_dizzy"][0], 1)
        self.assertEqual(measurements["dizzy"]["Location_Center_Y"][0], 5)

    def test_03_02_bad_cellprofiler(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((11, 17))
        image[2:-2, 2:-2] = 1

        # Get the strides wrong (I broke it accidentally this way before...)
        image_metadata = [
            ["Foo",
             [["Y", image.shape[0], image.strides[0]],
              ["X", image.shape[1], image.strides[1]]]]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), CELLPROFILER_EXCEPTION_1)

    def test_03_03_run_missing_measurement(self):
        # Regression test of knime-bridge issue #6
        #
        # Missing measurement causes exception
        #
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.use_advanced.value = True
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        flag_module = FlagImage()
        flag_module.module_num = 3
        flag = flag_module.flags[0]
        flag.wants_skip.value = True
        criterion = flag.measurement_settings[0]
        criterion.source_choice.value = S_IMAGE
        criterion.measurement.value = "Count_dizzy"
        criterion.wants_minimum.value = True
        criterion.minimum_value.value = 1000
        pipeline.add_module(flag_module)

        measureobjectsizeshape = MeasureObjectSizeShape()
        measureobjectsizeshape.module_num = 4
        measureobjectsizeshape.object_groups[0].name.value = "dizzy"
        pipeline.add_module(measureobjectsizeshape)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((11, 17))
        image[2:-2, 2:-2] = 1

        image_metadata = [
            ["Foo",
             [["Y", image.shape[0], image.strides[0] / 8],
              ["X", image.shape[1], image.strides[1] / 8]]]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), RUN_REPLY_1)
        metadata = json.loads(response.pop(0))
        data = response.pop(0)
        measurements = self.decode_measurements(metadata, data)
        self.assertEqual(measurements[cpmeas.IMAGE]["Count_dizzy"][0], 1)
        self.assertEqual(measurements["dizzy"]["Location_Center_Y"][0], 5)
        self.assertEqual(len(measurements["dizzy"]["AreaShape_Area"]), 0)

    def test_04_01_run_group(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.use_advanced.value = True
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((2, 11, 17))
        image[0, 2:-2, 2:-2] = 1
        image[1, 2:-2, 2:7] = 1
        image[1, 2:-2, 10:-2] = 1

        image_metadata = [
            ["Foo",
             [["Z", image.shape[0], image.strides[0] / 8],
              ["Y", image.shape[1], image.strides[1] / 8],
              ["X", image.shape[2], image.strides[2] / 8]]]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_GROUP_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), RUN_REPLY_1)
        metadata = json.loads(response.pop(0))
        data = response.pop(0)
        measurements = self.decode_measurements(metadata, data)
        self.assertEqual(len(measurements[cpmeas.IMAGE][cpmeas.IMAGE_NUMBER]), 2)
        self.assertEqual(measurements[cpmeas.IMAGE]["Count_dizzy"][0], 1)
        self.assertEqual(measurements[cpmeas.IMAGE]["Count_dizzy"][1], 2)
        self.assertEqual(measurements["dizzy"]["Location_Center_Y"][0], 5)

    def test_04_02_bad_cellprofiler(self):
        pipeline = cpp.Pipeline()
        load_images = LoadImages()
        load_images.module_num = 1
        load_images.images[0].channels[0].image_name.value = "Foo"
        pipeline.add_module(load_images)
        identify = IdentifyPrimaryObjects()
        identify.module_num = 2
        identify.x_name.value = "Foo"
        identify.y_name.value = "dizzy"
        identify.threshold.threshold_scope.value = TS_GLOBAL
        identify.threshold.global_operation.value = TM_MANUAL
        identify.threshold.manual_threshold.value = .5
        identify.exclude_size.value = False
        pipeline.add_module(identify)

        pipeline_txt = StringIO()
        pipeline.savetxt(pipeline_txt)

        image = np.zeros((11, 17))
        image[2:-2, 2:-2] = 1

        # Get the strides wrong (I broke it accidentally this way before...)
        # And there's more wrong in this one.
        image_metadata = [
            ["Foo",
             [["Y", image.shape[0], image.strides[0]],
              ["X", image.shape[1], image.strides[1]]]]]
        message = [
            zmq.Frame(self.session_id),
            zmq.Frame(),
            zmq.Frame(RUN_GROUP_REQ_1),
            zmq.Frame(pipeline_txt.getvalue()),
            zmq.Frame(json.dumps(image_metadata)),
            zmq.Frame(image)]
        self.socket.send_multipart(message)
        response = self.socket.recv_multipart()
        self.assertEqual(response.pop(0), self.session_id)
        self.assertEqual(response.pop(0), "")
        self.assertEqual(response.pop(0), CELLPROFILER_EXCEPTION_1)

    def decode_measurements(self, metadata, data):
        offset = 0
        ddata = {}
        self.assertEqual(len(metadata), 4)
        for object_name, md in metadata[0]:
            items = {}
            ddata[object_name] = items
            for feature, count in md:
                next_offset = offset + count * 8
                items[feature] = np.frombuffer(
                        data[offset:next_offset], np.float64)
                offset = next_offset
        for object_name, md in metadata[1]:
            if object_name not in ddata:
                items = {}
                ddata[object_name] = items
            else:
                items = ddata[object_name]
            for feature, count in md:
                next_offset = offset + count * 4
                items[feature] = np.frombuffer(
                        data[offset:next_offset], np.float32)
                offset = next_offset
        for object_name, md in metadata[2]:
            if object_name not in ddata:
                items = {}
                ddata[object_name] = items
            else:
                items = ddata[object_name]
            for feature, count in md:
                next_offset = offset + count * 4
                items[feature] = np.frombuffer(
                        data[offset:next_offset], np.int32)
                offset = next_offset
        return ddata
示例#7
0
def main():
    #
    # For Windows build with Ilastik, look for site-packages
    # in order to find Ilastik sources.
    #
    if hasattr(sys, 'frozen') and sys.platform == "win32":
        root = os.path.split(sys.argv[0])[0]
        if len(root) == 0:
            root = os.curdir
        root = os.path.abspath(root)
        site_packages = os.path.join(root, 'site-packages').encode('utf-8')
        if os.path.exists(site_packages) and os.path.isdir(site_packages):
            import site
            site.addsitedir(site_packages)
    #
    # For OS/X set up the UI elements that users expect from
    # an app.
    #
    if sys.platform == "darwin":
        from cellprofiler.icons import get_builtin_images_path

        icon_path = os.path.join(get_builtin_images_path(),
                                 "artwork/CellProfilerIcon.png")
        os.environ["APP_NAME_%d" % os.getpid()] = "CellProfilerWorker"
        os.environ["APP_ICON_%d" % os.getpid()] = icon_path

    # Start the JVM
    from cellprofiler.utilities.cpjvm import cp_start_vm, cp_stop_vm
    cp_start_vm()

    deadman_start_socket = the_zmq_context.socket(zmq.PAIR)
    deadman_start_socket.bind(DEADMAN_START_ADDR)

    # Start the deadman switch thread.
    start_daemon_thread(target=exit_on_stdin_close, name="exit_on_stdin_close")
    deadman_start_socket.recv()
    deadman_start_socket.close()
    # Limit Ilastik to one job thread.
    try:
        from ilastik.core.jobMachine import GLOBAL_WM
        try:
            GLOBAL_WM.set_thread_count(1)
        except:
            GLOBAL_WM.setThreadCount(1)
    except:
        pass

    from cellprofiler.knime_bridge import KnimeBridgeServer
    with AnalysisWorker(work_announce_address) as worker:
        worker_thread = threading.Thread(target=worker.run,
                                         name="WorkerThread")
        worker_thread.setDaemon(True)
        worker_thread.start()
        with KnimeBridgeServer(the_zmq_context, knime_bridge_address,
                               NOTIFY_ADDR, NOTIFY_STOP):
            enter_run_loop()
            worker_thread.join()

    #
    # Shutdown - need to handle some global cleanup here
    #
    try:
        from ilastik.core.jobMachine import GLOBAL_WM
        GLOBAL_WM.stopWorkers()
    except:
        logger.warn("Failed to stop Ilastik")
    try:
        cp_stop_vm()
    except:
        logger.warn("Failed to stop the JVM", exc_info=1)