From c32ba0f78e5e3a289b7cfc9f6d357fb74d7f185f Mon Sep 17 00:00:00 2001
From: Gabriel Studer <gabriel.studer@unibas.ch>
Date: Tue, 9 May 2023 11:53:08 +0200
Subject: [PATCH] Add "swapped" TMScore to TMAlignResult/MMAlignResult

That's the TMscore when using the other structure as reference
---
 modules/bindings/doc/tmtools.rst         |  2 ++
 modules/bindings/pymod/export_tmalign.cc |  6 ++++--
 modules/bindings/pymod/tmtools.py        |  6 ++++--
 modules/bindings/src/wrap_tmalign.cc     |  7 ++++++-
 modules/bindings/src/wrap_tmalign.hh     | 16 +++++++++++-----
 5 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/modules/bindings/doc/tmtools.rst b/modules/bindings/doc/tmtools.rst
index f55cdb458..6d1307e7f 100644
--- a/modules/bindings/doc/tmtools.rst
+++ b/modules/bindings/doc/tmtools.rst
@@ -105,6 +105,7 @@ generated in order to call the executable.
 
   :param rmsd:          RMSD of the superposed residues
   :param tm_score:      TMScore of the superposed residues
+  :param tm_score_swapped: TMScore when reference is swapped
   :param aligned_length: Number of superposed residues
   :param transform:     Transformation matrix to superpose first chain onto 
                         reference
@@ -175,6 +176,7 @@ comparing full biounits:
 
   :param rmsd:          RMSD of the superposed residues
   :param tm_score:      TMScore of the superposed residues
+  :param tm_score_swapped: TMScore when reference is swapped
   :param aligned_length: Number of superposed residues
   :param transform:     Transformation matrix to superpose mdl onto reference 
   :param alignments:    Alignments of all mapped chains, with first sequence
diff --git a/modules/bindings/pymod/export_tmalign.cc b/modules/bindings/pymod/export_tmalign.cc
index 5d2e4a300..060421d01 100644
--- a/modules/bindings/pymod/export_tmalign.cc
+++ b/modules/bindings/pymod/export_tmalign.cc
@@ -46,10 +46,11 @@ ost::bindings::MMAlignResult WrapMMAlignView(const ost::mol::EntityView& ent1,
 }
 
 void export_TMAlign() {
-  class_<ost::bindings::TMAlignResult>("TMAlignResult", init<Real, Real, int, const geom::Mat4&, 
+  class_<ost::bindings::TMAlignResult>("TMAlignResult", init<Real, Real, Real, int, const geom::Mat4&, 
                                                              const ost::seq::AlignmentHandle&>())
     .add_property("rmsd", make_function(&ost::bindings::TMAlignResult::GetRMSD))
     .add_property("tm_score", make_function(&ost::bindings::TMAlignResult::GetTMScore))
+    .add_property("tm_score_swapped", make_function(&ost::bindings::TMAlignResult::GetTMScoreSwapped))
     .add_property("aligned_length", make_function(&ost::bindings::TMAlignResult::GetAlignedLength))
     .add_property("transform", make_function(&ost::bindings::TMAlignResult::GetTransform,
                                return_value_policy<reference_existing_object>()))
@@ -57,12 +58,13 @@ void export_TMAlign() {
                                return_value_policy<reference_existing_object>()))
   ;
 
-  class_<ost::bindings::MMAlignResult>("MMAlignResult", init<Real, Real, const geom::Mat4&, int,
+  class_<ost::bindings::MMAlignResult>("MMAlignResult", init<Real, Real, Real, int, const geom::Mat4&,
                                                              const ost::seq::AlignmentList&,
                                                              const std::vector<String>&,
                                                              const std::vector<String>&>())
     .add_property("rmsd", make_function(&ost::bindings::MMAlignResult::GetRMSD))
     .add_property("tm_score", make_function(&ost::bindings::MMAlignResult::GetTMScore))
+    .add_property("tm_score_swapped", make_function(&ost::bindings::MMAlignResult::GetTMScoreSwapped))
     .add_property("transform", make_function(&ost::bindings::MMAlignResult::GetTransform,
                                return_value_policy<reference_existing_object>()))
     .add_property("aligned_length", make_function(&ost::bindings::MMAlignResult::GetAlignedLength))
diff --git a/modules/bindings/pymod/tmtools.py b/modules/bindings/pymod/tmtools.py
index 94fc4ceed..d58691c04 100644
--- a/modules/bindings/pymod/tmtools.py
+++ b/modules/bindings/pymod/tmtools.py
@@ -55,7 +55,8 @@ def _CleanupFiles(dir_name):
 def _ParseTmAlign(lines,lines_matrix):
   info_line=lines[12].split(',')
   aln_length=int(info_line[0].split('=')[1].strip())
-  rmsd=float(info_line[1].split('=')[1].strip())  
+  rmsd=float(info_line[1].split('=')[1].strip())
+  tm_score_swapped=float(lines[13].split('=')[1].split('(')[0].strip())
   tm_score=float(lines[14].split('=')[1].split('(')[0].strip())
   tf1=[float(i.strip()) for i in lines_matrix[2].split()]
   tf2=[float(i.strip()) for i in lines_matrix[3].split()]
@@ -69,7 +70,8 @@ def _ParseTmAlign(lines,lines_matrix):
   alignment = seq.CreateAlignment()
   alignment.AddSequence(seq2)
   alignment.AddSequence(seq1)
-  return ost.bindings.TMAlignResult(rmsd, tm_score, aln_length, tf, alignment)
+  return ost.bindings.TMAlignResult(rmsd, tm_score, tm_score_swapped,
+                                    aln_length, tf, alignment)
 
 def _RunTmAlign(tmalign, tmp_dir):
   model1_filename=os.path.join(tmp_dir, 'model01.pdb')
diff --git a/modules/bindings/src/wrap_tmalign.cc b/modules/bindings/src/wrap_tmalign.cc
index 0084bac5b..78c372dba 100644
--- a/modules/bindings/src/wrap_tmalign.cc
+++ b/modules/bindings/src/wrap_tmalign.cc
@@ -160,6 +160,8 @@ MMAlignResult MMalign_final_hacked(
     MMAlignResult res;
     res.rmsd = rmsd0;
     res.tm_score = TM1;
+    res.tm_score_swapped = TM2;
+    res.aligned_length = n_ali8;
     res.transform = geom::Mat4(u0[0][0], u0[0][1], u0[0][2], t0[0],
                                u0[1][0], u0[1][1], u0[1][2], t0[1],
                                u0[2][0], u0[2][1], u0[2][2], t0[2],
@@ -405,6 +407,7 @@ TMAlignResult WrappedTMAlign(const geom::Vec3List& pos_one,
   // collect results and return
   TMAlignResult res;
   res.tm_score = TM1;
+  res.tm_score_swapped = TM2;
   res.rmsd = rmsd0;
   res.aligned_length = n_ali8;
   res.transform = geom::Mat4(u0[0][0], u0[0][1], u0[0][2], t0[0],
@@ -460,7 +463,9 @@ MMAlignResult WrappedMMAlign(const std::vector<geom::Vec3List>& pos_one,
     ent1_mapped_chains.push_back(seq1[0].GetName());
     ent2_mapped_chains.push_back(seq2[0].GetName());
     return MMAlignResult(tm_result.rmsd, tm_result.tm_score,
-                         tm_result.transform, tm_result.aligned_length,
+                         tm_result.tm_score_swapped,
+                         tm_result.aligned_length,
+                         tm_result.transform,
                          alns, ent1_mapped_chains,
                          ent2_mapped_chains);
   }
diff --git a/modules/bindings/src/wrap_tmalign.hh b/modules/bindings/src/wrap_tmalign.hh
index 79bdc689b..282209ca5 100644
--- a/modules/bindings/src/wrap_tmalign.hh
+++ b/modules/bindings/src/wrap_tmalign.hh
@@ -31,9 +31,10 @@ struct TMAlignResult {
 
   TMAlignResult() { }
 
-  TMAlignResult(Real rm, Real tm, int aln_l, const geom::Mat4& t, 
+  TMAlignResult(Real rm, Real tm, Real tm_swp, int aln_l, const geom::Mat4& t, 
                 const ost::seq::AlignmentHandle& aln): rmsd(rm),
                                                        tm_score(tm),
+                                                       tm_score_swapped(tm_swp),
                                                        aligned_length(aln_l),
                                                        transform(t),
                                                        alignment(aln) { } 
@@ -41,11 +42,13 @@ struct TMAlignResult {
 
   Real rmsd;
   Real tm_score;
+  Real tm_score_swapped;
   int aligned_length;
   geom::Mat4 transform;
   ost::seq::AlignmentHandle alignment;
 
   Real GetTMScore() { return tm_score; }
+  Real GetTMScoreSwapped() { return tm_score_swapped; }
   Real GetRMSD() { return rmsd; }
   int GetAlignedLength() { return aligned_length; }
   const geom::Mat4& GetTransform() { return transform; }
@@ -56,13 +59,14 @@ struct MMAlignResult {
 
   MMAlignResult() { }
 
-  MMAlignResult(Real rm, Real tm, const geom::Mat4& t,
-                int al, const ost::seq::AlignmentList& alns,
+  MMAlignResult(Real rm, Real tm, Real tm_swp, int al, const geom::Mat4& t,
+                const ost::seq::AlignmentList& alns,
                 const std::vector<String>& e1c,
                 const std::vector<String>& e2c): rmsd(rm),
                                                  tm_score(tm),
-                                                 transform(t),
+                                                 tm_score_swapped(tm_swp),
                                                  aligned_length(al),
+                                                 transform(t),
                                                  alignments(alns),
                                                  ent1_mapped_chains(e1c),
                                                  ent2_mapped_chains(e2c) { } 
@@ -70,13 +74,15 @@ struct MMAlignResult {
 
   Real rmsd;
   Real tm_score;
-  geom::Mat4 transform;
+  Real tm_score_swapped;
   int aligned_length;
+  geom::Mat4 transform;
   ost::seq::AlignmentList alignments;
   std::vector<String> ent1_mapped_chains;
   std::vector<String> ent2_mapped_chains;
 
   Real GetTMScore() { return tm_score; }
+  Real GetTMScoreSwapped() { return tm_score_swapped; }
   Real GetRMSD() { return rmsd; }
   int GetAlignedLength() { return aligned_length; }
   const geom::Mat4& GetTransform() { return transform; }
-- 
GitLab