Repository: cogent3/cogent3
Pull request #2258 (2025-03-21 22:32:54)

Fix dotplot alignment path for new_type
## Summary by Sourcery

Bug Fixes:
- Fix dotplot alignment path for new_type Alignments.


Patch:
diff --git a/changelog.d/20250314_131212_Gavin.Huttley.md b/changelog.d/20250314_131212_Gavin.Huttley.md
index 03528f6a2..d06efdc24 100644
--- a/changelog.d/20250314_131212_Gavin.Huttley.md
+++ b/changelog.d/20250314_131212_Gavin.Huttley.md
@@ -30,12 +30,12 @@ Uncomment the section that is right (remove the HTML comment wrapper).
   For example, `use_hook="my_package"` would invoke the one defined above. Set `use_hook="cogent3"`
   to force using the cogent3 default.
 
-<!--
+
 ### BUG
 
-- A bullet item for the BUG category.
+- Dotplot on new_type Alignments now show the alignment path 🎉
+
 
--->
 <!--
 ### DOC
 
diff --git a/src/cogent3/core/new_alignment.py b/src/cogent3/core/new_alignment.py
index b5ebdb103..9f17e11bc 100644
--- a/src/cogent3/core/new_alignment.py
+++ b/src/cogent3/core/new_alignment.py
@@ -1485,10 +1485,11 @@ class SequenceCollection:
             msg = f"{name1}, {name2} missing"
             raise ValueError(msg)
 
-        seq1 = self.get_seq(seqname=name1, copy_annotations=False)
-        seq2 = self.get_seq(seqname=name2, copy_annotations=False)
-        annotated = seq1.is_annotated(biotype=biotype) or seq2.is_annotated(
-            biotype=biotype,
+        seq1 = self.seqs[name1]
+        seq2 = self.seqs[name2]
+        annotated = any(
+            self.annotation_db.num_matches(seqid=self._name_map[n], biotype=biotype)
+            for n in [name1, name2]
         )
         dotplot = Dotplot(
             seq1,
@@ -1508,9 +1509,9 @@ class SequenceCollection:
         )
 
         if annotated:
-            data = getattr(seq1, "data", seq1)
+            data = getattr(seq1, "seq", seq1)
             bottom = data.get_drawable(biotype=biotype)
-            data = getattr(seq2, "data", seq2)
+            data = getattr(seq2, "seq", seq2)
             left = data.get_drawable(biotype=biotype, vertical=True)
             dotplot = AnnotatedDrawable(
                 dotplot,
diff --git a/src/cogent3/draw/dotplot.py b/src/cogent3/draw/dotplot.py
index 3f2ecafbf..93d40f4a4 100644
--- a/src/cogent3/draw/dotplot.py
+++ b/src/cogent3/draw/dotplot.py
@@ -56,7 +56,8 @@ def _convert_input(seq, moltype):
     if hasattr(seq, "map"):
         # already an Aligned instance
         gap_map = seq.map
-        seq = seq.data
+        # handling new_type and old type Aligned
+        seq = getattr(seq, "seq", seq.data)
         return gap_map, seq
 
     seq = (


Test patch:
diff --git a/tests/test_draw/test_new_draw_integration.py b/tests/test_draw/test_new_draw_integration.py
index 628a10e36..3e7505da7 100644
--- a/tests/test_draw/test_new_draw_integration.py
+++ b/tests/test_draw/test_new_draw_integration.py
@@ -93,40 +93,61 @@ def check_drawable_styles(method, styles, **kwargs):
 
 @pytest.fixture
 def dotplot_seqs():
-    data = {
+    return {
         "Human": "CAGATTTGGCAGTT-",
         "Mouse": "CAGATTCAGCAGGTG",
-        "Rat": "CAGATTCAGCAGG--G",
+        "Rat": "CAGATTCAGCAG--G",
     }
-    return new_alignment.make_unaligned_seqs(data, moltype="dna")
 
 
-def test_dotplot_base_cases(dotplot_seqs):
+@pytest.mark.parametrize("aligned", [True, False])
+def test_dotplot_base_cases(dotplot_seqs, aligned):
     """exercising dotplot method"""
+    seqs = (
+        new_alignment.make_aligned_seqs(dotplot_seqs, moltype="dna")
+        if aligned
+        else new_alignment.make_unaligned_seqs(dotplot_seqs, moltype="dna")
+    )
     # with provided names
-    plot = dotplot_seqs.dotplot(name1="Human", name2="Mouse")
+    plot = seqs.dotplot(name1="Human", name2="Mouse")
     assert str(plot.seq1) != str(plot.seq2)
 
     # without providing names
-    plot = dotplot_seqs.dotplot()
+    plot = seqs.dotplot()
     assert str(plot.seq1) != str(plot.seq2)
 
     # providing only one name
-    plot = dotplot_seqs.dotplot(name1="Human")
+    plot = seqs.dotplot(name1="Human")
     assert str(plot.seq1) != str(plot.seq2)
 
     # a collection of one sequence should make dotplot with itself
-    less_seqs = dotplot_seqs.take_seqs("Human")
+    less_seqs = seqs.take_seqs("Human")
     plot = less_seqs.dotplot()
     assert str(plot.seq1) == str(plot.seq2)
 
     # k larger than window should raise an error
     with pytest.raises(AssertionError):
-        dotplot_seqs.dotplot(window=5, k=11)
+        seqs.dotplot(window=5, k=11)
 
     # names not in the collection should raise an error
     with pytest.raises(ValueError):
-        dotplot_seqs.dotplot(name1="Human", name2="Dog")
+        seqs.dotplot(name1="Human", name2="Dog")
+
+
+def test_dotplot_aligned_path():
+    """exercising dotplot method"""
+    dotplot_seqs = {
+        "Human": "TTAATGAAGTAGGTTCCAGTACTAATGAAGTGGGCTCCAGTATTAATGAAATAGGTTCCAGTGATGAAAACATTCAAGCA",
+        "Mouse": "TTCATGAAGTATGTTCCACT------------------------------------------GGTGACTCCTTCCCAGGA",
+    }
+    seqs = new_alignment.make_aligned_seqs(dotplot_seqs, moltype="dna")
+    plot = seqs.dotplot()
+    # trigger construction of figure dict
+    _ = plot.figure
+    # make sure the aligned path trace exists
+    trace = plot.traces[1] if plot.traces[1]["name"] == "Alignment" else plot.traces[0]
+    # should have coordinates
+    assert len(trace["x"])
 
 
 @pytest.mark.parametrize("with_annotations", [True, False])