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

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

Improved querying (#40)

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