001package org.biopax.paxtools.pattern.util;
002
003import org.biopax.paxtools.model.level3.*;
004
005import java.util.Collections;
006import java.util.HashSet;
007import java.util.Set;
008
009/**
010 * THis class is used for comparing modification features of two PhysicalEntity objects of same
011 * EntityReference.
012 *
013 * @author Ozgun Babur
014 */
015public class DifferentialModificationUtil
016{
017        /**
018         * Gets the differential features.
019         * @param before first entity
020         * @param after second entity
021         * @return array of differential features. index 0: gained features, index 1: lost features
022         */
023        public static Set<ModificationFeature>[] getChangedModifications(PhysicalEntity before,
024                PhysicalEntity after)
025        {
026                Set<Modification> set1 = collectFeatures(before);
027                Set<Modification> set2 = collectFeatures(after);
028
029                Set<Modification> temp = new HashSet<Modification>(set1);
030                set1.removeAll(set2);
031                set2.removeAll(temp);
032
033                return new Set[]{collectFeatures(set2), collectFeatures(set1)};
034        }
035
036        public static Set<String> collectChangedPhosphorylationSites(PhysicalEntity before,
037                PhysicalEntity after, boolean gained)
038        {
039                Set<ModificationFeature> set = getChangedModifications(before, after)[gained ? 0 : 1];
040                Set<String> sites = new HashSet<String>();
041                for (ModificationFeature mf : set)
042                {
043                        String lett = getPhosphoSiteLetter(mf);
044                        if (lett != null)
045                        {
046                                int site = getPhosphoSite(mf);
047                                if (site > 0)
048                                {
049                                        sites.add(lett + site);
050                                }
051                        }
052                }
053                return sites;
054        }
055
056        private static Set<Modification> collectFeatures(PhysicalEntity pe)
057        {
058                Set<Modification> set = new HashSet<Modification>();
059
060                for (EntityFeature f : pe.getFeature())
061                {
062                        if (f instanceof ModificationFeature)
063                                set.add(new Modification((ModificationFeature) f));
064                }
065                return set;
066        }
067
068        private static Set<ModificationFeature> collectFeatures(Set<Modification> wrappers)
069        {
070                if (wrappers.isEmpty()) return Collections.emptySet();
071
072                Set<ModificationFeature> set = new HashSet<ModificationFeature>();
073
074                for (Modification wrapper : wrappers)
075                {
076                        set.add(wrapper.mf);
077                }
078                return set;
079        }
080
081        /**
082         * Wrapper for ModificationFeature.
083         */
084        private static class Modification
085        {
086                ModificationFeature mf;
087
088                Modification(ModificationFeature mf)
089                {
090                        this.mf = mf;
091                }
092
093                @Override
094                public int hashCode()
095                {
096                        int code = 0;
097
098                        SequenceModificationVocabulary type = mf.getModificationType();
099                        if (type != null)
100                        {
101                                for (String term : type.getTerm())
102                                {
103                                        code += term.hashCode();
104                                }
105                        }
106
107                        SequenceLocation loc = mf.getFeatureLocation();
108                        if (loc != null)
109                        {
110                                if (loc instanceof SequenceInterval)
111                                {
112                                        SequenceSite begin = ((SequenceInterval) loc).getSequenceIntervalBegin();
113                                        SequenceSite end = ((SequenceInterval) loc).getSequenceIntervalEnd();
114
115                                        if (begin != null) code += begin.getSequencePosition();
116                                        if (end != null) code += end.getSequencePosition();
117                                }
118                                else if (loc instanceof SequenceSite)
119                                {
120                                        code += ((SequenceSite) loc).getSequencePosition();
121                                }
122                        }
123                        return code;
124                }
125
126                @Override
127                public boolean equals(Object obj)
128                {
129                        if (!(obj instanceof Modification)) return false;
130
131                        Modification m = (Modification) obj;
132
133                        if (mf == m.mf) return true;
134
135                        if (mf.getModificationType() == null || m.mf.getModificationType() == null)
136                                return false;
137
138                        if (!mf.getModificationType().getTerm().containsAll(
139                                m.mf.getModificationType().getTerm())) return false;
140
141                        if (mf.getFeatureLocation() == null && m.mf.getFeatureLocation() == null) return true;
142
143                        if (mf.getFeatureLocation() == null || m.mf.getFeatureLocation() == null) return false;
144
145                        return mf.getFeatureLocation().equivalenceCode() ==
146                                m.mf.getFeatureLocation().equivalenceCode();
147                }
148        }
149
150        private static String getPhosphoSiteLetter(ModificationFeature mf)
151        {
152                if (mf.getModificationType() != null)
153                {
154                        for (String term : mf.getModificationType().getTerm())
155                        {
156                                term = term.toLowerCase();
157                                if (term.contains("phospho"))
158                                {
159                                        if (term.contains("serine")) return "S";
160                                        if (term.contains("threonine")) return "T";
161                                        if (term.contains("tyrosine")) return "Y";
162                                }
163                        }
164                }
165                return null;
166        }
167
168        private static int getPhosphoSite(ModificationFeature mf)
169        {
170                SequenceLocation loc = mf.getFeatureLocation();
171                if (loc != null && loc instanceof SequenceSite)
172                {
173                        return ((SequenceSite) loc).getSequencePosition();
174                }
175                return -1;
176        }
177}