Repository 'ashlar'
hg clone https://toolshed.g2.bx.psu.edu/repos/perssond/ashlar

Changeset 3:ef68bc2a4dbc (2024-02-09)
Previous changeset 2:33ab2058c6d9 (2022-09-20) Next changeset 4:0b8423c7ee3e (2025-02-26)
Commit message:
planemo upload for repository https://github.com/ohsu-comp-bio/ashlar commit 69f200fcfa0b1d17de50466c51d8c5468fdeb54c
modified:
ashlar.xml
macros.xml
removed:
pyramid_upgrade.py
b
diff -r 33ab2058c6d9 -r ef68bc2a4dbc ashlar.xml
--- a/ashlar.xml Tue Sep 20 17:33:50 2022 +0000
+++ b/ashlar.xml Fri Feb 09 22:48:46 2024 +0000
b
@@ -51,6 +51,10 @@
 
         -c $adv.align_channel
 
+        #if $adv.stitch_alpha
+        --stitch-alpha $adv.stitch_alpha
+        #end if
+
         #if $adv.filter_sigma
         --filter-sigma $adv.filter_sigma
         #end if
@@ -73,20 +77,10 @@
             #end for
         #end if
 
-        $adv.pyramid
         $adv.flip_mosaic_x
         $adv.flip_mosaic_y
 
-        -f registered.ome.tif;
-
-        #if $upgrade.decide == "do_upgrade"
-            python3 '${__tool_directory__}/pyramid_upgrade.py'
-            registered.ome.tif
-
-            #if $upgrade.markers_file
-                -n `echo \$(cat $upgrade.markers_file | tail -n +2 | awk -F, '{print \$3}')`;
-            #end if
-        #end if
+        -o registered.ome.tif;
     ]]></command>
 
     <inputs>
@@ -96,24 +90,13 @@
         <param name="flip_x" type="boolean" truevalue="--flip-x" falsevalue="" label="Flip X-axis"/>
         <param name="flip_y" type="boolean" truevalue="--flip-y" falsevalue="" label="Flip Y-axis"/>
         <param name="max_shift" type="integer" value="30" label="Maximum allowed per-tile corrective shift" help="In micros"/>
-        <conditional name="upgrade">
-            <param name="decide" type="select" label="Upgrade to BF6-Compliant OME-TIFF Pyramid">
-                <option value="do_upgrade">Upgrade Pyramid</option>
-                <option value="dont_upgrade">Leave Legacy Pyramid</option>
-            </param>
-            <when value="do_upgrade">
-                <param name="markers_file" type="data" format="csv,tabular" optional="true" label="Markers File (optional)"/>
-            </when>
-            <when value="dont_upgrade">
-            </when>
-        </conditional>
         <section name="adv" title="Advanced Options" expanded="false">
             <param name="align_channel" type="integer" value="0" label="Align Channel Number"/>
+            <param name="stitch_alpha" type="float" optional="true" label="Alpha"/>
             <param name="filter_sigma" type="float" optional="true" label="Sigma"/>
             <param name="tile_size" type="integer"  optional="true" label="Cyto Mask Channel"/>
             <param name="flip_mosaic_x" type="boolean" truevalue="--flip-mosaic-x" falsevalue="" label="Flip output image horizontally"/>
             <param name="flip_mosaic_y" type="boolean" truevalue="--flip-mosaic-y" falsevalue="" label="Flip output image vertically"/>
-            <param name="pyramid" type="boolean" checked="true" truevalue="--pyramid" falsevalue="" label="Write output as a single pyramidal TIFF"/>
         </section>
     </inputs>
 
@@ -130,7 +113,7 @@
             </param>
             <output name="output" ftype="ome.tiff">
                 <assert_contents>
-                    <has_size value="4000000" delta="1000000" />
+                    <has_size value="500000" delta="400000" />
                 </assert_contents>
             </output>
         </test>
b
diff -r 33ab2058c6d9 -r ef68bc2a4dbc macros.xml
--- a/macros.xml Tue Sep 20 17:33:50 2022 +0000
+++ b/macros.xml Fri Feb 09 22:48:46 2024 +0000
b
@@ -12,11 +12,11 @@
     </xml>
     <xml name="citations">
         <citations>
-            <citation type="doi">10.1101/2021.04.20.440625</citation>
+            <citation type="doi">10.1093/bioinformatics/btac544</citation>
         </citations>
     </xml>
 
-    <token name="@TOOL_VERSION@">1.14.0</token>
-    <token name="@VERSION_SUFFIX@">1</token>
+    <token name="@TOOL_VERSION@">1.18.0</token>
+    <token name="@VERSION_SUFFIX@">0</token>
     <token name="@CMD_BEGIN@">ashlar</token>
 </macros>
b
diff -r 33ab2058c6d9 -r ef68bc2a4dbc pyramid_upgrade.py
--- a/pyramid_upgrade.py Tue Sep 20 17:33:50 2022 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
[
b'@@ -1,566 +0,0 @@\n-import argparse\n-import dataclasses\n-import fractions\n-import io\n-import os\n-import re\n-import reprlib\n-import struct\n-import sys\n-import xml.etree.ElementTree\n-from typing import Any, List\n-\n-\n-datatype_formats = {\n-    1: "B",  # BYTE\n-    2: "s",  # ASCII\n-    3: "H",  # SHORT\n-    4: "I",  # LONG\n-    5: "I",  # RATIONAL (pairs)\n-    6: "b",  # SBYTE\n-    7: "B",  # UNDEFINED\n-    8: "h",  # SSHORT\n-    9: "i",  # SLONG\n-    10: "i",  # SRATIONAL (pairs)\n-    11: "f",  # FLOAT\n-    12: "d",  # DOUBLE\n-    13: "I",  # IFD\n-    16: "Q",  # LONG8\n-    17: "q",  # SLONG8\n-    18: "Q",  # IFD8\n-}\n-rational_datatypes = {5, 10}\n-\n-\n-class TiffSurgeon:\n-    """Read, manipulate and write IFDs in BigTIFF files."""\n-\n-    def __init__(self, path, *, writeable=False, encoding=None):\n-        self.path = path\n-        self.writeable = writeable\n-        self.encoding = encoding\n-        self.endian = ""\n-        self.ifds = None\n-        self.file = open(self.path, "r+b" if self.writeable else "rb")\n-        self._validate()\n-\n-    def _validate(self):\n-        signature = self.read("2s")\n-        signature = signature.decode("ascii", errors="ignore")\n-        if signature == "II":\n-            self.endian = "<"\n-        elif signature == "MM":\n-            self.endian = ">"\n-        else:\n-            raise FormatError(f"Not a TIFF file (signature is \'{signature}\').")\n-        version = self.read("H")\n-        if version == 42:\n-            raise FormatError("Cannot process classic TIFF, only BigTIFF.")\n-        offset_size, reserved, first_ifd_offset = self.read("H H Q")\n-        if version != 43 or offset_size != 8 or reserved != 0:\n-            raise FormatError("Malformed TIFF, giving up!")\n-        self.first_ifd_offset = first_ifd_offset\n-\n-    def read(self, fmt, *, file=None):\n-        if file is None:\n-            file = self.file\n-        endian = self.endian or "="\n-        size = struct.calcsize(endian + fmt)\n-        raw = file.read(size)\n-        value = self.unpack(fmt, raw)\n-        return value\n-\n-    def write(self, fmt, *values):\n-        if not self.writeable:\n-            raise ValueError("File is opened as read-only.")\n-        raw = self.pack(fmt, *values)\n-        self.file.write(raw)\n-\n-    def unpack(self, fmt, raw):\n-        assert self.endian or re.match(r"\\d+s", fmt), \\\n-            "can\'t unpack non-string before endianness is detected"\n-        fmt = self.endian + fmt\n-        size = struct.calcsize(fmt)\n-        values = struct.unpack(fmt, raw[:size])\n-        if len(values) == 1:\n-            return values[0]\n-        else:\n-            return values\n-\n-    def pack(self, fmt, *values):\n-        assert self.endian, "can\'t pack without endian set"\n-        fmt = self.endian + fmt\n-        raw = struct.pack(fmt, *values)\n-        return raw\n-\n-    def read_ifds(self):\n-        ifds = [self.read_ifd(self.first_ifd_offset)]\n-        while ifds[-1].offset_next:\n-            ifds.append(self.read_ifd(ifds[-1].offset_next))\n-        self.ifds = ifds\n-\n-    def read_ifd(self, offset):\n-        self.file.seek(offset)\n-        num_tags = self.read("Q")\n-        buf = io.BytesIO(self.file.read(num_tags * 20))\n-        offset_next = self.read("Q")\n-        try:\n-            tags = TagSet([self.read_tag(buf) for i in range(num_tags)])\n-        except FormatError as e:\n-            raise FormatError(f"IFD at offset {offset}, {e}") from None\n-        ifd = Ifd(tags, offset, offset_next)\n-        return ifd\n-\n-    def read_tag(self, buf):\n-        tag = Tag(*self.read("H H Q 8s", file=buf))\n-        value, offset_range = self.tag_value(tag)\n-        tag = dataclasses.replace(tag, value=value, offset_range=offset_range)\n-        return tag\n-\n-    def append_ifd_sequence(self, ifds):\n-        """Write list of IFDs as a chained sequence at the end of the file.\n-\n-        Returns a list of new Ifd objects with updated offsets.\n-\n-        """\n-        self.file.seek(0, os.SEEK_END)\n-        new_ifds = ['..b'f"Number of channels: {size_c}")\n-    print(f"Pyramid sub-resolutions ({num_levels - 1} total):")\n-    for dim_x, dim_y in page_dims[size_c::size_c]:\n-        print(f"    {dim_x} x {dim_y}")\n-    software = tiff.ifds[0].tags.get_value(305, "<not set>")\n-    print(f"Software: {software}")\n-    print()\n-\n-    print("Updating OME-XML metadata...")\n-    # We already verified there is nothing but Image elements under the root.\n-    for other_image in root[1:]:\n-        root.remove(other_image)\n-    for tiffdata in pixels.findall("ome:TiffData", xml_ns):\n-        pixels.remove(tiffdata)\n-    new_tiffdata = xml.etree.ElementTree.Element(\n-        f"{{{xml_ns[\'ome\']}}}TiffData",\n-        attrib={"IFD": "0", "PlaneCount": str(size_c)},\n-    )\n-    # A valid OME-XML Pixels begins with size_c Channels; then comes TiffData.\n-    pixels.insert(size_c, new_tiffdata)\n-\n-    if args.channel_names:\n-        print("Renaming channels...")\n-        channels = pixels.findall("ome:Channel", xml_ns)\n-        for channel, name in zip(channels, args.channel_names):\n-            channel.attrib["Name"] = name\n-\n-    fix_attrib_namespace(root)\n-    # ElementTree.tostring would have been simpler but it only supports\n-    # xml_declaration and default_namespace starting with Python 3.8.\n-    xml_file = io.BytesIO()\n-    tree = xml.etree.ElementTree.ElementTree(root)\n-    tree.write(\n-        xml_file,\n-        encoding="utf-8",\n-        xml_declaration=True,\n-        default_namespace=xml_ns["ome"],\n-    )\n-    new_omexml = xml_file.getvalue()\n-\n-    print("Writing new TIFF headers...")\n-    stale_ranges = [ifd.offset_range for ifd in tiff.ifds]\n-    main_ifds = tiff.ifds[:size_c]\n-    channel_sub_ifds = [tiff.ifds[c + size_c::size_c] for c in range(size_c)]\n-    for i, (main_ifd, sub_ifds) in enumerate(zip(main_ifds, channel_sub_ifds)):\n-        for ifd in sub_ifds:\n-            if 305 in ifd.tags:\n-                stale_ranges.append(ifd.tags[305].offset_range)\n-                del ifd.tags[305]\n-            ifd.tags.insert(tiff.append_tag_data(254, 3, 1))\n-        if i == 0:\n-            stale_ranges.append(main_ifd.tags[305].offset_range)\n-            stale_ranges.append(main_ifd.tags[270].offset_range)\n-            old_software = main_ifd.tags[305].value.replace("Faas", "F*a*a*s")\n-            new_software = f"pyramid_upgrade.py (was {old_software})"\n-            main_ifd.tags.insert(tiff.append_tag_data(305, 2, new_software))\n-            main_ifd.tags.insert(tiff.append_tag_data(270, 2, new_omexml))\n-        else:\n-            if 305 in main_ifd.tags:\n-                stale_ranges.append(main_ifd.tags[305].offset_range)\n-                del main_ifd.tags[305]\n-        sub_ifds[:] = tiff.append_ifd_sequence(sub_ifds)\n-        offsets = [ifd.offset for ifd in sub_ifds]\n-        main_ifd.tags.insert(tiff.append_tag_data(330, 16, offsets))\n-    main_ifds = tiff.append_ifd_sequence(main_ifds)\n-    tiff.write_first_ifd_offset(main_ifds[0].offset)\n-\n-    print("Clearing old headers and tag values...")\n-    # We overwrite all the old IFDs and referenced data values with obvious\n-    # "filler" as a courtesy to anyone who might need to poke around in the TIFF\n-    # structure down the road. A real TIFF parser wouldn\'t see the stale data,\n-    # but a human might just scan for the first thing that looks like a run of\n-    # OME-XML and not realize it\'s been replaced with something else. The filler\n-    # content is the repeated string "unused " with square brackets at the\n-    # beginning and end of each filled IFD or data value.\n-    filler = b"unused "\n-    f_len = len(filler)\n-    for r in stale_ranges:\n-        tiff.file.seek(r.start)\n-        tiff.file.write(b"[")\n-        f_total = len(r) - 2\n-        for i in range(f_total // f_len):\n-            tiff.file.write(filler)\n-        tiff.file.write(b" " * (f_total % f_len))\n-        tiff.file.write(b"]")\n-\n-    tiff.close()\n-\n-    print()\n-    print("Success!")\n-\n-\n-if __name__ == "__main__":\n-    main()\n'