~ubuntu-branches/ubuntu/wily/nibabel/wily-proposed

« back to all changes in this revision

Viewing changes to tools/dicomfs.wsgi

  • Committer: Package Import Robot
  • Author(s): Yaroslav Halchenko
  • Date: 2012-05-06 12:58:22 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20120506125822-3jiwjkmdqcxkrior
Tags: 1.2.0-1
* New upstream release: bugfixes, support for new formats
  (Freesurfer, ECAT, etc), nib-ls tool.
* debian/copyright
  - corrected reference to the format specs
  - points to github's repository as the origin of sources
  - removed lightunit license/copyright -- removed upstream
  - added netcdf module license/copyright terms
* debian/control
  - added python-fuse to Recommends and Build-Depends for dicomfs
  - boosted policy compliance to 3.9.3 (no further changes)
* debian/watch
  - adjusted to download numbered tag

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*-
 
2
# vi: set ft=python sts=4 ts=4 sw=4 et:
 
3
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
 
4
#
 
5
#   See COPYING file distributed along with the NiBabel package for the
 
6
#   copyright and license terms.
 
7
#
 
8
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
 
9
# Copyright (C) 2011 Christian Haselgrove
 
10
 
 
11
import sys
 
12
import traceback
 
13
import urllib
 
14
import cgi
 
15
import jinja2
 
16
from nibabel import dft
 
17
 
 
18
def html_unicode(u):
 
19
    return cgi.escape(u.encode('utf-8'))
 
20
 
 
21
# this is the directory containing the DICOM data, or None for all cached data
 
22
base_dir = '/path/to/DICOM'
 
23
base_dir = None
 
24
 
 
25
template_env = jinja2.Environment(autoescape=True)
 
26
template_env.filters['urlquote'] = urllib.quote
 
27
 
 
28
index_template = """<html><head><title>data</title></head>
 
29
<body>
 
30
Home
 
31
<br />
 
32
<br />
 
33
{% for p in patients|sort %}
 
34
    Patient: <a href="{{ p|urlquote }}/">{{ p }}</a>
 
35
    <br />
 
36
    {% if patients[p]|length == 1 %}
 
37
        1 study
 
38
    {% else %}
 
39
        {{ patients[p]|length }} studies
 
40
    {% endif %}
 
41
    <br />
 
42
{% endfor %}
 
43
</body>
 
44
</html>
 
45
"""
 
46
 
 
47
patient_template = """<html><head><title>data</title></head>
 
48
<body>
 
49
<a href="../">Home</a> -&gt; Patient {{ studies[0].patient_name_or_uid() }}
 
50
<br />
 
51
<br />
 
52
Patient name: {{ studies[0].patient_name }}
 
53
<br />
 
54
Patient ID: {{ studies[0].patient_id }}
 
55
<br />
 
56
Patient birth date: {{ studies[0].patient_birth_date }}
 
57
<br />
 
58
Patient sex: {{ studies[0].patient_sex }}
 
59
<br />
 
60
<ul>
 
61
{% for s in studies %}
 
62
    <li><a href="{{ s.date|urlquote }}_{{ s.time|urlquote }}/">Study {{ s.uid }}</a></li>
 
63
    <ul>
 
64
    <li>Date: {{ s.date }}</li>
 
65
    <li>Time: {{ s.time }}</li>
 
66
    <li>Comments: {{ s.comments }}</li>
 
67
    <li>Series: {{ s.series|length }}</li>
 
68
{% endfor %}
 
69
</ul>
 
70
</body>
 
71
</html>
 
72
"""
 
73
 
 
74
patient_date_time_template = """
 
75
<html><head><title>data</title></head>
 
76
<body>
 
77
<a href="../../">Home</a> -&gt; <a href="../../{{ study.patient_name_or_uid() }}/">Patient {{ study.patient_name_or_uid() }}</a> -&gt; Study {{ study.date}} {{ study.time }}
 
78
<br />
 
79
<br />
 
80
Patient name: <a href="../../{{ study.patient_name_or_uid() }}/">{{ study.patient_name }}</a>
 
81
<br />
 
82
Study UID: {{ study.uid }}
 
83
<br />
 
84
Study date: {{ study.date }}
 
85
<br />
 
86
Study time: {{ study.time }}
 
87
<br />
 
88
Study comments: {{ study.comments }}
 
89
{% if study.series|length == 0 %}
 
90
    <br />
 
91
    No series.
 
92
{% else %}
 
93
    <ul>
 
94
    {% for s in study.series %}
 
95
        <li>Series {{ s.number }} (<a href="{{ s.number }}/nifti">NIfTI</a>)</li>
 
96
        <ul>
 
97
        <li>Series UID: {{ s.uid }}</li>
 
98
        <li>Series description: {{ s.description }}</li>
 
99
        <li>Series dimensions: {{ s.rows }}x{{ s.columns }}x{{ s.storage_instances|length }}</li>
 
100
        </ul>
 
101
        <img src="{{ s.number }}/png" />
 
102
    {% endfor %}
 
103
    </ul>
 
104
{% endif %}
 
105
</body>
 
106
</html>
 
107
"""
 
108
 
 
109
class HandlerError:
 
110
 
 
111
    def __init__(self, status, output):
 
112
        self.status = status
 
113
        self.output = output
 
114
        return
 
115
 
 
116
def application(environ, start_response):
 
117
    try:
 
118
        (status, c_type, output) = handler(environ)
 
119
    except HandlerError, exc:
 
120
        status = exc.status
 
121
        output = exc.output
 
122
        c_type = 'text/plain'
 
123
    except:
 
124
        (exc_type, exc_value, exc_traceback) = sys.exc_info()
 
125
        lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
 
126
        status = '500 Internal Server Error'
 
127
        output = ''.join(lines)
 
128
        c_type = 'text/plain'
 
129
    response_headers = [('Content-Type', c_type), 
 
130
                        ('Content-Length', str(len(output)))]
 
131
    if c_type == 'image/nifti':
 
132
        response_headers.append(('Content-Disposition', 'attachment; filename=image.nii'))
 
133
    start_response(status, response_headers)
 
134
    return [output]
 
135
 
 
136
def handler(environ):
 
137
    if environ['PATH_INFO'] == '' or environ['PATH_INFO'] == '/':
 
138
        return ('200 OK', 'text/html', index(environ))
 
139
    parts = environ['PATH_INFO'].strip('/').split('/')
 
140
    if len(parts) == 1:
 
141
        return ('200 OK', 'text/html', patient(parts[0]))
 
142
    if len(parts) == 2:
 
143
        return ('200 OK', 'text/html', patient_date_time(parts[0], parts[1]))
 
144
    if len(parts) == 4:
 
145
        if parts[3] == 'nifti':
 
146
            return ('200 OK', 'image/nifti', nifti(parts[0], parts[1], parts[2]))
 
147
        elif parts[3] == 'png':
 
148
            return ('200 OK', 'image/png', png(parts[0], parts[1], parts[2]))
 
149
    raise HandlerError('404 Not Found', "%s not found\n" % environ['PATH_INFO'])
 
150
 
 
151
def study_cmp(a, b):
 
152
    if a.date < b.date:
 
153
        return -1
 
154
    if a.date > b.date:
 
155
        return 1
 
156
    if a.time < b.time:
 
157
        return -1
 
158
    if a.time > b.time:
 
159
        return 1
 
160
    return 0
 
161
 
 
162
def index(environ):
 
163
    patients = {}
 
164
    for s in dft.get_studies(base_dir):
 
165
        patients.setdefault(s.patient_name_or_uid(), []).append(s)
 
166
    template = template_env.from_string(index_template)
 
167
    return template.render(patients=patients).encode('utf-8')
 
168
 
 
169
def patient(patient):
 
170
    studies = [ s for s in dft.get_studies() if s.patient_name_or_uid() == patient ]
 
171
    if len(studies) == 0:
 
172
        raise HandlerError('404 Not Found', 'patient %s not found\n' % patient)
 
173
    studies.sort(study_cmp)
 
174
    template = template_env.from_string(patient_template)
 
175
    return template.render(studies=studies).encode('utf-8')
 
176
 
 
177
def patient_date_time(patient, date_time):
 
178
    study = None
 
179
    for s in dft.get_studies():
 
180
        if s.patient_name_or_uid() != patient:
 
181
            continue
 
182
        if date_time != '%s_%s' % (s.date, s.time):
 
183
            continue
 
184
        study = s
 
185
        break
 
186
    if study is None:
 
187
        raise HandlerError, ('404 Not Found', 'study not found')
 
188
    template = template_env.from_string(patient_date_time_template)
 
189
    return template.render(study=study).encode('utf-8')
 
190
 
 
191
def nifti(patient, date_time, scan):
 
192
    study = None
 
193
    for s in dft.get_studies():
 
194
        if s.patient_name_or_uid() != patient:
 
195
            continue
 
196
        if date_time != '%s_%s' % (s.date, s.time):
 
197
            continue
 
198
        study = s
 
199
        break
 
200
    if study is None:
 
201
        raise HandlerError, ('404 Not Found', 'study not found')
 
202
    ser = None
 
203
    for series in s.series:
 
204
        if series.number != scan:
 
205
            continue
 
206
        ser = series
 
207
        break
 
208
    if ser is None:
 
209
        raise HandlerError, ('404 Not Found', 'series not found')
 
210
    return ser.as_nifti()
 
211
 
 
212
def png(patient, date_time, scan):
 
213
    study = None
 
214
    for s in dft.get_studies():
 
215
        if s.patient_name_or_uid() != patient:
 
216
            continue
 
217
        if date_time != '%s_%s' % (s.date, s.time):
 
218
            continue
 
219
        study = s
 
220
        break
 
221
    if study is None:
 
222
        raise HandlerError, ('404 Not Found', 'study not found')
 
223
    ser = None
 
224
    for series in s.series:
 
225
        if series.number != scan:
 
226
            continue
 
227
        ser = series
 
228
        break
 
229
    if ser is None:
 
230
        raise HandlerError, ('404 Not Found', 'series not found')
 
231
    index = len(ser.storage_instances) / 2
 
232
    return ser.as_png(index, True)
 
233
 
 
234
if __name__ == '__main__':
 
235
    import wsgiref.simple_server
 
236
    httpd = wsgiref.simple_server.make_server('', 8080, application)
 
237
    httpd.serve_forever()
 
238
 
 
239
# eof