@@ -79,18 +79,51 @@ public class EntityFinder {
7979 */
8080 public static final double GAP_COVERAGE_THRESHOLD = 0.3 ;
8181
82- //private Structure s;
83- private List <List <Chain >> allModels ;
82+
83+ private List <List <Chain >> polyModels ;
84+ private List <List <Chain >> nonPolyModels ;
85+ private List <List <Chain >> waterModels ;
8486
8587 public EntityFinder (Structure s ) {
86- allModels = new ArrayList <List <Chain >>();
88+ List < List < Chain >> allModels = new ArrayList <List <Chain >>();
8789 for (int i =0 ;i <s .nrModels ();i ++) {
88- this . allModels .add (s .getModel (i ));
90+ allModels .add (s .getModel (i ));
8991 }
92+ initModels (allModels );
9093 }
9194
9295 public EntityFinder (List <List <Chain >> allModels ) {
93- this .allModels = allModels ;
96+ initModels (allModels );
97+ }
98+
99+ private void initModels (List <List <Chain >> allModels ) {
100+ polyModels = new ArrayList <>();
101+ nonPolyModels = new ArrayList <>();
102+ waterModels = new ArrayList <>();
103+
104+ for (List <Chain > model :allModels ) {
105+
106+ List <Chain > polyChains = new ArrayList <>();
107+ List <Chain > nonPolyChains = new ArrayList <>();
108+ List <Chain > waterChains = new ArrayList <>();
109+
110+ polyModels .add (polyChains );
111+ nonPolyModels .add (nonPolyChains );
112+ waterModels .add (waterChains );
113+
114+ for (Chain c :model ) {
115+
116+ if (StructureTools .isChainWaterOnly (c )) {
117+ waterChains .add (c );
118+
119+ } else if (StructureTools .isChainPureNonPolymer (c )) {
120+ nonPolyChains .add (c );
121+
122+ } else {
123+ polyChains .add (c );
124+ }
125+ }
126+ }
94127 }
95128
96129 /**
@@ -102,18 +135,18 @@ public List<EntityInfo> findEntities() {
102135
103136 TreeMap <String ,EntityInfo > chainIds2entities = findCompoundsFromAlignment ();
104137
105- List <EntityInfo > compounds = findUniqueCompounds (chainIds2entities );
138+ List <EntityInfo > entities = findUniqueEntities (chainIds2entities );
106139
107- createPurelyNonPolyCompounds ( compounds );
140+ createPurelyNonPolyEntities ( polyModels , nonPolyModels , waterModels , entities );
108141
109- return compounds ;
142+ return entities ;
110143 }
111144
112145 /**
113146 * Utility method to obtain a list of unique entities from the chainIds2entities map
114147 * @return
115148 */
116- private static List <EntityInfo > findUniqueCompounds (TreeMap <String ,EntityInfo > chainIds2entities ) {
149+ private static List <EntityInfo > findUniqueEntities (TreeMap <String ,EntityInfo > chainIds2entities ) {
117150
118151 List <EntityInfo > list = new ArrayList <EntityInfo >();
119152
@@ -130,45 +163,71 @@ private static List<EntityInfo> findUniqueCompounds(TreeMap<String,EntityInfo> c
130163 return list ;
131164 }
132165
133- private void createPurelyNonPolyCompounds (List <EntityInfo > compounds ) {
134-
135- List <Chain > pureNonPolymerChains = new ArrayList <Chain >();
136- for (int i =0 ;i <allModels .get (0 ).size ();i ++) {
137- if (StructureTools .isChainPureNonPolymer (allModels .get (0 ).get (i ))) {
138- pureNonPolymerChains .add (allModels .get (0 ).get (i ));
139- }
166+ /**
167+ * Given all chains of all models find entities for the nonpolymers and water chains within them,
168+ * assigning entity ids, types and descriptions to them. The result is written back to the passed entities List.
169+ * @param allModels
170+ * @param entities
171+ */
172+ public static void createPurelyNonPolyEntities (List <List <Chain >> polyModels , List <List <Chain >> nonPolyModels , List <List <Chain >> waterModels , List <EntityInfo > entities ) {
173+
174+ // let's find first the max entity id to assign entity ids to the newly found entities
175+ int maxMolId = 0 ;
176+ if (!entities .isEmpty ()) {
177+ maxMolId = Collections .max (entities , new Comparator <EntityInfo >() {
178+ @ Override
179+ public int compare (EntityInfo o1 , EntityInfo o2 ) {
180+ return new Integer (o1 .getMolId ()).compareTo (o2 .getMolId ());
181+ }
182+ }).getMolId ();
140183 }
141-
142- if (!pureNonPolymerChains .isEmpty ()) {
143-
144- int maxMolId = 0 ; // if we have no compounds at all we just use 0, so that first assignment is 1
145- if (!compounds .isEmpty ()) {
146- Collections .max (compounds , new Comparator <EntityInfo >() {
147- @ Override
148- public int compare (EntityInfo o1 , EntityInfo o2 ) {
149- return new Integer (o1 .getMolId ()).compareTo (o2 .getMolId ());
150- }
151- }).getMolId ();
152- }
153-
154- int molId = maxMolId + 1 ;
155- // for the purely non-polymeric chains we assign additional compounds
156- for (Chain c : pureNonPolymerChains ) {
157- EntityInfo comp = new EntityInfo ();
158- comp .addChain (c );
159- comp .setMolId (molId );
160- if (StructureTools .isChainWaterOnly (c )) {
161- comp .setType (EntityType .WATER );
162- } else {
163- comp .setType (EntityType .NONPOLYMER );
184+ // we go one over the max
185+ maxMolId ++;
186+
187+ // TODO do this correctly for all models, not just first one!
188+
189+ if (!nonPolyModels .get (0 ).isEmpty ()) {
190+ List <EntityInfo > nonPolyEntities = new ArrayList <>();
191+ for (Chain c : nonPolyModels .get (0 )) {
192+ // we assume there's only 1 group per non-poly chain
193+ String molecPdbName = c .getAtomGroup (0 ).getPDBName ();
194+
195+ EntityInfo nonPolyEntity = findNonPolyEntityWithDescription (molecPdbName , nonPolyEntities );
196+ if (nonPolyEntity == null ) {
197+ nonPolyEntity = new EntityInfo ();
198+ nonPolyEntity .setDescription (molecPdbName );
199+ nonPolyEntity .setType (EntityType .NONPOLYMER );
200+ nonPolyEntity .setMolId (maxMolId ++);
201+ nonPolyEntities .add (nonPolyEntity );
202+
164203 }
165- logger .warn ("Chain {} is purely non-polymeric, will assign a new Compound (entity) to it (entity id {})" , c .getId (), molId );
166- molId ++;
167-
168- compounds .add (comp );
204+ nonPolyEntity .addChain (c );
205+ c .setEntityInfo (nonPolyEntity );
169206 }
170-
207+ entities .addAll (nonPolyEntities );
208+ }
209+
210+ if (!waterModels .get (0 ).isEmpty ()) {
211+ EntityInfo waterEntity = new EntityInfo ();
212+ waterEntity .setType (EntityType .WATER );
213+ waterEntity .setDescription ("water" );
214+ waterEntity .setMolId (maxMolId );
215+
216+ for (Chain waterChain :waterModels .get (0 )) {
217+ waterEntity .addChain (waterChain );
218+ waterChain .setEntityInfo (waterEntity );
219+ }
220+ entities .add (waterEntity );
221+ }
222+
223+
224+ }
225+
226+ private static EntityInfo findNonPolyEntityWithDescription (String description , List <EntityInfo > nonPolyEntities ) {
227+ for (EntityInfo e :nonPolyEntities ) {
228+ if (e .getDescription ().equals (description )) return e ;
171229 }
230+ return null ;
172231 }
173232
174233
@@ -221,13 +280,8 @@ private TreeMap<String,EntityInfo> findCompoundsFromAlignment() {
221280 // first we determine which chains to consider: anything not looking
222281 // polymeric (protein or nucleotide chain) should be discarded
223282 Set <Integer > polyChainIndices = new TreeSet <Integer >();
224- List <Chain > pureNonPolymerChains = new ArrayList <Chain >();
225- for (int i =0 ;i <allModels .get (0 ).size ();i ++) {
226- if (StructureTools .isChainPureNonPolymer (allModels .get (0 ).get (i ))) {
227- pureNonPolymerChains .add (allModels .get (0 ).get (i ));
228- } else {
229- polyChainIndices .add (i );
230- }
283+ for (int i =0 ;i <polyModels .get (0 ).size ();i ++) {
284+ polyChainIndices .add (i );
231285 }
232286
233287
@@ -241,8 +295,8 @@ private TreeMap<String,EntityInfo> findCompoundsFromAlignment() {
241295
242296 if (j <=i ) continue ;
243297
244- Chain c1 = allModels .get (0 ).get (i );
245- Chain c2 = allModels .get (0 ).get (j );
298+ Chain c1 = polyModels .get (0 ).get (i );
299+ Chain c2 = polyModels .get (0 ).get (j );
246300
247301 Map <Integer ,Integer > positionIndex1 = new HashMap <Integer , Integer >();
248302 Map <Integer ,Integer > positionIndex2 = new HashMap <Integer , Integer >();
@@ -308,6 +362,8 @@ private TreeMap<String,EntityInfo> findCompoundsFromAlignment() {
308362 ent .addChain (c2 );
309363 ent .setMolId (molId ++);
310364 ent .setType (EntityType .POLYMER );
365+ c1 .setEntityInfo (ent );
366+ c2 .setEntityInfo (ent );
311367 chainIds2compounds .put (c1 .getId (), ent );
312368 chainIds2compounds .put (c2 .getId (), ent );
313369
@@ -319,11 +375,13 @@ private TreeMap<String,EntityInfo> findCompoundsFromAlignment() {
319375 logger .debug ("Adding chain {} to entity {}" ,c1 .getId (),c2 .getId ());
320376 ent = chainIds2compounds .get (c2 .getId ());
321377 ent .addChain (c1 );
378+ c1 .setEntityInfo (ent );
322379 chainIds2compounds .put (c1 .getId (), ent );
323380
324381 } else {
325382 logger .debug ("Adding chain {} to entity {}" ,c2 .getId (),c1 .getId ());
326383 ent .addChain (c2 );
384+ c2 .setEntityInfo (ent );
327385 chainIds2compounds .put (c2 .getId (), ent );
328386
329387 }
@@ -347,13 +405,14 @@ private TreeMap<String,EntityInfo> findCompoundsFromAlignment() {
347405
348406 // anything not in a Compound will be its own Compound
349407 for (int i :polyChainIndices ) {
350- Chain c = allModels .get (0 ).get (i );
408+ Chain c = polyModels .get (0 ).get (i );
351409 if (!chainIds2compounds .containsKey (c .getId ())) {
352410 logger .debug ("Creating a 1-member Compound for chain {}" ,c .getId ());
353411
354412 EntityInfo ent = new EntityInfo ();
355413 ent .addChain (c );
356414 ent .setMolId (molId ++);
415+ c .setEntityInfo (ent );
357416
358417 chainIds2compounds .put (c .getId (),ent );
359418 }
0 commit comments