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
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
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
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
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
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)
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)
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
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
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
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
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
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)
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()
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)
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)
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)
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)
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
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
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
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
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)
def setUp(self): super(EpisodeSubrecordsTestCase, self).setUp() self.episode_subrecords = {i for i in subrecords.episode_subrecords()}
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)
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)
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)