merge trunk into model change 3.6
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / molecular / SingleReadAlignment.java
1 /**
2 *
3 */
4 package eu.etaxonomy.cdm.model.molecular;
5
6 import javax.persistence.Entity;
7 import javax.persistence.FetchType;
8 import javax.persistence.Lob;
9 import javax.persistence.ManyToOne;
10 import javax.xml.bind.annotation.XmlAccessType;
11 import javax.xml.bind.annotation.XmlAccessorType;
12 import javax.xml.bind.annotation.XmlElement;
13 import javax.xml.bind.annotation.XmlIDREF;
14 import javax.xml.bind.annotation.XmlRootElement;
15 import javax.xml.bind.annotation.XmlSchemaType;
16 import javax.xml.bind.annotation.XmlType;
17
18 import org.hibernate.annotations.Cascade;
19 import org.hibernate.annotations.CascadeType;
20 import org.hibernate.annotations.Type;
21 import org.hibernate.envers.Audited;
22
23 import eu.etaxonomy.cdm.model.common.VersionableEntity;
24
25 /**
26 * @author a.mueller
27 */
28 @XmlAccessorType(XmlAccessType.FIELD)
29 @XmlType(name = "SingleReadAlignment", propOrder = {
30 "consensusAlignment",
31 "singleRead",
32 "shifts",
33 "editedSequence",
34 "reverseComplement",
35 "firstSeqPosition",
36 "leftCutPosition",
37 "rightCutPosition"
38 })
39 @XmlRootElement(name = "SingleReadAlignment")
40 @Entity
41 @Audited
42 public class SingleReadAlignment extends VersionableEntity {
43 private static final long serialVersionUID = 6141518347067279304L;
44
45 /** @see #getDnaMarker() */
46 @XmlElement(name = "ConsensusAlignment")
47 @XmlIDREF
48 @XmlSchemaType(name = "IDREF")
49 @ManyToOne(fetch = FetchType.LAZY)
50 //for now we do not cascade but expect the user to save the sequence manually
51 private Sequence consensusAlignment;
52
53 /** @see #getDnaMarker() */
54 @XmlElement(name = "SingleRead")
55 @XmlIDREF
56 @XmlSchemaType(name = "IDREF")
57 @ManyToOne(fetch = FetchType.LAZY)
58 @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
59 private SingleRead singleRead;
60
61 //TODO XML mapping / user type
62 @Type(type="shiftUserType")
63 private Shift[] shifts = new Shift[0];
64
65 private Integer firstSeqPosition;
66
67 private Integer leftCutPosition;
68
69 private Integer rightCutPosition;
70
71 @XmlElement(name = "EditedSequence")
72 @Lob
73 private String editedSequence;
74
75 @XmlElement(name = "ReverseComplement")
76 private boolean reverseComplement;
77
78
79 public static class Shift implements Cloneable{
80 public int position;
81 public int shift;
82
83 public Shift(){};
84 public Shift(int position, int steps) {
85 this.position = position;
86 this.shift = steps;
87 }
88
89 @Override
90 public String toString(){
91 return String.valueOf(position) + "," + String.valueOf(shift);
92 }
93 @Override
94 protected Object clone() throws CloneNotSupportedException {
95 return super.clone();
96 }
97 }
98
99 //****************** FACTORY *******************/
100
101 public static SingleReadAlignment NewInstance(Sequence consensusSequence, SingleRead singleRead){
102 return new SingleReadAlignment(consensusSequence, singleRead, null, null);
103 }
104
105 public static SingleReadAlignment NewInstance(Sequence consensusSequence, SingleRead singleRead,
106 Shift[] shifts, String editedSequence){
107 return new SingleReadAlignment(consensusSequence, singleRead, shifts, editedSequence);
108 }
109
110 // ***************** CONSTRUCTOR *************************/
111
112 protected SingleReadAlignment(){};
113
114 private SingleReadAlignment(Sequence consensusAlignment, SingleRead singleRead,
115 Shift[] shifts, String editedSequence){
116 setConsensusAlignment(consensusAlignment);
117 setSingleRead(singleRead);
118 this.shifts = shifts;
119 this.editedSequence = editedSequence;
120 }
121
122
123 // ****************** GETTER / SETTER ***********************/
124
125 //consensus sequence
126 public Sequence getConsensusSequence() {
127 return consensusAlignment;
128 }
129 public void setConsensusAlignment(Sequence consensusAlignment) {
130 if (this.consensusAlignment != null && this.consensusAlignment.getSingleReadAlignments().contains(this)){
131 this.consensusAlignment.removeSingleReadAlignment(this);
132 }
133 this.consensusAlignment = consensusAlignment;
134 if (consensusAlignment != null && ! consensusAlignment.getSingleReadAlignments().contains(this)){
135 consensusAlignment.addSingleReadAlignment(this);
136 }
137 }
138
139 public SingleRead getSingleRead() {
140 return singleRead;
141 }
142 public void setSingleRead(SingleRead singleRead) {
143 // if (this.singleRead != null xxx){
144 // this.singleRead.removeSingleReadAlignment(this);
145 // }
146 this.singleRead = singleRead;
147 // if (singleRead != null && singleRead.getSingleReadAlignments().contains(this)){
148 // singleRead.addSingleReadAlignment(this);
149 // }
150 }
151
152 //shifts
153 public Shift[] getShifts() {
154 return shifts == null ? new Shift[0] : shifts;
155 }
156 public void setShifts(Shift[] shifts) {
157 this.shifts = shifts;
158 if (shifts == null){
159 shifts = new Shift[0];
160 }
161 }
162
163 //edited sequence
164 public String getEditedSequence() {
165 return editedSequence;
166 }
167
168 public void setEditedSequence(String editedSequence) {
169 this.editedSequence = editedSequence;
170 }
171
172
173 public boolean isReverseComplement() {
174 return reverseComplement;
175 }
176
177 public void setReverseComplement(boolean reverseComplement) {
178 this.reverseComplement = reverseComplement;
179 }
180
181 // ******************* CLONE *********************/
182
183
184
185 @Override
186 public Object clone() throws CloneNotSupportedException {
187 SingleReadAlignment result = (SingleReadAlignment)super.clone();
188
189 //deep copy shifts
190 Shift[] oldShifts = this.getShifts();
191 int shiftLength = oldShifts.length;
192 Shift[] newShift = new Shift[shiftLength];
193 for (int i = 0; i< shiftLength; i++){
194 Shift oldShift = oldShifts[i];
195 newShift[0] = (Shift)oldShift.clone();
196 }
197
198 //all other objects can be reused
199 return result;
200 }
201
202 /**
203 * Returns the position in the {@link Sequence sequence}
204 * this {@link SingleReadAlignment single read align} is attached to
205 * where the output of the visible part of the pherogram starts.
206 * @return a valid index in the sequence carrying this data area
207 * @see http://bioinfweb.info/LibrAlign/Documentation/api/latest/info/bioinfweb/libralign/dataarea/implementations/pherogram/PherogramArea.html#getFirstSeqPos
208 *
209 */
210 public Integer getFirstSeqPosition() {
211 return firstSeqPosition;
212 }
213
214 /**
215 * @see #getFirstSeqPosition()
216 */
217 public void setFirstSeqPosition(Integer firstSeqPosition) {
218 this.firstSeqPosition = firstSeqPosition;
219 }
220
221 /**
222 * Returns the first base call index of the pherogram which has not been cut off.
223 * @return a base call index > 0
224 * @see http://bioinfweb.info/LibrAlign/Documentation/api/latest/info/bioinfweb/libralign/pherogram/PherogramComponent.html#getLeftCutPosition
225 */
226 public Integer getLeftCutPosition() {
227 return leftCutPosition;
228 }
229
230 /**
231 * @param see {@link #getLeftCutPosition()}
232 */
233 public void setLeftCutPosition(Integer leftCutPosition) {
234 this.leftCutPosition = leftCutPosition;
235 }
236
237 /**
238 * Returns the first base call index of the pherogram that has been cut off (so that the length of the visible
239 * area of the pherogram can be calculated as getRightCutPosition()
240 * @return a base call inde
241 * @see http://bioinfweb.info/LibrAlign/Documentation/api/latest/info/bioinfweb/libralign/pherogram/PherogramComponent.html#getRightCutPosition
242 */
243 public Integer getRightCutPosition() {
244 return rightCutPosition;
245 }
246
247 /**
248 * @param see {@link #getRightCutPosition()}
249 */
250 public void setRightCutPosition(Integer rightCutPosition) {
251 this.rightCutPosition = rightCutPosition;
252 }
253
254 }