class Aliquots(models.Model): id_explant = models.ForeignKey(Explant_details, null=True, blank=True, db_column='id_explant') idType = models.ForeignKey(TissueType, blank=True, null=True, db_column='idType') id_genealogy = models.CharField(max_length=45, unique=True) history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) class Meta: verbose_name_plural = 'aliquots' db_table = 'aliquots' def __unicode__(self): return self.id_genealogy def save(self, *args, **kwargs): from django_transaction_signals import defer if settings.USE_GRAPH_DB == True and 'admin' not in get_WG(): if self.pk is not None: print "non inserisco nodo, gia' presente" else: print self if self.id_genealogy is not None and self.id_explant is not None and self.pk is None: print "salvo aliquota da espianto nel grafo" defer(add_aliquot_node, self) super(Aliquots, self).save(*args, **kwargs) else: super(Aliquots, self).save(*args, **kwargs)
class Container(models.Model): idContainerType = models.ForeignKey(ContainerType, db_column='idContainerType', verbose_name='Container Type') idFatherContainer = models.ForeignKey('self', db_column='idFatherContainer', verbose_name='Father Container', null=True, blank=True) idGeometry = models.ForeignKey(Geometry, db_column='idGeometry', verbose_name='Geometry', null=True, blank=True) position = models.CharField(max_length=10, null=True, blank=True) barcode = models.CharField(max_length=45, unique=True) availability = models.BooleanField() full = models.BooleanField(default=False) owner = models.CharField(max_length=45, null=True, blank=True) present = models.BooleanField(default=True) oneUse = models.BooleanField() history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) class Meta: verbose_name_plural = 'container' db_table = 'container' def __unicode__(self): return self.barcode
class BioMice(models.Model): objects = WgObjectManager() phys_mouse_id = models.ForeignKey(Mice, blank=True, db_column='phys_mice_id') id_genealogy = models.CharField(max_length=45, null=True) id_group = models.ForeignKey(Groups, db_column='id_group', null=True, blank=True) notes = models.CharField(max_length=45, blank=True, null=True) history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) class Meta: verbose_name_plural = 'bio_mice' db_table = 'bio_mice' def __unicode__(self): return self.id_genealogy def save(self, *args, **kwargs): from django_transaction_signals import defer if settings.USE_GRAPH_DB == True and 'admin' not in get_WG(): if self.pk is None: print "differisco", self.id_genealogy defer(add_mice_node, self) else: print "non differisco" super(BioMice, self).save(*args, **kwargs) def save_old(self, *args, **kwargs): super(BioMice, self).save(*args, **kwargs)
class Programmed_explant(models.Model): objects = WgObjectRelatedManager() id_scope = models.ForeignKey(Scope_details, db_column='id_scope') id_mouse = models.ForeignKey(BioMice, db_column='id_mouse') done = models.BooleanField() scopeNotes = models.TextField(blank=True, null=True) history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) #unique_together = ("id_mouse", "done") class Meta: verbose_name_plural = 'programmed_explant' db_table = 'programmed_explant'
class Account(models.Model): email = models.CharField(unique=True, max_length=255, null=False) #noEncrypt pwd_hash = models.CharField(max_length=255, null=False) #noEncrypt salt1 = models.CharField(max_length=255, null=False) #noEncrypt salt2 = models.CharField(max_length=255, null=False) f_name = models.CharField(max_length=90, null=False) l_name = models.CharField(max_length=90, null=False) age = models.CharField(max_length=64, null=False) history = audit.AuditTrail() def __str__(self): return msg_decrypt(self.email)
class Mice(models.Model): id_mouse_strain = models.ForeignKey(Mouse_strain, blank=True, db_column='id_mouse_strain') barcode = models.CharField(max_length=32, blank=True, unique=True) available_date = models.DateField('available date', blank=True) #arrival_date = models.DateField('arrival date',blank=True, db_column='arrival_date') arrival_date = models.DateField(db_column='arrival_date') birth_date = models.DateField('birth date', blank=True) death_date = models.DateField('death date', blank=True) gender = models.CharField(max_length=1, choices=GENDERCHOICE) id_status = models.ForeignKey(Status, db_column='id_status') id_source = models.ForeignKey(Source, db_column='id_source') #id_cancer_research_group = models.ForeignKey(Cancer_research_group, db_column='id_cancer_research_group') notes = models.CharField(max_length=45, blank=True) created_by = models.ForeignKey(User, db_column='created_by', blank=True, null=True) history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) class Meta: verbose_name_plural = 'phys_mice' db_table = 'phys_mice' def __unicode__(self): return self.barcode def report(self): page = markup.page() page.tr() page.td(str(self.barcode), align='center') page.td(str(self.birth_date), align='center') page.td(str(self.available_date), align='center') page.td(str(self.id_mouse_strain), align='center') page.td(str(self.gender), align='center') page.td(str(self.id_status), align='center') page.td(str(self.id_source), align='center') page.tr.close() return page def list_mice(self): text = self.barcode + ", " + self.gender return text def __getattribute__(self, name): #ritorna il valore dell'attributo 'name' return object.__getattribute__(self, name)
class Implant_details(models.Model): objects = WgObjectRelatedManager() id_mouse = models.ForeignKey(BioMice, db_column='id_mouse') id_series = models.ForeignKey(Series, db_column='id_series') aliquots_id = models.ForeignKey(Aliquots, db_column='aliquots_id') bad_quality_flag = models.BooleanField() site = models.ForeignKey(Site, db_column='site') history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) class Meta: verbose_name_plural = 'implant_details' db_table = 'implant_details'
class Qualitative_measure(models.Model): objects = WgObjectRelatedManager() id_value = models.ForeignKey(Qualitative_values, db_column='id_value') id_mouse = models.ForeignKey(BioMice, db_column='id_mouse') id_series = models.ForeignKey(Measurements_series, db_column='id_series') weight = models.FloatField() notes = models.CharField(max_length=255, blank=True) history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) class Meta: verbose_name_plural = 'qualitative_measure' db_table = 'qualitative_measure' def __unicode__(self): return str(self.id_value)
class Mice_has_arms(models.Model): objects = WgObjectRelatedManager() id_mouse = models.ForeignKey(BioMice, db_column='id_mouse') id_operator = models.ForeignKey(User, db_column='id_operator') id_protocols_has_arms = models.ForeignKey( Protocols_has_arms, db_column='id_protocols_has_arms') id_prT = models.ForeignKey(Pr_treatment, db_column='id_prT', blank=True, null=True) start_date = models.DateTimeField(blank=True, null=True) expected_end_date = models.DateTimeField(blank=True, null=True) end_date = models.DateTimeField(blank=True, null=True) history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) class Meta: verbose_name_plural = 'mice_has_arms' db_table = 'mice_has_arms' def __unicode__(self): return str(self.id_operator)
class Aliquot(models.Model): genealogyID = models.CharField('Genealogy ID', max_length=30) idContainer = models.ForeignKey('Container', db_column='idContainer', verbose_name='Container', null=True, blank=True) position = models.CharField(max_length=10, null=True, blank=True) startTimestamp = models.DateTimeField('Start Timestamp', blank=True, null=True) endTimestamp = models.DateTimeField('End Timestamp', blank=True, null=True) startOperator = models.ForeignKey(User, db_column='startOperator', related_name='startOper', verbose_name='Start Operator', blank=True, null=True) endOperator = models.ForeignKey(User, db_column='endOperator', related_name='endOper', verbose_name='End Operator', blank=True, null=True) history = audit.AuditTrail(track_fields=(('username', models.CharField(max_length=30), getUsername), )) class Meta: verbose_name_plural = 'aliquots' db_table = 'aliquot' def __unicode__(self): return self.genealogyID + ' is in ' + str( self.idContainer) + ' ' + self.position
class Tree(models.Model): def __init__(self, *args, **kwargs): super(Tree, self).__init__(*args, **kwargs) #save, in order to get ID for the tree #owner properties based on wiki/DatabaseQuestions plot = models.ForeignKey(Plot) tree_owner = models.CharField(max_length=256, null=True, blank=True) steward_name = models.CharField(max_length=256, null=True, blank=True) #only modifyable by admin steward_user = models.ForeignKey( User, null=True, blank=True, related_name="steward") #only modifyable by admin sponsor = models.CharField(max_length=256, null=True, blank=True) #only modifyable by us species = models.ForeignKey(Species, verbose_name="Scientific name", null=True, blank=True) species_other1 = models.CharField(max_length=255, null=True, blank=True) species_other2 = models.CharField(max_length=255, null=True, blank=True) orig_species = models.CharField(max_length=256, null=True, blank=True) dbh = models.FloatField(null=True, blank=True) #gets auto-set on save height = models.FloatField( null=True, blank=True, error_messages={'invalid': "Error: This value must be a number."}) canopy_height = models.FloatField( null=True, blank=True, error_messages={'invalid': "Error: This value must be a number."}) date_planted = models.DateField(null=True, blank=True) date_removed = models.DateField(null=True, blank=True) present = models.BooleanField(default=True) last_updated = models.DateTimeField(auto_now=True) last_updated_by = models.ForeignKey( User, related_name='updated_by') # TODO set to current user s_order = models.IntegerField(null=True, blank=True) photo_count = models.IntegerField(null=True, blank=True) objects = models.GeoManager() history = audit.AuditTrail() projects = models.CharField(max_length=20, null=True, blank=True) import_event = models.ForeignKey(ImportEvent) condition = models.CharField( max_length=256, null=True, blank=True, choices=Choices().get_field_choices('condition')) canopy_condition = models.CharField( max_length=256, null=True, blank=True, choices=Choices().get_field_choices('canopy_condition')) readonly = models.BooleanField(default=False) def has_common_attributes(self): if self.get_flag_count > 0: return True if self.species: spp = self.species if spp.flower_conspicuous or spp.fall_conspicuous or spp.palatable_human or spp.native_status: return True return False def get_absolute_url(self): return "/trees/%i/" % self.id def get_condition_display(self): for key, value in Choices().get_field_choices('condition'): if key == self.condition: return value return None def get_scientific_name(self): if self.species: sn = self.species.scientific_name if not sn: sn = self.species.genus if self.species.cultivar_name: sn += " '%s'" % self.species.cultivar_name return sn else: return 'unavailable' def get_common_name(self): if self.species: return self.species.common_name return 'unavailable' def get_eco_impact(self): tr = TreeResource.objects.filter(tree=self) if tr: return "%0.2f" % tr[0].total_benefit() def get_action_count(self): return len(self.treeaction_set.all()) def get_alert_count(self): return len(self.treealert_set.all()) def get_flag_count(self): return len(self.treeflags_set.all()) def get_stewardship_count(self): return len(self.treestewardship_set.all()) def get_active_pends(self): pends = self.treepending_set.filter(status='pending') return pends def get_active_geopends(self): pends = PlotPending.objects.filter(status='pending').filter(tree=self) return pends def set_environmental_summaries(self): if not self.species or not self.dbh: logging.debug('no species or no dbh ..') return None tr = TreeResource.objects.filter(tree=self) #check see if we have an existing tree resource if not tr: logging.debug('no tree resource for tree id %s' % self.id) if self.species.resource.all(): logging.info( ' but .. we do have a resource for species id %s; creating tr' % self.species.id) tr = TreeResource(tree=self) else: return None else: tr = tr[0] if not self.species.resource.all(): #delete old TR if it exists tr.delete() return None #calc results and set them resource = self.species.resource.all()[0] #todo: and region base_resources = resource.calc_base_resources(RESOURCE_NAMES, self.dbh) results = resource.calc_resource_summaries(base_resources) if not results: logging.warning( 'Unable to calc results for %s, deleting TreeResource if it exists' % self) if tr.id: tr.delete() return None #update summaries for k, v in results.items(): setattr(tr, k, v) #print k, v #print getattr(tr,k) tr.save() logging.debug('tr saved.. tree id is %s' % (tr.tree.id)) return True def is_complete(self): if self.species >= 0 and self.dbh: return True else: return False def set_species(self, species_id, commit=True): """ sets the species, and updates the species tree count """ self.old_species = self.species new_species = Species.objects.get(id=species_id) self.species = new_species if commit: self.save() def save(self, *args, **kwargs): #save new neighborhood/zip connections if needed self.photo_count = self.treephoto_set.count() self.projects = "" for fl in self.treeflags_set.all(): self.projects = self.projects + " " + fl.key super(Tree, self).save(*args, **kwargs) self.set_environmental_summaries() #set new species counts if hasattr(self, 'old_species') and self.old_species: self.old_species.save() if hasattr(self, 'species') and self.species: self.species.save() super(Tree, self).save(*args, **kwargs) def quick_save(self, *args, **kwargs): super(Tree, self).save(*args, **kwargs) self.set_environmental_summaries() #set new species counts if hasattr(self, 'old_species') and self.old_species: self.old_species.save() if hasattr(self, 'species') and self.species: self.species.save() def update_aggregate(self, ag_model, location): agg = ag_model.objects.filter(location=location) if agg: agg = agg[0] else: agg = ag_model(location=location) #print agg.__dict__ #summaries = [] trees = Tree.objects.filter(plot__geometry__within=location.geometry) plots = Plot.objects.filter(geometry__within=location.geometry) #print trees agg.total_trees = trees.count() agg.total_plots = plots.count() trees = trees.exclude(Q(dbh=None) | Q(dbh=0.0)).exclude(species=None) #print agg.total_trees #TODO figure out how to summarize diff stratum stuff field_names = [ x.name for x in ResourceSummaryModel._meta.fields if not x.name == 'id' ] if agg.total_trees == 0: for f in field_names: setattr(agg, f, 0.0) else: #TODO speed this up for f in field_names: fn = 'treeresource__' + f s = trees.aggregate(Sum(fn))[fn + '__sum'] or 0.0 setattr(agg, f, s) agg.save() def percent_complete(self): has = 0 attr = settings.COMPLETE_ARRAY for item in attr: if hasattr(self, item): if getattr(self, item): has += 1 elif hasattr(self.plot, item): if getattr(self.plot, item): has += 1 return has / float(len(attr)) * 100 def validate_all(self): #print watch_tests for test, method in watch_tests.iteritems(): #print test result = getattr(self, method)() #print result # check for results and save - passed tests return None if not result: TreeWatch.objects.filter(tree=self, key=watch_choices[test]).delete() continue # if identical watch already exists skip it if TreeWatch.objects.filter(tree=self, key=watch_choices[test], value=result): continue TreeWatch.objects.filter(tree=self, key=watch_choices[test]).delete() self.treewatch_set.create( key=watch_choices[test], value=result, ) def validate_proximity(self, return_trees=False, max_count=1): if not self.plot.geometry: return None return self.plot.validate_proximity() # Disallowed combinations: # Dead + 0% loss, Dead + 25% loss, Dead + 50% loss, Dead + 75% loss # Excellent + 100% loss, Excellent + 75% loss def validate_canopy_condition(self): if not self.canopy_condition or not self.condition: return None cond = self.condition c_cond = self.canopy_condition if cond == 'Dead': if not c_cond == 'Little or None (up to 100% missing)' and not c_cond == 'None': return cond + ", " + c_cond elif cond == 'Excellent': if c_cond == 'Little or None (up to 100% missing)' or c_cond == 'Large Gaps (up to 75% missing)': return cond + ", " + c_cond return None # discussions: http://www.nativetreesociety.org/measure/tdi/diameter_height_ratio.htm def validate_height_dbh(self): if not self.height or not self.dbh: return None getcontext().prec = 3 cbh = self.dbh * math.pi cbh_feet = cbh * .75 / 9 float_ratio = self.height / cbh_feet hd_ratio = Decimal(float_ratio.__str__()) #print hd_ratio if hd_ratio < 100: return None return round(hd_ratio, 2).__str__() def validate_max_dbh(self): if not self.dbh or not self.species or not self.species.v_max_dbh: return None if self.dbh > self.species.v_max_dbh: return "%s (species max: %s )" % (str( self.dbh), str(self.species.v_max_dbh)) return None def validate_max_height(self): if not self.height or not self.species or not self.species.v_max_height: return None if self.height > self.species.v_max_height: return "%s (species max: %s)" % (str( self.height), str(self.species.v_max_height)) return None def __unicode__(self): if self.species: return '%s, %s, %s' % (self.species.common_name or '', self.species.scientific_name, self.plot.geocoded_address) else: return self.plot.geocoded_address
class Plot(models.Model): present = models.BooleanField(default=True) width = models.FloatField( null=True, blank=True, error_messages={'invalid': "Error: This value must be a number."}) length = models.FloatField( null=True, blank=True, error_messages={'invalid': "Error: This value must be a number."}) type = models.CharField(max_length=256, null=True, blank=True, choices=Choices().get_field_choices('plot_type')) powerline_conflict_potential = models.CharField( max_length=256, choices=Choices().get_field_choices('powerline_conflict_potential'), help_text="Are there overhead powerlines present?", null=True, blank=True, default='3') sidewalk_damage = models.CharField( max_length=256, null=True, blank=True, choices=Choices().get_field_choices('sidewalk_damage')) address_street = models.CharField(max_length=256, blank=True, null=True) address_city = models.CharField(max_length=256, blank=True, null=True) address_zip = models.CharField(max_length=30, blank=True, null=True) neighborhood = models.ManyToManyField(Neighborhood, null=True) neighborhoods = models.CharField( max_length=150, null=True, blank=True) # Really this should be 'blank=True' and null=False zipcode = models.ForeignKey( ZipCode, null=True, blank=True) # Because it is calculated in the save method geocoded_accuracy = models.IntegerField(null=True, blank=True) geocoded_address = models.CharField(max_length=256, null=True, blank=True) geocoded_lat = models.FloatField(null=True, blank=True) geocoded_lon = models.FloatField(null=True, blank=True) geometry = models.PointField(srid=4326) #geocoded_geometry = models.PointField(null=True, srid=4326) #owner_geometry = models.PointField(null=True, srid=4326) #should we keep this? last_updated = models.DateTimeField(auto_now=True) last_updated_by = models.ForeignKey( User, related_name='plot_updated_by') # TODO set to current user history = audit.AuditTrail() import_event = models.ForeignKey(ImportEvent) objects = models.GeoManager() #original data to help owners associate back to their own db data_owner = models.ForeignKey(User, related_name="owner", null=True, blank=True) owner_orig_id = models.CharField(max_length=256, null=True, blank=True) owner_additional_id = models.CharField(max_length=255, null=True, blank=True) owner_additional_properties = models.TextField( null=True, blank=True, help_text="Additional Properties (not searchable)") readonly = models.BooleanField(default=False) def validate(self): self.full_clean() em = ExclusionMask.objects.filter(geometry__contains=self.geometry) if em.count() > 0: raise ValidationError( "Geometry may not be within an exclusion zone.") def get_plot_type_display(self): for key, value in Choices().get_field_choices('plot_type'): if key == self.type: return value return None def get_plot_size(self): length = self.length width = self.width if length == None: length = 'Missing' elif length == 99: length = '15+ ft' else: length = '%.2f ft' % length if width == None: width = 'Missing' elif width == 99: width = '15+ ft' else: width = '%.2f ft' % width #print length, width return '%s x %s' % (length, width) def get_sidewalk_damage_display(self): for key, value in Choices().get_field_choices('sidewalk_damage'): if key == self.sidewalk_damage: return value return None def get_powerline_conflict_display(self): for key, value in Choices().get_field_choices( 'powerline_conflict_potential'): if key == self.powerline_conflict_potential: return value return None def get_stewardship_count(self): return len(self.plotstewardship_set.all()) def current_tree(self): trees = Tree.objects.filter(present=True, plot=self) if len(trees) > 0: return trees[0] else: return None def get_active_pends(self): pends = self.plotpending_set.filter(status='pending') return pends def get_active_pends_with_tree_pends(self): plot_pends = self.plotpending_set.filter(status='pending') if self.current_tree(): tree_pends = self.current_tree().get_active_pends() else: tree_pends = [] pends = list(chain(plot_pends, tree_pends)) return pends def get_plot_type_display(self): for key, value in Choices().get_field_choices('plot_type'): if key == self.type: return value return None def get_plot_size(self): length = self.length width = self.width if length == None: length = 'Missing' elif length == 99: length = '15+ ft' else: length = '%.2f ft' % length if width == None: width = 'Missing' elif width == 99: width = '15+ ft' else: width = '%.2f ft' % width return '%s x %s' % (length, width) def get_sidewalk_damage_display(self): for key, value in Choices().get_field_choices('sidewalk_damage'): if key == self.sidewalk_damage: return value return None def get_powerline_conflict_potential(self): for key, value in Choices().get_field_choices( 'powerline_conflict_potential'): if key == self.powerline_conflict_potential: return value return None def quick_save(self, *args, **kwargs): super(Plot, self).save(*args, **kwargs) def save(self, *args, **kwargs): self.validate() pnt = self.geometry n = Neighborhood.objects.filter(geometry__contains=pnt) z = ZipCode.objects.filter(geometry__contains=pnt) if n: oldns = self.neighborhoods self.neighborhoods = "" for nhood in n: if nhood: self.neighborhoods = self.neighborhoods + " " + nhood.id.__str__( ) else: self.neighborhoods = "" oldns = None if self.id: oldn = self.neighborhood.all() oldz = self.zipcode else: oldn = [] oldz = None super(Plot, self).save(*args, **kwargs) if n: self.neighborhood.clear() for nhood in n: if nhood: self.neighborhood.add(nhood) else: self.neighborhood.clear() if z: self.zipcode = z[0] else: self.zipcode = None super(Plot, self).save(*args, **kwargs) if self.neighborhoods != oldns: done = [] if n: for nhood in n: if nhood.id in done: continue if self.current_tree(): self.current_tree().update_aggregate( AggregateNeighborhood, nhood) else: self.update_aggregate(AggregateNeighborhood, nhood) done.append(nhood.id) if oldn: for nhood in oldn: if nhood.id in done: continue if self.current_tree(): self.current_tree().update_aggregate( AggregateNeighborhood, nhood) else: self.update_aggregate(AggregateNeighborhood, nhood) done.append(nhood.id) if self.current_tree() and z and z[0] != oldz: if z: self.current_tree().update_aggregate(AggregateZipCode, z[0]) if oldz: self.current_tree().update_aggregate(AggregateZipCode, oldz) def update_aggregate(self, ag_model, location): agg = ag_model.objects.filter(location=location) if agg: agg = agg[0] else: agg = ag_model(location=location) #print agg.__dict__ #summaries = [] trees = Tree.objects.filter(plot__geometry__within=location.geometry) plots = Plot.objects.filter(geometry__within=location.geometry) #print trees agg.total_trees = trees.count() agg.total_plots = plots.count() agg.save() def validate_proximity(self, return_trees=False, max_count=1): if not self.geometry: return None nearby = Plot.objects.filter(present=True, geometry__distance_lte=(self.geometry, D(ft=10.0))) if nearby.count() > max_count: if return_trees: return nearby return (nearby.count() - max_count).__str__() #number greater than max_count allows return None