From 0f5fa6f7e7537fdb98236331efc4b22edb36bcb4 Mon Sep 17 00:00:00 2001
From: Nicolas MAILLET <nicolas.maillet@pasteur.fr>
Date: Wed, 16 May 2018 16:51:50 +0200
Subject: [PATCH] Correct bug when several rules apply at same time

---
 rpg/digest.py |  7 ++++---
 rpg/rule.py   | 29 +++++++++++++++++++++++------
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/rpg/digest.py b/rpg/digest.py
index 9d8bcf4..ca94621 100644
--- a/rpg/digest.py
+++ b/rpg/digest.py
@@ -243,13 +243,14 @@ def one_digest(pep, enz):
             ret.inc_nb_cleavage()
             # current position
             previous_pos = pos
-        # Default: do not cut this position
-        cut = False
         before = True
         # Check each rules
         for rul in enz.rules:
+            # Default: do not cut this position
+            cut = None
             # Apply the rule: if we need to cut
-            if rule.handle_rule(pep.sequence, pos, rul, cut):
+            cut = rule.handle_rule(pep.sequence, pos, rul, cut)
+            if cut is True:
                 # Random to handle miscleavage
                 tmp_rand = random.random() * 100
                 # Rand > ratio_miscleavage, no miscleavage occurs
diff --git a/rpg/rule.py b/rpg/rule.py
index 8c1312d..6dcf802 100644
--- a/rpg/rule.py
+++ b/rpg/rule.py
@@ -786,7 +786,7 @@ def handle_rule(seq, pos, a_rule, cut):
     :type cut: bool
 
     :return: `True` if sequence must be cutted
-    :rtype: bool
+    :rtype: bool or None
     """
 
     # return of the function: should we cut this?
@@ -799,11 +799,28 @@ def handle_rule(seq, pos, a_rule, cut):
         # If the rule applies, i.e. the letter to watch is the good one
         if (pos + a_rule.index) >= 0 and \
                 seq[pos + a_rule.index] == a_rule.letter:
-            ret = a_rule.cut
-            # Handle the rules (exceptions)
-            for rul in a_rule.rules:
-                # Apply the rule: do we need to cut?
-                ret = handle_rule(seq, pos, rul, ret)
+            # If no previous 'False' and this is cutting
+            if a_rule.cut and ret is not False:
+                ret = True
+                # Handle the sub-rules (exceptions)
+                for rul in a_rule.rules:
+                    # Apply the rule: do we need to cut?
+                    ret = handle_rule(seq, pos, rul, ret)
+            # Is is not cutting
+            elif not a_rule.cut:
+                # Reinit
+                ret = None
+                # Handle sub-rules
+                if a_rule.rules:
+                    # Handle the rules (exceptions)
+                    for rul in a_rule.rules:
+                        # Apply the rule: do we need to cut?
+                        ret = handle_rule(seq, pos, rul, ret)
+                # No sub-rules and not cutting
+                else:
+                    # We are at the end a of rule that applies
+                    # and say to NOT cut. So it will never cut.
+                    ret = False
     # Doesn't work: begin or end of sequence, don't change cut value
     except IndexError:
         pass
-- 
GitLab