source: trunk/src/groovy/dbnp/query/StudySearch.groovy @ 1501

Last change on this file since 1501 was 1501, checked in by robert@…, 9 years ago
  • Number of seconds for the rest controller to keep data in cache is now a configuration option
  • After searching, it is possible to choose which action to perform on the search results.
  • Property svn:keywords set to Rev Author Date
File size: 7.8 KB
Line 
1/**
2 * StudySearch Domain Class
3 *
4 * This class provides querying capabilities for searching for studies
5 *
6 * @author  Robert Horlings (robert@isdat.nl)
7 * @since       20110118
8 * @package     dbnp.query
9 *
10 * Revision information:
11 * $Rev: 1501 $
12 * $Author: robert@isdat.nl $
13 * $Date: 2011-02-07 15:07:54 +0000 (ma, 07 feb 2011) $
14 */
15package dbnp.query
16
17import java.util.List;
18import java.util.Map;
19
20import dbnp.studycapturing.*
21import org.dbnp.gdt.*
22import org.apache.commons.logging.LogFactory;
23
24class StudySearch extends Search {
25        private static final log = LogFactory.getLog(this);
26
27        public StudySearch() {
28                super();
29                this.entity = "Study";
30        }
31
32        /**
33         * Searches for studies based on the given criteria. All criteria have to be satisfied and
34         * criteria for the different entities are satisfied as follows:
35         *
36         *              Study.title = 'abc'             
37         *                              All returned studies will have title 'abc'
38         *             
39         *              Subject.species = 'human'
40         *                              All returned studies will have one or more subjects with species = 'human' 
41         *
42         *              Sample.name = 'sample 1'
43         *                              All returned studies will have one or more samples with name = 'sample 1'
44         *
45         *              Event.startTime = '0s'
46         *                              All returned studies will have one or more events with start time = '0s' 
47         *
48         *              Assay.module = 'metagenomics'
49         *                              All returned studies will have one or more assays with module = 'metagenomics' 
50         *
51         * When searching the system doesn't look at the connections between different entities. This means,
52         * the system doesn't look for human subjects having a sample with name 'sample 1'. The sample 1 might
53         * as well belong to a mouse subject and still the study satisfies the criteria.
54         *
55         * When searching for more than one criterion per entity, these are taken combined. Searching for
56         *
57         *              Subject.species = 'human'
58         *              Subject.name = 'Jan'
59         *
60         *  will result in all studies having a human subject named 'Jan'. Studies with only a mouse subject
61         *  named 'Jan' or a human subject named 'Kees' won't satisfy the criteria.
62         *     
63         */
64        @Override
65        void executeAnd() {
66                def studies = Study.list().findAll { it.canRead( this.user ) };
67
68                // If no criteria are found, return all studies
69                if( !criteria || criteria.size() == 0 ) {
70                        results = studies;
71                        return;
72                }
73
74                // Perform filters
75                studies = filterOnStudyCriteria( studies );
76                studies = filterOnSubjectCriteria( studies );
77                studies = filterOnSampleCriteria( studies );
78                studies = filterOnEventCriteria( studies );
79                studies = filterOnSamplingEventCriteria( studies );
80                studies = filterOnAssayCriteria( studies );
81
82                studies = filterOnModuleCriteria( studies );
83
84                // Save matches
85                results = studies;
86        }
87
88        /**
89         * Searches for studies based on the given criteria. Only one criteria have to be satisfied and
90         * criteria for the different entities are satisfied as follows:
91         *
92         *              Study.title = 'abc'
93         *                              The returned study will have title 'abc'
94         *
95         *              Subject.species = 'human'
96         *                              The returned study will have one or more subjects with species = 'human'
97         *
98         *              Sample.name = 'sample 1'
99         *                              The returned study will have one or more samples with name = 'sample 1'
100         *
101         *              Event.startTime = '0s'
102         *                              The returned study will have one or more events with start time = '0s'
103         *
104         *              Assay.module = 'metagenomics'
105         *                              The returned study will have one or more assays with module = 'metagenomics'
106         *
107         * When searching the system doesn't look at the connections between different entities. This means,
108         * the system doesn't look for human subjects having a sample with name 'sample 1'. The sample 1 might
109         * as well belong to a mouse subject and still the study satisfies the criteria.
110         *
111         * When searching for more than one criterion per entity, these are taken separately. Searching for
112         *
113         *              Subject.species = 'human'
114         *              Subject.name = 'Jan'
115         *
116         *  will result in all studies having a human subject or a subject named 'Jan'. Studies with only a
117         *  mouse subject named 'Jan' or a human subject named 'Kees' will satisfy the criteria.
118         *
119         */
120        @Override
121        void executeOr() {
122                def allStudies = Study.list().findAll { it.canRead( this.user ) };
123
124                // If no criteria are found, return all studies
125                if( !criteria || criteria.size() == 0 ) {
126                        results = allStudies;
127                        return;
128                }
129
130                // Perform filters
131                def studies = []
132                studies = ( studies + filterOnStudyCriteria( allStudies - studies ) ).unique();
133                studies = ( studies + filterOnSubjectCriteria( allStudies - studies ) ).unique();
134                studies = ( studies + filterOnSampleCriteria( allStudies - studies ) ).unique();
135                studies = ( studies + filterOnEventCriteria( allStudies - studies ) ).unique();
136                studies = ( studies + filterOnSamplingEventCriteria( allStudies - studies ) ).unique();
137                studies = ( studies + filterOnAssayCriteria( allStudies - studies ) ).unique();
138               
139                studies = ( studies + filterOnModuleCriteria( allStudies - studies ) ).unique();
140               
141                // Save matches
142                results = studies;
143        }
144
145        /**
146         * Filters the given list of studies on the study criteria
147         * @param studies       Original list of studies
148         * @return                      List with all studies that match the Study criteria
149         */
150        protected List filterOnStudyCriteria( List studies ) {
151                return filterOnTemplateEntityCriteria(studies, "Study", { study, criterion -> return criterion.getFieldValue( study ) })
152        }
153
154        /**
155         * Filters the given list of studies on the subject criteria
156         * @param studies       Original list of studies
157         * @return                      List with all studies that match the Subject-criteria
158         */
159        protected List filterOnSubjectCriteria( List studies ) {
160                return filterOnTemplateEntityCriteria(studies, "Subject", { study, criterion ->
161                        return study.subjects?.collect { criterion.getFieldValue( it ); }
162                })
163        }
164
165        /**
166         * Filters the given list of studies on the sample criteria
167         * @param studies       Original list of studies
168         * @return                      List with all studies that match the sample-criteria
169         */
170        protected List filterOnSampleCriteria( List studies ) {
171                return filterOnTemplateEntityCriteria(studies, "Sample", { study, criterion ->
172                        return study.samples?.collect { criterion.getFieldValue( it ); }
173                })
174        }
175
176        /**
177         * Filters the given list of studies on the event criteria
178         * @param studies       Original list of studies
179         * @return                      List with all studies that match the event-criteria
180         */
181        protected List filterOnEventCriteria( List studies ) {
182                return filterOnTemplateEntityCriteria(studies, "Event", { study, criterion ->
183                        return study.events?.collect { criterion.getFieldValue( it ); }
184                })
185        }
186
187        /**
188         * Filters the given list of studies on the sampling event criteria
189         * @param studies       Original list of studies
190         * @return                      List with all studies that match the event-criteria
191         */
192        protected List filterOnSamplingEventCriteria( List studies ) {
193                return filterOnTemplateEntityCriteria(studies, "SamplingEvent", { study, criterion ->
194                        return study.samplingEvents?.collect { criterion.getFieldValue( it ); }
195                })
196        }
197
198        /**
199         * Filters the given list of studies on the assay criteria
200         * @param studies       Original list of studies
201         * @return                      List with all studies that match the assay-criteria
202         */
203        protected List filterOnAssayCriteria( List studies ) {
204                return filterOnTemplateEntityCriteria(studies, "Assay", { study, criterion ->
205                        return study.assays?.collect { criterion.getFieldValue( it ); }
206                })
207        }
208
209        /**
210         * Returns the saved field data that could be shown on screen. This means, the data
211         * is filtered to show only data of the query results. Also, the study title and sample
212         * name are filtered out, in order to be able to show all data on the screen without
213         * checking further
214         *
215         * @return      Map with the entity id as a key, and a field-value map as value
216         */
217        public Map getShowableResultFields() {
218                Map showableFields = super.getShowableResultFields()
219                showableFields.each { sampleElement ->
220                        sampleElement.value = sampleElement.value.findAll { fieldElement ->
221                                fieldElement.key != "Study title" && fieldElement.key != "Subject species"
222                        }
223                }
224                return showableFields
225        }
226}
Note: See TracBrowser for help on using the repository browser.