source: trunk/grails-app/controllers/nl/tno/massSequencing/AssaySampleController.groovy @ 71

Last change on this file since 71 was 71, checked in by robert@…, 8 years ago

Made some textual changes

File size: 7.5 KB
Line 
1package nl.tno.massSequencing
2
3import java.util.List;
4import org.codehaus.groovy.grails.commons.ConfigurationHolder
5import nl.tno.massSequencing.classification.Classification
6
7class AssaySampleController {
8        def fastaService
9        def sampleExcelService
10        def fileService
11        def workerService
12
13        /**
14         * Shows information about this assaySample in dialog style
15         */
16        def show = {
17                AssaySample assaySample = AssaySample.get( params.id as long );
18
19                if( !assaySample ) {
20                        render "Sample not found";
21                        return
22                }
23
24                if (!assaySample.assay.study.canRead( session.user ) ) {
25                        flash.error = "You don't have the right authorizaton to access sample " + assaySample.sample.name
26                        redirect(controller: 'study')
27                        return null
28                }
29
30                // Determine the number of classifications for this sample
31                def numClassifications = Classification.executeQuery( "SELECT SUM( c.unclassified ) FROM Classification c WHERE c.assaySample = :assaySample", [ "assaySample": assaySample ] )
32
33                [assaySample: assaySample, entityType: params.entityType, numClassifications: numClassifications ? ( numClassifications[ 0 ] ?: 0 )  : 0 ]
34        }
35
36        def sequenceLengthHistogram = {
37                def id = params.long( 'id' );
38                def assaySample = id ? AssaySample.get( id ) : null
39
40                if( !id || !assaySample ) {
41                        flash.message = "No sample selected";
42                        redirect( action: "index" );
43                        return;
44                }
45               
46                def title = "sample " + assaySample.sample.name + " (" + assaySample.assay.study.name + " / " + assaySample.assay.name + ")"
47                renderSequenceLengthHistogram( title, [assaySample] )
48        }
49       
50        def sequenceLengthHistogramForRun = {
51                def id = params.long( 'id' );
52                def run = id ? Run.get( id ) : null
53
54                if( !id || !run ) {
55                        flash.message = "No run selected";
56                        redirect( controller: 'run', action: "index" );
57                        return;
58                }
59               
60                def title = "run " + run.name
61                renderSequenceLengthHistogram( title, run.assaySamples?.toList() )
62        }
63       
64        def sequenceLengthHistogramForAssay = {
65                def id = params.long( 'id' );
66                def assay = id ? Assay.get( id ) : null
67
68                if( !id || !assay ) {
69                        flash.message = "No assay selected";
70                        redirect( controller: 'assay', action: "index" );
71                        return;
72                }
73               
74                def title = "assay " + assay.name
75                renderSequenceLengthHistogram( title, assay.assaySamples?.toList() )
76        }
77       
78        def sequenceLengthHistogramForStudy = {
79                def id = params.long( 'id' );
80                def assay = id ? Study.get( id ) : null
81
82                if( !id || !study ) {
83                        flash.message = "No study selected";
84                        redirect( controller: 'study', action: "index" );
85                        return;
86                }
87               
88                def title = "study " + study.name
89                renderSequenceLengthHistogram( title, study.assays*.assaySamples.flatten().unique().findAll { it } )
90        }
91        /**
92         * Renders a histogram for the given assaySamples
93         * @param title
94         * @param assaySamples
95         */
96        protected void renderSequenceLengthHistogram( String title, def assaySamples ) {
97                log.debug "Rendering histogram for " + assaySamples?.size() + " samples";
98               
99                def numSequences = assaySamples.collect { it.numSequences() }.sum()
100                render( view: "sequenceLengthHistogram", model: [ title: title, numSequences: numSequences, histogram: fastaService.sequenceLengthHistogram( assaySamples ) ] );
101        }
102
103        /**
104         * Exports data about one or more runs in fasta format
105         */
106        def exportAsFasta = {
107                def assaySamples = getAssaySamples( params )?.unique();
108
109                if( assaySamples?.size() == 0 ) {
110                        flash.error = "No samples selected";
111                        redirect( action: "list" );
112                        return;
113                }
114
115                // Start the export in the background
116                def name = "samples";
117                def returnUrl = createLink( controller: params.entityType, action: "show", id: params.entityId ).toString()
118                def finishUrl = createLink( controller: "assaySample", action: 'downloadFasta', params: [ processId: '%s' ] ).toString();
119                def url = fastaService.startExportProcess( assaySamples, session, name, returnUrl, finishUrl )
120
121                // Show a waiting screen
122                redirect( url: url );
123        }
124       
125        def downloadFasta = {
126                def processId = params.processId;
127               
128                // Export the sequences and quality scores
129                response.setHeader "Content-disposition", "attachment; filename=" + session.process[ processId ].name  + ".zip"
130                try {
131                        response.outputStream << fileService.get( session.process[ processId ].filename ).newInputStream();
132                        response.outputStream.flush();
133                } catch( Exception e ) {
134                        log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." );
135                        e.printStackTrace();
136                } finally {
137                        // Delete the file since it has to be downloaded only once
138                        fileService.delete( session.process[ processId ].filename );
139                }
140        }
141       
142        /**
143         * Export metadata of selected samples in excel format
144         */
145        def exportMetaData = {
146                def assaySamples = getAssaySamples( params );
147                def name
148
149                if( assaySamples?.size() == 0 ) {
150                        flash.error = "No samples selected";
151                        redirect( action: "list" );
152                        return;
153                }
154
155                name = "samples";
156
157                // Export the metadata
158                try {
159                        // The export functionality needs a assaysSample-tag list, but it
160                        // should be empty when only exporting metadata
161                        def tags = [];
162                        assaySamples.unique().each { assaySample ->
163                                tags << [assaySampleId: assaySample.id, sampleName: assaySample.sample.name, assayName: assaySample.assay.name, studyName: assaySample.assay.study.name, tag: "-"]
164                        }
165                        response.setHeader "Content-disposition", "attachment; filename=${name}.xls"
166                       
167                        sampleExcelService.sessionToken = session.sessionToken
168                       
169                        if( !sampleExcelService.exportExcelSampleData( assaySamples.unique(), tags, response.outputStream ) ) {
170                                flash.error = "An error occurred while fetching sample data. Maybe the session has timed out.";
171                                response.setHeader( "Content-disposition", "" );
172                                redirect( action: "index" );
173                        }
174                        response.outputStream.flush();
175                } catch( Exception e ) {
176                        log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." );
177                        e.printStackTrace();
178                }
179        }
180
181        /**
182         * Shows a form to edit the specified assaySample in dialog mode
183         */
184        def editForm = {
185                // load assaySample with id specified by param.id
186                AssaySample assaySample = AssaySample.get( params.id as long );
187
188                if( !assaySample ) {
189                        render "Sample not found";
190                        return
191                }
192
193                if (!assaySample.assay.study.canWrite( session.user ) ) {
194                        flash.error = "You don't have the right authorizaton to access sample " + assaySample.sample.name
195                        redirect(controller: params.parent ?: "run" )
196                        return null
197                }
198
199                [parent: params.parent ?: "run", parentId: params.parentId ?: assaySample.run?.id, assaySample: assaySample]
200        }
201
202        def update = {
203               
204                // load assaySample with id specified by param.id
205                AssaySample assaySample = AssaySample.get( params.id as long );
206
207                if( !assaySample) {
208                        redirect(controller: params.parent ?: "run", action: 'list')
209                        return
210                }
211
212                assaySample.properties = params.sample
213               
214                if( assaySample.save() ) {
215                        flash.message = "Sample succesfully saved";
216                } else {
217                        flash.error = "Sample could not be saved: " + assaySample.getErrors();
218                }
219
220                redirect( controller: params.parent ?: "run", action: 'show', id: params.parentId ?: assaySample.run?.id )
221        }
222
223        protected List getAssaySamples( params ) {
224                def ids = params.list( 'ids' );
225                def tokens = params.list( 'tokens' );
226               
227                ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) }
228               
229                if( !ids && !tokens ) {
230                        def message = "No assaysample ids given"
231                        flash.error = message
232                        redirect( controller: "run", action: "index" );
233                        return;
234                }
235               
236                def samples = [];
237               
238                if( ids ) 
239                        samples += AssaySample.executeQuery( "FROM AssaySample a WHERE a.id IN (:ids)", [ "ids": ids ] );
240               
241                if( tokens )
242                        samples += AssaySample.executeQuery( "FROM AssaySample a WHERE a.sample.sampleToken IN (:tokens)", [ "tokens": tokens ] );
243                       
244                return samples; 
245        }
246}
Note: See TracBrowser for help on using the repository browser.