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
RevLine 
[27]1package nl.tno.massSequencing
[4]2
[49]3import java.util.List;
[70]4import org.codehaus.groovy.grails.commons.ConfigurationHolder
[49]5
[4]6class AssaySampleController {
[49]7        def fastaService
[62]8        def sampleExcelService
[70]9        def fileService
10        def workerService
[4]11
[49]12        /**
13         * Shows information about this assaySample in dialog style
14         */
[4]15        def show = {
16                AssaySample assaySample = AssaySample.get( params.id as long );
[49]17
[4]18                if( !assaySample ) {
19                        render "Sample not found";
20                        return
21                }
[49]22
[7]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
[49]29
[7]30                [assaySample: assaySample, entityType: params.entityType]
[4]31        }
[49]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                }
[59]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
[49]50
[59]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() )
[49]59        }
[59]60       
61        def sequenceLengthHistogramForAssay = {
62                def id = params.long( 'id' );
63                def assay = id ? Assay.get( id ) : null
[49]64
[59]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        }
[44]88        /**
[59]89         * Renders a histogram for the given assaySamples
90         * @param title
91         * @param assaySamples
92         */
93        protected void renderSequenceLengthHistogram( String title, def assaySamples ) {
[67]94                log.debug "Rendering histogram for " + assaySamples?.size() + " samples";
[63]95               
[59]96                def numSequences = assaySamples.collect { it.numSequences() }.sum()
97                render( view: "sequenceLengthHistogram", model: [ title: title, numSequences: numSequences, histogram: fastaService.sequenceLengthHistogram( assaySamples ) ] );
98        }
99
100        /**
[49]101         * Exports data about one or more runs in fasta format
102         */
103        def exportAsFasta = {
[70]104                def assaySamples = getAssaySamples( params )?.unique();
[49]105
106                if( assaySamples?.size() == 0 ) {
107                        flash.error = "No samples selected";
108                        redirect( action: "list" );
109                        return;
110                }
111
[70]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 )
[49]117
[70]118                // Show a waiting screen
119                redirect( url: url );
120        }
121       
122        def downloadFasta = {
123                def processId = params.processId;
124               
[49]125                // Export the sequences and quality scores
[70]126                response.setHeader "Content-disposition", "attachment; filename=" + session.process[ processId ].name  + ".zip"
[49]127                try {
[70]128                        response.outputStream << fileService.get( session.process[ processId ].filename ).newInputStream();
[49]129                        response.outputStream.flush();
130                } catch( Exception e ) {
131                        log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." );
[52]132                        e.printStackTrace();
[70]133                } finally {
134                        // Delete the file since it has to be downloaded only once
135                        fileService.delete( session.process[ processId ].filename );
[49]136                }
137        }
[62]138       
139        /**
140         * Export metadata of selected samples in excel format
141         */
142        def exportMetaData = {
143                def assaySamples = getAssaySamples( params );
144                def name
[49]145
[62]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"
[70]163                       
164                        sampleExcelService.sessionToken = session.sessionToken
165                       
[62]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
[49]178        /**
[44]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                }
[49]189
[44]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        }
[49]198
[44]199        def update = {
[57]200               
[44]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
[57]210               
[44]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        }
[49]219
220        protected List getAssaySamples( params ) {
221                def ids = params.list( 'ids' );
[63]222                def tokens = params.list( 'tokens' );
223               
[49]224                ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) }
[63]225               
226                if( !ids && !tokens ) {
[49]227                        def message = "No assaysample ids given"
228                        flash.error = message
229                        redirect( controller: "run", action: "index" );
230                        return;
231                }
[63]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; 
[49]242        }
[4]243}
Note: See TracBrowser for help on using the repository browser.