source: trunk/grails-app/domain/nl/tno/metagenomics/AssaySample.groovy @ 9

Last change on this file since 9 was 9, checked in by robert@…, 8 years ago
File size: 4.9 KB
Line 
1package nl.tno.metagenomics
2
3/**
4 * Represents a samples that is used in an assay.
5 *
6 * @author Robert Horlings (robert@isdat.nl)
7 *
8 */
9class AssaySample {
10        // To be computed in run time
11        private long _numSequences = -1;
12        private float _averageQuality = -1.0;
13
14        Integer numUniqueSequences      // Number of unique sequences / OTUs. Is only available after preprocessing
15
16        String oligoNumber              // Oligonumber used to identify the sample
17        String tagSequence              // Tag originally used to identify the sample
18        String tagName                  // Tag name
19
20        static belongsTo  = [ assay: Assay, sample: Sample, run: Run ]
21        static hasMany    = [ sequenceData: SequenceData ]
22
23        static constraints = {
24                numUniqueSequences(nullable: true)
25                oligoNumber(nullable: true)
26               
27                /*
28                , validator: { value, obj, errors ->
29                        // When one oligoNumber is used in different assaysamples,
30                        // they must also have the same tagSequences and tagNames
31                       
32                        // Check whether this oligoNumber exists in the database
33                        def otherAssaySamples = AssaySample.findAllByOligoNumber( value )
34                        if( !otherAssaySamples || otherAssaySamples.size() == 0 ) {
35                                return true;
36                        }
37                       
38                        // Loop through the other assaysamples with this oligonumber
39                        otherAssaySamples.each { otherAS ->
40                                // Only check other objects, don't compare with itself (because that
41                                // way it wouldn't be possible anymore to edit an object)
42                                if( otherAS.id != obj.id ) {
43                                        if( otherAS.tagSequence != obj.tagSequence || otherAS.tagName != obj.tagName ) {
44                                                return false;
45                                        }
46                                }
47                        }
48                       
49                        return true
50                }
51                 */
52                tagSequence(nullable: true)
53                tagName(nullable:true)
54                run(nullable: true);
55        }
56
57        static mapping = {
58                columns {
59                        numSequences index:'numsequences_idx'
60                }
61                sequenceData cascade: "all-delete-orphan"
62        }
63
64        /**
65         * Returns the number of files in the system, belonging to this
66         * assay-sample combination.
67         *
68         * @return
69         */
70        public int numFiles() {
71                if( !sequenceData )
72                        return 0
73
74                int numFiles = 0;
75                sequenceData.each { numFiles += it.numFiles() }
76
77                return numFiles;
78        }
79
80        /**
81         * Returns the number of sequence files in the system, belonging to this
82         * assay-sample combination.
83         *
84         * @return
85         */
86        public int numSequenceFiles() {
87                if( !sequenceData )
88                        return 0
89
90                int numFiles = 0;
91                sequenceData.each {
92                        if( it.sequenceFile )
93                                numFiles++
94                }
95
96                return numFiles;
97        }
98       
99        /**
100         * Returns the number of quality files in the system, belonging to this
101         * assay-sample combination.
102         *
103         * @return
104         */
105        public int numQualityFiles() {
106                if( !sequenceData )
107                        return 0
108
109                int numFiles = 0;
110                sequenceData.each {
111                        if( it.qualityFile )
112                                numFiles++
113                }
114
115                return numFiles;
116        }
117       
118        /**
119         * Returns the number of sequences in the files on the system, belonging to this
120         * assay-sample combination.
121         *
122         * @return
123         */
124        public long numSequences() {
125                if( _numSequences > -1 )
126                        return _numSequences;
127
128                if( !sequenceData )
129                        return 0
130
131                long numSequences = 0;
132                sequenceData.each { numSequences += it.numSequences }
133
134                // Save as cache
135                _numSequences = numSequences;
136
137                return numSequences;
138        }
139
140        /**
141         * Returns the average quality of the sequences in the files on the system,
142         * belonging to this assay-sample combination.
143         *
144         * @return
145         */
146        public float averageQuality() {
147                if( _averageQuality > -1 )
148                        return _averageQuality;
149
150                if( !sequenceData )
151                        return 0.0
152
153                int numSequences = 0;
154                float averageQuality = 0.0;
155
156                sequenceData.each {
157                        numSequences += it.numSequences
158                        averageQuality = averageQuality + ( it.averageQuality - averageQuality ) / numSequences * it.numSequences;
159                }
160
161                // Save as cache
162                _averageQuality = averageQuality;
163
164                return averageQuality;
165        }
166       
167        /**
168         * Reset the statistics to their default value, in order to ensure that the values are recomputed next time.
169         */
170        public void resetStats() {
171                _numSequences = -1;
172                _averageQuality = -1;
173        }
174       
175        /**
176         * Check whether this assay-sample combination contains information that should be saved in trash on a delete
177         * @return
178         */
179        public boolean containsData() {
180                return tagSequence || tagName || oligoNumber || numFiles() > 0;
181        }
182       
183        /**
184         * Move information that should be kept on delete to another assaySample object.
185         * 
186         * N.B. The sequencedata objects are really moved, so removed from the original object!
187         * 
188         * @param otherAssaySample      Object to move
189         */
190        public void moveValuableDataTo( AssaySample otherAssaySample ) {
191                // Copy properties
192                otherAssaySample.tagSequence = tagSequence;
193                otherAssaySample.oligoNumber = oligoNumber;
194                otherAssaySample.tagName         = tagName;
195                otherAssaySample.run         = run;
196               
197                // Move attached data
198                def dataList = sequenceData?.toList()
199                def otherAssay = otherAssaySample.assay;
200               
201                if( dataList && dataList.size() > 0 ) {
202                        for( def j = dataList.size() - 1; j >= 0; j-- ) {
203                                // Copy data
204                                dataList[j].sample = otherAssaySample;
205                                this.removeFromSequenceData( dataList[j] );
206                                otherAssaySample.addToSequenceData( dataList[j] );
207                                dataList[j].save();
208                        }
209                }
210        }
211}
Note: See TracBrowser for help on using the repository browser.