001package org.biopax.paxtools.impl.level3; 002 003 004import org.biopax.paxtools.model.BioPAXElement; 005import org.biopax.paxtools.model.level3.*; 006import org.biopax.paxtools.util.BPCollections; 007import org.biopax.paxtools.util.ClassFilterSet; 008import org.hibernate.annotations.Cache; 009import org.hibernate.annotations.*; 010import org.hibernate.search.annotations.Indexed; 011 012import javax.persistence.Entity; 013import javax.persistence.*; 014import java.util.Set; 015 016import static org.biopax.paxtools.util.SetEquivalenceChecker.hasEquivalentIntersection; 017 018@Entity 019@Proxy(proxyClass=Evidence.class) 020@Indexed 021@DynamicUpdate @DynamicInsert 022@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 023public class EvidenceImpl extends XReferrableImpl implements Evidence 024{ 025 026 private Set<ExperimentalForm> experimentalForm; 027 private Set<Score> confidence; 028 private Set<EvidenceCodeVocabulary> evidenceCode; 029 030 /** 031 * Constructor. 032 */ 033 public EvidenceImpl() 034 { 035 this.confidence = BPCollections.I.createSafeSet(); 036 this.evidenceCode = BPCollections.I.createSafeSet(); 037 this.experimentalForm = BPCollections.I.createSafeSet(); 038 } 039 040 // 041 // BioPAXElement interface implementation 042 // 043 //////////////////////////////////////////////////////////////////////////// 044 045 @Transient 046 public Class<? extends Evidence> getModelInterface() 047 { 048 return Evidence.class; 049 } 050 051 052 // 053 // Evidence interface implementation 054 // 055 //////////////////////////////////////////////////////////////////////////// 056 057 058 /** 059 * Confidence in the containing instance. Usually a statistical measure. 060 * 061 * @return a set of scores representing confidence 062 */ 063 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 064 @OneToMany(targetEntity = ScoreImpl.class)//, cascade={CascadeType.ALL}) 065 @JoinTable(name="confidence") 066 public Set<Score> getConfidence() 067 { 068 return confidence; 069 } 070 071 /** 072 * Confidence in the containing instance. Usually a statistical measure. 073 * 074 * WARNING: This method should only be used for batch operations and with care. For regular 075 * manipulation use add/remove instead. 076 * 077 * @param confidence a set of scores representing confidence 078 */ 079 080 public void setConfidence(Set<Score> confidence) 081 { 082 this.confidence = confidence; 083 } 084 085 /** 086 * Confidence in the containing instance. Usually a statistical measure. 087 * 088 * @param confidence a new confidence measure to add 089 */ 090 public void addConfidence(Score confidence) 091 { 092 if(confidence != null) 093 this.confidence.add(confidence); 094 } 095 096 /** 097 * Confidence in the containing instance. Usually a statistical measure. 098 * 099 * @param confidence a confidence measure to be removed. 100 */ 101 public void removeConfidence(Score confidence) 102 { 103 if(confidence != null) 104 this.confidence.remove(confidence); 105 } 106 107 108 /** 109 * A pointer to a term in an external controlled vocabulary, such as the GO, PSI-MI or BioCyc 110 * evidence codes, that describes the nature of the support, such as 'traceable author statement' 111 * or 'yeast two-hybrid'. 112 * 113 * @return a set of evidence codes for this evidence type. 114 */ 115 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 116 @ManyToMany(targetEntity = EvidenceCodeVocabularyImpl.class) 117 @JoinTable(name="evidencecode") 118 public Set<EvidenceCodeVocabulary> getEvidenceCode() 119 { 120 return evidenceCode; 121 } 122 123 /** 124 * A pointer to a term in an external controlled vocabulary, such as the GO, PSI-MI or BioCyc 125 * evidence codes, that describes the nature of the support, such as 'traceable author statement' 126 * or 'yeast two-hybrid'. 127 * 128 * WARNING: This method should only be used for batch operations and with care. For regular 129 * manipulation use add/remove instead. 130 * 131 * @param evidenceCode a new set of evidence codes for this evidence type. 132 */ 133 public void setEvidenceCode(Set<EvidenceCodeVocabulary> evidenceCode) 134 { 135 this.evidenceCode = evidenceCode; 136 } 137 138 /** 139 * A pointer to a term in an external controlled vocabulary, such as the GO, PSI-MI or BioCyc 140 * evidence codes, that describes the nature of the support, such as 'traceable author statement' 141 * or 'yeast two-hybrid'. 142 * 143 * @param evidenceCode a new evidence code for this evidence. 144 */ 145 public void addEvidenceCode(EvidenceCodeVocabulary evidenceCode) 146 { 147 if(evidenceCode != null) 148 this.evidenceCode.add(evidenceCode); 149 } 150 151 /** 152 * A pointer to a term in an external controlled vocabulary, such as the GO, PSI-MI or BioCyc 153 * evidence codes, that describes the nature of the support, such as 'traceable author statement' 154 * or 'yeast two-hybrid'. 155 * 156 * @param evidenceCode to be removed 157 */ 158 public void removeEvidenceCode(EvidenceCodeVocabulary evidenceCode) 159 { 160 if(evidenceCode != null) 161 this.evidenceCode.remove(evidenceCode); 162 } 163 164 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 165 @ManyToMany(targetEntity = ExperimentalFormImpl.class)//, cascade={CascadeType.ALL}) 166 @JoinTable(name="experimentalForm") 167 public Set<ExperimentalForm> getExperimentalForm() 168 { 169 return experimentalForm; 170 } 171 172 public void setExperimentalForm(Set<ExperimentalForm> experimentalForm) 173 { 174 this.experimentalForm = experimentalForm; 175 } 176 177 public void addExperimentalForm(ExperimentalForm experimentalForm) 178 { 179 if(experimentalForm != null) 180 this.experimentalForm.add(experimentalForm); 181 } 182 183 public void removeExperimentalForm(ExperimentalForm experimentalForm) 184 { 185 if(experimentalForm != null) 186 this.experimentalForm.remove(experimentalForm); 187 } 188 189// ------------------------ INTERFACE METHODS ------------------------ 190 191 /** 192 * Answers whether two Evidence objects are semantically equivalent. 193 * (Currently, it considers only member UnificationXrefs and EvidenceCodeVocabularies 194 * for comparison...) 195 * 196 * TODO: review; add comparing ExperimentalForm and Confidence values... 197 * 198 */ 199 @Override 200 protected boolean semanticallyEquivalent(BioPAXElement element) { 201 if(! (element instanceof Evidence) ) return false; 202 Evidence that = (Evidence) element; // not null (guaranteed by here) 203 boolean hasAllEquivEvidenceCodes = false; 204 205 if(this.getEvidenceCode().isEmpty()) { 206 if(that.getEvidenceCode().isEmpty()) { 207 hasAllEquivEvidenceCodes = true; 208 } 209 } else { 210 if(!that.getEvidenceCode().isEmpty()) { 211 Set<EvidenceCodeVocabulary> shorter; 212 Set<EvidenceCodeVocabulary> longer; 213 if (this.getEvidenceCode().size() < that.getEvidenceCode().size()) 214 { 215 shorter = this.getEvidenceCode(); 216 longer = that.getEvidenceCode(); 217 } else { 218 longer = this.getEvidenceCode(); 219 shorter = that.getEvidenceCode(); 220 } 221 222 /* each ECV in the 'shorter' set must find its equivalent 223 * in the 'longer' set; 224 * otherwise two Evidence objects (this and that) are not equiv. 225 */ 226 hasAllEquivEvidenceCodes = true; // initial guess 227 for(EvidenceCodeVocabulary secv : shorter) { 228 boolean foundEquiv = false; 229 for(EvidenceCodeVocabulary lecv : longer) { 230 if(secv.isEquivalent(lecv)) { 231 foundEquiv = true; 232 } 233 } 234 if(!foundEquiv) { 235 hasAllEquivEvidenceCodes = false; 236 break; 237 } 238 } 239 } 240 } 241 242 //consider publication xrefs! 243 boolean hasCommonPublicationXref = hasEquivalentIntersection( 244 new ClassFilterSet<Xref, PublicationXref>(getXref(), PublicationXref.class), 245 new ClassFilterSet<Xref, PublicationXref>(that.getXref(), PublicationXref.class)); 246 247 return super.semanticallyEquivalent(element) && hasAllEquivEvidenceCodes && hasAllEquivEvidenceCodes; 248 } 249 250}