source: trunk/src/groovy/dbnp/query/SampleSearch.groovy @ 1456

Last change on this file since 1456 was 1456, checked in by business@…, 10 years ago

moved gdt package to org.dbnp, moved tests for RelTime?, TemplateEntity?, Template etc. to gdt plugin

  • Property svn:keywords set to Rev Author Date
File size: 6.3 KB
Line 
1/**
2 * SampleSearch Domain Class
3 *
4 * This class provides querying capabilities for searching for samples
5 *
6 * @author  Robert Horlings (robert@isdat.nl)
7 * @since       20110118
8 * @package     dbnp.query
9 *
10 * Revision information:
11 * $Rev: 1456 $
12 * $Author: business@keesvanbochove.nl $
13 * $Date: 2011-01-31 12:27:30 +0000 (ma, 31 jan 2011) $
14 */
15package dbnp.query
16
17import dbnp.studycapturing.*
18
19class SampleSearch extends Search {
20        public SampleSearch() {
21                this.entity = "Sample";
22        }
23
24        /**
25         * Searches for samples based on the given criteria. All criteria have to be satisfied and
26         * criteria for the different entities are satisfied as follows:
27         *
28         *              Sample.title = 'abc'           
29         *                              Only samples are returned from studies with title 'abc'
30         *             
31         *              Subject.species = 'human'
32         *                              Only samples are returned from subjects with species = 'human' 
33         *
34         *              Sample.name = 'sample 1'
35         *                              Only samples are returned with name = 'sample 1'
36         *
37         *              Event.startTime = '0s'
38         *                              Only samples are returned from subjects that have had an event with start time = '0s' 
39         *
40         *              SamplingEvent.startTime = '0s'
41         *                              Only samples are returned that have originated from a sampling event with start time = '0s' 
42         *
43         *              Assay.module = 'metagenomics'
44         *                              Only samples are returned that have been processed in an assay with module = metagenomics 
45         *
46         * When searching for more than one criterion per entity, these are taken combined. Searching for
47         *
48         *              Subject.species = 'human'
49         *              Subject.name = 'Jan'
50         *
51         *  will result in all samples from a human subject named 'Jan'. Samples from a mouse subject
52         *  named 'Jan' or a human subject named 'Kees' won't satisfy the criteria.
53         *     
54         */
55        @Override
56        void execute() {
57                // TODO: check for authorization for these studies?
58
59                // If no criteria are found, return all samples
60                if( !criteria || criteria.size() == 0 ) {
61                        results = Sample.list();
62                        return;
63                }
64
65                // We expect the sample criteria to be the most discriminative, and discard
66                // the most samples. (e.g. by searching on sample title of sample type). For
67                // that reason we first look through the list of studies. However, when the
68                // user didn't enter any sample criteria, this will be an extra step, but doesn't
69                // cost much time to process.
70                def samples = []
71                if( getEntityCriteria( 'Study' ).size() > 0 ) {
72                        def studies = Study.findAll();
73                       
74                        studies = filterOnStudyCriteria( studies );
75                       
76                        if( studies.size() == 0 ) {
77                                results = [];
78                                return;
79                        }
80                       
81                        def c = Sample.createCriteria()
82                        samples = c.list {
83                                'in'( 'parent', studies )
84                        }
85                } else {
86                        samples = Sample.findAll()
87                }
88
89                samples = filterOnSubjectCriteria( samples );
90                samples = filterOnSampleCriteria( samples );
91                samples = filterOnEventCriteria( samples );
92                samples = filterOnSamplingEventCriteria( samples );
93                samples = filterOnAssayCriteria( samples );
94               
95                // Save matches
96                results = samples;
97        }
98
99        /**
100         * Filters the given list of samples on the sample criteria
101         * @param samples       Original list of samples
102         * @return                      List with all samples that match the Sample-criteria
103         */
104        protected List filterOnStudyCriteria( List studies ) {
105                return filterEntityList( studies, getEntityCriteria( 'Study' ), { study, criterion ->
106                        return criterion.matchOne( study );
107                });
108        }
109
110        /**
111         * Filters the given list of samples on the subject criteria
112         * @param samples       Original list of samples
113         * @return                      List with all samples that match the Subject-criteria
114         */
115        protected List filterOnSubjectCriteria( List samples ) {
116                return filterEntityList( samples, getEntityCriteria( 'Subject' ), { sample, criterion ->
117                        if( !sample.parentSubject )
118                                return false
119
120                        return criterion.matchOne( sample.parentSubject );
121                });
122        }
123
124        /**
125         * Filters the given list of samples on the sample criteria
126         * @param samples       Original list of samples
127         * @return                      List with all samples that match the sample-criteria
128         */
129        protected List filterOnSampleCriteria( List samples ) {
130                return filterEntityList( samples, getEntityCriteria( 'Sample' ), { sample, criterion ->
131                        if( !sample  )
132                                return false
133
134                        return criterion.matchOne( sample );
135                });
136        }
137
138        /**
139         * Filters the given list of samples on the event criteria
140         * @param samples       Original list of samples
141         * @return                      List with all samples that match the event-criteria
142         */
143        protected List filterOnEventCriteria( List samples ) {
144                println "Event criteria: " + getEntityCriteria( 'Event' )
145                return filterEntityList( samples, getEntityCriteria( 'Event' ), { sample, criterion ->
146                        if( !sample || !sample.parentEventGroup || !sample.parentEventGroup.events || sample.parentEventGroup.events.size() == 0 )
147                                return false
148               
149                        return criterion.matchAny( sample.parentEventGroup.events.toList() );
150                });
151        }
152
153        /**
154         * Filters the given list of samples on the sampling event criteria
155         * @param samples       Original list of samples
156         * @return                      List with all samples that match the event-criteria
157         */
158        protected List filterOnSamplingEventCriteria( List samples ) {
159                return filterEntityList( samples, getEntityCriteria( 'SamplingEvent' ), { sample, criterion ->
160                        if( !sample.parentEvent )
161                                return false
162
163                        return criterion.matchOne( sample.parentEvent );
164                });
165        }
166
167
168        /**
169         * Filters the given list of samples on the assay criteria
170         * @param samples       Original list of samples
171         * @return                      List with all samples that match the assay-criteria
172         */
173        protected List filterOnAssayCriteria( List samples ) {
174                if( !samples?.size() )
175                        return [];
176
177                if( getEntityCriteria( 'Assay' ).size() == 0 )
178                        return samples
179                       
180                // There is no sample.assays property, so we have to look for assays another way: just find
181                // all assays that match the criteria
182                def assays = filterEntityList( Assay.list(), getEntityCriteria( 'Assay' ), { assay, criterion ->
183                        if( !assay )
184                                return false
185
186                        return criterion.matchOne( assay );
187                });
188               
189                // If no assays match these criteria, then no samples will match either
190                if( assays.size() == 0 )
191                        return [];
192                       
193                // Now filter the samples on whether they are attached to the filtered assays
194                return samples.findAll { sample ->
195                        if( !sample.parent )
196                                return false;
197                       
198                        def studyAssays = assays.findAll { it.parent.equals( sample.parent ); }
199                       
200                        // See if this sample is present in any of the matching assays. If so,
201                        // this sample matches the criteria
202                        for( def assay in studyAssays ) {
203                                if( assay.samples?.contains( sample ) ) 
204                                        return true;
205                        }
206                       
207                        return false;
208                }
209        }
210
211}
Note: See TracBrowser for help on using the repository browser.