001package org.biopax.paxtools.io.sif.level3; 002 003import org.apache.commons.logging.Log; 004import org.apache.commons.logging.LogFactory; 005import org.biopax.paxtools.controller.ModelUtils; 006import org.biopax.paxtools.model.BioPAXElement; 007import org.biopax.paxtools.model.Model; 008import org.biopax.paxtools.model.level3.Complex; 009import org.biopax.paxtools.model.level3.EntityReference; 010import org.biopax.paxtools.model.level3.PhysicalEntity; 011import org.biopax.paxtools.model.level3.SimplePhysicalEntity; 012import org.biopax.paxtools.util.AccessibleSet; 013 014import java.util.HashMap; 015import java.util.HashSet; 016import java.util.Map; 017import java.util.Set; 018 019/** 020 * @author Emek Demir 021 */ 022public class Grouper 023{ 024 private static final Log log = LogFactory.getLog(Grouper.class); 025 026 Map<BioPAXElement, Group> element2GroupMap = new HashMap<BioPAXElement, Group>(); 027 028 AccessibleSet<Group> groups = new AccessibleSet<Group>(); 029 030 Map<BioPAXElement, Set<Group>> delegated = new HashMap<BioPAXElement, Set<Group>>(); 031 032 033 Set<EntityReference> ersToBeGrouped ; 034 035 Set<Complex> complexesToBeGrouped; 036 037 public static GroupMap inferGroups(Model model) 038 { 039 ModelUtils.normalizeGenerics(model); 040 Grouper grouper =new Grouper(); 041 return new GroupMap(grouper.inferGroups(model, grouper)); 042 } 043 044 private Map<BioPAXElement, Group> inferGroups(Model model, Grouper grouper) 045 { 046 ersToBeGrouped = new HashSet<EntityReference>(model.getObjects(EntityReference.class)); 047 complexesToBeGrouped = new HashSet<Complex>(model.getObjects(Complex.class)); 048 049 for (EntityReference er : ersToBeGrouped) 050 { 051 addIfNotNull(er, inferGroupFromER(er, model)); 052 } 053 for (Complex complex : complexesToBeGrouped) 054 { 055 addIfNotNull(complex, inferGroupFromComplex(complex, model)); 056 } 057 058 return element2GroupMap; 059 060 } 061 062 private void addIfNotNull(BioPAXElement element, final Group group) 063 { 064 if (group != null) 065 { 066 Group equivalentGroup = groups.access(group); 067 if (equivalentGroup == null) 068 { 069 equivalentGroup = group; 070 groups.add(equivalentGroup); 071 } else 072 { 073 equivalentGroup.sources.addAll(group.sources); 074 } 075 element2GroupMap.put(element, equivalentGroup); 076 } 077 078 } 079 080 private Group inferGroupFromComplex(Complex complex, Model model) 081 { 082 Group group = new Group(true, complex); 083 Set<PhysicalEntity> PElvlMembers = complex.getMemberPhysicalEntity(); 084 if (PElvlMembers.isEmpty()) 085 { 086 for (PhysicalEntity component : complex.getComponent()) 087 { 088 if (component instanceof SimplePhysicalEntity) 089 { 090 EntityReference er = this.element2GroupMap.get(component); 091 if(er==null) 092 er = ((SimplePhysicalEntity) component).getEntityReference(); 093 094 if (er != null) 095 { 096 group.addMember(er); 097 } else 098 { 099 addOrDelegate(component, group); 100 } 101 } else if (component instanceof Complex) 102 { 103 addOrDelegate(component, group); 104 } 105 } 106 } else 107 { 108 //If this is a reactome generic it should not have any components? 109 if (!complex.getComponent().isEmpty()) 110 { 111 log.debug("Generic complex with both membership types (" + complex.getRDFId() + "). Skipping."); 112 } else 113 { 114 group = new Group(false, complex); 115 group.genericClass = Complex.class; 116 for (PhysicalEntity member : PElvlMembers) 117 { 118 if (member instanceof Complex) 119 { 120 addOrDelegate(member, group); 121 } else 122 { 123 log.debug("Non complex PE member for complex (" + member.getRDFId() + "->" + complex 124 .getRDFId() + 125 "). Skipping"); 126 } 127 } 128 129 } 130 } 131 Set<Group> groups = delegated.get(complex); 132 if (groups != null) 133 { 134 for (Group owner : groups) 135 { 136 owner.addSubgroup(group); 137 } 138 } 139 ModelUtils.copySimplePointers(model, complex, group); 140 return group; 141 } 142 143 private void addOrDelegate(BioPAXElement member, Group owner) 144 { 145 Group subgroup = element2GroupMap.get(member); 146 if (subgroup != null) owner.addSubgroup(subgroup); 147 else 148 { 149 Set<Group> groups = delegated.get(member); 150 if (groups == null) 151 { 152 groups = new HashSet<Group>(); 153 delegated.put(member, groups); 154 } 155 groups.add(owner); 156 } 157 } 158 159 private Group inferGroupFromER(EntityReference element, Model model) 160 { 161 Group group = new Group(false, element); 162 163 for (EntityReference member : element.getMemberEntityReference()) 164 { 165 if(group.genericClass==null) 166 { 167 group.genericClass = member.getModelInterface(); 168 } 169 group.addMember(member); 170 } 171 172 Set<Group> owners = delegated.get(element); 173 if (owners != null) 174 { 175 for (Group owner : owners) 176 { 177 owner.addSubgroup(group); 178 } 179 } 180 ModelUtils.copySimplePointers(model, element, group); 181 return group.isEmpty() ? null : group; 182 } 183}