From 6072dffd4db43b21ecbf3bbe80aa1abd46fc9706 Mon Sep 17 00:00:00 2001 From: Diane Trout Date: Tue, 21 Oct 2008 19:44:25 +0000 Subject: [PATCH] Merge in new modules from htsworkflow branch. However I renamed things to simpler names. analys_track -> analysis exp_track -> experiments fctracker -> samples htsw_reports -> reports As a result this check in probably wont work as I haven't finished updating all the imports --- .../{fctracker => analysis}/__init__.py | 0 htsworkflow/frontend/analysis/an_urls.py | 6 + htsworkflow/frontend/analysis/main.py | 91 ++ htsworkflow/frontend/analysis/models.py | 117 ++ htsworkflow/frontend/experiments/__init__.py | 0 htsworkflow/frontend/experiments/et_urls.py | 12 + htsworkflow/frontend/experiments/exptrack.py | 194 ++++ htsworkflow/frontend/experiments/models.py | 163 +++ htsworkflow/frontend/experiments/views.py | 60 + htsworkflow/frontend/reports/LibraryInfo.xml | 1024 +++++++++++++++++ htsworkflow/frontend/reports/__init__.py | 0 htsworkflow/frontend/reports/ht_urls.py | 5 + htsworkflow/frontend/reports/libinfopar.py | 93 ++ htsworkflow/frontend/reports/models.py | 238 ++++ htsworkflow/frontend/reports/utils.py | 61 + htsworkflow/frontend/samples/__init__.py | 0 .../frontend/{fctracker => samples}/models.py | 0 .../frontend/{fctracker => samples}/views.py | 0 htsworkflow/frontend/settings.py | 92 +- htsworkflow/frontend/urls.py | 8 +- 20 files changed, 2151 insertions(+), 13 deletions(-) rename htsworkflow/frontend/{fctracker => analysis}/__init__.py (100%) create mode 100644 htsworkflow/frontend/analysis/an_urls.py create mode 100644 htsworkflow/frontend/analysis/main.py create mode 100644 htsworkflow/frontend/analysis/models.py create mode 100755 htsworkflow/frontend/experiments/__init__.py create mode 100755 htsworkflow/frontend/experiments/et_urls.py create mode 100755 htsworkflow/frontend/experiments/exptrack.py create mode 100755 htsworkflow/frontend/experiments/models.py create mode 100755 htsworkflow/frontend/experiments/views.py create mode 100644 htsworkflow/frontend/reports/LibraryInfo.xml create mode 100644 htsworkflow/frontend/reports/__init__.py create mode 100644 htsworkflow/frontend/reports/ht_urls.py create mode 100644 htsworkflow/frontend/reports/libinfopar.py create mode 100644 htsworkflow/frontend/reports/models.py create mode 100644 htsworkflow/frontend/reports/utils.py create mode 100644 htsworkflow/frontend/samples/__init__.py rename htsworkflow/frontend/{fctracker => samples}/models.py (100%) rename htsworkflow/frontend/{fctracker => samples}/views.py (100%) diff --git a/htsworkflow/frontend/fctracker/__init__.py b/htsworkflow/frontend/analysis/__init__.py similarity index 100% rename from htsworkflow/frontend/fctracker/__init__.py rename to htsworkflow/frontend/analysis/__init__.py diff --git a/htsworkflow/frontend/analysis/an_urls.py b/htsworkflow/frontend/analysis/an_urls.py new file mode 100644 index 0000000..57fa33e --- /dev/null +++ b/htsworkflow/frontend/analysis/an_urls.py @@ -0,0 +1,6 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('', + (r'^updStatus$', 'htswfrontend.analys_track.main.updStatus'), + (r'^getProjects/$', 'htswfrontend.analys_track.main.getProjects'), +) diff --git a/htsworkflow/frontend/analysis/main.py b/htsworkflow/frontend/analysis/main.py new file mode 100644 index 0000000..015a69c --- /dev/null +++ b/htsworkflow/frontend/analysis/main.py @@ -0,0 +1,91 @@ +# some core functions of analysis manager module +from django.http import HttpResponse +from datetime import datetime +from string import * +import re +from htswfrontend import settings +from htswfrontend.analys_track.models import Task, Project +from django.core.exceptions import ObjectDoesNotExist + +def updStatus(request): + ClIP = request.META['REMOTE_ADDR'] + #Check client access permission + granted = False + if (settings.ALLOWED_ANALYS_IPS.has_key(ClIP)): granted = True + if not granted: return HttpResponse("access denied.") + + output='' + taskid=-1; + # Check required param + if request.has_key('taskid'): taskid = request['taskid'] + else: return HttpResponse('missing param task id') + + try: + rec = Task.objects.get(id=taskid) + mytimestamp = datetime.now().__str__() + mytimestamp = re.sub(pattern=":[^:]*$",repl="",string=mytimestamp) + if request.has_key('msg'): + rec.task_status += ", "+request['msg']+" ("+mytimestamp+")" + else : + rec.task_status = "Registered ("+mytimestamp+")" + rec.save() + output = "Hello "+settings.ALLOWED_ANALYS_IPS[ClIP]+". Updated status for task "+taskid + except ObjectDoesNotExist: + output = "entry not found: taskid="+taskid + + return HttpResponse(output) + + +def getProjects(request): + ClIP = request.META['REMOTE_ADDR'] + #Check client access permission + granted = False + if (settings.ALLOWED_ANALYS_IPS.has_key(ClIP)): granted = True + if not granted: return HttpResponse("access denied.") + + outputfile = '' + + All=False + if (request.has_key('mode')): + if request['mode']=='all': + All=True + + try: + if(All): + rec = Project.objects.all().distinct() + else: + rec = Project.objects.filter(tasks__task_status__exact='defined').distinct() + + outputfile = '' + outputfile += '\n' + for p in rec: + outputfile += '\n' + outputfile += '\n' + prj_tasks = p.tasks.all() + for t in prj_tasks: + outputfile += '\n' + if (t.apply_calc == 'QuEST' or t.apply_calc == 'WingPeaks' or t.apply_calc == 'MACS'): + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + + if (t.apply_calc == 'ProfileReads' or t.apply_calc == 'qPCR'): + outputfile += '\n<'+t.apply_calc+' TaskId="'+t.id.__str__()+'" Name="'+t.task_name+'" Genome="'+t.subject1.library_species.use_genome_build+'" Library="'+t.subject1.library_id+'"/>' + + if (t.apply_calc == 'CompareLibs'): + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + + #if (t.apply_calc == 'ComparePeakCalls'): + # + # outputfile += '\n' + # TO DO: Define these new fields in Task: PCaller1 (QuEST,WingPeaks), PCaller2, Set1(FK to self), Set2 (FK..) ALL NULL=TRUE + outputfile += '\n' + outputfile += '\n' + except ObjectDoesNotExist: + outputfile = "" + + return HttpResponse(outputfile, mimetype='text/plain') diff --git a/htsworkflow/frontend/analysis/models.py b/htsworkflow/frontend/analysis/models.py new file mode 100644 index 0000000..301be27 --- /dev/null +++ b/htsworkflow/frontend/analysis/models.py @@ -0,0 +1,117 @@ +from django.db import models +from datetime import datetime +from htswfrontend.fctracker.models import Library +from string import * + +class Task(models.Model): + task_name = models.CharField(max_length=50,unique=True, db_index=True) + subject1 = models.ForeignKey(Library,related_name='sbj1_library',verbose_name="Subject") + subject2 = models.ForeignKey(Library,related_name='sbj2_library',verbose_name="Subject 2 / Control",blank=True,null=True) + CALCS = ( + ('QuEST', 'QuEST Peak Calling'), + ('WingPeaks', 'Wing Peak Calling'), + ('MACS', 'MACS Peak Calling'), + ('qPCR', 'In Silico qPCR'), + ('CompareLibs', 'Compare Libaraies'), + ('ComparePeakCalls','Compare Peak Calls'), + ('ProfileReads','Profile Reads') + ) + apply_calc = models.CharField(max_length=50,choices=CALCS,verbose_name='Applied Calculation') + ## userid = # logged in user + task_status = models.CharField(max_length=500,blank=True,null=True,default='defined') + results_location = models.CharField(max_length=2000,blank=True,null=True) + submitted_on = models.DateTimeField(core=True,default=datetime.now()) + run_note = models.CharField(max_length=500,blank=True,null=True) + + def __str__(self): + return '"%s" - %s on [%s]/[%s]' % (self.task_name,self.apply_calc,self.subject1,self.subject2) + + def InProjects(self): + return '...' + ps = self.project_set.all() + pstr = 'In ' + return pstr + for p in ps: + pstr += '%s, ' % (p.project_name) + return pstr + + class Admin: + list_display = ('task_name','apply_calc','subject1','subject2','InProjects','submitted_on','task_status') + list_filter = ('apply_calc',) + search_fields = ['task_name','id','=subject1__library_id','=subject2__library_id'] + fields = ( + (None, { + 'fields': (('task_name'),('apply_calc'),('subject1'),('subject2')) + }), + ('system fields', { + 'classes': 'collapse', + 'fields': (('submitted_on'),('task_status','run_note')) + }), + ) + + +class Project(models.Model): + project_name = models.CharField(max_length=50,unique=True, db_index=True) + tasks = models.ManyToManyField(Task,related_name='project_tasks',null=True,filter_interface=models.HORIZONTAL) + project_notes = models.CharField(max_length=500,blank=True,null=True) + + def __str__(self): + return '%s' % (self.project_name) + + def ProjectTasks(self): + ptasks = self.tasks.all().order_by('id') + surl = 'http://m304-apple-server.stanford.edu/projects/' + tstr = '' + Style = '' + if len(ptasks) > 8: Style = ' style="height:200px;overflow:auto" ' + tstr += '
' + tstr += '' + isregistered = False + for t in ptasks: + tstr += '' % (t.task_name,replace(t.task_status,'Complete','Complete')) + if t.task_status != 'defined': isregistered = True + + tstr += '
TasksJob Status
%s%s
' + tstr += '
' + tstr += '
' + tstr += '
' + if isregistered: + tstr += 'VIEW PROJECT RESULTS' + tstr += '(view in new window)' + else: + tstr += 'REGISTERING ...' + + tstr += '
' + tstr += '' + tstr += '
' + return tstr + + ProjectTasks.allow_tags = True + + def ProjTitle(self): + ptasks = self.tasks.all().order_by('id') + tasks_counter = '('+len(ptasks).__str__() + ' tasks)' + htmlstr = '%s
%s' % (self.project_name,tasks_counter) + return htmlstr + + ProjTitle.allow_tags = True + + class Admin: + list_display = ('ProjTitle','ProjectTasks') + list_filter = () + search_fields = ['project_name','=tasks__subject1__library_id','=tasks__subject2__library_id','tasks__subject1__library_name','tasks__subject2__library_name','project_notes'] + fields = ( + (None, { + 'fields': (('project_name'),('tasks'),('project_notes'))}), + ) diff --git a/htsworkflow/frontend/experiments/__init__.py b/htsworkflow/frontend/experiments/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/htsworkflow/frontend/experiments/et_urls.py b/htsworkflow/frontend/experiments/et_urls.py new file mode 100755 index 0000000..7ad709d --- /dev/null +++ b/htsworkflow/frontend/experiments/et_urls.py @@ -0,0 +1,12 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('', + + (r'^$', 'htswfrontend.exp_track.views.index'), + (r'^liblist$', 'htswfrontend.exp_track.views.test_Libs'), + #(r'^(?P.+)/$', 'gaworkflow.frontend.exp_track.views.detail'), + (r'^(?P.+)/$', 'htswfrontend.exp_track.views.makeFCSheet'), + (r'^updStatus$', 'htswfrontend.exp_track.exptrack.updStatus'), + (r'^getConfile$', 'htswfrontend.exp_track.exptrack.getConfile'), + (r'^getLanesNames$', 'htswfrontend.exp_track.exptrack.getLaneLibs') +) diff --git a/htsworkflow/frontend/experiments/exptrack.py b/htsworkflow/frontend/experiments/exptrack.py new file mode 100755 index 0000000..6486b5c --- /dev/null +++ b/htsworkflow/frontend/experiments/exptrack.py @@ -0,0 +1,194 @@ +# some core functions of the exp tracker module +from django.http import HttpResponse +from datetime import datetime +from string import * +import re +from htswfrontend import settings +from htswfrontend.exp_track.models import FlowCell, DataRun +from htswfrontend.fctracker.models import Library +from django.core.exceptions import ObjectDoesNotExist +from django.core.mail import send_mail, mail_admins + +def updStatus(request): + output='' + user = 'none' + pswd = '' + UpdatedStatus = 'unknown' + fcid = 'none' + runfolder = 'unknown' + ClIP = request.META['REMOTE_ADDR'] + granted = False + + if request.has_key('user'): + user = request['user'] + + #Check access permission + if (user == 'rami' and settings.ALLOWED_IPS.has_key(ClIP)): granted = True + if not granted: return HttpResponse("access denied.") + + + # ~~~~~~Parameters for the job ~~~~ + if request.has_key('fcid'): + fcid = request['fcid'] + else: + return HttpResponse('missing fcid') + + if request.has_key('runf'): + runfolder = request['runf'] + else: + return HttpResponse('missing runf') + + + if request.has_key('updst'): + UpdatedStatus = request['updst'] + else: + return HttpResponse('missing status') + + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + # Update Data Run status in DB + # Try get rec. If not found return 'entry not found + ', if found try update and return updated + try: + rec = DataRun.objects.get(run_folder=runfolder) + rec.run_status = UpdatedStatus + + #if there's a message update that too + mytimestamp = datetime.now().__str__() + mytimestamp = re.sub(pattern=":[^:]*$",repl="",string=mytimestamp) + if request.has_key('msg'): + rec.run_note += ", "+request['msg']+" ("+mytimestamp+")" + else : + if UpdatedStatus == '1': + rec.run_note = "Started ("+mytimestamp+")" + + rec.save() + output = "Hello "+settings.ALLOWED_IPS[ClIP]+". Updated to:'"+DataRun.RUN_STATUS_CHOICES[int(UpdatedStatus)][1].__str__()+"'" + except ObjectDoesNotExist: + output = "entry not found: "+fcid+", "+runfolder + + + #Notify researcher by email + # Doesn't work + #send_mail('Exp Tracker', 'Data Run Status '+output, 'rrauch@stanford.edu', ['rrrami@gmail.com'], fail_silently=False) + #mail_admins("test subject", "testing , testing", fail_silently=False) + # gives error: (49, "Can't assign requested address") + return HttpResponse(output) + +def generateConfile(request,fcid): + #granted = False + #ClIP = request.META['REMOTE_ADDR'] + #if (settings.ALLOWED_IPS.has_key(ClIP)): granted = True + + #if not granted: return HttpResponse("access denied.") + + cnfgfile = 'READ_LENGTH 25\n' + cnfgfile += 'ANALYSIS eland\n' + cnfgfile += 'GENOME_FILE all_chr.fa\n' + cnfgfile += 'ELAND_MULTIPLE_INSTANCES 8\n' + genome_dir = 'GENOME_DIR /Volumes/Genomes/' + eland_genome = 'ELAND_GENOME /Volumes/Genomes/' + + try: + rec = FlowCell.objects.get(flowcell_id=fcid) + + cnfgfile += '1:'+genome_dir+rec.lane_1_library.library_species.use_genome_build+'\n' + cnfgfile += '1:'+eland_genome+rec.lane_1_library.library_species.use_genome_build+'\n' + + cnfgfile += '2:'+genome_dir+rec.lane_2_library.library_species.use_genome_build+'\n' + cnfgfile += '2:'+eland_genome+rec.lane_2_library.library_species.use_genome_build+'\n' + + cnfgfile += '3:'+genome_dir+rec.lane_3_library.library_species.use_genome_build+'\n' + cnfgfile += '3:'+eland_genome+rec.lane_3_library.library_species.use_genome_build+'\n' + + cnfgfile += '4:'+genome_dir+rec.lane_4_library.library_species.use_genome_build+'\n' + cnfgfile += '4:'+eland_genome+rec.lane_4_library.library_species.use_genome_build+'\n' + + cnfgfile += '5:'+genome_dir+rec.lane_5_library.library_species.use_genome_build+'\n' + cnfgfile += '5:'+eland_genome+rec.lane_5_library.library_species.use_genome_build+'\n' + + cnfgfile += '6:'+genome_dir+rec.lane_6_library.library_species.use_genome_build+'\n' + cnfgfile += '6:'+eland_genome+rec.lane_6_library.library_species.use_genome_build+'\n' + + cnfgfile += '7:'+genome_dir+rec.lane_7_library.library_species.use_genome_build+'\n' + cnfgfile += '7:'+eland_genome+rec.lane_7_library.library_species.use_genome_build+'\n' + + cnfgfile += '8:'+genome_dir+rec.lane_8_library.library_species.use_genome_build+'\n' + cnfgfile += '8:'+eland_genome+rec.lane_8_library.library_species.use_genome_build + + except ObjectDoesNotExist: + cnfgfile = 'Entry not found for fcid = '+fcid + + return cnfgfile + +def getConfile(request): + granted = False + ClIP = request.META['REMOTE_ADDR'] + if (settings.ALLOWED_IPS.has_key(ClIP)): granted = True + + if not granted: return HttpResponse("access denied. IP: "+ClIP) + + fcid = 'none' + cnfgfile = '' + runfolder = 'unknown' + if request.has_key('fcid'): + fcid = request['fcid'] + if request.has_key('runf'): + runfolder = request['runf'] + try: + rec = DataRun.objects.get(run_folder=runfolder) #,flowcell_id=fcid) + cnfgfile = rec.config_params + #match_str = re.compile(r"READ_LENGTH.+$") + match_str = re.compile('^READ_LENGTH.+') + if not match_str.search(cnfgfile): + cnfgfile = generateConfile(request,fcid) + if match_str.search(cnfgfile): + rec = DataRun.objects.get(run_folder=runfolder) #,flowcell_id=fcid) + rec.config_params = cnfgfile + rec.save() + else: + cnfgfile = 'Failed generating config params for RunFolder = '+runfolder +', Flowcell id = '+ fcid+ ' Config Text:\n'+cnfgfile + + except ObjectDoesNotExist: + cnfgfile = 'Entry not found for RunFolder = '+runfolder + + return HttpResponse(cnfgfile) + +def getLaneLibs(request): + granted = False + ClIP = request.META['REMOTE_ADDR'] + if (settings.ALLOWED_IPS.has_key(ClIP)): granted = True + + if not granted: return HttpResponse("access denied.") + + fcid = 'none' + outputfile = '' + if request.has_key('fcid'): + fcid = request['fcid'] + try: + rec = FlowCell.objects.get(flowcell_id=fcid) + #Ex: 071211 + year = datetime.today().year.__str__() + year = replace(year,'20','') + month = datetime.today().month + if month < 10: month = "0"+month.__str__() + else: month = month.__str__() + day = datetime.today().day + if day < 10: day = "0"+day.__str__() + else: day = day.__str__() + mydate = year+month+day + outputfile = '' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + outputfile += '\n' + except ObjectDoesNotExist: + outputfile = 'Flowcell entry not found for: '+fcid + else: outputfile = 'Missing input: flowcell id' + + return HttpResponse(outputfile) diff --git a/htsworkflow/frontend/experiments/models.py b/htsworkflow/frontend/experiments/models.py new file mode 100755 index 0000000..08397e6 --- /dev/null +++ b/htsworkflow/frontend/experiments/models.py @@ -0,0 +1,163 @@ +from django.db import models +from htswfrontend.fctracker.models import * + +class FlowCell(models.Model): + + flowcell_id = models.CharField(max_length=20, unique=True, db_index=True, core=True) + run_date = models.DateTimeField(core=True) + advanced_run = models.BooleanField(default=False) + read_length = models.IntegerField(default=32) #Stanford is currenlty 25 + + lane_1_library = models.ForeignKey(Library, related_name="lane_1_library") + lane_2_library = models.ForeignKey(Library, related_name="lane_2_library") + lane_3_library = models.ForeignKey(Library, related_name="lane_3_library") + lane_4_library = models.ForeignKey(Library, related_name="lane_4_library") + lane_5_library = models.ForeignKey(Library, related_name="lane_5_library") + lane_6_library = models.ForeignKey(Library, related_name="lane_6_library") + lane_7_library = models.ForeignKey(Library, related_name="lane_7_library") + lane_8_library = models.ForeignKey(Library, related_name="lane_8_library") + + lane_1_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5) + lane_2_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5) + lane_3_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5) + lane_4_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5) + lane_5_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5) + lane_6_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5) + lane_7_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5) + lane_8_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5) + + lane_1_cluster_estimate = models.IntegerField(blank=True, null=True) + lane_2_cluster_estimate = models.IntegerField(blank=True, null=True) + lane_3_cluster_estimate = models.IntegerField(blank=True, null=True) + lane_4_cluster_estimate = models.IntegerField(blank=True, null=True) + lane_5_cluster_estimate = models.IntegerField(blank=True, null=True) + lane_6_cluster_estimate = models.IntegerField(blank=True, null=True) + lane_7_cluster_estimate = models.IntegerField(blank=True, null=True) + lane_8_cluster_estimate = models.IntegerField(blank=True, null=True) + + # lane_1_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_1_primer") + # lane_2_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_2_primer") + # lane_3_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_3_primer") + # lane_4_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_4_primer") + # lane_5_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_5_primer") + # lane_6_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_6_primer") + # lane_7_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_7_primer") + # lane_8_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_8_primer") + + #Machine Names + CLUSTER_MAC = ( + ('M304','Cardinal'), + ('R349','R349'), + ('Tinkerbell','Tinkerbell'), + ('BitBit','BitBit'), + ) + + SEQ_MAC = ( + ('EAS149','Stanford'), + ('EAS46','EAS46'), + ('EAS45','Paris'), + ('Britney','Britney'), + ) + + cluster_mac_id = models.CharField(max_length=50, choices=CLUSTER_MAC, default='BitBit') + seq_mac_id = models.CharField(max_length=50, choices=SEQ_MAC, verbose_name = 'Sequencer', default='Britney') + + notes = models.TextField(blank=True) + + def __str__(self): + #return '%s (%s)' % (self.flowcell_id, self.run_date) + return '%s' % (self.flowcell_id) + + def Create_LOG(self): + str = '' #New!' + str +='Create LOG' + return str + Create_LOG.allow_tags = True + + def Lanes(self): + return '
1)%s2)%s3)%s4)%s5)%s6)%s7)%s8)%s
' % (self.lane_1_library,self.lane_2_library,self.lane_3_library,self.lane_4_library,self.lane_5_library,self.lane_6_library,self.lane_7_library,self.lane_8_library) + Lanes.allow_tags = True + + class Meta: + ordering = ["-run_date"] + + class Admin: + save_on_top = True + date_hierarchy = "run_date" + save_on_top = True + search_fields = ['flowcell_id','seq_mac_id','cluster_mac_id','=lane_1_library__library_id','=lane_2_library__library_id','=lane_3_library__library_id','=lane_4_library__library_id','=lane_5_library__library_id','=lane_6_library__library_id','=lane_7_library__library_id','=lane_8_library__library_id'] + list_display = ('flowcell_id','seq_mac_id','run_date', 'Create_LOG','Lanes') + list_filter = ('seq_mac_id','cluster_mac_id') + fields = ( + (None, { + 'fields': ('run_date', ('flowcell_id','cluster_mac_id','seq_mac_id'), ('read_length'),) + }), + ('Lanes:', { + ##'fields' : (('lane_1_library', 'lane_1_pM', 'lane_1_cluster_estimate', 'lane_1_primer'), ('lane_2_library', 'lane_2_pM', 'lane_2_cluster_estimate', 'lane_2_primer'), ('lane_3_library', 'lane_3_pM', 'lane_3_cluster_estimate', 'lane_3_primer'), ('lane_4_library', 'lane_4_pM', 'lane_4_cluster_estimate', 'lane_4_primer'), ('lane_5_library', 'lane_5_pM', 'lane_5_cluster_estimate', 'lane_5_primer'), ('lane_6_library', 'lane_6_pM', 'lane_6_cluster_estimate', 'lane_6_primer'), ('lane_7_library', 'lane_7_pM', 'lane_7_cluster_estimate', 'lane_7_primer'), ('lane_8_library', 'lane_8_pM', 'lane_8_cluster_estimate', 'lane_8_primer'),) + 'fields' : (('lane_1_library', 'lane_1_pM', 'lane_1_cluster_estimate'), ('lane_2_library', 'lane_2_pM', 'lane_2_cluster_estimate'), ('lane_3_library', 'lane_3_pM', 'lane_3_cluster_estimate'), ('lane_4_library', 'lane_4_pM', 'lane_4_cluster_estimate'), ('lane_5_library', 'lane_5_pM', 'lane_5_cluster_estimate'), ('lane_6_library', 'lane_6_pM', 'lane_6_cluster_estimate'), ('lane_7_library', 'lane_7_pM', 'lane_7_cluster_estimate'), ('lane_8_library', 'lane_8_pM', 'lane_8_cluster_estimate'),) + }), + (None, { + 'fields' : ('notes',) + }), + ) + + +### ----------------------- +class DataRun(models.Model): + ConfTemplate = "CONFIG PARAMS WILL BE GENERATED BY THE PIPELINE SCRIPT.\nYOU'LL BE ABLE TO EDIT AFTER IF NEEDED." + run_folder = models.CharField(max_length=50,unique=True, db_index=True) + fcid = models.ForeignKey(FlowCell,verbose_name="Flowcell Id") + config_params = models.TextField(default=ConfTemplate) + run_start_time = models.DateTimeField(core=True) + RUN_STATUS_CHOICES = ( + (0, 'Sequencer running'), ##Solexa Data Pipeline Not Yet Started'), + (1, 'Data Pipeline Started'), + (2, 'Data Pipeline Interrupted'), + (3, 'Data Pipeline Finished'), + (4, 'CollectReads Started'), + (5, 'CollectReads Finished'), + (6, 'QC Finished'), + (7, 'DONE'), + ) + run_status = models.IntegerField(choices=RUN_STATUS_CHOICES, default=0) + run_note = models.TextField(blank=True) + + + def main_status(self): + str = '= 5: + str += ' style="color:green">' + str += ''+self.RUN_STATUS_CHOICES[self.run_status][1]+'' + str += '

' #New!' + str +='
View QC Page' + else: + str += '>'+self.RUN_STATUS_CHOICES[self.run_status][1] + + str += '' + return str + main_status.allow_tags = True + + main_status.allow_tags = True + + def Flowcell_Info(self): + str = ''+self.fcid.__str__()+'' + str += ' (c: '+self.fcid.cluster_mac_id+', s: '+self.fcid.seq_mac_id+')' + str += '
' + str +='View/hide lanes' + str += '
' + LanesList = '1: '+self.fcid.lane_1_library.__str__()+' ('+self.fcid.lane_1_library.library_species.use_genome_build+')
2: '+self.fcid.lane_2_library.__str__()+' ('+self.fcid.lane_2_library.library_species.use_genome_build+')
3: '+self.fcid.lane_3_library.__str__()+' ('+self.fcid.lane_3_library.library_species.use_genome_build+')
4: '+self.fcid.lane_4_library.__str__()+' ('+self.fcid.lane_4_library.library_species.use_genome_build+')
5: '+self.fcid.lane_5_library.__str__()+' ('+self.fcid.lane_5_library.library_species.use_genome_build+')
6: '+self.fcid.lane_6_library.__str__()+' ('+self.fcid.lane_6_library.library_species.use_genome_build+')
7: '+self.fcid.lane_7_library.__str__()+' ('+self.fcid.lane_7_library.library_species.use_genome_build+')
8: '+self.fcid.lane_8_library.__str__()+' ('+self.fcid.lane_8_library.library_species.use_genome_build+')' + str += LanesList ## self.fcid.Lanes() + str += '
' + str += '
Edit Flowcell record' + #str += 'New!' + str +='GA LOG Page' + str += '
' + str += '
' + return str + Flowcell_Info.allow_tags = True + + class Admin: + search_fields = ['run_folder','run_note','config_params','=fcid__lane_1_library__library_id','=fcid__lane_2_library__library_id','=fcid__lane_3_library__library_id','=fcid__lane_4_library__library_id','=fcid__lane_5_library__library_id','=fcid__lane_6_library__library_id','=fcid__lane_7_library__library_id','=fcid__lane_8_library__library_id'] + + list_display = ('run_folder','Flowcell_Info','run_start_time','main_status','run_note') + list_filter = ('run_status','run_start_time') diff --git a/htsworkflow/frontend/experiments/views.py b/htsworkflow/frontend/experiments/views.py new file mode 100755 index 0000000..3888016 --- /dev/null +++ b/htsworkflow/frontend/experiments/views.py @@ -0,0 +1,60 @@ +# Create your views here. +#from django.template import Context, loader +#shortcut to the above modules +from django.shortcuts import render_to_response, get_object_or_404 +#from htswfrontend.fctracker.models import * +from htswfrontend.exp_track.models import * +from django.http import HttpResponse +from django.core.exceptions import ObjectDoesNotExist + +def index(request): + all_runs = DataRun.objects.all().order_by('-run_start_time') + #t = loader.get_template('exptrack/index.html') + #c = Context({ + # 'data_run_list': all_runs, + #}) + #return HttpResponse(t.render(c)) + # shortcut to the above module usage + return render_to_response('exptrack/index.html',{'data_run_list': all_runs}) + +def detail(request, run_folder): + html_str = '

Exp Track Details Page

' + html_str += 'Run Folder: '+run_folder + r = get_object_or_404(DataRun,run_folder=run_folder) + return render_to_response('exptrack/detail.html',{'run_f': r}) + +def makeFCSheet(request,fcid): + # get Flowcell by input fcid + # ... + rec = None + try: + rec = FlowCell.objects.get(flowcell_id=fcid) + except ObjectDoesNotExist: + pass + lanes = ['1','2','3','4','5','6','7','8'] + return render_to_response('exptrack/flowcellSheet.html',{'fc': rec}) + +def test_Libs(request): + str = '' + str += '' + allLibs = Library.objects.all() + #allLibs = Library.objects.filter(antibody__isnull=False) + for L in allLibs: + str += '' + str += '' + str += '' + + str += '
Lib IDCurrent Libaray Name (Free Text)Auto-composed Libaray Name (antibody + celline + libid + species + [replicate])
'+L.library_id+''+L.library_name+'' + str += L.experiment_type+'_' + if L.cell_line.cellline_name != 'Unknown': + str += L.cell_line.cellline_name+'_' + + try: + if L.antibody is not None: + str += L.antibody.nickname + '_' + except Antibody.DoesNotExist: + pass + + str += 'Rep'+L.replicate.__str__() + str += '
' + return HttpResponse(str) diff --git a/htsworkflow/frontend/reports/LibraryInfo.xml b/htsworkflow/frontend/reports/LibraryInfo.xml new file mode 100644 index 0000000..4e7992a --- /dev/null +++ b/htsworkflow/frontend/reports/LibraryInfo.xml @@ -0,0 +1,1024 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/htsworkflow/frontend/reports/__init__.py b/htsworkflow/frontend/reports/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/htsworkflow/frontend/reports/ht_urls.py b/htsworkflow/frontend/reports/ht_urls.py new file mode 100644 index 0000000..39871b8 --- /dev/null +++ b/htsworkflow/frontend/reports/ht_urls.py @@ -0,0 +1,5 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('', + (r'^updLibInfo$', 'htswfrontend.htsw_reports.libinfopar.refreshLibInfoFile'), +) diff --git a/htsworkflow/frontend/reports/libinfopar.py b/htsworkflow/frontend/reports/libinfopar.py new file mode 100644 index 0000000..56c75ad --- /dev/null +++ b/htsworkflow/frontend/reports/libinfopar.py @@ -0,0 +1,93 @@ +from django.http import HttpResponse +from datetime import datetime +from string import * +import re +from xml.sax import make_parser +from xml.sax.handler import ContentHandler +import urllib +import urllib2 +import os + +''' +Example library node from LibraryInfo.xml: + + + + + +''' +class LibInfoHandler(ContentHandler): + + def __init__ (self, searchTerm): + self.searchTerm= searchTerm + self.currlibid = '' + self.LanesCount, self.ReadsCount = 0, 0 + self.Msg = '' + + def startElement(self, name, attrs): + if name == 'Library': + self.currlibid = attrs.get('Name',"") + elif name == 'Track' and self.searchTerm == self.currlibid: + self.LanesCount += len(attrs.get('Lane',"")) + self.ReadsCount += int(attrs.get('Count',"")) + else: + self.Msg += ' | name = '+name+', currlibid = '+ self.currlibid + return + + #def characters (self, ch): + # return .. + + #def endElement(self, name): + # return .. + + +## TO DO: Change this to read the LibraryInfo.xml only ONCE per ReoprtRequest (do it in the models.py). + Read it directly from the analysis_server + +def getLibReads(libid): + searchTerm= libid + parser = make_parser() + curHandler = LibInfoHandler(searchTerm) + parser.setContentHandler(curHandler) + parser.parse(open('/htsworkflow/htswfrontend/htswfrontend/htsw_reports/LibInfo/LibraryInfo.xml')) + arRes = [] + arRes.append(curHandler.LanesCount) + arRes.append(curHandler.ReadsCount) + return arRes + +def getWebPage(url,params): + pdata = urllib.urlencode(params) + req = urllib2.Request(url,pdata) + wpage = urllib2.urlopen(req) + restext = wpage.read() + wpage.close() + return restext + +def refreshLibInfoFile(request): + varStatus = 'getting conf file from exp trac server' + url = 'http://m304-apple-server.stanford.edu/ENCODE/LibraryInfo.xml' + params = {} + readw = getWebPage(url,params) + # make sure file content starts as xml + match_str = re.compile('^<\?xml.+') + if match_str.search(readw): ##tempstr): + # Rename current file with timestamp + year = datetime.today().year.__str__() + year = replace(year,'20','') + month = datetime.today().month + if month < 10: month = "0"+month.__str__() + else: month = month.__str__() + day = datetime.today().day + if day < 10: day = "0"+day.__str__() + else: day = day.__str__() + mydate = year+month+day + folder = '/htsworkflow/htswfrontend/htswfrontend/htsw_reports/LibInfo/' + os.rename(folder+'LibraryInfo.xml',folder+mydate+'_LibraryInfo.xml') + # create file in curret folder + file_path = os.path.join(folder,'LibraryInfo.xml') + f = open(file_path, 'w') + f.write(readw) + f.close() + varStatus = 'OK. LibraryInfo.xml refreshed at Web server.' + else: + varStatus = 'Failed reading valid LibraryInfo.xml server reply:\n'+readw + return HttpResponse(varStatus) diff --git a/htsworkflow/frontend/reports/models.py b/htsworkflow/frontend/reports/models.py new file mode 100644 index 0000000..8554688 --- /dev/null +++ b/htsworkflow/frontend/reports/models.py @@ -0,0 +1,238 @@ +from django.db import models +from django.db.models import Q +from django.core.exceptions import ObjectDoesNotExist +from datetime import datetime +from htswfrontend.fctracker.models import * +from htswfrontend.analys_track.models import * +from htswfrontend.exp_track.models import * +from string import * +from htswfrontend.htsw_reports.utils import * +import re +##from p1 import LibInfo +from libinfopar import * + +## This is a table based REPORT generator. The goal is to display a Progress Report for all the ENCODE projects, based on Study Name (e.g. NRSF, FOXP2, Methy-Seq on .. etc). + +class ProgressReport(models.Model): + st_sbj = models.ForeignKey(Project,limit_choices_to = Q(project_name__startswith='ENCODE '),related_name='project',db_index=True,verbose_name="Studied Subject") + interactome_complete = models.BooleanField(default=False) + + def Study(self): + str = self.st_sbj.__str__() + str += '

' + str += 'Edit Project' + return str + Study.allow_tags = True + + def submit_to_DCC(self): + varText = '' + if self.note_about_DCC: + varText += '
Note:
'+self.note_about_DCC + return '%s
%s' % (self.submitted_to_DCC,varText) + submit_to_DCC.allow_tags = True + + def submit_to_NCBI(self): + varText = '' + if self.note_about_NCBI: + varText += '
Note:
'+self.note_about_NCBI + return '%s
%s' % (self.submitted_to_NCBI,varText) + submit_to_NCBI.allow_tags = True + + ## -- Utility functions <-- This method was transfered to untils.py + + ## --- LIBARAY PREPARATION SECTION + def getLibIds(self): + ptasks = self.st_sbj.tasks.distinct() + arLibs = [] + for t in ptasks: + if t.subject1 is not None: + arLibs.append(t.subject1.library_id) + if t.subject2 is not None: + arLibs.append(t.subject2.library_id) + arLibs = unique(arLibs) + return arLibs #.sort() + + def getFCInfo(self,libid): ## This is the haviest function + arFCLanes = [] + ##Test return arFCLanes + # can't get this to work: FC_L1 = FlowCell.objects.filter(lane_5_library__exact=libid) + allFCs = FlowCell.objects.all() + for f in allFCs: + entry = '' + lanes = [] + #found = False +# for i in range(1,9): +# if eval('f.lane_'+i.__str__()+'_library.library_id==libid'): +# lanes.append(i.__str__()) +# found = True + +# maybe a bit faster this way: + if f.lane_1_library.library_id==libid: + lanes.append('1') + #found = True + if f.lane_2_library.library_id==libid: + lanes.append('2') + #found = True + if f.lane_3_library.library_id==libid: + lanes.append('3') + #found = True + if f.lane_4_library.library_id==libid: + lanes.append('4') + #found = True + if f.lane_5_library.library_id==libid: + lanes.append('5') + #found = True + if f.lane_6_library.library_id==libid: + lanes.append('6') + #found = True + if f.lane_7_library.library_id==libid: + lanes.append('7') + #found = True + if f.lane_8_library.library_id==libid: + lanes.append('8') + #found = True + + + #if found: + if len(lanes)>0: + rundate = re.sub(pattern="\s.*$",repl="",string=f.run_date.__str__()) + entry = ''+f.flowcell_id + ' Lanes No.: '+','.join(lanes)+' ('+rundate+')' + arFCLanes.append(entry) + if len(arFCLanes)==0: + arFCLanes.append('Flowcell not found.') + return arFCLanes + + def ab_batch(self): + ## To have the Company's lot number, apearing on the (source) tube, we need to add new Field in Library. + arlibs = self.getLibIds() + tstr = '
    ' ##Ab from '+len(arlibs).__str__()+' libs: ' + arRows = [] + for l in arlibs: + try: + rec = Library.objects.get(library_id=l,antibody__isnull=False) + arRows.append('
  • '+rec.antibody.antibodies+' for '+rec.antibody.antigene+' (src:'+rec.antibody.source+', cat:'+rec.antibody.catalog+')
  • ') + except ObjectDoesNotExist: + tstr += "" + tstr += "".join(unique(arRows))+'
' + return tstr + ab_batch.allow_tags = True + + def cell_line(self): + arlibs = self.getLibIds() + tstr = '
    ' + arRows = [] + for l in arlibs: + try: + rec = Library.objects.get(library_id=l) + arRows.append('
  • '+rec.cell_line.cellline_name+' ('+rec.condition.condition_name+')
  • ') + except ObjectDoesNotExist: + tstr += "" + tstr += "".join(unique(arRows))+'
' + return tstr + cell_line.allow_tags = True + + def cell_harvest_batch(self): # <- data now displayed in "cell_line" + ## name + date + arlibs = self.getLibIds() + tstr = '
    ' + arRows = [] + for l in arlibs: + try: + rec = Library.objects.get(library_id=l) + arRows.append('
  • '+rec.condition.condition_name+'
  • ') + except ObjectDoesNotExist: + tstr += "" + tstr += "".join(unique(arRows))+'
' + return tstr + cell_harvest_batch.allow_tags = True + + def ChIP_made(self): + ## person + date + return '...' + + def library(self): + ## Lib Id + Date + Person + tstr = '' + arlibs = self.getLibIds() ##.sort() + arlibs = arlibs + tstr +='view /hide' + tstr += '
    ' + arRows = [] + for l in arlibs: + try: + rec = Library.objects.get(library_id=l) + arRows.append('
  • '+rec.library_id+': '+rec.library_name+'.
    Made By: '+rec.made_by+', On: '+ rec.creation_date.__str__()+'
  • ') + except ObjectDoesNotExist: + tstr += "" + tstr += "".join(unique(arRows))+'
' + return tstr + library.allow_tags = True + + + ## -- SEQUENCING SECTION + def sequencing(self): + ## FCId + Lane + Date + arlibs = self.getLibIds() + tstr ='view /hide' + tstr += '
    ' + for l in arlibs: + tstr += '
  • '+l+':
    '+(' / '.join(self.getFCInfo(l)))+'
  • ' + tstr += '
' + return tstr + sequencing.allow_tags = True + + def aligned_reads(self): + ## Mega reads/lane + arlibs = self.getLibIds() + tstr = 'view /hide' + tstr += '
' + tstr += '' + LanesCnt, ReadsCnt = 0, 0 + for l in arlibs: + res = getLibReads(l) + LanesCnt += res[0] + ReadsCnt += res[1] + rc = "%1.2f" % (res[1]/1000000.0) + tstr += '' + tstr += '
Library IdTotal LanesM Reads
'+l+''+res[0].__str__()+''+rc+'
' + #tstr += 'Project results page' + tstr += '
' + myNum = (ReadsCnt/1000000.0) + myNum = "%1.2f" % (myNum) + tstr += '
Total: '+LanesCnt.__str__()+' lanes and '+myNum+' M Reads
' + tstr += 'Project results page' + return tstr + aligned_reads.allow_tags = True + + def peak_calling(self): + # date + what etc.. + return 'coming up ..' + + QPCR = models.CharField(max_length=500,blank=True,null=True) + submitted_to_DCC = models.DateTimeField(core=True,blank=True,null=True) + submitted_to_NCBI = models.DateTimeField(core=True,blank=True,null=True) + note_about_DCC = models.TextField(blank=True) + note_about_NCBI = models.TextField(blank=True) + + def __str__(self): + return '"%s" - %s' % (self.st_sbj,self.interactome_complete) + + class Meta: + #verbose_name_plural = "Reports" + ordering = ["id"] + + class Admin: + list_display = ('Study','ab_batch','cell_line','library','sequencing','aligned_reads','QPCR','submit_to_DCC','submit_to_NCBI','interactome_complete') + ## list_filter = ('interactome_complete') + + +############################################# diff --git a/htsworkflow/frontend/reports/utils.py b/htsworkflow/frontend/reports/utils.py new file mode 100644 index 0000000..7b2d1b8 --- /dev/null +++ b/htsworkflow/frontend/reports/utils.py @@ -0,0 +1,61 @@ +def unique(s): + """Return a list of the elements in s, but without duplicates. + For example, unique([1,2,3,1,2,3]) is some permutation of [1,2,3], + unique("abcabc") some permutation of ["a", "b", "c"], and + unique(([1, 2], [2, 3], [1, 2])) some permutation of + [[2, 3], [1, 2]]. + For best speed, all sequence elements should be hashable. Then + unique() will usually work in linear time. + If not possible, the sequence elements should enjoy a total + ordering, and if list(s).sort() doesn't raise TypeError it's + assumed that they do enjoy a total ordering. Then unique() will + usually work in O(N*log2(N)) time. + If that's not possible either, the sequence elements must support + equality-testing. Then unique() will usually work in quadratic + time. + """ + + n = len(s) + if n == 0: + return [] + + # Try using a dict first, as that's the fastest and will usually + # work. If it doesn't work, it will usually fail quickly, so it + # usually doesn't cost much to *try* it. It requires that all the + # sequence elements be hashable, and support equality comparison. + u = {} + try: + for x in s: + u[x] = 1 + except TypeError: + del u # move on to the next method + else: + return u.keys() + # We can't hash all the elements. Second fastest is to sort, + # which brings the equal elements together; then duplicates are + # easy to weed out in a single pass. + # NOTE: Python's list.sort() was designed to be efficient in the + # presence of many duplicate elements. This isn't true of all + # sort functions in all languages or libraries, so this approach + # is more effective in Python than it may be elsewhere. + try: + t = list(s) + t.sort() + except TypeError: + del t # move on to the next method + else: + assert n > 0 + last = t[0] + lasti = i = 1 + while i < n: + if t[i] != last: + t[lasti] = last = t[i] + lasti += 1 + i += 1 + return t[:lasti] + # Brute force is all that's left. + u = [] + for x in s: + if x not in u: + u.append(x) + return u diff --git a/htsworkflow/frontend/samples/__init__.py b/htsworkflow/frontend/samples/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/htsworkflow/frontend/fctracker/models.py b/htsworkflow/frontend/samples/models.py similarity index 100% rename from htsworkflow/frontend/fctracker/models.py rename to htsworkflow/frontend/samples/models.py diff --git a/htsworkflow/frontend/fctracker/views.py b/htsworkflow/frontend/samples/views.py similarity index 100% rename from htsworkflow/frontend/fctracker/views.py rename to htsworkflow/frontend/samples/views.py diff --git a/htsworkflow/frontend/settings.py b/htsworkflow/frontend/settings.py index c9bee20..ec40041 100644 --- a/htsworkflow/frontend/settings.py +++ b/htsworkflow/frontend/settings.py @@ -1,18 +1,79 @@ +""" +Generate settings for the Django Application. + +To make it easier to customize the application the settings can be +defined in a configuration file read by ConfigParser. + +The options understood by this module are (with their defaults): + + [frontend] + email_host=localhost + email_port=25 + database_engine=sqlite3 + database_name=/path/to/db + + [admins] + #name1=email1 + + [allowed_hosts] + #name1=ip + localhost=127.0.0.1 + + [allowed_analysis_hosts] + #name1=ip + localhost=127.0.0.1 + +""" +import ConfigParser import os +def options_to_list(dest, section_name): + """ + Load a options from section_name and store in a dictionary + """ + if options.has_section(section_name): + for name in options.options(section_name): + dest.append( options.get(section_name, name) ) + +def options_to_dict(dest, section_name): + """ + Load a options from section_name and store in a dictionary + """ + if options.has_section(section_name): + for name in options.options(section_name): + dest[name] = options.get(section_name, name) + +# define your defaults here +options = ConfigParser.SafeConfigParser( + { 'email_host': 'localhost', + 'email_port': '25', + 'database_engine': 'sqlite3', + 'database_name': + os.path.abspath('/htsworkflow/htswfrontend/dev_fctracker.db'), + 'time_zone': 'America/Los_Angeles', + }) + +options.read([os.path.expanduser("~/.htsworkflow.ini"), + '/etc/htsworkflow.ini',]) + # Django settings for elandifier project. DEBUG = True TEMPLATE_DEBUG = DEBUG -ADMINS = ( - # ('Your Name', 'your_email@domain.com'), -) +ADMINS = [] +options_to_list(ADMINS, 'admins') MANAGERS = ADMINS -DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. -DATABASE_NAME = os.path.abspath('../../fctracker.db') # Or path to database file if using sqlite3. +EMAIL_HOST = options.get('frontend', 'email_host') +EMAIL_PORT = int(options.get('frontend', 'email_port')) + +# 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. +DATABASE_ENGINE = options.get('frontend', 'database_engine') + +# Or path to database file if using sqlite3. +DATABASE_NAME = options.get('frontend', 'database_name' ) DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. @@ -23,7 +84,7 @@ DATABASE_PORT = '' # Set to empty string for default. Not used with # although not all variations may be possible on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. -TIME_ZONE = 'America/Los_Angeles' +TIME_ZONE = options.get('frontend', 'time_zone') # Language code for this installation. All choices can be found here: # http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes @@ -72,7 +133,7 @@ TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. - os.path.abspath("../../templates"), + os.path.abspath("../templates"), ) INSTALLED_APPS = ( @@ -83,12 +144,21 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'htsworkflow.frontend.eland_config', 'htsworkflow.frontend.fctracker', + # modules from htsworkflow branch + #'htswfrontend.exp_track', + #'htswfrontend.analys_track', + #'htswfrontend.htsw_reports', 'django.contrib.databrowse', ) # Project specific settings -UPLOADTO_HOME = os.path.abspath('../../uploads') -UPLOADTO_CONFIG_FILE = os.path.join(UPLOADTO_HOME, 'eland_config') -UPLOADTO_ELAND_RESULT_PACKS = os.path.join(UPLOADTO_HOME, 'eland_results') -UPLOADTO_BED_PACKS = os.path.join(UPLOADTO_HOME, 'bed_packs') +ALLOWED_IPS={'localhost': '127.0.0.1'} +options_to_dict(ALLOWED_IPS, 'allowed_hosts') + +ALLOWED_ANALYS_IPS = {'localhost': '127.0.0.1'} +options_to_dict(ALLOWED_ANALYS_IPS, 'allowed_analysis_hosts') +#UPLOADTO_HOME = os.path.abspath('../../uploads') +#UPLOADTO_CONFIG_FILE = os.path.join(UPLOADTO_HOME, 'eland_config') +#UPLOADTO_ELAND_RESULT_PACKS = os.path.join(UPLOADTO_HOME, 'eland_results') +#UPLOADTO_BED_PACKS = os.path.join(UPLOADTO_HOME, 'bed_packs') diff --git a/htsworkflow/frontend/urls.py b/htsworkflow/frontend/urls.py index a791b85..e06d92d 100644 --- a/htsworkflow/frontend/urls.py +++ b/htsworkflow/frontend/urls.py @@ -11,6 +11,10 @@ urlpatterns = patterns('', (r'^eland_config/', include('htsworkflow.frontend.eland_config.urls')), # Admin: (r'^admin/', include('django.contrib.admin.urls')), - # Databrowser: - (r'^databrowse/(.*)', databrowse.site.root), + # ExpTrack: + (r'^experiments/', include('htswfrontend.experiments.et_urls')), + # AnalysTrack: + (r'^analysis/', include('htswfrontend.analysis.an_urls')), + # Report Views: + # (r'^reports/', include('gaworkflow.frontend....urls')), ) -- 2.30.2