Skip to content
This repository has been archived by the owner on Aug 24, 2022. It is now read-only.

Commit

Permalink
calculate turnaround
Browse files Browse the repository at this point in the history
  • Loading branch information
anatskiy committed Jun 10, 2018
1 parent 1507533 commit 6298d0f
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 55 deletions.
2 changes: 1 addition & 1 deletion pooling/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def get_request(self, obj):
return self._get_request(obj).get('pk', None)

def get_request_name(self, obj):
return self._get_request(obj).get('name', '')
return self._get_request(obj).get('name', None)

def get_concentration_c1(self, obj):
pooling_object = self._get_pooling_object(obj)
Expand Down
12 changes: 9 additions & 3 deletions pooling/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,14 @@ def get_context(self, queryset):
# Get Requests in one query
requests = Request.objects.filter(
Q(libraries__in=library_ids) | Q(samples__in=sample_ids)
).prefetch_related('samples').values(
'pk', 'name', 'libraries__id', 'samples__id'
).prefetch_related(
'libraries',
'samples'
).values(
'pk',
'name',
'libraries__id',
'samples__id',
).distinct()

requests_map = {}
Expand All @@ -106,7 +112,7 @@ def get_context(self, queryset):
'pk': item['pk'],
'name': item['name'],
}
else:
if item['samples__id']:
requests_map[item['samples__id'], 'Sample'] = {
'pk': item['pk'],
'name': item['name'],
Expand Down
24 changes: 8 additions & 16 deletions report/templates/report.html
Original file line number Diff line number Diff line change
Expand Up @@ -166,27 +166,19 @@
<caption>Turnaround (all-time)</caption>
<thead>
<tr>
<th width="50%">Step</th>
<th width="50%">Average # of Days</th>
{% for column in turnaround.columns %}
<th>{{ column }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in turnaround.rows %}
<tr>
<td>Library Preparation</td>
<td>{{ turnaround.library_preparation|to_int }}</td>
</tr>
<tr>
<td>Pooling</td>
<td>{{ turnaround.pooling|to_int }}</td>
</tr>
<tr>
<td>Sequencing</td>
<td>{{ turnaround.sequencing|to_int }}</td>
</tr>
<tr>
<td>Complete Workflow</td>
<td>{{ turnaround.complete_workflow|to_int }}</td>
{% for column in turnaround.columns %}
<td>{{ row|get_value:column }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>

Expand Down
82 changes: 47 additions & 35 deletions report/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required

from .sql import QUERY, LIBRARY_SELECT, SAMPLE_SELECT, SAMPLE_JOINS
import numpy as np
from pandas import DataFrame

from common.utils import print_sql_queries
from .sql import QUERY, LIBRARY_SELECT, SAMPLE_SELECT, SAMPLE_JOINS

Organization = apps.get_model('common', 'Organization')
PrincipalInvestigator = apps.get_model('common', 'PrincipalInvestigator')
Expand Down Expand Up @@ -209,27 +210,17 @@ def get_pi_sequencer_counts(self):
return OrderedDict(sorted(data.items()))

def get_turnaround(self):
columns = [
'library_preparation',
'pooling',
'sequencing',
'complete_workflow',
]

query = '''
CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS SELECT
L.id,
CAST('Library' AS CHAR) rtype,
CAST('Library' AS CHAR(7)) rtype,
L.create_time date1,
CAST(NULL AS TIMESTAMPTZ) date2,
P.create_time date3
FROM library_library L
LEFT JOIN pooling_pooling P
ON L.id = P.library_id;
CAST(NULL AS TIMESTAMPTZ) date2
FROM library_library L;
CREATE TEMPORARY TABLE IF NOT EXISTS temp2 AS SELECT
L.id,
MIN(F.create_time) date4
MIN(F.create_time) date3
FROM library_library L
LEFT JOIN index_generator_pool_libraries PR
ON L.id = PR.library_id
Expand All @@ -245,19 +236,16 @@ def get_turnaround(self):
CREATE TEMPORARY TABLE IF NOT EXISTS temp3 AS SELECT
S.id,
CAST('Sample' AS CHAR) rtype,
CAST('Sample' AS CHAR(6)) rtype,
S.create_time date1,
LP.create_time date2,
P.create_time date3
LP.create_time date2
FROM sample_sample S
LEFT JOIN library_preparation_librarypreparation LP
ON S.id = LP.sample_id
LEFT JOIN pooling_pooling P
ON S.id = P.sample_id;
ON S.id = LP.sample_id;
CREATE TEMPORARY TABLE IF NOT EXISTS temp4 AS SELECT
S.id,
MIN(F.create_time) date4
MIN(F.create_time) date3
FROM sample_sample S
LEFT JOIN index_generator_pool_samples PR
ON S.id = PR.sample_id
Expand All @@ -272,16 +260,7 @@ def get_turnaround(self):
GROUP BY S.id;
SELECT
FLOOR(AVG(CASE
WHEN rtype = 'Library' THEN NULL
ELSE DATE_PART('day', date2 - date1)
END)) "Library Preparation",
FLOOR(AVG(CASE
WHEN rtype = 'Library' THEN DATE_PART('day', date3 - date1)
ELSE DATE_PART('day', date3 - date2)
END)) "Pooling",
FLOOR(AVG(DATE_PART('day', date4 - date3))) "Sequencing",
FLOOR(AVG(DATE_PART('day', date4 - date1))) "Complete Workflow"
rtype, date1, date2, date3
FROM (
SELECT *
FROM temp1 t1
Expand All @@ -295,8 +274,41 @@ def get_turnaround(self):

with connection.cursor() as c:
c.execute(query)
return dict(zip(columns, c.fetchone()))
return dict(zip(columns, (0, 0, 0, 0)))
columns = [x[0] for x in c.description]
df = DataFrame(c.fetchall(), columns=columns)

df['Request -> Preparation'] = df.date2 - df.date1
df['Preparation -> Sequencing'] = df.date3 - df.date2
df['Complete Workflow'] = df.date3 - df.date1

agg_samples_df = \
df[df.rtype == 'Sample'].aggregate(['mean', 'std']).fillna(0)
agg_samples_df = (agg_samples_df / np.timedelta64(1, 'D')).astype(int)

agg_libraries_df = df[df.rtype == 'Library'].iloc[:, -1]\
.aggregate(['mean', 'std']).fillna(0)
agg_libraries_df = \
(agg_libraries_df / np.timedelta64(1, 'D')).astype(int)

columns = [
'Turnaround',
'Sample (days)',
'Sample Deviation (days)',
'Library (days)',
'Library Deviation (days)',
]

result_df = DataFrame(columns=columns)
result_df[columns[0]] = df.columns[4:]
result_df[columns[1]] = agg_samples_df.loc['mean'].values
result_df[columns[2]] = agg_samples_df.loc['std'].values
result_df[columns[3]] = [0] * 2 + [agg_libraries_df.loc['mean']]
result_df[columns[4]] = [0] * 2 + [agg_libraries_df.loc['std']]

return {
'columns': columns,
'rows': result_df.T.to_dict().values(),
}

@staticmethod
def _get_data(counts):
Expand Down
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ sphinx-rtd-theme
xlwt
fpdf
numpy
pandas
jupyter
bioblend
python-docx
Expand Down

0 comments on commit 6298d0f

Please sign in to comment.