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}