Project

General

Profile

Download (11 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.model.molecular;
10

    
11
import java.util.HashSet;
12
import java.util.Set;
13

    
14
import javax.persistence.Column;
15
import javax.persistence.Entity;
16
import javax.persistence.FetchType;
17
import javax.persistence.ManyToOne;
18
import javax.persistence.OneToMany;
19
import javax.xml.bind.annotation.XmlAccessType;
20
import javax.xml.bind.annotation.XmlAccessorType;
21
import javax.xml.bind.annotation.XmlAttribute;
22
import javax.xml.bind.annotation.XmlElement;
23
import javax.xml.bind.annotation.XmlElementWrapper;
24
import javax.xml.bind.annotation.XmlIDREF;
25
import javax.xml.bind.annotation.XmlRootElement;
26
import javax.xml.bind.annotation.XmlSchemaType;
27
import javax.xml.bind.annotation.XmlType;
28

    
29
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
30
import org.hibernate.annotations.Cascade;
31
import org.hibernate.annotations.CascadeType;
32
import org.hibernate.envers.Audited;
33
import org.hibernate.search.annotations.Field;
34
import org.hibernate.search.annotations.IndexedEmbedded;
35

    
36
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
37
import eu.etaxonomy.cdm.model.common.EventBase;
38
import eu.etaxonomy.cdm.model.media.Media;
39
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
40
import eu.etaxonomy.cdm.model.term.DefinedTerm;
41
import eu.etaxonomy.cdm.model.term.TermType;
42

    
43
/**
44
 * The physical process of amplification (also called PCR) extracts and replicates parts of the DNA of
45
 * a given {@link #getDnaSample() DNA Sample} . The part of the DNA being replicated is defined by the
46
 * {@link Amplification#getDnaMarker() marker} (also called locus) - implemented in CDM as a {@link DefinedTerm}
47
 * of term type {@link TermType#DnaMarker}.
48
 *
49
 * <BR>
50
 * To execute the replication {@link Primer primers} (short DNA fractions) are
51
 * used. They may work in both directions of the DNA part therefore we do have a
52
 * {@link #getForwardPrimer() forward primer} and a {@link #getReversePrimer() reverse primer}.
53
 * Most (or all?) amplifications require a {@link #getPurification() purification process}. Additionally
54
 * some use {@link #getCloning()} for replication.
55
 *
56
 * <H3>Quality control</H3>
57
 * <BR>
58
 * For quality control the resulting product (PCR) is tested using a chromatographic method called
59
 * electrophoresis. The parameters (voltage, ladder used, running time, and gel concentration) used
60
 * for this electrophoresis as well as the resulting
61
 * {@link #getGelPhoto() photo} are also relevant for an amplification.
62
 *
63
 * We have 2 classes to store the core data for an amplification: {@link Amplification} and {@link AmplificationResult}.
64
 * <BR>
65
 * In {@link Amplification} we store all data that is equal for an amplification event which includes amplification
66
 * of many {@link DnaSample dna samples}. Those data which are relevant only for a specific dna sample are
67
 * stored in {@link AmplificationResult}. Theoretically this includes data on the resulting PCR. However, as the
68
 * PCR itself is not persistent we do not store further information on it in the CDM and do not handle
69
 * {@link AmplificationResult} as a {@link DerivedUnit}.
70
 * <BR>
71
 * This may change in future: https://dev.e-taxonomy.eu/redmine/issues/3717.
72
 * <BR>
73
 *
74
 * @author a.mueller
75
 * @since 2013-07-05
76
 *
77
 * @see Amplification
78
 */
79
@XmlAccessorType(XmlAccessType.FIELD)
80
@XmlType(name = "AmplificationResult", propOrder = {
81
	"dnaSample",
82
	"amplification",
83
	"cloning",
84
	"successful",
85
	"successText",
86
	"gelPhoto",
87
	"singleReads"
88
})
89
@XmlRootElement(name = "AmplificationResult")
90
@Entity
91
@Audited
92
public class AmplificationResult extends AnnotatableEntity{
93

    
94
	private static final long serialVersionUID = -8614860617229484621L;
95
	private static final Logger logger = LogManager.getLogger(AmplificationResult.class);
96

    
97
    /** @see #getDnaSample() */
98
	@XmlElement( name = "DnaSample")
99
    @XmlIDREF
100
    @XmlSchemaType(name = "IDREF")
101
    @ManyToOne(fetch = FetchType.LAZY)
102
    @IndexedEmbedded
103
    private DnaSample dnaSample;
104

    
105
   /** @see #getAmplification() */
106
	@XmlElement( name = "Amplification")
107
    @XmlIDREF
108
    @XmlSchemaType(name = "IDREF")
109
    @ManyToOne(fetch = FetchType.LAZY)
110
	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
111
	@IndexedEmbedded
112
    private Amplification amplification;
113

    
114
    @XmlElementWrapper(name = "SingleReads")
115
    @XmlElement(name = "SingleRead")
116
    @XmlIDREF
117
    @XmlSchemaType(name = "IDREF")
118
    @OneToMany(mappedBy="amplificationResult" , fetch = FetchType.LAZY)
119
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
120
	private Set<SingleRead> singleReads = new HashSet<>();
121

    
122
    @XmlElement(name = "Cloning")
123
    @XmlIDREF
124
    @XmlSchemaType(name = "IDREF")
125
    @ManyToOne(fetch=FetchType.LAZY)
126
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
127
    private Cloning cloning;
128

    
129
	/** @see #getSuccessful() */
130
    @XmlAttribute(name = "successful")
131
    private Boolean successful;
132

    
133
    /** @see #getSuccessText() */
134
    @XmlElement(name = "successText")
135
	@Field
136
    @Column(length=255)
137
	private String successText;
138
//
139
//    /** @see #getGelRunningTime() */
140
//	@XmlElement(name = "gelRunningTime")
141
//	@Field(analyze = Analyze.NO)
142
//	@NumericField
143
//	private Double gelRunningTime;
144

    
145
    @XmlElement(name = "GelPhoto")
146
    @XmlIDREF
147
    @XmlSchemaType(name = "IDREF")
148
    @ManyToOne(fetch=FetchType.LAZY)
149
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
150
	private Media gelPhoto;
151

    
152

    
153
// ********************* FACTORY METHODS ************************/
154

    
155
	public static AmplificationResult NewInstance(DnaSample dnaSample){
156
		AmplificationResult result = new AmplificationResult();
157
		dnaSample.addAmplificationResult(result);
158
		return result;
159
	}
160

    
161
	public static AmplificationResult NewInstance(SingleRead singleRead){
162
	    AmplificationResult result = new AmplificationResult();
163
	    result.addSingleRead(singleRead);
164
	    return result;
165
	}
166

    
167
	public static AmplificationResult NewInstance(DnaSample dnaSample,
168
			Amplification amplification) {
169
		AmplificationResult result = new AmplificationResult();
170
		dnaSample.addAmplificationResult(result);
171
		result.setAmplification(amplification);
172
		return result;
173
	}
174

    
175
	public static AmplificationResult NewInstance(){
176
	    return new AmplificationResult();
177
	}
178

    
179

    
180
// ******************* CONSTRUCTOR *******************************/
181

    
182
	protected AmplificationResult(){}
183

    
184

    
185
//********************* GETTER / SETTER ************/
186

    
187

    
188
	/**
189
	 * The {@link DnaSample dna sample} which is the input for this {@link AmplificationResult amplification}.
190
	 */
191
	public DnaSample getDnaSample() {
192
		return dnaSample;
193
	}
194

    
195
	/**
196
	 * For use by DnaSample.addAmplification(ampl.) only. For now.
197
	 * @see #getDnaSample()
198
	 */
199
	protected void setDnaSample(DnaSample dnaSample) {
200
		this.dnaSample = dnaSample;
201
	}
202

    
203
	/**
204
	 * The {@link Amplification amplification event} this amplification result resulted from.
205
	 * @see #setAmplification(Amplification)
206
	 * @see Amplification
207
	 * @return the amplification event
208
	 */
209
	public Amplification getAmplification() {
210
		return amplification;
211
	}
212
	/**
213
	 * {@link #getAmplification()}
214
	 * @param amplification
215
	 */
216
	public void setAmplification(Amplification amplification) {
217
		this.amplification = amplification;
218
	}
219

    
220
	/**
221
	 * The {@link SingleRead single sequences} created by using this amplification's result (PCR).
222
	 */
223
	public Set<SingleRead> getSingleReads() {
224
		return singleReads;
225
	}
226

    
227
	public void addSingleRead(SingleRead singleRead){
228
		if (singleRead.getAmplificationResult() != null){
229
			singleRead.getAmplificationResult().singleReads.remove(singleRead);
230
		}
231
		this.singleReads.add(singleRead);
232
		singleRead.setAmplificationResult(this);
233
	}
234

    
235
	public void removeSingleRead(SingleRead singleRead){
236
	    if(this.singleReads.contains(singleRead)){
237
	        this.singleReads.remove(singleRead);
238
	        singleRead.setAmplificationResult(null);
239
	    }
240
	}
241

    
242
	/**
243
	 * @see #getSingleReads()
244
	 */
245
	//TODO private until it is clear how bidirectionality is handled
246
	@SuppressWarnings("unused")
247
	private void setSingleReads(Set<SingleRead> singleReads) {
248
		this.singleReads = singleReads;
249
	}
250

    
251
	/**
252
	 * Information if this amplification was successful or not. Success may be defined
253
	 * by the results of the electrophoresis.
254
	 *
255
	 * @see #getSuccessText()
256
	 */
257
	public Boolean getSuccessful() {
258
		return successful;
259
	}
260

    
261
	/**
262
	 * @see #getSuccessful()
263
	 * @see #getSuccessText()
264
	 */
265
	public void setSuccessful(Boolean successful) {
266
		this.successful = successful;
267
	}
268

    
269
	/**
270
	 * Freetext about the success of this amplification explaining
271
	 * in detail why it is concidered to be successful/unsucessful
272
	 *
273
	 * @see #getSuccessful()
274
	 */
275
	public String getSuccessText() {
276
		return successText;
277
	}
278

    
279
	/**
280
	 * @see #getSuccessText()
281
	 * @see #getSuccessful()
282
	 */
283
	public void setSuccessText(String successText) {
284
		this.successText = successText;
285
	}
286

    
287
	/**
288
	 * The {@link Cloning cloning process} involved in this amplification.
289
	 */
290
	public Cloning getCloning() {
291
		return cloning;
292
	}
293

    
294
	/**
295
	 * @see #getCloning()
296
	 */
297
	public void setCloning(Cloning cloning) {
298
		this.cloning = cloning;
299
	}
300
//
301
//	/**
302
//	 * The time for running the electrophoresis quality check.
303
//	 * Base unit is minutes [min].
304
//	 */
305
//	public Double getGelRunningTime() {
306
//		return gelRunningTime;
307
//	}
308
//
309
//	/**
310
//	 * @see #getGelRunningTime()
311
//	 */
312
//	public void setGelRunningTime(Double gelRunningTime) {
313
//		this.gelRunningTime = gelRunningTime;
314
//	}
315

    
316

    
317
	/**
318
	 * The photo taken from the electrophoresis result showing the quality of the amplification.
319
	 * Gelphotos often do show multiple electrophoresis results. One may either cut or mark
320
	 * the part of the photo that displays <code>this</code> amplification. However, this may make
321
	 * the concrete media file unusable for other amplifications also represented by the same image.
322
	 * @see #getElectrophoresisVoltage()
323
	 * @see #getLadderUsed()
324
	 * @see #getGelConcentration()
325
	 * @see #getGelRunningTime()
326
	 */
327
	public Media getGelPhoto() {
328
		return gelPhoto;
329
	}
330

    
331

    
332
	/**
333
	 * @param gelPhoto the gelPhoto to set
334
	 */
335
	public void setGelPhoto(Media gelPhoto) {
336
		this.gelPhoto = gelPhoto;
337
	}
338

    
339

    
340
	// ********************** CLONE ***********************************/
341
	/**
342
	 * Clones <i>this</i> amplification. This is a shortcut that enables to create
343
	 * a new instance that differs only slightly from <i>this</i> amplification by
344
	 * modifying only some of the attributes.<BR><BR>
345
	 *
346
	 *
347
	 * @see EventBase#clone()
348
	 * @see java.lang.Object#clone()
349
	 */
350
	@Override
351
	public AmplificationResult clone()  {
352
		try{
353
			AmplificationResult result = (AmplificationResult)super.clone();
354

    
355
			result.singleReads = new HashSet<SingleRead>();
356
			for (SingleRead seq: this.singleReads){
357
				result.singleReads.add(seq);
358

    
359
			}
360

    
361
			//don't change dnaSample, marker, successful, successText, forwardPrimer,
362
			//reversePrimer, purifiaction, cloning, ladderUsed, electrophoresisVoltage,
363
			//gelRunningTime, gelPhoto, gelConcentration
364
			return result;
365
		}catch (CloneNotSupportedException e) {
366
			logger.warn("Object does not implement cloneable");
367
			e.printStackTrace();
368
			return null;
369
		}
370
	}
371

    
372
}
(2-2/14)