Example #1
0
 async def send_results(self, results, uuid, finished=False):
     if self.data.job_is_cancelled(uuid):
         raise JobCancelledError()
     images = await result_images(results)
     if self.data.job_is_cancelled(uuid):
         raise JobCancelledError()
     if finished:
         msg = Message(self.data).finish_job(
             job_id=uuid,
             num_images=len(results),
             image_descriptions=[{
                 "title": result.title,
                 "desc": result.desc
             } for result in results],
         )
     else:
         msg = Message(self.data).task_result(
             job_id=uuid,
             num_images=len(results),
             image_descriptions=[{
                 "title": result.title,
                 "desc": result.desc
             } for result in results],
         )
     log_message(msg)
     # NOTE: make sure the following broadcast_event messages are sent atomically!
     # (that is: keep the code below synchronous, and only send the messages
     # once the images have finished encoding, and then send all at once)
     futures = []
     futures.append(self.event_registry.broadcast_event(msg))
     for image in images:
         raw_bytes = image.read()
         futures.append(
             self.event_registry.broadcast_event(raw_bytes, binary=True))
     await asyncio.gather(*futures)
Example #2
0
 async def send_results(self,
                        results: AnalysisResultSet,
                        job_id,
                        analysis_id,
                        details,
                        finished=False):
     if self.state.job_state.is_cancelled(job_id):
         raise JobCancelledError()
     images = await result_images(results)
     if self.state.job_state.is_cancelled(job_id):
         raise JobCancelledError()
     if finished:
         msg = Message(self.state).finish_job(
             job_id=job_id,
             num_images=len(results),
             image_descriptions=[{
                 "title":
                 result.title,
                 "desc":
                 result.desc,
                 "includeInDownload":
                 result.include_in_download
             } for result in results],
         )
         self.state.analysis_state.set_results(analysis_id, details,
                                               results, job_id)
     else:
         msg = Message(self.state).task_result(
             job_id=job_id,
             num_images=len(results),
             image_descriptions=[{
                 "title":
                 result.title,
                 "desc":
                 result.desc,
                 "includeInDownload":
                 result.include_in_download
             } for result in results],
         )
     log_message(msg)
     # NOTE: make sure the following broadcast_event messages are sent atomically!
     # (that is: keep the code below synchronous, and only send the messages
     # once the images have finished encoding, and then send all at once)
     futures = []
     futures.append(self.event_registry.broadcast_event(msg))
     for image in images:
         raw_bytes = image.read()
         futures.append(
             self.event_registry.broadcast_event(raw_bytes, binary=True))
     await asyncio.gather(*futures)
Example #3
0
 async def run_sd_udf(self, roi, stddev_udf, executor, cancel_id, job_is_cancelled):
     result_iter = UDFRunner([stddev_udf]).run_for_dataset_async(
         self.dataset, executor, roi=roi, cancel_id=cancel_id
     )
     async for (sd_udf_results,) in result_iter:
         pass
     if job_is_cancelled():
         raise JobCancelledError()
     return roi, consolidate_result(sd_udf_results)
Example #4
0
    async def run_udf(self, job_id, dataset, dataset_id, analysis, analysis_id, details):
        udf = analysis.get_udf()
        roi = analysis.get_roi()

        executor = self.state.executor_state.get_executor()
        msg = Message(self.state).start_job(
            job_id=job_id, analysis_id=analysis_id,
        )
        log_message(msg)
        self.write(msg)
        self.finish()
        self.event_registry.broadcast_event(msg)

        if hasattr(analysis, 'controller'):
            return await analysis.controller(
                cancel_id=job_id, executor=executor,
                job_is_cancelled=lambda: self.state.job_state.is_cancelled(job_id),
                send_results=lambda results, finished: self.send_results(
                    results, job_id, finished=finished,
                    details=details, analysis_id=analysis_id,
                )
            )

        t = time.time()
        post_t = time.time()
        window = 0.3
        # FIXME: allow to set correction data for a dataset via upload and local loading
        corrections = dataset.get_correction_data()
        result_iter = UDFRunner([udf]).run_for_dataset_async(
            dataset, executor, roi=roi, cancel_id=job_id, corrections=corrections,
        )
        async for udf_results in result_iter:
            window = min(max(window, 2*(t - post_t)), 5)
            if time.time() - t < window:
                continue
            results = await sync_to_async(
                analysis.get_udf_results,
                udf_results=udf_results.buffers[0],
                roi=roi,
                damage=udf_results.damage
            )
            post_t = time.time()
            await self.send_results(results, job_id, analysis_id, details)
            # The broadcast might have taken quite some time due to
            # backpressure from the network
            t = time.time()

        if self.state.job_state.is_cancelled(job_id):
            raise JobCancelledError()
        results = await sync_to_async(
            analysis.get_udf_results,
            udf_results=udf_results.buffers[0],
            roi=roi,
            damage=udf_results.damage
        )
        await self.send_results(results, job_id, analysis_id, details, finished=True)
Example #5
0
    async def run_udf(self, uuid, ds, analysis):
        udf = analysis.get_udf()
        roi = analysis.get_roi()

        # FIXME: register_job for UDFs?
        self.data.register_job(uuid=uuid, job=udf, dataset=ds)

        # FIXME: code duplication
        executor = self.data.get_executor()
        msg = Message(self.data).start_job(
            job_id=uuid,
        )
        log_message(msg)
        self.write(msg)
        self.finish()
        self.event_registry.broadcast_event(msg)

        if hasattr(analysis, 'controller'):
            return await analysis.controller(
                cancel_id=uuid, executor=executor,
                job_is_cancelled=lambda: self.data.job_is_cancelled(uuid),
                send_results=lambda results, finished: self.send_results(results, uuid,
                finished=finished)
            )

        t = time.time()
        post_t = time.time()
        window = 0.3
        result_iter = UDFRunner(udf).run_for_dataset_async(
            ds, executor, roi=roi, cancel_id=uuid
        )
        async for udf_results in result_iter:
            window = min(max(window, 2*(t - post_t)), 5)
            if time.time() - t < window:
                continue
            results = await run_blocking(
                analysis.get_udf_results,
                udf_results=udf_results,
                roi=roi,
            )
            post_t = time.time()
            await self.send_results(results, uuid)
            # The broadcast might have taken quite some time due to
            # backpressure from the network
            t = time.time()

        if self.data.job_is_cancelled(uuid):
            raise JobCancelledError()
        results = await run_blocking(
            analysis.get_udf_results,
            udf_results=udf_results,
            roi=roi,
        )
        await self.send_results(results, uuid, finished=True)
Example #6
0
    async def run_job(self, uuid, ds, analysis):
        job = analysis.get_job()
        full_result = job.get_result_buffer()

        self.data.register_job(uuid=uuid, job=job, dataset=job.dataset)
        executor = self.data.get_executor()
        msg = Message(self.data).start_job(
            job_id=uuid,
        )
        log_message(msg)
        self.write(msg)
        self.finish()
        self.event_registry.broadcast_event(msg)

        t = time.time()
        post_t = time.time()
        window = 0.3
        async for result in executor.run_job(job, cancel_id=uuid):
            for tile in result:
                tile.reduce_into_result(full_result)
            window = min(max(window, 2*(t - post_t)), 5)
            if time.time() - t < window:
                continue
            post_t = time.time()

            results = await run_blocking(
                analysis.get_results,
                job_results=full_result,
            )

            await self.send_results(results, uuid)
            # The broadcast might have taken quite some time due to
            # backpressure from the network
            t = time.time()

        if self.data.job_is_cancelled(uuid):
            raise JobCancelledError()
        results = await run_blocking(
            analysis.get_results,
            job_results=full_result,
        )
        await self.send_results(results, uuid, finished=True)
Example #7
0
    async def controller(self, cancel_id, executor, job_is_cancelled, send_results):

        roi, sd_udf_results = await self.get_sd_results(executor, cancel_id, job_is_cancelled)
        udf = self.get_cluster_udf(sd_udf_results)

        result_iter = UDFRunner([udf]).run_for_dataset_async(
            self.dataset, executor, cancel_id=cancel_id
        )
        async for (udf_results,) in result_iter:
            pass

        if job_is_cancelled():
            raise JobCancelledError()

        results = await run_blocking(
            self.get_udf_results,
            udf_results=udf_results,
            roi=roi,
        )
        await send_results(results, True)
Example #8
0
    async def controller(self, cancel_id, executor, job_is_cancelled,
                         send_results):
        stddev_udf = StdDevUDF()

        roi = self.get_sd_roi()

        result_iter = UDFRunner(stddev_udf).run_for_dataset_async(
            self.dataset, executor, roi=roi, cancel_id=cancel_id)
        async for sd_udf_results in result_iter:
            pass

        if job_is_cancelled():
            raise JobCancelledError()

        sd_udf_results['var'].data
        sd_udf_results['num_frame'].data

        sd_udf_results = dict(sd_udf_results.items())
        sd_udf_results['var'] = sd_udf_results['var'].data / sd_udf_results[
            'num_frame'].data
        sd_udf_results['std'] = np.sqrt(sd_udf_results['var'].data)
        sd_udf_results['mean'] = sd_udf_results[
            'sum_frame'].data / sd_udf_results['num_frame'].data
        sd_udf_results['num_frame'] = sd_udf_results['num_frame'].data
        sd_udf_results['sum_frame'] = sd_udf_results['sum_frame'].data

        center = (self.parameters["cy"], self.parameters["cx"])
        rad_in = self.parameters["ri"]
        rad_out = self.parameters["ro"]
        delta = self.parameters["delta"]
        n_peaks = self.parameters["n_peaks"]
        min_dist = self.parameters["min_dist"]
        savg = sd_udf_results['mean']
        sstd = sd_udf_results['std']
        sshape = sstd.shape
        if not (center is None or rad_in is None or rad_out is None):
            mask_out = 1 * _make_circular_mask(center[1], center[0], sshape[1],
                                               sshape[0], rad_out)
            mask_in = 1 * _make_circular_mask(center[1], center[0], sshape[1],
                                              sshape[0], rad_in)
            mask = mask_out - mask_in
            masked_sstd = sstd * mask
        else:
            masked_sstd = sstd

        coordinates = peak_local_max(masked_sstd,
                                     num_peaks=n_peaks,
                                     min_distance=min_dist)

        udf = feature.FeatureVecMakerUDF(delta=delta,
                                         savg=savg,
                                         coordinates=coordinates)

        result_iter = UDFRunner(udf).run_for_dataset_async(self.dataset,
                                                           executor,
                                                           cancel_id=cancel_id)
        async for udf_results in result_iter:
            pass

        if job_is_cancelled():
            raise JobCancelledError()

        results = await run_blocking(
            self.get_udf_results,
            udf_results=udf_results,
            roi=roi,
        )
        await send_results(results, True)
Example #9
0
    async def controller(self, cancel_id, executor, job_is_cancelled,
                         send_results):
        stddev_udf = StdDevUDF()

        roi = self.get_sd_roi()

        result_iter = UDFRunner(stddev_udf).run_for_dataset_async(
            self.dataset, executor, roi=roi, cancel_id=cancel_id)
        async for sd_udf_results in result_iter:
            pass

        if job_is_cancelled():
            raise JobCancelledError()

        sd_udf_results = consolidate_result(sd_udf_results)

        center = (self.parameters["cy"], self.parameters["cx"])
        rad_in = self.parameters["ri"]
        rad_out = self.parameters["ro"]
        n_peaks = self.parameters["n_peaks"]
        min_dist = self.parameters["min_dist"]
        sstd = sd_udf_results['std']
        sshape = sstd.shape
        if not (center is None or rad_in is None or rad_out is None):
            mask_out = 1 * _make_circular_mask(center[1], center[0], sshape[1],
                                               sshape[0], rad_out)
            mask_in = 1 * _make_circular_mask(center[1], center[0], sshape[1],
                                              sshape[0], rad_in)
            mask = mask_out - mask_in
            masked_sstd = sstd * mask
        else:
            masked_sstd = sstd

        coordinates = peak_local_max(masked_sstd,
                                     num_peaks=n_peaks,
                                     min_distance=min_dist)

        y = coordinates[..., 0]
        x = coordinates[..., 1]
        z = range(len(y))

        mask = sparse.COO(shape=(len(y), ) + tuple(self.dataset.shape.sig),
                          coords=(z, y, x),
                          data=1)

        udf = ApplyMasksUDF(mask_factories=lambda: mask,
                            mask_count=len(y),
                            mask_dtype=np.uint8,
                            use_sparse=True)

        result_iter = UDFRunner(udf).run_for_dataset_async(self.dataset,
                                                           executor,
                                                           cancel_id=cancel_id)
        async for udf_results in result_iter:
            pass

        if job_is_cancelled():
            raise JobCancelledError()

        results = await run_blocking(
            self.get_udf_results,
            udf_results=udf_results,
            roi=roi,
        )
        await send_results(results, True)