ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/owl/trunk/proteinstructure/ContactMap.java
Revision: 143
Committed: Tue May 15 10:06:47 2007 UTC (17 years, 5 months ago) by duarte
File size: 21982 byte(s)
Log Message:
FIXED BUG: last commit didn't fix bug correctly:
Changed the ContactMap constructor to put into residueNums and residueTypes nums from 1 to maximum of residues.keySet()

Made public accode and chain fields in Graph
Line File contents
1 package proteinstructure;
2 import java.util.HashMap;
3 import java.util.TreeMap;
4 import java.util.ArrayList;
5 import java.lang.Math;
6 import java.util.Collections;
7
8 public class ContactMap {
9
10 // NOTE: residueNums and residueTypes contain also the unobserved or non standard residues
11 // residues and nums2serials contain only observed standard amino acids
12 // If someone wants to check if i_num or i is unobserved,
13 // then this can be done by checking whether nums2serials has such key (for i_num) or value (for i)
14 // WHERE DO WE USE i or i_num:
15 // - i: for contact map iteration and sequence separation
16 // - i_num: for residue types and common neighbours
17 public Integer[] residueNums; // array with all residue nums
18 public String[] residueTypes; // array with all 1-letter code residue type
19 public TreeMap<Integer,String> residues = new TreeMap<Integer,String>();// map from nums to types
20 public HashMap<Integer,Integer> nums2serials = new HashMap<Integer,Integer>(); // map from residue nums to residue serials (i.e. the indexes of the arrays above)
21
22 public int t; // size of contact map
23 public int effT; // effective size of contact map (do not count the SKIPPED cells)
24 public int l; // length of contact map/protein
25 public int numObsStandAA = 0; // Nr. of standard observed amino acids
26 public int numContacts = 0; // Nr. of contacts
27
28 public EdgeState[][] CM;
29 public HashMap<Integer,HashMap<Integer,TreeMap<Integer,String>>> CNs; // hashmap containing neighbourhoods, access a single one through getComNbs
30
31 public ContactMap() {
32 }
33
34 /**
35 * Constructs a ContactMap passing a list of contacts, the full residue sequence and a map of residue nums to types (only observed standard aas)
36 * @param contacts ArrayList of contacts (as Contact objects)
37 * @param residues map from num to types (only observed standard aas)
38 * @param sequence String with full sequence (i.e. also unobserved and non-standard residues, denoted by X)
39 */
40 public ContactMap(ArrayList<Contact> contacts, TreeMap<Integer,String> residues, String sequence) {
41 this.residues=residues;
42 if (sequence.equals("")){ // no sequence given: we use residues only to initialise arrays
43 int i=0;
44 int maxnum = Collections.max(residues.keySet());
45 residueTypes = new String[maxnum];
46 residueNums = new Integer[maxnum];
47 // if residues TreeMap has correct residue numbering then this should take care of gaps, except for gaps at the end of the sequence
48 for (int num=1;num<=maxnum;num++) {
49 // residueNums will contain all nums starting from 1 to the maxnum
50 residueNums[i]=num;
51 if (residues.containsKey(num)) {
52 // we put the observed nums into residueTypes
53 residueTypes[i]=residues.get(num);
54 // in nums2serials we want only observed residues thus we only add nums that are in residues TreeMap
55 nums2serials.put(num, i);
56 } else {
57 // and for the unobserved nums we use an "X" for the residue type
58 residueTypes[i]="X";
59 }
60 i++;
61 }
62 } else { // if sequence given (full sequence): we use residues+sequence to initialise arrays
63 // we create residueTypes and residueNums arrays from full sequence string
64 residueTypes = new String[sequence.length()];
65 residueNums = new Integer[sequence.length()];
66 for (int i=0;i<sequence.length();i++){
67 residueTypes[i] = String.valueOf(sequence.charAt(i));
68 residueNums[i] = i+1;
69 }
70 // we initialise nums2serials using residues and residueNums
71 nums2serials = new HashMap<Integer,Integer>();
72 for (int i=0;i<residueNums.length;i++){
73 // nums2serials must only contain the standard observed aa, so only members of residues TreeMap
74 if (residues.containsKey(residueNums[i])){
75 nums2serials.put(residueNums[i],i);
76 }
77 }
78 }
79 // initialisation of l, numObsStandAA, t, effT from 4 above
80 l = this.residueNums.length;
81 numObsStandAA = this.residues.size();
82 t = (int)((l*(l-1))/2);
83 effT = (int)((numObsStandAA*(numObsStandAA-1))/2);
84 // initialisation of CM
85 CM = new EdgeState[l][l];
86 // first we fill with NONCONTACTs (or SKIPPEDs if the i,j is not in nums2serials)
87 for (int i=0;i<l;i++){
88 for (int j=0;j<l;j++) {
89 if ((!this.nums2serials.containsValue(i)) || (!this.nums2serials.containsValue(j))) {
90 CM[i][j] = EdgeState.SKIPPED;
91 } else {
92 CM[i][j] = EdgeState.NONCONTACT;
93 }
94 }
95 }
96 // then we fill the CONTACTs
97 // the contacts ArrayList we pass as argument must contain the full bidirectional list of contacts
98 for (Contact cont:contacts){
99 int i_num = cont.i;
100 int j_num = cont.j;
101 CM[nums2serials.get(i_num)][nums2serials.get(j_num)]=EdgeState.CONTACT;
102 }
103 // and initialise numContacts
104 numContacts = contacts.size();
105 // finally we initialise the CNs HashMap
106 getAllComNbs();
107 }
108
109 /**
110 * Gets the number of contacts, non contacts and skipped cells due to unobserved residues
111 * from the part of the ContactMap >=(above) the given diagonal
112 * @param diagonal
113 * @return
114 */
115 public int[] getCMStats(int diagonal) {
116 int[] result = new int[3];
117 for (int d=Math.max(1, diagonal);d<l;d++){
118 for (int i=0, j=i+d;i<l-d+1 && j<l;i++, j++){
119 if (CM[i][j] == EdgeState.CONTACT) result[0]++;
120 if (CM[i][j] == EdgeState.NONCONTACT) result[1]++;
121 if (CM[i][j] == EdgeState.SKIPPED) result[2]++;
122 }
123 }
124 return result;
125 }
126
127 /**
128 * Gets the common neighbourhood for residues i_num, j_num from the precomputed HashMap.
129 * If there is no neighborhood between the two residues it returns an empty TreeMap
130 * @param i_num
131 * @param j_num
132 * @return
133 */
134 public TreeMap<Integer,String> getComNbs(int i_num, int j_num) {
135 // we initialise to an empty TreeMap, if there is no cn for i_num, j_num we return it empty
136 TreeMap<Integer,String> cn = new TreeMap<Integer,String>();
137
138 if (CNs.containsKey(i_num) && CNs.get(i_num).containsKey(j_num)) {
139 cn = CNs.get(i_num).get(j_num);
140 }
141
142 return cn;
143 }
144
145 /**
146 * Gets the common neighbourhood for residues i_num, j_num from the precomputed HashMap
147 * that are >= (above)/<= (below) the given diagonal
148 * If there is no neighborhood between the two residues it returns an empty TreeMap
149 * @param i_num
150 * @param j_num
151 * @param diagonal
152 * @param above
153 * @return
154 */
155 public TreeMap<Integer,String> getComNbs(int i_num, int j_num, int diagonal, boolean above) {
156 // we initialise to an empty TreeMap, if there is no cn for i_num, j_num we return it empty
157 TreeMap<Integer,String> cn = new TreeMap<Integer,String>();
158
159 int threshold = diagonal;
160
161 if (CNs.containsKey(i_num) && CNs.get(i_num).containsKey(j_num)) {
162 cn = CNs.get(i_num).get(j_num);
163 }
164
165 if (!cn.isEmpty()) {
166 ArrayList<Integer> nums2eliminate = new ArrayList<Integer>();
167 for (int num:cn.keySet()){
168 // here we eliminate all the common neighbours that are below or above the given diagonal
169 // (first storing the keys in an ArrayList and then removing from TreeMap)
170 // num, i_num and j_num are nums (i.e. serial numbers from db)
171 if (above) {
172 // just for clarification, the opposite condition is: Math.abs(n-i)>=j-i && Math.abs(n-j)>=j-i
173 if ((Math.abs(nums2serials.get(num)-nums2serials.get(i_num)) < threshold || (Math.abs(nums2serials.get(num)-nums2serials.get(j_num)) < threshold))) {
174 nums2eliminate.add(num);
175 }
176 } else {
177 // just for clarification, the opposite condition is: Math.abs(n-i)<=j-i && Math.abs(n-j)<=j-i
178 if ((Math.abs(nums2serials.get(num)-nums2serials.get(i_num)) > threshold || (Math.abs(nums2serials.get(num)-nums2serials.get(j_num)) > threshold))) {
179 nums2eliminate.add(num);
180 }
181 }
182 }
183 for (int num:nums2eliminate){
184 cn.remove(num); //now we remove all the detected non-valid common neighbours
185 }
186 }
187
188 return cn;
189 }
190
191 /**
192 * Gets the common neighbourhood for residues i_num, j_num from the precomputed HashMap
193 * that are >= (above)/<= (below) the current diagonal
194 * If there is no neighborhood between the two residues it returns an empty TreeMap
195 * @param i_num
196 * @param j_num
197 * @param above (true if above diagonal)
198 * @return
199 */
200 public TreeMap<Integer,String> getComNbs(int i_num, int j_num, boolean above) {
201 return getComNbs(i_num, j_num, Math.abs(nums2serials.get(j_num)-nums2serials.get(i_num)), above);
202 }
203
204 /**
205 * Get all common neighbors for this contact map object. Updates the CNs member and also returns it
206 * @return CNs
207 */
208 public HashMap<Integer,HashMap<Integer,TreeMap<Integer,String>>> getAllComNbs() {
209 // first we reset the existing CNs
210 this.CNs = new HashMap<Integer,HashMap<Integer,TreeMap<Integer,String>>>();
211 // initialise a cns4j HashMap which will store all cn TreeMaps for each j
212 HashMap<Integer,TreeMap<Integer,String>> cns4j = new HashMap<Integer,TreeMap<Integer,String>>();
213 // initialise a cn TreeMap which will store all cns for a given i,j
214 TreeMap<Integer,String> cn = new TreeMap<Integer,String>();
215 for (int i=0;i<l;i++){
216 for (int j=i+1;j<l;j++) {
217 for (int k=0;k<l;k++) { // for each i,j we scan all possible contacts k
218 if ((k != i) && (k != j) &&
219 CM[Math.min(i,k)][Math.max(i,k)].contact() && CM[Math.min(j,k)][Math.max(j,k)].contact()) {
220 cn.put(residueNums[k],residueTypes[k]);
221 // we could have used the following, but would be slower
222 //updateCNsHashMap(residueNums[i],residueNums[j],residueNums[k]);
223 }
224 } // end k
225 if (!cn.isEmpty()) {
226 cns4j.put(residueNums[j], cn);
227 }
228 cn = new TreeMap<Integer,String>(); // reset cn for next k
229 } // end j
230 CNs.put(residueNums[i], cns4j);
231 cns4j = new HashMap<Integer,TreeMap<Integer,String>>(); // reset cns4j for next i
232 } // end i
233
234 return this.CNs;
235 }
236
237 /**
238 * Convenience method to update the monster CNs HashMap without thinking too much
239 * @param i_num
240 * @param j_num
241 * @param k_num
242 */
243 public void updateCNsHashMap(int i_num, int j_num, int k_num) {
244 if (CNs.containsKey(i_num)){
245 HashMap<Integer,TreeMap<Integer,String>> cns4j = CNs.get(i_num);
246 if (cns4j.containsKey(j_num)){
247 cns4j.get(j_num).put(k_num, residueTypes[nums2serials.get(k_num)]);
248 } else {
249 TreeMap<Integer,String> cn = new TreeMap<Integer,String>();
250 cn.put(k_num, residueTypes[nums2serials.get(k_num)]);
251 cns4j.put(j_num,cn);
252 }
253 } else {
254 HashMap<Integer,TreeMap<Integer,String>> cns4j = new HashMap<Integer,TreeMap<Integer,String>>();
255 TreeMap<Integer,String> cn = new TreeMap<Integer,String>();
256 cn.put(k_num, residueTypes[nums2serials.get(k_num)]);
257 cns4j.put(j_num, cn);
258 CNs.put(i_num, cns4j);
259 }
260 }
261
262 /**
263 * Update all common neighbors given contact (this method should be used only for prediction)
264 * @param i
265 * @param j
266 * @param
267 * @return
268 */
269 public void updateComNbsGivenContact(int i, int j, boolean below) {
270
271 if (CM[i][j].contact()) { // if contact predicted just in case
272
273 if (below) { // if known contacts are only below the diagonal
274 int d = Math.abs(i-j);
275 int[] idxs = {i, j};
276 for (int idx:idxs){
277 for (int r=Math.max(0,idx-d);r<idx;r++) {
278 if ((r != i) && CM[r][idx].contact()) {
279 updateCNsHashMap(residueNums[Math.min(i,r)],residueNums[Math.max(i,r)],residueNums[idx]);
280 }
281 }
282
283 for (int c=idx+1;c<=Math.min(l-1,idx+d);c++) {
284 if ((c != j) && CM[idx][c].contact()) {
285 updateCNsHashMap(residueNums[i],residueNums[c],residueNums[idx]);
286 }
287 }
288 }
289
290 for (int b=i+1; b<j; b++) { // update i-j's common neighbors
291 if (CM[i][b].contact() && CM[b][j].contact()) {
292 updateCNsHashMap(residueNums[i],residueNums[j],residueNums[b]);
293 }
294 }
295 } else { // if known contacts can be also above the diagonal
296 for (int k=0;k<l;k++) {
297 if ((k != i) && (k != j)) {
298 if (CM[i][j].contact() && CM[Math.min(i,k)][Math.max(i,k)].contact()) {
299 updateCNsHashMap(residueNums[Math.min(j,k)],residueNums[Math.max(j,k)],residueNums[i]);
300 }
301 if (CM[i][j].contact() && CM[Math.min(j,k)][Math.max(j,k)].contact()) {
302 updateCNsHashMap(residueNums[Math.min(i,k)],residueNums[Math.max(i,k)],residueNums[j]);
303 }
304 if (CM[Math.min(i,k)][Math.max(i,k)].contact() && CM[Math.min(j,k)][Math.max(j,k)].contact()) {
305 updateCNsHashMap(residueNums[i],residueNums[j],residueNums[k]);
306 }
307 }
308 }
309 }
310 }
311 }
312
313 /**
314 * Returns true if this contact map has no contacts at all
315 * @return
316 */
317 public boolean hasNoContacts() {
318 boolean noContacts = true;
319 for (int i=0;i<l;i++){
320 for (int j=i+1;j<l;j++){
321 if (this.CM[i][j].contact()) {
322 noContacts = false;
323 return noContacts;
324 }
325 }
326 }
327 return noContacts;
328 }
329
330 /**
331 * Returns whether the given cell has at least N common neighbors
332 * @param i_num
333 * @param j_num
334 * @param N
335 * @return
336 */
337 public boolean cellHasNComNbs(int i_num, int j_num, int N){
338 TreeMap<Integer,String> cn = getComNbs(i_num, j_num);
339 boolean hasNCNs = false;
340 if (((N==0) && cn.isEmpty()) || ((N!=0) && cn.size()>=N)) hasNCNs=true;
341 return hasNCNs;
342 }
343
344 /**
345 * Returns number of contacts in the whole contact map with at least N common neighbors
346 * Useful to find out how many contacts don't have common neighbors at all (N=0)
347 * Will only count the ones above given diagonal value (use diagonal=1 for count in whole contact map)
348 * @param N
349 * @param diagonal
350 * @return
351 */
352 public int getNumContactsWithNComNbs(int N, int diagonal){
353 int numContactsWithNcns = 0;
354 for (int d=Math.max(1, diagonal);d<l;d++){
355 for (int i=0, j=i+d;i<l-d+1 && j<l;i++, j++){
356 if (CM[i][j].contact()){
357 if (cellHasNComNbs(residueNums[i], residueNums[j], N)){
358 numContactsWithNcns++;
359 }
360 }
361 }
362 }
363 return numContactsWithNcns;
364 }
365
366 /**
367 * Puts into a new ContactMap object the part of this ContactMap that is strictly below the given diagonal (i.e. not including the diagonal itself)
368 * The rest is filled with NONCONTACT
369 * @param diagonal
370 * @return
371 */
372 //TODO we fill above range diagonals with NONCONTACT, thus we are "forcing" the return object to be a OrigCM but we want this method for ContactMap's, how to solve this?
373 public ContactMap cutCMToBelowRange(int diagonal) {
374 ContactMap newcm = this.semiDeepCopy(true);
375 for (int d=1;d<Math.min(diagonal,l);d++){
376 for (int i=0, j=i+d;i<l-d+1 && j<l;i++, j++){
377 newcm.CM[i][j]=this.CM[i][j];
378 }
379 }
380
381 for (int d=Math.min(diagonal,l);d<l;d++) {
382 for (int i=0, j=i+d;i<l-d+1 && j<l;i++, j++){
383 newcm.CM[i][j] = EdgeState.NONCONTACT;
384 }
385 }
386 newcm.getAllComNbs(); // finally we re-calculate the common neighbours for the new contact map
387 newcm.updateNumContacts(); // and we recount contacts
388 return newcm;
389 }
390
391 /**
392 * From all contacts in smallerCM, gets a contact map which contains only those contacts that are reachable from this ContactMap
393 * @param smallerCM
394 * @return
395 */
396 public ContactMap getReachable(ContactMap smallerCM){
397 ContactMap newcm = this.semiDeepCopy(true);
398 for (int i=0;i<l;i++) {
399 for (int j=i+1;j<l;j++){
400 // we loop through all contacts of this contact map
401 if (this.CM[i][j].contact()) {
402 // if for this contact there's at least 1 cn in smallerCM
403 if (smallerCM.cellHasNComNbs(residueNums[i],residueNums[j], 1)){
404 // we assign contact, the rest is kept as it was initialised with semiDeepCopy
405 newcm.CM[i][j]=EdgeState.CONTACT;
406 }
407 }
408 }
409 }
410 newcm.getAllComNbs(); // finally we re-calculate the CNs for the new ContactMap before returning it
411 newcm.updateNumContacts(); // and we recount contacts
412 return newcm;
413 }
414
415 /**
416 * Returns a new ContactMap result of subtracting smallerCM ContactMap from this ContactMap (set subtraction)
417 * @param smallerCM
418 * @return
419 */
420 public ContactMap subtract (ContactMap smallerCM){
421 ContactMap newcm = this.semiDeepCopy(false); // we copied this cm with all its contacts
422 for (int i=0;i<l;i++) {
423 for (int j=i+1;j<l;j++){
424 // if contact exists in bigger set and also in smaller set then we eliminate it
425 if (this.CM[i][j].contact() && smallerCM.CM[i][j].contact()) {
426 // we assign NONCONTACT
427 newcm.CM[i][j]=EdgeState.NONCONTACT;
428 }
429 }
430 }
431 newcm.getAllComNbs(); // finally we re-calculate the CNs for the new ContactMap before returning it
432 newcm.updateNumContacts(); // and we recount contacts
433 return newcm;
434 }
435
436 /**
437 * Returns a new ContactMap result of adding secondCM to this ContactMap (set union)
438 * @param secondCM
439 * @return
440 */
441 public ContactMap add (ContactMap secondCM){
442 ContactMap newcm = this.semiDeepCopy(false); // we copied this cm with all its contacts
443 for (int i=0;i<l;i++) {
444 for (int j=i+1;j<l;j++){
445 // if contact doesn't exist in first set, but exists in second set then we add the contact to the resulting set
446 if (!this.CM[i][j].contact() && secondCM.CM[i][j].contact()) {
447 // we assign CONTACT
448 newcm.CM[i][j]=EdgeState.CONTACT;
449 }
450 }
451 }
452 newcm.getAllComNbs(); // finally we re-calculate the CNs for the new ContactMap before returning it
453 newcm.updateNumContacts(); // and we recount contacts
454 return newcm;
455 }
456
457 /**
458 * The method performs a semi deep copy of a ContactMap. By semi deep I mean:
459 * primitives are copied, CM and CNs are copied but residueNums, residueTypes,residues,nums2serials are not copied, but only re-referenced
460 * This is because we don't really need to copy the arrays as they should always stay the same between source and destination
461 * If blanckCM is true then CM and CNs will be just initialised to UNKNOWN in CM and blanks in CNs
462 * @return
463 * @param blankCM
464 */
465 public ContactMap semiDeepCopy(boolean blankCM){
466 ContactMap destinationCM = new ContactMap();
467 // primitives we simply copy
468 destinationCM.t = this.t;
469 destinationCM.effT = this.effT;
470 destinationCM.l = this.l;
471 destinationCM.numObsStandAA = this.numObsStandAA;
472 destinationCM.numContacts = 0; // we wipe it out initially, it stays so unless blankCM is true where is copied from this.numContacts
473 // we don't deep copy here, we can reference the same arrays, they will be always the same for source and destination
474 // TODO should we deep copy the arrays too??
475 destinationCM.residueNums = this.residueNums;
476 destinationCM.residueTypes = this.residueTypes;
477 destinationCM.residues = this.residues;
478 destinationCM.nums2serials = this.nums2serials;
479 // the only thing we need to deep copy is the ContactMap
480 destinationCM.CM = new EdgeState[l][l];
481 if (!blankCM){
482 for (int i=0;i<l;i++) {
483 for (int j=i+1;j<l;j++){
484 destinationCM.CM[i][j] = this.CM[i][j]; //enum copies should be alright
485 }
486 }
487 destinationCM.numContacts=this.numContacts;
488 } else {
489 for (int i=0;i<l;i++) {
490 for (int j=i+1;j<l;j++){
491 destinationCM.CM[i][j] = EdgeState.UNKNOWN;
492 }
493 }
494 }
495 // for CNs we create a new object and call the getAllComNbs that gets CNs from the already copied ContactMap array
496 destinationCM.CNs = new HashMap<Integer,HashMap<Integer,TreeMap<Integer,String>>>();
497 if (!blankCM){
498 destinationCM.CNs = destinationCM.getAllComNbs();
499 }
500 return destinationCM;
501 }
502
503 /**
504 * Semi deep copy from given otherCM to this ContactMap all data member fields
505 * @param otherCM
506 * @param blankCM true if we want a blank ContactMap matrix, false if we want to copy from otherCM.CM
507 */
508 public void semiDeepCopyFromOtherCM(ContactMap otherCM, boolean blankCM){
509 // primitives we simply copy
510 this.t = otherCM.t;
511 this.effT = otherCM.effT;
512 this.l = otherCM.l;
513 this.numObsStandAA = otherCM.l;
514 this.numContacts = 0;
515 // we don't deep copy here, we can reference the same arrays, they will be always the same for source and destination
516 // TODO should we deep copy the arrays too??
517 this.residueNums = otherCM.residueNums;
518 this.residueTypes = otherCM.residueTypes;
519 this.residues = otherCM.residues;
520 this.nums2serials = otherCM.nums2serials;
521 // the only thing we need to deep copy is the ContactMap
522 this.CM = new EdgeState[l][l];
523 if (!blankCM){
524 for (int i=0;i<l;i++) {
525 for (int j=i+1;j<l;j++){
526 CM[i][j] = otherCM.CM[i][j]; //enum copies should be alright
527 }
528 }
529 this.numContacts=otherCM.numContacts;
530 } else {
531 for (int i=0;i<l;i++) {
532 for (int j=i+1;j<l;j++){
533 CM[i][j] = EdgeState.UNKNOWN;
534 }
535 }
536 }
537 // for CNs we create a new object and call the getAllComNbs that gets CNs from the already copied ContactMap array
538 this.CNs = new HashMap<Integer,HashMap<Integer,TreeMap<Integer,String>>>();
539 if (!blankCM){
540 this.CNs = this.getAllComNbs();
541 }
542
543 }
544
545 /**
546 * To update the numContacts data member, to be used after a ContactMap matrix has been changed in a ContactMap object
547 *
548 */
549 public void updateNumContacts(){
550 this.numContacts=0;
551 for (int i=0;i<l;i++){
552 for (int j=i+1;j<l;j++) {
553 if (this.CM[i][j].contact()) this.numContacts++;
554 }
555 }
556 }
557
558 /**
559 * Returns true if this ContactMap and otherCM have exactly the same set of contacts (true/false, disregarding other EdgeStates)
560 * @param otherCM
561 * @return
562 */
563 public boolean hasSameContacts (ContactMap otherCM){
564 boolean coincides = true;
565 for (int i=0;i<l;i++){
566 for (int j=i+1;j<l;j++) {
567 if ((this.CM[i][j].contact() && !otherCM.CM[i][j].contact())
568 || !this.CM[i][j].contact() && otherCM.CM[i][j].contact()) {
569 coincides = false;
570 return coincides;
571 }
572 }
573 }
574 return coincides;
575 }
576
577 /**
578 * Returns a boolean matrix with the contact map
579 */
580 public boolean[][] getBoolMatrix(){
581 boolean[][] cmbool = new boolean[l][l];
582 for (int i=0;i<l;i++){
583 for (int j=0;j<l;j++) {
584 cmbool[i][j]=CM[i][j].contact();
585 }
586 }
587 return cmbool;
588 }
589
590 /**
591 * Returns an int (0,1) matrix with the contact map
592 */
593 public int[][] getIntMatrix(){
594 int[][] cmint = new int[l][l];
595 for (int i=0;i<l;i++){
596 for (int j=0;j<l;j++) {
597 cmint[i][j]=0;
598 if (CM[i][j].contact()){
599 cmint[i][j]=1;
600 }
601 }
602 }
603 return cmint;
604 }
605
606 }