001package org.biopax.paxtools.io.sif.level3; 002 003import org.biopax.paxtools.model.BioPAXLevel; 004import org.biopax.paxtools.model.level3.*; 005 006import java.util.HashMap; 007import java.util.Map; 008 009/** 010 * This enum handles types of modifications and contains utility methods for extracting them. 011 */ 012public enum ChangeType { 013 /** 014 * A modification type was explicitly removed. ( Very RARE since NOT-FEATURE is currently not adopted by most 015 * pathway databases.) 016 */ 017 EXIST_TO_NOT_EXIST, 018 /** 019 * A modification type "disappeared. (Common removal type) 020 */ 021 EXIST_TO_UNKNOWN, 022 /** 023 * A modification type "appeared" (Common addition type) 024 */ 025 UNKNOWN_TO_NOT_EXIST, 026 /** 027 * No addition or removal. 028 */ 029 UNCHANGED, 030 /** 031 * A modification type that was known to be non-existing simply become unknown. No know instances, this is here 032 * for completeness 033 */ 034 NOT_EXIST_TO_UNKNOWN, 035 036 /** 037 * The most common addition form - a modification type "appeared". 038 */ 039 UNKNOWN_TO_EXIST, 040 041 /** 042 * A modification type was explicitly added. ( Very RARE since NOT-FEATURE is currently not adopted by most 043 * pathway databases.) 044 */ 045 NOT_EXIST_TO_EXIST; 046 047 /** 048 * Special static entity feature used for representing changes that effect existence of protein -i.e. translation 049 * or degradation. 050 */ 051 public static final EntityFeature EXISTENCE = BioPAXLevel.L3.getDefaultFactory().create( 052 EntityFeature.class, "urn:org.biopax.paxtools.static/EXISTENCE"); 053 054 /** 055 * Special static entity feature used as a 'hack' to capture complex membership. 056 */ 057 public static final BindingFeature BINDING = BioPAXLevel.L3.getDefaultFactory().create( 058 BindingFeature.class, "urn:org.biopax.paxtools.static/BINDING"); 059 060 /** 061 * This method returns the features that are "changed" between the left and right physical entities. IF these are 062 * "contained" in another PE such as a complex or generic it also considers changes to those containers . 063 * @param left a simple physical entity to be compared. 064 * @param right a simple physical entity to be compared 065 * @param leftRoot if left is in a complex or represented as a generic actual participating entity that contains 066 * or subsumes left. 067 * @param rightRoot if right is in a complex or represented as a generic actual participating entity that contains 068 * or subsumes right. 069 * @return A Map of features of spe, annotated with a change type, direction is from-left-to-right. 070 */ 071 public static Map<EntityFeature, ChangeType> getDeltaFeatures(PhysicalEntity left, PhysicalEntity right, 072 PhysicalEntity leftRoot, PhysicalEntity rightRoot) { 073 Map<EntityFeature, ChangeType> result = new HashMap<EntityFeature, ChangeType>(); 074 if (left == null) { 075 result.put(EXISTENCE, NOT_EXIST_TO_EXIST); 076 077 for (EntityFeature entityFeature : right.getFeature()) { 078 result.put(entityFeature, NOT_EXIST_TO_EXIST); 079 } 080 } 081 else if (right == null) 082 { 083 result.put(EXISTENCE, EXIST_TO_NOT_EXIST); 084 for (EntityFeature entityFeature : left.getFeature()) { 085 result.put(entityFeature, EXIST_TO_NOT_EXIST); 086 } 087 } 088 else 089 { 090 for (EntityFeature lFeat : left.getFeature()) { 091 if (right.getFeature().contains(lFeat)) 092 { 093 result.put(lFeat, UNCHANGED); 094 } 095 else if (right.getNotFeature().contains(lFeat)) { 096 result.put(lFeat, EXIST_TO_NOT_EXIST); 097 } else { 098 result.put(lFeat, EXIST_TO_UNKNOWN); 099 } 100 } 101 for (EntityFeature lFeat : left.getNotFeature()) { 102 if (right.getFeature().contains(lFeat)) { 103 result.put(lFeat, NOT_EXIST_TO_EXIST); 104 } 105 else if 106 (right.getNotFeature().contains(lFeat)) { 107 result.put(lFeat, UNCHANGED); 108 } else { 109 result.put(lFeat, NOT_EXIST_TO_UNKNOWN); 110 } 111 } 112 for (EntityFeature rFeat : right.getFeature()) { 113 if (!result.containsKey(rFeat)) { 114 result.put(rFeat, UNKNOWN_TO_EXIST); 115 } 116 } 117 for (EntityFeature rFeat : right.getNotFeature()) { 118 if (!result.containsKey(rFeat)) { 119 result.put(rFeat, UNKNOWN_TO_NOT_EXIST); 120 } 121 } 122 boolean leftInComplex = leftRoot instanceof Complex; 123 boolean rightInComplex = rightRoot instanceof Complex; 124 125 ChangeType bindingDirection = null; 126 if (leftInComplex) { 127 if (!rightInComplex || ((Complex) leftRoot).getComponent().contains(rightRoot)) { 128 bindingDirection = EXIST_TO_NOT_EXIST; 129 } else if (((Complex) rightRoot).getComponent().contains(leftRoot)) { 130 bindingDirection = NOT_EXIST_TO_EXIST; 131 } 132 } 133 else if (rightInComplex) { 134 bindingDirection = NOT_EXIST_TO_EXIST; 135 } 136 if(bindingDirection!=null) 137 { 138 result.put(BINDING,bindingDirection); 139 } 140 } 141 142 return result; 143 144 } 145}