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

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