Package WholeCellKB :: Package public :: Module views
[hide private]
[frames] | no frames]

Source Code for Module WholeCellKB.public.views

   1  ''' 
   2  Whole-cell knowledge base views 
   3   
   4  Author: Jonathan Karr, jkarr@stanford.edu 
   5  Affiliation: Covert Lab, Department of Bioengineering, Stanford University 
   6  Last updated: 2012-07-17 
   7  ''' 
   8   
   9  from copy import deepcopy 
  10  from django.contrib.auth import login as auth_login, logout as auth_logout 
  11  from django.contrib.auth.decorators import login_required 
  12  from django.contrib.auth.forms import AuthenticationForm 
  13  from django.contrib.auth.models import User 
  14  from django.core.exceptions import ValidationError, ObjectDoesNotExist 
  15  from django.core.urlresolvers import reverse 
  16  from django.db.models import Count, Sum, Avg 
  17  from django.db.models.fields import BooleanField, NullBooleanField, AutoField, BigIntegerField, DecimalField, FloatField, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, SmallIntegerField 
  18  from django.db.models.fields.related import OneToOneField, RelatedObject, ManyToManyField, ForeignKey 
  19  from django.db.models.query import EmptyQuerySet 
  20  from django.http import Http404, HttpResponse, HttpResponseRedirect 
  21  from django.shortcuts import get_object_or_404 
  22  from django.utils.text import capfirst 
  23  from django.views.decorators.debug import sensitive_post_parameters 
  24  from django.views.decorators.cache import never_cache 
  25  from django.views.decorators.csrf import csrf_protect 
  26  from haystack.query import SearchQuerySet 
  27  from itertools import chain 
  28  from public import models 
  29  from public.forms import ExportDataForm, ImportDataForm 
  30  from public.helpers import getEntry, format_field_detail_view, objectToQuerySet, render_queryset_to_response, getObjectTypes, getModel, get_invalid_objects, get_edit_form_fields, get_edit_form_data 
  31  from public.helpers import validate_object_fields, validate_model_objects, validate_model_unique, save_object_data, batch_import_from_excel, readFasta 
  32  from public.helpers import PropertyDefinitionFilter, PygmentsStyle, PygmentsFormatter 
  33  from public.models import Entry, Parameter, Reference, Species, SpeciesComponent, ModelProperty, SimulationProperty 
  34  import pygments 
  35  from pygments.lexers import MatlabLexer 
  36  from pygments.token import Token 
  37  from urlparse import urlparse 
  38  import numpy 
  39  import os 
  40  import settings 
  41  import tempfile 
  42   
  43  MODEL_CODE_BASE_DIR = '/home/projects/WholeCell/simulation' 
44 45 -def index(request, species_wid=None):
46 if species_wid is not None and species_wid != '': 47 species = Species.objects.get(wid=species_wid) 48 else: 49 species = Species.objects.all() 50 if len(species) > 0: 51 species = species[0] 52 else: 53 species = None 54 content = [] 55 if species is not None: 56 content.append([ 57 [0, 'Compartments', models.Compartment.objects.filter(species__id = species.id).count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Compartment'})], 58 ]) 59 60 chrs = models.Chromosome.objects.filter(species__id = species.id) 61 chrcontent = chrs.aggregate(length=Sum('length')); 62 try: 63 gc_content = sum([chr.get_gc_content() * chr.length for chr in chrs]) / chrcontent['length'] 64 except TypeError, e: 65 gc_content = 0 66 content.append([ 67 [0, 'Chromosomes', chrs.count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Chromosome'})], 68 [1, 'Length', chrcontent['length'], 'nt'], 69 [1, 'GC-content', ('%0.1f' % (gc_content * 100)), '%'], 70 ]) 71 72 tus = models.TranscriptionUnit.objects.filter(species__id = species.id).annotate(num_genes = Count('genes')) 73 mons = tus.filter(num_genes__lte = 1) 74 nPolys = tus.filter(num_genes__gt = 1).count() 75 content.append([ 76 [0, 'Transcription units', tus.count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'TranscriptionUnit'})], 77 [1, 'Monocistrons', tus.count() - nPolys], 78 [1, 'Polycistrons', nPolys], 79 ]) 80 81 content.append([ 82 [0, 'Genes', models.Gene.objects.filter(species__id = species.id).count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Gene'})], 83 [1, 'mRNA', models.Gene.objects.filter(species__id = species.id, type__wid='mRNA').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Gene'}) + '?type=mRNA'], 84 [1, 'rRNA', models.Gene.objects.filter(species__id = species.id, type__wid='rRNA').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Gene'}) + '?type=rRNA'], 85 [1, 'sRNA', models.Gene.objects.filter(species__id = species.id, type__wid='sRNA').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Gene'}) + '?type=sRNA'], 86 [1, 'tRNA', models.Gene.objects.filter(species__id = species.id, type__wid='tRNA').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Gene'}) + '?type=tRNA'], 87 ]) 88 89 content.append([ 90 [0, 'Chromosome features', 91 models.ChromosomeFeature.objects.filter(species__id = species.id).count(), 92 None, 93 reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'ChromosomeFeature'}), 94 ], 95 [1, 'DnaA boxes', 96 models.ChromosomeFeature.objects.filter(species__id = species.id, type__parent__wid='ChromosomeFeature-DnaA_box').count(), 97 ], 98 [1, 'Short tandem repeats', 99 models.ChromosomeFeature.objects.filter(species__id = species.id, type__parent__wid='ChromosomeFeature-Short_Tandem_Repeat').count(), 100 ], 101 [1, 'Other', 102 models.ChromosomeFeature.objects.filter(species__id = species.id).exclude(type__parent__wid='ChromosomeFeature-DnaA_box').exclude(type__parent__wid='ChromosomeFeature-Short_Tandem_Repeat').count()], 103 ]) 104 105 content.append([ 106 [0, 'Metabolites', models.Metabolite.objects.filter(species__id = species.id).count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Metabolite'})], 107 [1, 'Amino acids', 108 models.Metabolite.objects.filter(species__id = species.id, type__wid='amino_acid').count() + 109 models.Metabolite.objects.filter(species__id = species.id, type__wid='modified_amino_acid').count() + 110 models.Metabolite.objects.filter(species__id = species.id, type__wid='non-standard_amino_acid').count() + 111 models.Metabolite.objects.filter(species__id = species.id, type__wid='vitamin_non-standard_amino_acid').count() 112 ], 113 [1, 'Antibiotic', 114 models.Metabolite.objects.filter(species__id = species.id, type__wid='antibiotic').count() + 115 models.Metabolite.objects.filter(species__id = species.id, type__parent__wid='antibiotic').count() 116 ], 117 [1, 'Gases', 118 models.Metabolite.objects.filter(species__id = species.id, type__wid='gas').count() + 119 models.Metabolite.objects.filter(species__id = species.id, type__parent__wid='gas').count() 120 ], 121 [1, 'Ions', 122 models.Metabolite.objects.filter(species__id = species.id, type__wid='ion').count() + 123 models.Metabolite.objects.filter(species__id = species.id, type__parent__wid='ion').count() 124 ], 125 [1, 'Lipids', 126 models.Metabolite.objects.filter(species__id = species.id, type__wid='lipid').count() + 127 models.Metabolite.objects.filter(species__id = species.id, type__parent__wid='lipid').count() + 128 models.Metabolite.objects.filter(species__id = species.id, type__parent__parent__wid='lipid').count() 129 ], 130 [1, 'Vitamins', 131 models.Metabolite.objects.filter(species__id = species.id, type__wid='vitamin').count() + 132 models.Metabolite.objects.filter(species__id = species.id, type__parent__wid='vitamin').count() 133 ], 134 ]) 135 136 mons = models.ProteinMonomer.objects.filter(species__id = species.id) 137 cpxs = models.ProteinComplex.objects.filter(species__id = species.id) 138 monDNABind = mons.filter(dna_footprint__length__gt=0).count() 139 monIntMem = mons.filter(localization__wid = 'm').exclude(signal_sequence__type = 'lipoprotein').count() + mons.filter(localization__wid = 'tm').exclude(signal_sequence__type = 'lipoprotein').count() 140 monLipo = mons.filter(signal_sequence__type = 'lipoprotein').count() 141 monSecreted = mons.filter(signal_sequence__type = 'secretory').count() 142 monTermOrg = mons.filter(localization__wid = 'tc').count() + mons.filter(localization__wid = 'tm').count() 143 cpxDNABind = cpxs.filter(dna_footprint__length__gt=0).count() 144 content.append([ 145 [0, 'Proteins', mons.count() + cpxs.count()], 146 [1, 'Monomers', mons.count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'ProteinMonomer'})], 147 [2, 'DNA-binding', monDNABind], 148 [2, 'Integral membrane', monIntMem], 149 [2, 'Lipoprotein', monLipo, None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'ProteinMonomer'}) + '?signal_sequence__type=lipoprotein'], 150 [2, 'Secreted', monSecreted, None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'ProteinMonomer'}) + '?signal_sequence__type=secretory'], 151 [2, 'Terminal organelle', monTermOrg], 152 [1, 'Complexes', cpxs.count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'ProteinComplex'})], 153 [2, 'DNA-binding', cpxDNABind], 154 ]) 155 156 rxns = models.Reaction.objects.filter(species__id = species.id) 157 content.append([ 158 [0, 'Reactions', rxns.count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'})], 159 [1, 'DNA damage', rxns.filter(processes__wid='Process_DNADamage').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_DNADamage'], 160 [1, 'DNA repair', rxns.filter(processes__wid='Process_DNARepair').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_DNARepair'], 161 [1, 'Metabolic', rxns.filter(processes__wid='Process_Metabolism').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_Metabolism'], 162 [1, 'Protein decay', rxns.filter(processes__wid='Process_ProteinDecay').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_ProteinDecay'], 163 [1, 'Protein modification', rxns.filter(processes__wid='Process_ProteinModification').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_ProteinModification'], 164 [1, 'Replication Initiation', rxns.filter(processes__wid='Process_ReplicationInitiation').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_ReplicationInitiation'], 165 [1, 'RNA decay', rxns.filter(processes__wid='Process_RNADecay').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_RNADecay'], 166 [1, 'RNA modification', rxns.filter(processes__wid='Process_RNAModification').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_RNAModification'], 167 [1, 'RNA processing', rxns.filter(processes__wid='Process_RNAProcessing').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_RNAProcessing'], 168 [1, 'Transcription', rxns.filter(processes__wid='Process_Transcription').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_Transcription'], 169 [1, 'Translation', rxns.filter(processes__wid='Process_Translation').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_Translation'], 170 [1, 'tRNA aminoacylation', rxns.filter(processes__wid='Process_tRNAAminoacylation').count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Reaction'}) + '?processes=Process_tRNAAminoacylation'], 171 [1, 'Other', rxns.exclude(processes__wid='Process_DNADamage') 172 .exclude(processes__wid='Process_DNARepair') 173 .exclude(processes__wid='Process_Metabolism') 174 .exclude(processes__wid='Process_ProteinDecay') 175 .exclude(processes__wid='Process_ProteinModification') 176 .exclude(processes__wid='Process_ReplicationInitiation') 177 .exclude(processes__wid='Process_RNADecay') 178 .exclude(processes__wid='Process_RNAModification') 179 .exclude(processes__wid='Process_RNAProcessing') 180 .exclude(processes__wid='Process_Transcription') 181 .exclude(processes__wid='Process_Translation') 182 .exclude(processes__wid='Process_tRNAAminoacylation') 183 .count()], 184 ]) 185 186 tr = models.TranscriptionalRegulation.objects.filter(species__id = species.id) 187 nTus = len(set([x[0] for x in tr.values_list('transcription_unit')])) 188 nTfs = len(set([x[0] for x in tr.values_list('transcription_factor')])) 189 content.append([ 190 [0, 'Transcriptional regulation'], 191 [1, 'Interactions', tr.count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'TranscriptionalRegulation'})], 192 [1, 'Transcriptional regulators', nTfs], 193 [1, 'Regulated promoters', nTus], 194 ]) 195 196 content.append([ 197 [0, 'Pathways', models.Pathway.objects.filter(species__id = species.id).count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Pathway'})], 198 ]) 199 content.append([ 200 [0, 'Stimuli', models.Stimulus.objects.filter(species__id = species.id).count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Stimulus'})], 201 ]) 202 203 204 nCellComp = models.Metabolite.objects.filter(species__id = species.id, biomass_composition__concentration__isnull=False).count() 205 nMediaComp = models.Metabolite.objects.filter(species__id = species.id, media_composition__concentration__isnull=False).count() 206 nKineticsKeq = models.Reaction.objects.filter(species__id = species.id, keq__isnull=False).count() 207 nKineticsKm = \ 208 models.Reaction.objects.filter(species__id = species.id, kinetics_forward__km__isnull=False).count() + \ 209 models.Reaction.objects.filter(species__id = species.id, kinetics_backward__km__isnull=False).count() 210 nKineticsVmax = \ 211 models.Reaction.objects.filter(species__id = species.id, kinetics_forward__vmax__isnull=False).count() + \ 212 models.Reaction.objects.filter(species__id = species.id, kinetics_backward__vmax__isnull=False).count() 213 nRnaExp = models.Gene.objects.filter(species__id = species.id, expression__isnull=False).count() 214 nRnaHl = models.Gene.objects.filter(species__id = species.id, half_life__isnull=False).count() 215 nStimuli = models.Stimulus.objects.filter(species__id = species.id, value__isnull=False).count() 216 nTrAffinity = models.TranscriptionalRegulation.objects.filter(species__id = species.id, affinity__isnull=False).count() 217 nTrActivity = models.TranscriptionalRegulation.objects.filter(species__id = species.id, activity__isnull=False).count() 218 nOther = models.Parameter.objects.filter(species__id = species.id).count() 219 nTotParameters = nCellComp + nMediaComp + nKineticsVmax + nRnaExp + nRnaHl + nStimuli + nTrAffinity + nTrActivity + nOther 220 221 content.append([ 222 [0, 'Quantitative parameters', nTotParameters], 223 [1, 'Cell composition', nCellComp], 224 [1, 'Media composition', nMediaComp], 225 [1, 'Reaction K<sub>eq</sub>', nKineticsKeq], 226 [1, 'Reaction K<sub>m</sub>', nKineticsKm], 227 [1, 'Reaction V<sub>max</sub>', nKineticsVmax], 228 [1, 'RNA expression', nRnaExp], 229 [1, 'RNA half-lives', nRnaHl], 230 [1, 'Stimulus values', nStimuli], 231 [1, 'Transcr. reg. activity', nTrAffinity], 232 [1, 'Transcr. reg. affinity', nTrActivity], 233 [1, 'Other', nOther, None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Parameter'})], 234 ]) 235 236 content.append([ 237 [0, 'Processes', models.Process.objects.filter(species__id = species.id).count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'Process'})], 238 ]) 239 240 content.append([ 241 [0, 'States', models.State.objects.filter(species__id = species.id).count(), None, reverse('public.views.list', kwargs={'species_wid': species.wid, 'model_type': 'State'})], 242 ]) 243 244 nContent = [len(x) for x in content] 245 totContent = sum(nContent) 246 cum = 0 247 idx = 0 248 breakIdxs = [0, 0] 249 for x in nContent: 250 cum += x 251 idx += 1 252 if cum > totContent * 1/ 3 and breakIdxs[0] == 0: 253 breakIdxs[0] = idx 254 if cum > totContent * 2 / 3 and breakIdxs[1] == 0: 255 breakIdxs[1] = idx 256 257 contentCol1 = [] 258 contentCol2 = [] 259 contentCol3 = [] 260 i = 0 261 for x in content[:breakIdxs[0]]: 262 i += 1 263 for y in x: 264 contentCol1.append([i] + y) 265 i = 0 266 for x in content[breakIdxs[0]:breakIdxs[1]]: 267 i += 1 268 for y in x: 269 contentCol2.append([i] + y) 270 i = 0 271 for x in content[breakIdxs[1]:]: 272 i += 1 273 for y in x: 274 contentCol3.append([i] + y) 275 276 sources = { 277 'total': 0, 278 'types': [], 279 'dates': [], 280 'evidence_parameters': [], 281 'evidence_species': [], 282 'evidence_media': [], 283 'evidence_pH': [], 284 'evidence_temperature': [], 285 } 286 if species is not None: 287 refs = models.Reference.objects.filter(species__id = species.id) 288 sources['total'] = refs.count() 289 sources['types'] = [ 290 {'type': 'Articles', 'count': refs.filter(species__id = species.id, type__wid='article').count()}, 291 {'type': 'Books', 'count': refs.filter(species__id = species.id, type__wid='book').count()}, 292 {'type': 'Thesis', 'count': refs.filter(species__id = species.id, type__wid='thesis').count()}, 293 {'type': 'Other', 'count': refs.filter(species__id = species.id, type__wid='misc').count()}, 294 ] 295 sources['dates'] = refs.filter(year__isnull=False).order_by('year').values('year').annotate(count=Count('year')) 296 297 298 nEstimated = models.Parameter.objects.filter(species__id = species.id, value__evidence__is_experimentally_constrained=False).count() 299 nExpConstrained = nTotParameters - nEstimated 300 sources['evidence_parameters'] = [ 301 {'type': 'Experimentally constrained', 'count': nExpConstrained}, 302 {'type': 'Computationally estimated', 'count': nEstimated}, 303 ] 304 305 306 sources['evidence_species'] = models.Evidence.objects.filter(species_component__species__id = species.id).values('species').annotate(count = Count('id')) 307 sources['evidence_media'] = models.Evidence.objects.filter(species_component__species__id = species.id).values('media').annotate(count = Count('id')) 308 sources['evidence_pH'] = models.Evidence.objects.filter(species_component__species__id = species.id).values('pH').annotate(count = Count('id')) 309 sources['evidence_temperature'] = models.Evidence.objects.filter(species_component__species__id = species.id).values('temperature').annotate(count = Count('id')) 310 311 return render_queryset_to_response( 312 request = request, 313 species_wid = species_wid, 314 data = { 315 'content': [contentCol1, contentCol2, contentCol3], 316 'contentRows': range(max(len(contentCol1), len(contentCol2), len(contentCol3))), 317 'sources': sources, 318 }, 319 templateFile = 'public/index.html')
320
321 -def about(request, species_wid=None):
322 return render_queryset_to_response( 323 species_wid = species_wid, 324 request = request, 325 templateFile = 'public/about.html', 326 data = { 327 'ROOT_URL': settings.ROOT_URL, 328 } 329 )
330
331 -def tutorial(request, species_wid=None):
332 return render_queryset_to_response( 333 species_wid = species_wid, 334 request = request, 335 templateFile = 'public/tutorial.html')
336
337 @login_required 338 -def contributors(request, species_wid=None):
339 queryset = User.objects.all().filter(is_active = True) 340 return render_queryset_to_response( 341 species_wid = species_wid, 342 request = request, 343 models = [User], 344 queryset = queryset, 345 templateFile = 'public/contributors.html')
346
347 @login_required 348 -def contributor(request, username, species_wid=None):
349 queryset = objectToQuerySet(get_object_or_404(User, username = username), model = User) 350 return render_queryset_to_response( 351 species_wid = species_wid, 352 request = request, 353 models = [User], 354 queryset = queryset, 355 templateFile = 'public/contributor.html')
356
357 -def search(request, species_wid = None):
358 query = request.GET.get('q', '') 359 engine = request.GET.get('engine', 'haystack') 360 361 if engine == 'haystack': 362 return search_haystack(request, species_wid, query) 363 else: 364 return search_google(request, species_wid, query)
365
366 -def search_haystack(request, species_wid, query):
367 #search 368 if species_wid is None: 369 species_wid = Species.objects.all()[0].wid 370 results = SearchQuerySet().filter(species_wid=species_wid).filter(content=query) 371 372 #calculate facets 373 facets = results.facet('model_type') 374 tmp = facets.facet_counts()['fields']['model_type'] 375 modelNameFacet = [] 376 objectTypes = getObjectTypes(is_public=request.user.is_anonymous()) 377 models = [] 378 for tmp2 in tmp: 379 modelName = objectTypes[objectTypes.index(tmp2[0])] 380 modelNameFacet.append({ 381 'name':modelName, 382 'verbose_name': getModel(modelName)._meta.verbose_name, 383 'count':tmp2[1], 384 }) 385 models.append(getModel(modelName)) 386 modelNameFacet.sort(lambda x, y:cmp(x['verbose_name'], y['verbose_name'])) 387 388 #narrow search by facets 389 model_type = request.GET.get('model_type', '') 390 if model_type: 391 results = results.models(getModel(model_type)) 392 393 #order results 394 results = results.order_by('wid') 395 396 #convert results to query set 397 queryset = EmptyQuerySet() 398 for object in results: 399 tmp = object.model.objects.none() 400 tmp._result_cache.append(object.object) 401 queryset = chain(queryset, tmp) 402 403 #form response 404 return render_queryset_to_response( 405 species_wid = species_wid, 406 request = request, 407 models = models, 408 queryset = queryset, 409 templateFile = 'public/search.html', 410 data = { 411 'query': query, 412 'engine': 'haystack', 413 'model_type': model_type, 414 'modelNameFacet': modelNameFacet, 415 })
416
417 -def search_google(request, species_wid, query):
418 return render_queryset_to_response( 419 species_wid = species_wid, 420 request = request, 421 templateFile = 'public/googleSearch.html', 422 data = { 423 'query': query, 424 'engine': 'google', 425 })
426
427 -def list(request, species_wid, model_type):
428 try: 429 getObjectTypes(is_public=request.user.is_anonymous()).index(model_type) 430 except ValueError: 431 raise Http404 432 433 species = Species.objects.get(wid=species_wid) 434 model = getModel(model_type) 435 objects = model.objects.all().filter(species__id=species.id) 436 437 facet_fields = [] 438 for field_full_name in model._meta.facet_fields: 439 #facet 440 field_names = str(field_full_name).split('__') 441 tmp_model = model 442 field_verbose_name = [] 443 for field_name in field_names: 444 field = tmp_model._meta.get_field_by_name(field_name)[0] 445 field_verbose_name.append(field.verbose_name) 446 if isinstance(field, (ForeignKey, ManyToManyField)): 447 tmp_model = field.rel.to 448 field_verbose_name = ' &#8250; '.join(field_verbose_name) 449 450 if isinstance(field, (ForeignKey, ManyToManyField)) and not issubclass(field.rel.to, Entry): 451 continue 452 453 if isinstance(field, (ForeignKey, ManyToManyField)): 454 tmp = model.objects.filter(species__id=species.id).order_by(field_full_name + '__name').values(field_full_name).annotate(count=Count(field_full_name)) 455 else: 456 tmp = model.objects.filter(species__id=species.id).order_by(field_full_name).values(field_full_name).annotate(count=Count(field_full_name)) 457 facets = [] 458 for facet in tmp: 459 value = facet[field_full_name] 460 if value is None or unicode(value) == '': 461 continue 462 463 if isinstance(field, (ForeignKey, ManyToManyField)): 464 tmp2 = tmp_model.objects.values('wid', 'name').get(id=value) 465 id = tmp2['wid'] 466 name = capfirst(tmp2['name']) 467 elif (field.choices is not None) and (len(field.choices) > 0) and (not isinstance(field, (BooleanField, NullBooleanField))): 468 id = value 469 choices = [x[0] for x in field.choices] 470 if id in choices: 471 name = field.choices[choices.index(id)][1] 472 else: 473 name = capfirst(value) 474 else: 475 id = value 476 name = capfirst(value) 477 if value is not None and unicode(value) != '': 478 facets.append({ 479 'id': unicode(id), 480 'name': unicode(name), 481 'count': facet['count']}) 482 if len(facets) > 1: 483 facet_fields.append({ 484 'name': field_full_name, 485 'verbose_name': field_verbose_name, 486 'facets': facets, 487 }) 488 489 #filter 490 val = request.GET.get(field_full_name) 491 if val: 492 if isinstance(field, (ForeignKey, ManyToManyField)): 493 kwargs = {field_full_name + '__wid': val} 494 elif isinstance(field, (BooleanField, NullBooleanField)): 495 kwargs = {field_full_name: val == 'True'} 496 elif isinstance(field, (AutoField, BigIntegerField, DecimalField, FloatField, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, SmallIntegerField)): 497 kwargs = {field_full_name: float(val)} 498 else: 499 kwargs = {field_full_name: val} 500 objects = objects.filter(**kwargs) 501 502 return render_queryset_to_response( 503 species_wid = species_wid, 504 request = request, 505 models = [model], 506 queryset = objects, 507 templateFile = 'public/list.html', 508 data = { 509 'model_type': model_type, 510 'model_verbose_name': model._meta.verbose_name, 511 'model_verbose_name_plural': model._meta.verbose_name_plural, 512 'facet_fields': facet_fields, 513 })
514
515 -def detail(request, species_wid, wid):
516 obj = getEntry(species_wid = species_wid, wid = wid) 517 if obj is None: 518 raise Http404 519 520 model = obj.__class__ 521 model_type = model.__name__ 522 fieldsets = deepcopy(model._meta.fieldsets) 523 524 #filter out type, metadata 525 fieldset_names = [x[0] for x in fieldsets] 526 if 'Type' in fieldset_names: 527 idx = fieldset_names.index('Type') 528 del fieldsets[idx] 529 530 #filter out empty fields 531 rmfieldsets = [] 532 for idx in range(len(fieldsets)): 533 rmfields = [] 534 for idx2 in range(len(fieldsets[idx][1]['fields'])): 535 if isinstance(fieldsets[idx][1]['fields'][idx2], dict): 536 field = fieldsets[idx][1]['fields'][idx2] 537 field_name = field['name'] 538 verbose_name = field['verbose_name'] 539 else: 540 field_name = fieldsets[idx][1]['fields'][idx2] 541 field = model._meta.get_field_by_name(field_name)[0] 542 if isinstance(field, RelatedObject): 543 verbose_name = capfirst(field.get_accessor_name()) 544 else: 545 verbose_name = field.verbose_name 546 547 data = format_field_detail_view(obj, field_name, request.user.is_anonymous()) 548 if (data is None) or (data == ''): 549 rmfields = [idx2] + rmfields 550 551 if issubclass(model, Parameter) and field_name == 'value': 552 is_modeled_url = reverse('public.views.viewParameterInSimulation', kwargs = { 553 'species_wid':species_wid, 554 'wid': wid, 555 }) 556 elif (isinstance(field, (ForeignKey, ManyToManyField)) and issubclass(field.rel.to, Parameter)) or \ 557 (isinstance(field, (RelatedObject)) and issubclass(field.model, Parameter)): 558 is_modeled_url = reverse('public.views.viewParametersInSimulation', kwargs = { 559 'species_wid':species_wid, 560 'wid': wid, 561 }) 562 else: 563 try: 564 if ModelProperty.objects.get(species__wid = species_wid, class_name = model_type, property_name = field_name).simulation_properties.exists(): 565 is_modeled_url = reverse('public.views.viewPropertyInSimulation', kwargs = { 566 'species_wid':species_wid, 567 'class_name': model_type, 568 'property_name': field_name, 569 }) 570 except ObjectDoesNotExist: 571 is_modeled_url = '' 572 573 fieldsets[idx][1]['fields'][idx2] = { 574 'name': field_name, 575 'verbose_name': verbose_name.replace(" ", '&nbsp;').replace("-", "&#8209;"), 576 'data': data, 577 'is_modeled_url': is_modeled_url, 578 } 579 for idx2 in rmfields: 580 del fieldsets[idx][1]['fields'][idx2] 581 if len(fieldsets[idx][1]['fields']) == 0: 582 rmfieldsets = [idx] + rmfieldsets 583 for idx in rmfieldsets: 584 del fieldsets[idx] 585 586 #form query set 587 qs = objectToQuerySet(obj, model = model) 588 589 #render response 590 return render_queryset_to_response( 591 species_wid = species_wid, 592 request = request, 593 models = [model], 594 queryset = qs, 595 templateFile = 'public/detail.html', 596 data = { 597 'model_type': model_type, 598 'model': model, 599 'fieldsets': fieldsets, 600 'message': request.GET.get('message', ''), 601 })
602
603 -def viewPropertyInSimulation(request, species_wid, class_name, property_name):
604 #get model 605 model = getModel(class_name) 606 607 #get verbose class name 608 verbose_class_name = model._meta.verbose_name 609 610 #get verbose property name 611 verbose_property_name = property_name 612 for fieldset in model._meta.fieldsets: 613 for field in fieldset[1]['fields']: 614 if isinstance(field, (str, unicode)) and field == property_name: 615 tmp = model._meta.get_field_by_name(property_name) 616 if len(tmp) > 0: 617 verbose_property_name = tmp[0].verbose_name 618 if isinstance(field, dict) and field['name'] == property_name: 619 verbose_property_name = field['verbose_name'] 620 621 #get associated simulation code properties 622 qs = ModelProperty.objects.get( 623 species__wid = species_wid, 624 class_name = class_name, 625 property_name = property_name 626 ).simulation_properties.all().order_by('class_name', 'property_name') 627 628 #organize simulation code properties by class 629 classes = {} 630 for object in qs: 631 if not classes.has_key(object.class_name): 632 classes[object.class_name] = [] 633 classes[object.class_name].append(object.property_name) 634 635 #highlight code for each simulation class 636 object_list = [] 637 for sim_class_name in classes: 638 sim_property_names = classes[sim_class_name] 639 sim_property_names.sort() 640 pathParts = sim_class_name.split('.') 641 codePath = "%s/src/+%s/%s.m" % (MODEL_CODE_BASE_DIR, '/+'.join(pathParts[0:-1]), pathParts[-1]) 642 if not os.path.isfile(codePath): 643 codePath = "%s/src/+%s/@%s/%s.m" % (MODEL_CODE_BASE_DIR, '/+'.join(pathParts[0:-1]), pathParts[-1], pathParts[-1]) 644 if not os.path.isfile(codePath): 645 continue 646 647 with open (codePath, "r") as codeFile: 648 code = codeFile.read() 649 650 lexer = MatlabLexer() 651 lexer.add_filter(PropertyDefinitionFilter(property_names = sim_property_names, tokentype=Token.Name.Variable)) 652 653 tokens = lexer.get_tokens(code) 654 655 object_list.append({ 656 'class_name': sim_class_name, 657 'property_names': sim_property_names, 658 'code': pygments.format(tokens, PygmentsFormatter(linenos='inline', linenostep=1, style=PygmentsStyle, noclasses=True)), 659 }) 660 661 #render response 662 return render_queryset_to_response( 663 species_wid = species_wid, 664 request = request, 665 models = [SimulationProperty], 666 queryset = qs, 667 templateFile = 'public/viewPropertyInSimulation.html', 668 data = { 669 'object_list': object_list, 670 'verbose_class_name': verbose_class_name, 671 'verbose_property_name': verbose_property_name, 672 })
673
674 -def viewParameterInSimulation(request, species_wid, wid):
675 #get associated simulation property 676 qs = Parameter.objects.filter(species__wid = species_wid, wid=wid) 677 if not qs[0].state is None: 678 sim_class_name = 'edu.stanford.covert.cell.sim.state.%s' % qs[0].state.wid.replace('State_', '') 679 verbose_class_name = '%s: %s' % (wid, qs[0].state.name) 680 else: 681 sim_class_name = 'edu.stanford.covert.cell.sim.process.%s' % qs[0].process.wid.replace('Process_', '') 682 verbose_class_name = '%s: %s' % (wid, qs[0].process.name) 683 sim_property_name = qs[0].name 684 verbose_property_name = qs[0].name 685 686 #highlight code for simulation class 687 pathParts = sim_class_name.split('.') 688 codePath = "%s/src/+%s/%s.m" % (MODEL_CODE_BASE_DIR, '/+'.join(pathParts[0:-1]), pathParts[-1]) 689 if not os.path.isfile(codePath): 690 codePath = "%s/src/+%s/@%s/%s.m" % (MODEL_CODE_BASE_DIR, '/+'.join(pathParts[0:-1]), pathParts[-1], pathParts[-1]) 691 692 if os.path.isfile(codePath): 693 with open (codePath, "r") as codeFile: 694 code = codeFile.read() 695 696 lexer = MatlabLexer() 697 lexer.add_filter(PropertyDefinitionFilter(property_names = [sim_property_name], tokentype=Token.Name.Variable)) 698 699 tokens = lexer.get_tokens(code) 700 701 object = { 702 'class_name': sim_class_name, 703 'property_names': [sim_property_name], 704 'code': pygments.format(tokens, PygmentsFormatter(linenos='inline', linenostep=1, style=PygmentsStyle, noclasses=True)), 705 } 706 else: 707 raise Http404 708 709 #render response 710 return render_queryset_to_response( 711 species_wid = species_wid, 712 request = request, 713 models = [Parameter], 714 queryset = qs, 715 templateFile = 'public/viewPropertyInSimulation.html', 716 data = { 717 'object_list': [object], 718 'verbose_class_name': verbose_class_name, 719 'verbose_property_name': verbose_property_name, 720 })
721
722 -def viewParametersInSimulation(request, species_wid, wid):
723 obj = getEntry(species_wid = species_wid, wid = wid) 724 if obj is None: 725 raise Http404 726 727 model = obj.__class__ 728 verbose_class_name = model._meta.verbose_name 729 verbose_property_name = '%s parameters' % obj.name 730 731 #get associated simulation property 732 qs = EmptyQuerySet() 733 for field in model._meta.get_all_related_objects() + model._meta.get_all_related_many_to_many_objects(): 734 accessor_name = field.get_accessor_name() 735 if accessor_name == '+': 736 continue 737 738 if isinstance(field, ForeignKey) and issubclass(field.rel.to, Parameter): 739 qs._result_cache.append(getattr(obj, accessor_name)) 740 if (isinstance(field, ManyToManyField) and issubclass(field.rel.to, Parameter)) or \ 741 (isinstance(field, RelatedObject) and issubclass(field.model, Parameter)): 742 qs2 = getattr(obj, accessor_name).all() 743 if len(qs2) > 0: 744 qs._result_cache.extend(qs2._result_cache) 745 746 classes = {} 747 for o in qs: 748 if not o.state is None: 749 sim_class_name = 'edu.stanford.covert.cell.sim.state.%s' % o.state.wid.replace('State_', '') 750 else: 751 sim_class_name = 'edu.stanford.covert.cell.sim.process.%s' % o.process.wid.replace('Process_', '') 752 if not classes.has_key(sim_class_name): 753 classes[sim_class_name] = [] 754 classes[sim_class_name].append(o.name) 755 756 #highlight code for simulation class 757 objects = [] 758 for sim_class_name in classes: 759 sim_property_names = classes[sim_class_name] 760 sim_property_names.sort() 761 pathParts = sim_class_name.split('.') 762 codePath = "%s/src/+%s/%s.m" % (MODEL_CODE_BASE_DIR, '/+'.join(pathParts[0:-1]), pathParts[-1]) 763 if not os.path.isfile(codePath): 764 codePath = "%s/src/+%s/@%s/%s.m" % (MODEL_CODE_BASE_DIR, '/+'.join(pathParts[0:-1]), pathParts[-1], pathParts[-1]) 765 if not os.path.isfile(codePath): 766 continue 767 with open (codePath, "r") as codeFile: 768 code = codeFile.read() 769 770 lexer = MatlabLexer() 771 lexer.add_filter(PropertyDefinitionFilter(property_names = sim_property_names, tokentype=Token.Name.Variable)) 772 773 tokens = lexer.get_tokens(code) 774 775 objects.append({ 776 'class_name': sim_class_name, 777 'property_names': sim_property_names, 778 'code': pygments.format(tokens, PygmentsFormatter(linenos='inline', linenostep=1, style=PygmentsStyle, noclasses=True)), 779 }) 780 781 #render response 782 return render_queryset_to_response( 783 species_wid = species_wid, 784 request = request, 785 models = [Parameter], 786 queryset = qs, 787 templateFile = 'public/viewPropertyInSimulation.html', 788 data = { 789 'object_list': objects, 790 'verbose_class_name': verbose_class_name, 791 'verbose_property_name': verbose_property_name, 792 })
793
794 @login_required 795 -def add(request, model_type, species_wid=None):
796 return edit(request, model_type=model_type, species_wid=species_wid, action='add')
797
798 @login_required 799 -def edit(request, wid=None, model_type=None, species_wid=None, action='edit'):
800 #retrieve object 801 if action == 'edit': 802 obj = getEntry(species_wid = species_wid, wid = wid) 803 if obj is None: 804 raise Http404 805 model = obj.__class__ 806 else: 807 model = getModel(model_type) 808 obj = model() 809 810 #save object 811 error_messages = {} 812 if request.method == 'POST': 813 submitted_data = get_edit_form_data(model, request.POST) 814 815 data = submitted_data 816 data['id'] = obj.id 817 data['species'] = species_wid 818 data['model_type'] = model.__name__ 819 820 try: 821 #validate is WID unique 822 if issubclass(model, SpeciesComponent): 823 qs = SpeciesComponent.objects.values('wid', 'model_type').filter(species__wid=species_wid) 824 else: 825 qs = model.objects.values('wid', 'model_type').all() 826 827 if action == 'edit': 828 qs = qs.exclude(id=obj.id) 829 830 wids = {} 831 for x in qs: 832 wids[x['wid']] = x['model_type'] 833 834 if data['wid'] in wids.keys(): 835 raise ValidationError({'wid': 'Value must be unique'}) 836 837 wids[data['wid']] = model.__name__ 838 839 #validate 840 data = validate_object_fields(model, data, wids, species_wid, data['wid']) 841 validate_model_objects(model, data) 842 validate_model_unique(model, [data]) 843 844 #save 845 obj = save_object_data(species_wid, obj, data, {}, request.user, save=False, save_m2m=False) 846 obj = save_object_data(species_wid, obj, data, {data['wid']: obj}, request.user, save=True, save_m2m=False) 847 obj = save_object_data(species_wid, obj, data, {data['wid']: obj}, request.user, save=True, save_m2m=True) 848 849 #redirect to details page 850 return HttpResponseRedirect(obj.get_absolute_url()) 851 except ValidationError as error: 852 error_messages = error.message_dict 853 854 #form query set 855 if action == 'edit': 856 obj = getEntry(species_wid = species_wid, wid = wid) 857 if obj is None: 858 raise Http404 859 qs = objectToQuerySet(obj, model = model) 860 else: 861 obj = None 862 qs = model.objects.none() 863 864 #display form 865 fields, initial_values = get_edit_form_fields(species_wid, model, obj=obj) 866 867 if request.method == 'POST': 868 initial_values = submitted_data 869 return render_queryset_to_response( 870 species_wid = species_wid, 871 request = request, 872 models = [model], 873 queryset = qs, 874 templateFile = 'public/edit.html', 875 data = { 876 'model_verbose_name': model._meta.verbose_name, 877 'action': action, 878 'fields': fields, 879 'references_choices': Reference.objects.filter(species__wid = species_wid).values_list('wid'), 880 'initial_values': initial_values, 881 'error_messages': error_messages, 882 } 883 )
884
885 @login_required 886 -def delete(request, species_wid, wid):
887 #retrieve object 888 obj = getEntry(species_wid = species_wid, wid = wid) 889 if obj is None: 890 raise Http404 891 model = obj.__class__ 892 qs = objectToQuerySet(obj, model = model) 893 894 #delete 895 if request.method == 'POST': 896 obj.delete() 897 return HttpResponseRedirect(reverse('public.views.list', kwargs={'species_wid':species_wid, 'model_type': model.__name__})) 898 899 #confirmation message 900 return render_queryset_to_response( 901 species_wid = species_wid, 902 request = request, 903 models = [model], 904 queryset = qs, 905 templateFile = 'public/delete.html', 906 data = { 907 'model_verbose_name': model._meta.verbose_name 908 } 909 )
910
911 -def exportData(request, species_wid=None):
912 getDict = request.GET.copy() 913 if getDict.get('format', ''): 914 getDict.__setitem__('species', getDict.get('species', species_wid)) 915 form = ExportDataForm(request.user.is_anonymous(), getDict or None) 916 if not form.is_valid(): 917 return render_queryset_to_response( 918 species_wid=species_wid, 919 request = request, 920 templateFile = 'public/exportDataForm.html', 921 data = { 922 'form': form 923 } 924 ) 925 else: 926 species = Species.objects.get(wid = form.cleaned_data['species']) 927 queryset = EmptyQuerySet() 928 models = [] 929 if form.cleaned_data['all_model_types'] == 'True': 930 model_types = getObjectTypes(superclass=Entry, is_public = request.user.is_anonymous()) 931 else: 932 model_types = form.cleaned_data['model_type'] 933 934 for model_type in model_types: 935 model = getModel(model_type) 936 if issubclass(model, SpeciesComponent): 937 queryset = chain(queryset, model.objects.filter(species__id=species.id).select_related(depth=2).all()) 938 else: 939 queryset = chain(queryset, model.objects.select_related(depth=2).filter(id=species.id)) 940 models.append(getModel(model_type)) 941 942 return render_queryset_to_response( 943 species_wid = species_wid, 944 request = request, 945 queryset = queryset, 946 templateFile = 'public/exportDataResult.html', 947 models = models) 948
949 @login_required 950 -def importData(request, species_wid=None):
951 if request.method == 'POST': 952 form = ImportDataForm(request.POST or None, request.FILES) 953 954 if form.is_valid(): 955 selected_species_wid = form.cleaned_data['species'] or form.cleaned_data['new_species'] 956 if selected_species_wid == '' or selected_species_wid is None: 957 form.species.errors += ['Please select a specices'] 958 else: 959 #save to temporary file 960 originalFileName, originalFileExtension = os.path.splitext(request.FILES['file'].name) 961 fid = tempfile.NamedTemporaryFile(suffix = originalFileExtension, delete = False) 962 filename = fid.name 963 for chunk in request.FILES['file'].chunks(): 964 fid.write(chunk) 965 fid.close() 966 967 #read file 968 if originalFileExtension == '.xlsx': 969 try: 970 batch_import_from_excel(selected_species_wid, filename, request.user) 971 success = True 972 message = 'Data successfully saved!' 973 except ValidationError as error: 974 success = False 975 message = 'Unable to import data: ' + ' '.join(error.messages) 976 elif originalFileExtension == '.fna': 977 success, message = readFasta(selected_species_wid, filename, request.user) 978 else: 979 raise Http404 980 981 #delete file 982 os.remove(filename) 983 984 #render response 985 return render_queryset_to_response( 986 species_wid = species_wid, 987 request = request, 988 templateFile = 'public/importDataResult.html', 989 data = { 990 'success': success, 991 'message': message, 992 }) 993 else: 994 form = ImportDataForm(None) 995 996 return render_queryset_to_response( 997 species_wid = species_wid, 998 request = request, 999 templateFile = 'public/importDataForm.html', 1000 data = { 1001 'form': form}, 1002 )
1003
1004 -def validate(request, species_wid):
1005 errors = get_invalid_objects(Species.objects.values('id').get(wid=species_wid)['id']) 1006 1007 return render_queryset_to_response( 1008 species_wid = species_wid, 1009 request = request, 1010 templateFile = 'public/validate.html', 1011 data = { 1012 'errors': errors 1013 }, 1014 )
1015
1016 @sensitive_post_parameters() 1017 @csrf_protect 1018 @never_cache 1019 -def login(request, species_wid=None):
1020 next = request.REQUEST.get('next', '') 1021 1022 if request.method == "POST": 1023 form = AuthenticationForm(data=request.POST) 1024 if form.is_valid(): 1025 auth_login(request, form.get_user()) 1026 1027 if request.session.test_cookie_worked(): 1028 request.session.delete_test_cookie() 1029 1030 return HttpResponseRedirect(next) 1031 else: 1032 form = AuthenticationForm(request) 1033 1034 request.session.set_test_cookie() 1035 1036 return render_queryset_to_response( 1037 species_wid = species_wid, 1038 request = request, 1039 templateFile = 'public/login.html', 1040 data = { 1041 'form': form, 1042 'next': next, 1043 })
1044
1045 -def logout(request, species_wid=None):
1046 auth_logout(request) 1047 return render_queryset_to_response( 1048 species_wid = species_wid, 1049 request = request, 1050 templateFile = 'public/logout.html', 1051 )
1052
1053 -def sitemap(request):
1054 return render_queryset_to_response( 1055 request = request, 1056 templateFile = 'public/sitemap.xml', 1057 data = { 1058 'ROOT_URL': settings.ROOT_URL, 1059 'qs_species': Species.objects.all(), 1060 } 1061 )
1062
1063 -def sitemap_toplevel(request):
1064 return render_queryset_to_response( 1065 request = request, 1066 templateFile = 'public/sitemap_toplevel.xml', 1067 data = { 1068 'ROOT_URL': settings.ROOT_URL, 1069 } 1070 )
1071
1072 -def sitemap_species(request, species_wid):
1073 species = Species.objects.get(wid=species_wid) 1074 return render_queryset_to_response( 1075 request = request, 1076 templateFile = 'public/sitemap_species.xml', 1077 data = { 1078 'ROOT_URL': settings.ROOT_URL, 1079 'species': species, 1080 'entries': SpeciesComponent.objects.filter(species__id = species.id), 1081 } 1082 )
1083