Example #1
0
    def to_dict(self, user, shallow=False):
        """
        Serialisation to JSON for Episodes
        """
        d = {
            'id'               : self.id,
            'category'         : self.category,
            'active'           : self.active,
            'date_of_admission': self.date_of_admission,
            'date_of_episode'  : self.date_of_episode,
            'discharge_date'   : self.discharge_date,
            'consistency_token': self.consistency_token
            }
        if shallow:
            return d

        for model in patient_subrecords():
            subrecords = model.objects.filter(patient_id=self.patient.id)
            d[model.get_api_name()] = [subrecord.to_dict(user)
                                       for subrecord in subrecords]
        for model in episode_subrecords():
            subrecords = model.objects.filter(episode_id=self.id)
            d[model.get_api_name()] = [subrecord.to_dict(user)
                                       for subrecord in subrecords]

        d['tagging'] = self.tagging_dict(user)

        d['episode_history'] = self._episode_history_to_dict(user)
        return d
Example #2
0
File: models.py Project: wjt/opal
    def to_dict(self, user, shallow=False):
        """
        Serialisation to JSON for Episodes
        """
        d = {
            'id': self.id,
            'category': self.category,
            'active': self.active,
            'date_of_admission': self.date_of_admission,
            'date_of_episode': self.date_of_episode,
            'discharge_date': self.discharge_date,
            'consistency_token': self.consistency_token
        }
        if shallow:
            return d

        for model in patient_subrecords():
            subrecords = model.objects.filter(patient_id=self.patient.id)
            d[model.get_api_name()] = [
                subrecord.to_dict(user) for subrecord in subrecords
            ]
        for model in episode_subrecords():
            subrecords = model.objects.filter(episode_id=self.id)
            d[model.get_api_name()] = [
                subrecord.to_dict(user) for subrecord in subrecords
            ]

        d['tagging'] = self.tagging_dict(user)

        d['episode_history'] = self._episode_history_to_dict(user)
        return d
Example #3
0
File: models.py Project: wjt/opal
    def to_dict(self, user, shallow=False):
        """
        Serialisation to JSON for Episodes
        """
        d = {
            "id": self.id,
            "category": self.category,
            "active": self.active,
            "date_of_admission": self.date_of_admission,
            "date_of_episode": self.date_of_episode,
            "discharge_date": self.discharge_date,
            "consistency_token": self.consistency_token,
        }
        if shallow:
            return d

        for model in patient_subrecords():
            subrecords = model.objects.filter(patient_id=self.patient.id)
            d[model.get_api_name()] = [subrecord.to_dict(user) for subrecord in subrecords]
        for model in episode_subrecords():
            subrecords = model.objects.filter(episode_id=self.id)
            d[model.get_api_name()] = [subrecord.to_dict(user) for subrecord in subrecords]

        d["tagging"] = self.tagging_dict(user)

        d["episode_history"] = self._episode_history_to_dict(user)
        return d
Example #4
0
    def serialised_episode_subrecords(self, episodes, user):
        """
        Return all serialised subrecords for this set of EPISODES
        in a nested hashtable where the outer key is the episode id,
        the inner key the subrecord API name.
        """
        episode_subs = defaultdict(dict)
        episode_ids = [e.id for e in episodes]

        for model in episode_subrecords():
            name = model.get_api_name()

            # Ensure there is an empty list for serialisation
            for episode_id in episode_ids:
                episode_subs[episode_id][name] = []

            subrecords = prefetch(
                model.objects.filter(episode__in=episodes)
            )

            for related in model._meta.many_to_many:
                subrecords = subrecords.prefetch_related(related.attname)

            for sub in subrecords:
                episode_subs[sub.episode_id][name].append(sub.to_dict(user))

        return episode_subs
Example #5
0
    def to_dict(self, user, shallow=False):
        """
        Serialisation to JSON for Episodes
        """
        d = {
            'id'               : self.id,
            'category_name'    : self.category_name,
            'active'           : self.active,
            'consistency_token': self.consistency_token,
            'start'            : self.start,
            'end'              : self.end,
            'stage'            : self.stage,
        }

        if shallow:
            return d

        for model in patient_subrecords():
            subrecords = model.objects.filter(patient_id=self.patient.id)

            d[model.get_api_name()] = [
                subrecord.to_dict(user) for subrecord in subrecords
            ]

        for model in episode_subrecords():
            subrecords = model.objects.filter(episode_id=self.id)

            d[model.get_api_name()] = [
                subrecord.to_dict(user) for subrecord in subrecords
            ]

        d['tagging'] = self.tagging_dict(user)
        return d
Example #6
0
 def save(self, *args, **kwargs):
     created = not bool(self.id)
     super(Episode, self).save(*args, **kwargs)
     if created:
         for subclass in episode_subrecords():
             if subclass._is_singleton:
                 subclass.objects.create(episode=self)
Example #7
0
    def save(self, *args, **kwargs):
        created = not bool(self.id)

        current_active_value = self.active
        category_active_value = self.category.is_active()

        if current_active_value != category_active_value:  # Disagreement
            if current_active_value != self.__original_active:
                # The value of self.active has been set by some code somewhere
                # not by __init__() e.g. the original database value at the
                # time of instance initalization.
                #
                # Rather than overriding this silently we should raise a
                # ValueError.
                msg = "Value of Episode.active has been set to {} but " \
                      "category.is_active() returns {}"
                raise ValueError(
                    msg.format(current_active_value, category_active_value)
                )

        self.active = category_active_value
        super(Episode, self).save(*args, **kwargs)

        # Re-set this in case we changed it once post initialization and then
        # the user subsequently saves this instance again
        self.__original_active = self.active

        if created:
            for subclass in episode_subrecords():
                if subclass._is_singleton:
                    subclass.objects.create(episode=self)
Example #8
0
    def make(self):
        sexes = ['Female', 'Male', 'Not Known', 'Not Specified']

        patient = models.Patient.objects.create()
        demographics = patient.demographics_set.get()
        hospital_number = random.randint(1000, 2000000)
        hospital_number = str(hospital_number)
        demographics.name = self.get_name()
        demographics.hospital_number = hospital_number
        demographics.nhs_number = hospital_number
        demographics.date_of_birth = self.get_birth_date()
        demographics.sex = random.choice(sexes)
        demographics.birth_place = foreign_key_or_free_text_generator(
            Demographics.birth_place)
        demographics.save()

        self.create_episode(patient)

        for subrecord in episode_subrecords():
            s = EpisodeSubrecordGenerator(subrecord,
                                          patient.episode_set.first())
            s.make()

        for subrecord in patient_subrecords():
            # we've already made the demographics above
            if subrecord.__name__ != "Demographics":
                s = PatientSubrecordGenerator(subrecord, patient)
                s.make()

        return patient
Example #9
0
    def make(self):
        sexes = ['Female', 'Male', 'Not Known', 'Not Specified']

        patient                      = models.Patient.objects.create()
        demographics                 = patient.demographics_set.get()
        hospital_number              = random.randint(1000, 2000000)
        hospital_number              = str(hospital_number)
        demographics.first_name      = random.choice(first_names)
        demographics.surname         = random.choice(last_names)
        demographics.hospital_number = hospital_number
        demographics.nhs_number      = hospital_number
        demographics.date_of_birth   = self.get_birth_date()
        demographics.sex             = random.choice(sexes)
        demographics.birth_place     = foreign_key_or_free_text_generator(
            Demographics.birth_place
        )
        demographics.save()

        self.create_episode(patient)

        for subrecord in episode_subrecords():
            s = EpisodeSubrecordGenerator(
                subrecord, patient.episode_set.first()
            )
            s.make()

        for subrecord in patient_subrecords():
            # we've already made the demographics above
            if subrecord.__name__ != "Demographics":
                s = PatientSubrecordGenerator(subrecord, patient)
                s.make()

        return patient
Example #10
0
    def serialised_episode_subrecords(self, episodes, user):
        """
        Return all serialised subrecords for this set of EPISODES
        in a nested hashtable where the outer key is the episode id,
        the inner key the subrecord API name.
        """
        episode_subs = defaultdict(dict)
        episode_ids = [e.id for e in episodes]

        for model in episode_subrecords():
            name = model.get_api_name()

            # Ensure there is an empty list for serialisation
            for episode_id in episode_ids:
                episode_subs[episode_id][name] = []

            subrecords = prefetch(model.objects.filter(episode__in=episodes))

            for related in model._meta.many_to_many:
                subrecords = subrecords.prefetch_related(related.attname)

            for sub in subrecords:
                episode_subs[sub.episode_id][name].append(sub.to_dict(user))

        return episode_subs
Example #11
0
File: models.py Project: wjt/opal
 def save(self, *args, **kwargs):
     created = not bool(self.id)
     super(Episode, self).save(*args, **kwargs)
     if created:
         for subclass in episode_subrecords():
             if subclass._is_singleton:
                 subclass.objects.create(episode=self)
Example #12
0
def generate_csv_files(root_dir, episodes, user):
    """ Generate the files and return a tuple of absolute_file_name, file_name
    """
    file_names = []

    file_name = "data_dictionary.html"
    full_file_name = os.path.join(root_dir, file_name)
    write_data_dictionary(full_file_name)
    file_names.append((full_file_name, file_name,))

    file_name = "episodes.csv"
    full_file_name = os.path.join(root_dir, file_name)
    renderer = EpisodeCsvRenderer(Episode, episodes, user)
    renderer.write_to_file(full_file_name)
    file_names.append((full_file_name, file_name,))

    for subrecord in subrecords():
        if getattr(subrecord, '_exclude_from_extract', False):
            continue
        file_name = '{0}.csv'.format(subrecord.get_api_name())
        full_file_name = os.path.join(root_dir, file_name)
        if subrecord in episode_subrecords():
            renderer = EpisodeSubrecordCsvRenderer(
                subrecord, episodes, user
            )
        else:
            renderer = PatientSubrecordCsvRenderer(
                subrecord, episodes, user
            )
        if renderer.count():
            renderer.write_to_file(full_file_name)
            file_names.append((full_file_name, file_name,))

    return file_names
Example #13
0
    def handle(self, *args, **options):
        logging.info("Creating Singletons")

        for subclass in patient_subrecords():
            if subclass._is_singleton:
                to_create = []
                related_name = subclass.__name__.lower()
                patients_to_be_updated = Patient.objects.filter(
                    **{related_name: None})
                for patient in patients_to_be_updated:
                    logging.info('Creating {0}'.format(subclass))
                    to_create.append(subclass(patient=patient))
                subclass.objects.bulk_create(to_create)

        for subclass in episode_subrecords():
            if subclass._is_singleton:
                to_create = []
                related_name = subclass.__name__.lower()
                episodes_to_be_updated = Episode.objects.filter(
                    **{related_name: None})
                for episode in episodes_to_be_updated:
                    logging.info('Creating {0}'.format(subclass))
                    to_create.append(subclass(episode=episode))
                subclass.objects.bulk_create(to_create)

        return
Example #14
0
    def bulk_update(self, dict_of_list_of_upgrades, user,
                    episode=None, force=False):
        """
                takes in a dictionary of api name to a list of fields and
                creates the required subrecords. If passed an episode
                sub record but no episode it will create an episode
                and attatch it.

                e.g. {"allergies": [
                            {"drug": "paracetomol"}
                            {"drug": "aspirin"}
                          ],
                      "diagnosis":[
                            {
                                "condition": "some test",
                                "details": "some details"
                            }
                          ]
                     }
        """
        if "demographics" not in dict_of_list_of_upgrades:
            if not self.id:
                dict_of_list_of_upgrades["demographics"] = [{}]

        if not self.id:
            self.save()

        #
        # We never want to be in the position where we don't have an episode.
        # If this patient has never had an episode, we create one now.
        # If the patient has preexisting episodes, we will either use an
        # episode passed in to us as a kwarg, or create a fresh episode for
        # this bulk update once we're sure we have episode subrecord data to
        # save.
        #
        if not self.episode_set.exists():
            episode = self.create_episode()

        for api_name, list_of_upgrades in dict_of_list_of_upgrades.items():

            if(api_name == "tagging"):
                episode.set_tag_names_from_tagging_dict(
                    list_of_upgrades[0], user
                )
                continue

            model = get_subrecord_from_api_name(api_name=api_name)
            if model in episode_subrecords():
                if episode is None:
                    episode = self.create_episode()
                    episode.save()

                model.bulk_update_from_dicts(episode, list_of_upgrades, user,
                                             force=force)
            else:
                # it's a patient subrecord
                model.bulk_update_from_dicts(self, list_of_upgrades, user,
                                             force=force)
Example #15
0
def get_subrecord_use(subrecord, episode_qs):
    """
    Get's all populated subrecords in an episode_qs.
    For singletons, populated means they have an updated flag
    """
    is_episode_subrecord = subrecord in subrecords.episode_subrecords()
    if subrecord._is_singleton:
        populated = subrecord.objects.exclude(updated=None)
    else:
        populated = subrecord.objects.all()

    if is_episode_subrecord:
        return populated.filter(episode__in=episode_qs).distinct()
    else:
        return populated.filter(patient__episode__in=episode_qs).distinct()
Example #16
0
    def post(self, request, pk=None, category=None, **kwargs):
        old = models.Episode.objects.get(pk=pk)
        new = models.Episode(patient=old.patient,
                             category_name=category,
                             date_of_admission=old.date_of_admission)
        new.save()

        for sub in episode_subrecords():
            if sub._is_singleton or not sub._clonable:
                continue
            for item in sub.objects.filter(episode=old):
                item.id = None
                item.episode = new
                item.save()
        serialised = new.to_dict(self.request.user)
        return _build_json_response(serialised)
Example #17
0
 def post(self, args, pk=None, category=None, **kwargs):
     old = models.Episode.objects.get(pk=pk)
     new = models.Episode(patient=old.patient,
                          category=category,
                          date_of_admission=old.date_of_admission)
     new.save()
     for sub in episode_subrecords():
         if sub._is_singleton:
             continue
         for item in sub.objects.filter(episode=old):
             item.id = None
             item.episode = new
             item.save()
     serialised = new.to_dict(self.request.user)
     glossolalia.admit(serialised)
     return _build_json_response(serialised)
Example #18
0
def get_probability_an_episode_uses_a_subrecord(subrecord_qs, episode_qs):
    """
    Given an episode queryset and a subrecord queryset,
    give me the probability that a given episode has a given subrecord.

    (some episodes could have more than one subrecord)
    """
    subrecord = subrecord_qs.model
    is_episode_subrecord = subrecord in subrecords.episode_subrecords()
    if is_episode_subrecord:
        id_count = subrecord_qs.values_list("episode_id",
                                            flat=True).distinct().count()
    else:
        id_count = subrecord_qs.values_list("patient__episode",
                                            flat=True).distinct().count()
    return round(Decimal(id_count) / episode_qs.count() * 100, 2)
Example #19
0
    def post(self, request, pk=None, category=None, **kwargs):
        old = models.Episode.objects.get(pk=pk)
        new = models.Episode(patient=old.patient,
                             category_name=category,
                             start=old.start)
        new.save()

        for sub in episode_subrecords():
            if sub._is_singleton or not sub._clonable:
                continue
            for item in sub.objects.filter(episode=old):
                item.id = None
                item.episode = new
                item.save()
        serialised = new.to_dict(self.request.user)
        return json_response(serialised)
Example #20
0
    def handle(self, *args, **options):
        logging.info("Creating Singletons")

        for patient in Patient.objects.all():
            logging.info('Examining {0}'.format(patient))
            for subclass in patient_subrecords():
                if subclass._is_singleton:
                    if subclass.objects.filter(patient=patient).count() == 0:
                        logging.info('Creating {0}'.format(subclass))
                        subclass.objects.create(patient=patient)

        for episode in Episode.objects.all():
            logging.info('Examining {0}'.format(episode))
            for subclass in episode_subrecords():
                if subclass._is_singleton:
                    if subclass.objects.filter(episode=episode).count() == 0:
                        logging.info('Creating {0}'.format(subclass))
                        subclass.objects.create(episode=episode)
        return
Example #21
0
def zip_archive(episodes, description, user):
    """
    Given an iterable of EPISODES, the DESCRIPTION of this set of episodes,
    and the USER for which we are extracting, create a zip archive suitable
    for download with all of these episodes as CSVs.
    """
    target_dir = tempfile.mkdtemp()
    target = os.path.join(target_dir, 'extract.zip')

    with zipfile.ZipFile(target, mode='w') as z:
        zipfolder = '{0}.{1}'.format(user.username, datetime.date.today())
        os.mkdir(os.path.join(target_dir, zipfolder))
        make_file_path = functools.partial(os.path.join, target_dir, zipfolder)
        zip_relative_file_path = functools.partial(os.path.join, zipfolder)

        file_name = "episodes.csv"
        full_file_name = make_file_path(file_name)
        episode_csv(episodes, user, full_file_name)
        z.write(full_file_name, zip_relative_file_path(file_name))

        for subrecord in episode_subrecords():
            if getattr(subrecord, '_exclude_from_extract', False):
                continue
            file_name = '{0}.csv'.format(subrecord.get_api_name())
            full_file_name = make_file_path(file_name)
            subrecord_csv(episodes, subrecord, full_file_name)
            z.write(full_file_name, zip_relative_file_path(file_name))

        for subrecord in patient_subrecords():
            if getattr(subrecord, '_exclude_from_extract', False):
                continue
            file_name = '{0}.csv'.format(subrecord.get_api_name())
            full_file_name = make_file_path(file_name)
            patient_subrecord_csv(episodes, subrecord, full_file_name)
            z.write(full_file_name, zip_relative_file_path(file_name))

        file_name = 'filter.txt'
        full_file_name = make_file_path(file_name)
        with open(full_file_name, 'w') as description_file:
            description_file.write(description)
        z.write(full_file_name, zip_relative_file_path(file_name))

    return target
Example #22
0
    def handle(self, *args, **options):
        print "Creating Singletons"

        for patient in Patient.objects.all():
            print 'Examining', patient
            for subclass in patient_subrecords():
                if subclass._is_singleton:
                    if subclass.objects.filter(patient=patient).count() == 0:
                        print 'Creating', subclass
                        subclass.objects.create(patient=patient)
                        
        for episode in Episode.objects.all():
            print 'Examining', episode
            for subclass in episode_subrecords():
                if subclass._is_singleton:
                    if subclass.objects.filter(episode=episode).count() == 0:
                        print 'Creating', subclass
                        subclass.objects.create(episode=episode)
        return
Example #23
0
def zip_archive(episodes, description, user):
    """
    Given an iterable of EPISODES, the DESCRIPTION of this set of episodes,
    and the USER for which we are extracting, create a zip archive suitable
    for download with all of these episodes as CSVs.
    """
    target_dir = tempfile.mkdtemp()
    target = os.path.join(target_dir, 'extract.zip')

    with zipfile.ZipFile(target, mode='w') as z:
        zipfolder = '{0}.{1}'.format(user.username, datetime.date.today())
        os.mkdir(os.path.join(target_dir, zipfolder))
        make_file_path = functools.partial(os.path.join, target_dir, zipfolder)
        zip_relative_file_path = functools.partial(os.path.join, zipfolder)

        file_name = "episodes.csv"
        full_file_name = make_file_path(file_name)
        episode_csv(episodes, user, full_file_name)
        z.write(full_file_name, zip_relative_file_path(file_name))

        for subrecord in episode_subrecords():
            file_name = '{0}.csv'.format(subrecord.get_api_name())
            full_file_name = make_file_path(file_name)
            subrecord_csv(episodes, subrecord, full_file_name)
            z.write(full_file_name, zip_relative_file_path(file_name))

        for subrecord in patient_subrecords():
            file_name = '{0}.csv'.format(subrecord.get_api_name())
            full_file_name = make_file_path(file_name)
            patient_subrecord_csv(episodes, subrecord, full_file_name)
            z.write(full_file_name, zip_relative_file_path(file_name))

        file_name = 'filter.txt'
        full_file_name = make_file_path(file_name)
        with open(full_file_name, 'w') as description_file:
            description_file.write(description)
        z.write(full_file_name, zip_relative_file_path(file_name))

    return target
Example #24
0
 def test_get_episode_subrecords(self):
     episode_subrecords = [i for i in subrecords.episode_subrecords()]
     self.assertNotIn(FamousLastWords, episode_subrecords)
     self.assertIn(HatWearer, episode_subrecords)
Example #25
0
 def setUp(self):
     super(EpisodeSubrecordsTestCase, self).setUp()
     self.episode_subrecords = {i for i in subrecords.episode_subrecords()}
Example #26
0
class OptionAdmin(admin.ModelAdmin):
    form = LookupListForm
    ordering = ['name']
    search_fields = ['name']
    inlines = [SynonymInline]


for model in lookuplists():
    admin.site.register(model, OptionAdmin)

admin.site.register(User, UserProfileAdmin)
admin.site.register(models.Patient, PatientAdmin)
admin.site.register(models.Episode, EpisodeAdmin)
admin.site.register(models.Tagging, TaggingAdmin)


for subclass in patient_subrecords():
    if not subclass._meta.abstract and not getattr(
            subclass, "_no_admin", False):
        admin.site.register(subclass, PatientSubrecordAdmin)

for subclass in episode_subrecords():
    if not subclass._meta.abstract and not getattr(
            subclass, "_no_admin", False):
        admin.site.register(subclass, EpisodeSubrecordAdmin)

admin.site.register(models.ContactNumber, MyAdmin)
admin.site.register(models.Role, MyAdmin)
admin.site.register(models.Macro, MyAdmin)
Example #27
0
 def setUp(self):
     super(EpisodeSubrecordsTestCase, self).setUp()
     self.episode_subrecords = {i for i in subrecords.episode_subrecords()}
Example #28
0
 def test_episode_subrecords(self, zipfile):
     extract.zip_archive(models.Episode.objects.all(), 'this', self.user)
     expected = len([i for i in subrecords.episode_subrecords()]) + 7
     self.assertEqual(
         expected, zipfile.ZipFile.return_value.__enter__.return_value.
         write.call_count)
Example #29
0

class OptionAdmin(admin.ModelAdmin):
    form = LookupListForm
    ordering = ['name']
    search_fields = ['name']
    inlines = [SynonymInline]


for model in lookuplists():
    admin.site.register(model, OptionAdmin)

admin.site.register(User, UserProfileAdmin)
admin.site.register(models.Patient, PatientAdmin)
admin.site.register(models.Episode, EpisodeAdmin)
admin.site.register(models.Tagging, TaggingAdmin)

for subclass in patient_subrecords():
    if not subclass._meta.abstract and not getattr(subclass, "_no_admin",
                                                   False):
        admin.site.register(subclass, PatientSubrecordAdmin)

for subclass in episode_subrecords():
    if not subclass._meta.abstract and not getattr(subclass, "_no_admin",
                                                   False):
        admin.site.register(subclass, EpisodeSubrecordAdmin)

admin.site.register(models.ContactNumber, MyAdmin)
admin.site.register(models.Role, MyAdmin)
admin.site.register(models.Macro, MyAdmin)