Additionally added displaying that information on the flowcell page.
class FileTypeAdmin(admin.ModelAdmin):
list_display = ('name', 'mimetype', 'regex')
admin.site.register(FileType, FileTypeAdmin)
-
+
# lane form setup needs to come before Flowcell form config
# as flowcell refers to the LaneInline class
class LaneForm(ModelForm):
comment = CharField(widget=TextInput(attrs={'size':'80'}), required=False)
-
+
class Meta:
model = Lane
}),
)
admin.site.register(Lane, LaneOptions)
-
+
class FlowCellOptions(admin.ModelAdmin):
date_hierarchy = "run_date"
save_on_top = True
admin.site.register(ClusterStation, ClusterStationOptions)
class SequencerOptions(admin.ModelAdmin):
- list_display = ('name', )
- fieldsets = ( ( None, { 'fields': ( 'name', ) } ), )
+ list_display = ('name', 'instrument_name', 'model')
+ fieldsets = ( ( None,
+ { 'fields': (
+ 'name', 'instrument_name', 'serial_number',
+ 'model', 'comment') } ), )
admin.site.register(Sequencer, SequencerOptions)
"name": "QSEQ tarfile",
"regex": ".*_l(?P<lane>[1-8])_r(?P<end>[1-4])\\.tar\\.bz2\\Z(?ms)"
}
+ },
+ { "model": "experiments.Sequencer",
+ "pk": 1,
+ "fields": {
+ "name": "Rotifer",
+ "instrument_name": "ILLUMINA-33A494",
+ "serial_number": "",
+ "model": "Illumina Genome Analyzer II",
+ "comment": "after 2010 pipeline name, was exchanged for hiseq"
+ }
+ },
+ { "model": "experiments.Sequencer",
+ "pk": 2,
+ "fields": {
+ "name": "Tardigrade",
+ "instrument_name": "ILLUMINA-EC5D15",
+ "serial_number": "",
+ "model": "Illumina Genome Analyzer IIx",
+ "comment": "after 2010 pipeline name"
+ }
+ },
+ { "model": "experiments.Sequencer",
+ "pk": 3,
+ "fields": {
+ "name": "Elsewhere",
+ "instrument_name": "",
+ "serial_number": "",
+ "model": "Unknown",
+ "comment": "Sequenced somewhere else"
+ }
+ },
+ { "model": "experiments.Sequencer",
+ "pk": 4,
+ "fields": {
+ "name": "Volvox",
+ "instrument_name": "HWI-ST0787",
+ "serial_number": "",
+ "model": "Illumina HiSeq 2000",
+ "comment": ""
+ }
+ },
+ { "model": "experiments.Sequencer",
+ "pk": 5,
+ "fields": {
+ "name": "Tardigrade (older)",
+ "instrument_name": "HWUSI-EAS627",
+ "serial_number": "",
+ "model": "Illumina Genome Analyzer II",
+ "comment": "earlier version of tardigrade"
+ }
+ },
+ { "model": "experiments.Sequencer",
+ "pk": 6,
+ "fields": {
+ "name": "Rotifer (older)",
+ "instrument_name": "HWUSI-EAS229",
+ "serial_number": "",
+ "model": "Illumina Genome Analyzer II",
+ "comment": "earlier rotifer name"
+ }
+ },
+ { "model": "experiments.Sequencer",
+ "pk": 7,
+ "fields": {
+ "name": "First sequencer",
+ "instrument_name": "USI-EAS44",
+ "serial_number": "",
+ "model": "Illumina Genome Analyzer I",
+ "comment": "our first sequencer"
+ }
}
-
]
\ No newline at end of file
{"pk": 1, "model": "experiments.clusterstation", "fields": {"name": "old"}},
{"pk": 2, "model": "experiments.clusterstation", "fields": {"name": "loaner"}},
{"pk": 3, "model": "experiments.clusterstation", "fields": {"name": "new"}},
- {"pk": 1, "model": "experiments.sequencer", "fields": {"name": "Rotifer (HWI-EAS229)"}},
- {"pk": 2, "model": "experiments.sequencer", "fields": {"name": "Tardigrade"}},
+ {"pk": 1, "model": "experiments.sequencer",
+ "fields": { "name": "Rotifer (HWI-EAS229)" }},
+ {"pk": 2, "model": "experiments.sequencer",
+ "fields": {"name": "Tardigrade",
+ "instrument_name": "ILLUMINA-EC5D15",
+ "model": "Illumina Genome Analyzer IIx"}
+ },
{"pk": 3, "model": "experiments.sequencer", "fields": {"name": "Sequenced somewhere else."}},
{"pk": 153, "model": "experiments.flowcell",
"fields": {
return unicode(self.name)
class Sequencer(models.Model):
- name = models.CharField(max_length=50, unique=True)
+ name = models.CharField(max_length=50, db_index=True)
+ instrument_name = models.CharField(max_length=50, db_index=True)
+ serial_number = models.CharField(max_length=50, db_index=True)
+ model = models.CharField(max_length=255)
+ comment = models.CharField(max_length=255)
def __unicode__(self):
- return unicode(self.name)
+ name = [unicode(self.name)]
+ if self.instrument_name is not None:
+ name.append("(%s)" % (unicode(self.instrument_name),))
+ return " ".join(name)
+
+ @models.permalink
+ def get_absolute_url(self):
+ return ('htsworkflow.frontend.experiments.views.sequencer',
+ [self.id])
+
class FlowCell(models.Model):
flowcell_id = models.CharField(max_length=20, unique=True, db_index=True)
"""Convert a list of lane entries into a dictionary indexed by library ID
"""
return dict( ((x['library_id'],x) for x in lane) )
+
+class TestSequencer(TestCase):
+ fixtures = ['test_flowcells.json',
+ ]
+
+ def test_name_generation(self):
+ seq = models.Sequencer()
+ seq.name = "Seq1"
+ seq.instrument_name = "HWI-SEQ1"
+ seq.model = "Imaginary 5000"
+
+ self.failUnlessEqual(unicode(seq), "Seq1 (HWI-SEQ1)")
+
+ def test_lookup(self):
+ fc = models.FlowCell.objects.get(pk=153)
+ self.failUnlessEqual(fc.sequencer.model,
+ "Illumina Genome Analyzer IIx")
+ self.failUnlessEqual(fc.sequencer.instrument_name,
+ "ILLUMINA-EC5D15")
+
+ def test_rdf(self):
+ response = self.client.get('/flowcell/FC12150/', apidata)
+ tree = fromstring(response.content)
+ divs = tree.xpath('//div[@rel="libns:sequenced_by"]',
+ namespaces=NSMAP)
+ self.failUnlessEqual(len(divs), 1)
+ self.failUnlessEqual(divs[0].attrib['rel'], 'libns:sequenced_by')
+ self.failUnlessEqual(divs[0].attrib['resource'], '/sequencer/2')
+
+ name = divs[0].xpath('./span[@property="libns:sequencer_name"]')
+ self.failUnlessEqual(len(name), 1)
+ self.failUnlessEqual(name[0].text, 'Tardigrade')
+ instrument = divs[0].xpath(
+ './span[@property="libns:sequencer_instrument"]')
+ self.failUnlessEqual(len(instrument), 1)
+ self.failUnlessEqual(instrument[0].text, 'ILLUMINA-EC5D15')
+ model = divs[0].xpath(
+ './span[@property="libns:sequencer_model"]')
+ self.failUnlessEqual(len(model), 1)
+ self.failUnlessEqual(model[0].text, 'Illumina Genome Analyzer IIx')
DataRun, \
DataFile, \
FlowCell, \
- Lane
+ Lane, \
+ Sequencer
from htsworkflow.frontend.experiments.experiments import \
estimateFlowcellDuration, \
estimateFlowcellTimeRemaining, \
#c = Context({
# 'data_run_list': all_runs,
#})
- #return HttpResponse(t.render(c))
+ #return HttpResponse(t.render(c))
# shortcut to the above module usage
- return render_to_response('experiments/index.html',{'data_run_list': all_runs})
-
+ return render_to_response('experiments/index.html',{'data_run_list': all_runs})
+
def detail(request, run_folder):
html_str = '<h2>Exp Track Details Page</h2>'
html_str += 'Run Folder: '+run_folder
if user.email is None or len(user.email) == 0:
warnings.append((user.admin_url(), user.username))
user=None
-
+
for user_email in email_lane.keys():
sending = ""
# build body
u'runfolder': 'blank',
u'finish_low': estimate_low,
u'finish_high': estimate_high,
- u'now': datetime.now(),
+ u'now': datetime.now(),
})
# build view
'warnings': warnings,
})
return HttpResponse(email_verify.render(verify_context))
-
+
def finishedEmail(request, pk):
"""
"""
fc = get_object_or_404(FlowCell, flowcell_id__startswith=flowcell_id)
fc.update_data_runs()
-
+
if lane_number is not None:
lanes = fc.lane_set.filter(lane_number=lane_number)
else:
context = RequestContext(request,
{'flowcell': fc,
'lanes': lanes})
-
+
return render_to_response('experiments/flowcell_detail.html',
context)
dataruns = []
for run in lane.flowcell.datarun_set.all():
dataruns.append((run, lane.lane_number, run.lane_files()[lane.lane_number]))
-
+
context = RequestContext(request,
{'lib': lane.library,
'lane': lane,
'flowcell': lane.flowcell,
'filtered_dataruns': dataruns})
-
+
return render_to_response('experiments/flowcell_lane_detail.html',
context)
"""Return the contents of filename if everything is approved
"""
data_file = get_object_or_404(DataFile, random_key = key)
-
+
mimetype = 'application/octet-stream'
if data_file.file_type.mimetype is not None:
mimetype = data_file.file_type.mimetype
mimetype=mimetype)
raise Http404
-
-
+
+
+def sequencer(request, sequencer_id):
+ sequencer = get_object_or_404(Sequencer, id=sequencer_id)
+ context = RequestContext(request,
+ {'sequencer': sequencer})
+ return render_to_response('experiments/sequencer.html', context)
<b>Flowcell</b>:
<a href="{{flowcell.get_absolute_url}}" property="libns:flowcell_id">{{flowcell.flowcell_id}}</a>{% if user.is_staff %}<a href="{{flowcell.get_admin_url}}"><img class="icon_button" src="/media/img/admin/icon_changelink.gif" alt="Edit"/></a>{% endif%}
<br property="rdf:type" content="libns:illumina_flowcell"/>
+ <div rel="libns:sequenced_by"
+ resource="{{flowcell.sequencer.get_absolute_url}}">
+ <b>Instrument</b>:
+ <span property="libns:sequencer_name">{{ flowcell.sequencer.name }}</span>
+ {% if flowcell.sequencer.instrument_name %}
+ (<span property="libns:sequencer_instrument">{{ flowcell.sequencer.instrument_name}}</span>)
+ {% endif %}
+ <br/>
+ <b>Instrument Model</b>:
+ <span property="libns:sequencer_model">{{flowcell.sequencer.model}}</span>
+ <br/>
+ </div>
<b>Run Date</b>:
<span property="libns:date" content="{{flowcell.run_date|date:'Y-m-d\TH:i:s'}}" datatype="xsd:dateTime">{{ flowcell.run_date }}</span><br/>
<b>Type</b>:
--- /dev/null
+{% extends "base_site.html" %}
+{% load adminmedia humanize i18n %}
+{% block extrahead %}
+ <!-- App Stuff -->
+ <link type="text/css" rel="stylesheet" href="/static/css/app.css" />
+ <script type="text/javascript" src="/static/js/jquery.min.js"></script>
+
+ {% block additional_javascript %}
+ {% endblock %}
+{% endblock %}
+
+{% block content %}
+ <h1>Sequencer</h1>
+ <dl about="{{sequencer.get_absolute_url}}" typeof="libns:sequencer">
+ <dt>Name</dt>
+ <dl property="libns:sequencer_name">{{sequencer.name}}</dl>
+ <dt>Instrument Name</dt>
+ <dl property="libns:insrument_name">{{sequencer.instrument_name}}</dl>
+ <dt>Model</dt>
+ <dl property="libns:model">{{sequencer.model}}</dl>
+ <dt>Comment</dt>
+ <dl></dl>
+ </dl>
+{% endblock %}
'htsworkflow.frontend.samples.views.library_id_to_admin_url'),
# sample / library information
(r'^samples/', include('htsworkflow.frontend.samples.urls')),
+ (r'^sequencer/(?P<sequencer_id>\w+)',
+ 'htsworkflow.frontend.experiments.views.sequencer'),
# Raw result files
(r'^results/(?P<flowcell_id>\w+)/(?P<cnm>C[0-9]+-[0-9]+)/summary/',
'htsworkflow.frontend.samples.views.summaryhtm_fc_cnm'),