@@ -490,14 +490,39 @@ public int getAlignedResIndex(Group g, Chain c) {
490490 Map <ResidueNumber ,Integer > map = chains2pdbResNums2ResSerials .get (c .getChainID ());
491491 int serial ;
492492 if (map !=null ) {
493- Integer alignedSerial = map .get (g .getResidueNumber ());
494-
495- if (alignedSerial ==null ) {
496- // the map doesn't contain this group, something's wrong: return -1
493+
494+ ResidueNumber resNum = g .getResidueNumber ();
495+ // the resNum will be null for groups that are SEQRES only and not in ATOM,
496+ // still it can happen that a group is in ATOM in one chain but not in other of the same compound.
497+ // This is what we try to find out here (analogously to what we do in initResSerialsMap() ):
498+ if (resNum ==null && c .getSeqResGroups ()!=null && !c .getSeqResGroups ().isEmpty ()) {
499+ int index = -1 ;
500+ for (int i =0 ;i <c .getSeqResGroups ().size ();i ++) {
501+ if (g ==c .getSeqResGroup (i )) {
502+ index = i ; break ;
503+ }
504+ }
505+
506+ resNum = findResNumInOtherChains (index , c );
507+
508+ }
509+
510+ if (resNum == null ) {
511+ // still null, we really can't map
497512 serial = -1 ;
498- } else {
499- serial = alignedSerial ;
500513 }
514+ else {
515+
516+ Integer alignedSerial = map .get (resNum );
517+
518+ if (alignedSerial ==null ) {
519+ // the map doesn't contain this group, something's wrong: return -1
520+ serial = -1 ;
521+ } else {
522+ serial = alignedSerial ;
523+ }
524+ }
525+
501526 } else {
502527 // no seqres groups available we resort to using the pdb residue numbers are given
503528 serial = g .getResidueNumber ().getSeqNum ();
@@ -519,9 +544,44 @@ private void initResSerialsMap(Chain c) {
519544 chains2pdbResNums2ResSerials .put (c .getChainID (), resNums2ResSerials );
520545
521546 for (int i =0 ;i <c .getSeqResGroups ().size ();i ++) {
522- resNums2ResSerials .put (c .getSeqResGroup (i ).getResidueNumber (), i +1 );
547+
548+ // The seqres group will have a null residue number whenever its corresponding atom group doesn't exist
549+ // because it is missing in the electron density.
550+ // However, it can be observed in the density in other chains of the same compound,
551+ // to be complete we go and look for the residue number in other chains, so that we have a
552+ // seqres to atom mapping as complete as possible (with all known atom groups of any chain of this compound)
553+
554+ ResidueNumber resNum = c .getSeqResGroup (i ).getResidueNumber ();
555+
556+ if (resNum ==null ) {
557+ resNum = findResNumInOtherChains (i ,c );
558+ }
559+
560+ // NOTE that resNum will still be null here for cases where the residue
561+ // is missing in atom groups (not observed in density) in all chains
562+ // Thus the mapping will not be possible for residues that are only in SEQRES groups
563+ resNums2ResSerials .put (resNum , i +1 );
523564 }
524565 }
566+
567+ private ResidueNumber findResNumInOtherChains (int i , Chain chain ) {
568+ for (Chain c : getChains ()) {
569+ if (c == chain ) continue ;
570+
571+ Group seqResGroup = c .getSeqResGroup (i );
572+
573+ if (seqResGroup ==null ) {
574+ logger .warn ("The SEQRES group is null for index {} in chain {}, whilst it wasn't null in chain {}" ,
575+ i , c .getChainID (), chain .getChainID ());
576+ continue ;
577+ }
578+
579+ if (seqResGroup .getResidueNumber ()!=null ) return seqResGroup .getResidueNumber ();
580+
581+ }
582+
583+ return null ;
584+ }
525585
526586 /**
527587 * Return the ref chain id value.
0 commit comments