Example #1
0
def update_frame_error_result_metric_properties():
    # Start by finding the image source ids
    start_time = time.time()
    logging.getLogger(__name__).info(
        "Updating 'metric_properties' for all FrameErrorResult objects ...")
    logging.getLogger(__name__).info("Loading set of referenced metric IDs...")
    metric_ids = FrameErrorResult._mongometa.collection.distinct('metric')

    # Autoload the image source type
    logging.getLogger(__name__).info(
        f"Autoloading metric types ({time.time() - start_time}s) ...")
    autoload_modules(Metric, ids=metric_ids)

    logging.getLogger(__name__).info(
        f"Found {len(metric_ids)} metrics, updating information "
        f"({time.time() - start_time}s) ...")
    n_updated = 0
    for metric_id in metric_ids:
        metric = Metric.objects.get({'_id': metric_id})
        metric_properties = metric.get_properties()
        n_updated += FrameErrorResult.objects.raw({
            'metric': metric_id
        }).update(
            {
                '$set': {
                    'metric_properties': {
                        str(k): json_value(v)
                        for k, v in metric_properties.items()
                    }
                }
            },
            upsert=False)
    logging.getLogger(__name__).info(
        f"Updated {n_updated} FrameErrorResult objects in {time.time() - start_time}s "
    )
Example #2
0
def update_frame_error_image_information(only_missing: bool = False,
                                         batch_size: int = 5000):
    """
    Update the image_properties field on the image
    :return:
    """
    # Find the ids
    start_time = time.time()
    logging.getLogger(__name__).info(
        "Updating 'image_properties' for all FrameError objects ...")
    logging.getLogger(__name__).info("Loading set of referenced image IDs...")
    if only_missing:
        frame_errors = FrameError.objects.raw({
            'image_properties': {
                '$exists': False
            }
        }).only('image').values()
    else:
        frame_errors = FrameError.objects.all().only('image').values()

    # Do the distinct, rather than hold a cursor through all the loops
    # We expect this set to be about 1GB
    image_ids = set(error_obj['image'] for error_obj in frame_errors)

    # Work out how many batches to do. Images will be loaded in a batch to create a single bulk_write
    logging.getLogger(__name__).info(
        f"Found {len(image_ids)} image ids, "
        f"updating information {batch_size} images at a time "
        f"({time.time() - start_time}s) ...")
    n_updated = 0
    updates_sent = 0
    for batch_ids in grouper(image_ids, batch_size):
        # For each image, update all frame error objects that link to it
        images = Image.objects.raw({'_id': {'$in': batch_ids}})
        write_operations = [
            UpdateMany({'image': image.pk}, {
                '$set': {
                    'image_properties': {
                        str(k): json_value(v)
                        for k, v in image.get_properties().items()
                    }
                }
            }) for image in images
        ]
        result = FrameError._mongometa.collection.bulk_write(write_operations,
                                                             ordered=False)
        n_updated += result.modified_count
        updates_sent += len(write_operations)
        logging.getLogger(__name__).info(
            f"Updates sent for {updates_sent} images, updating {n_updated} FrameErrors"
            f" in {time.time() - start_time}s ...")
    logging.getLogger(__name__).info(
        f"Updated {n_updated} FrameError objects in {time.time() - start_time}s "
    )
Example #3
0
    def test_update_system_information(self):
        random = np.random.RandomState(13)
        system = SystemWithProperties(
            properties={'my_system_property': random.randint(10, 420)})
        system.save()
        metric = MockMetric()
        metric.save()
        image_collection = make_image_collection(10)
        trial_results = make_trials(system, image_collection, 3, random)

        trial_errors = []
        all_frame_errors = []
        for repeat_idx, trial_result in enumerate(trial_results):
            frame_errors = []
            for frame_result in trial_result.results:
                frame_error = FrameError(
                    trial_result=trial_result,
                    image=frame_result.image,
                    repeat=repeat_idx,
                    timestamp=frame_result.timestamp,
                    motion=frame_result.motion,
                    processing_time=frame_result.processing_time,
                    num_features=frame_result.num_features,
                    num_matches=frame_result.num_matches,
                    tracking=frame_result.tracking_state,
                    absolute_error=None,
                    relative_error=None,
                    noise=None)
                frame_error.save()
                frame_errors.append(frame_error)
                all_frame_errors.append(frame_error)
            trial_errors.append(TrialErrors(frame_errors=frame_errors))
        # Trial results are found based on the metric results, so we need to make that
        metric_result = make_frame_error_result(metric=metric,
                                                trial_results=trial_results,
                                                errors=trial_errors)
        metric_result.save()

        update_data.update_frame_errors_system_properties()

        # Check that the image properties have been updated
        for frame_error in all_frame_errors:
            frame_error.refresh_from_db()
            system_properties = frame_error.trial_result.system.get_properties(
                None, frame_error.trial_result.settings)
            # Convert the properties to a JSON serialisable value
            system_properties = {
                str(k): json_value(v)
                for k, v in system_properties.items()
            }
            self.assertEqual(system_properties, frame_error.system_properties)
Example #4
0
    def test_update_metric_properties(self):
        random = np.random.RandomState(13)
        system = MockSystem()
        system.save()
        metric = MetricWithProperties(properties={
            'metric_property_1': 'linear',
            'metric_property_2': 10
        })
        metric.save()
        image_collection = make_image_collection(10)
        trial_results = make_trials(system, image_collection, 3, random)

        trial_errors = []
        for repeat_idx, trial_result in enumerate(trial_results):
            frame_errors = []
            for frame_result in trial_result.results:
                frame_error = make_frame_error(trial_result=trial_result,
                                               frame_result=frame_result,
                                               image=None,
                                               system=None,
                                               repeat_index=repeat_idx,
                                               loop_distances=[],
                                               loop_angles=[],
                                               absolute_error=None,
                                               relative_error=None,
                                               systemic_error=None,
                                               noise=None)
                frame_error.save()
                frame_errors.append(frame_error)
            trial_errors.append(TrialErrors(frame_errors=frame_errors))
        metric_result = FrameErrorResult(
            metric=metric,
            trial_results=trial_results,
            system=system,
            image_source=image_collection,
            success=True,
            errors=trial_errors
            # Metric result is missing the metric properties
        )
        metric_result.save()

        update_data.update_frame_error_result_metric_properties()
        metric_result.refresh_from_db()

        metric_properties = metric.get_properties()
        metric_properties = {
            str(k): json_value(v)
            for k, v in metric_properties.items()
        }
        self.assertEqual(metric_properties, metric_result.metric_properties)
Example #5
0
def update_frame_errors_system_properties():
    # Start with the frame error result, which will tell us which trial results have been measured
    start_time = time.time()
    logging.getLogger(__name__).info(
        "Updating 'system_properties' for all FrameError objects ...")
    logging.getLogger(__name__).info("Getting set of trial result ids...")
    trial_result_ids = FrameErrorResult._mongometa.collection.distinct(
        'trial_results')

    # Get the unique system ids
    logging.getLogger(__name__).info(
        f"Getting set of system ids ({time.time() - start_time})...")
    system_ids = TrialResult._mongometa.collection.distinct('system')

    # Autoload the types for the trial and systems
    logging.getLogger(__name__).info(
        f"Autoloading types ({time.time() - start_time})...")
    autoload_modules(VisionSystem, ids=system_ids)
    autoload_modules(TrialResult, ids=trial_result_ids)

    # Get the set of system ids used in those trials
    logging.getLogger(__name__).info(
        f"Updating information from {len(trial_result_ids)} trials "
        f"over {len(system_ids)} systems...")
    n_updated = 0
    for system_id in system_ids:
        system = VisionSystem.objects.get({'_id': system_id})
        for trial_result in TrialResult.objects.raw({
                '_id': {
                    '$in': trial_result_ids
                },
                'system': system_id
        }).only('_id', 'settings'):
            system_properties = system.get_properties(None,
                                                      trial_result.settings)
            n_updated += FrameError.objects.raw({
                'trial_result': trial_result.pk
            }).update(
                {
                    '$set': {
                        'system_properties': {
                            str(k): json_value(v)
                            for k, v in system_properties.items()
                        }
                    }
                },
                upsert=False)  # We definitely don't want to upsert
    logging.getLogger(__name__).info(
        f"Updated {n_updated} FrameError objects in {time.time() - start_time}s "
    )
Example #6
0
    def test_update_image_information(self):
        random = np.random.RandomState(13)
        system = MockSystem()
        system.save()
        metric = MockMetric()
        metric.save()
        image_collection = make_image_collection(10)
        trial_results = make_trials(system, image_collection, 3, random)

        frame_errors = []
        for repeat_idx, trial_result in enumerate(trial_results):
            for frame_result in trial_result.results:
                frame_error = FrameError(
                    trial_result=trial_result,
                    image=frame_result.image,
                    repeat=repeat_idx,
                    timestamp=frame_result.timestamp,
                    motion=frame_result.motion,
                    processing_time=frame_result.processing_time,
                    num_features=frame_result.num_features,
                    num_matches=frame_result.num_matches,
                    tracking=frame_result.tracking_state,
                    absolute_error=None,
                    relative_error=None,
                    noise=None)
                frame_error.save()
                frame_errors.append(frame_error)

        update_data.update_frame_error_image_information(only_missing=False,
                                                         batch_size=5)

        # Check that the image properties have been updated
        for frame_error in frame_errors:
            frame_error.refresh_from_db()
            image_properties = frame_error.image.get_properties()
            # Convert the properties to a JSON serialisable value
            image_properties = {
                str(k): json_value(v)
                for k, v in image_properties.items()
            }
            self.assertEqual(image_properties, frame_error.image_properties)
Example #7
0
def update_frame_error_result_image_source_properties():
    # Start by finding the image source ids
    start_time = time.time()
    logging.getLogger(__name__).info(
        "Updating 'image_source_properties' for all FrameErrorResult objects ..."
    )
    logging.getLogger(__name__).info(
        "Loading set of referenced image source IDs...")
    image_source_ids = FrameErrorResult._mongometa.collection.distinct(
        'image_source')

    # Autoload the image source type
    logging.getLogger(__name__).info(
        f"Autoloading image source types ({time.time() - start_time}s) ...")
    autoload_modules(ImageSource, ids=image_source_ids)

    logging.getLogger(__name__).info(
        f"Found {len(image_source_ids)} image sources, updating information "
        f"({time.time() - start_time}s) ...")
    n_updated = 0
    for image_source_id in image_source_ids:
        image_source = ImageSource.objects.get({'_id': image_source_id})
        image_source_properties = image_source.get_properties()
        n_updated += FrameErrorResult.objects.raw({
            'image_source':
            image_source_id
        }).update(
            {
                '$set': {
                    'image_source_properties': {
                        str(k): json_value(v)
                        for k, v in image_source_properties.items()
                    }
                }
            },
            upsert=False)
    logging.getLogger(__name__).info(
        f"Updated {n_updated} FrameErrorResult objects in {time.time() - start_time}s "
    )
Example #8
0
    def test_update_image_information_only_missing(self):
        random = np.random.RandomState(13)
        system = MockSystem()
        system.save()
        metric = MockMetric()
        metric.save()
        image_collection = make_image_collection(10)
        trial_results = make_trials(system, image_collection, 3, random)

        non_updated_ids = set()
        frame_errors = []
        for repeat_idx, trial_result in enumerate(trial_results):
            for frame_idx, frame_result in enumerate(trial_result.results):
                frame_error = FrameError(
                    trial_result=trial_result,
                    image=frame_result.image,
                    repeat=repeat_idx,
                    timestamp=frame_result.timestamp,
                    motion=frame_result.motion,
                    processing_time=frame_result.processing_time,
                    num_features=frame_result.num_features,
                    num_matches=frame_result.num_matches,
                    tracking=frame_result.tracking_state,
                    absolute_error=None,
                    relative_error=None,
                    noise=None)
                if int(frame_idx) % 4 == 3:
                    # These properties should remain
                    frame_error.image_properties = {
                        'default_property_1': 1.2,
                        'default_property_2': str(frame_result.image.pk)
                    }
                    non_updated_ids.add(frame_result.image.pk)
                elif int(frame_error.repeat + frame_error.timestamp) % 4 == 0:
                    # These ones should be overriden because there will be at least one other
                    # frame error that is missing these properties, and we update them all at once
                    frame_error.image_properties = {
                        'overwritten_property_1': 3.2,
                        'overwritten_property_2': str(frame_result.image.pk)
                    }
                frame_error.save()
                frame_errors.append(frame_error)

        update_data.update_frame_error_image_information(only_missing=True)

        # Check that the image properties have been updated
        for frame_error in frame_errors:
            frame_error.refresh_from_db()
            image_properties = frame_error.image.get_properties()
            # Convert the properties to a JSON serialisable value
            image_properties = {
                str(k): json_value(v)
                for k, v in image_properties.items()
            }
            if frame_error.image.pk in non_updated_ids:
                self.assertEqual(
                    {
                        'default_property_1': 1.2,
                        'default_property_2': str(frame_error.image.pk)
                    }, frame_error.image_properties)
            else:
                self.assertEqual(image_properties,
                                 frame_error.image_properties)