diff --git a/config/datatypes_conf.xml.sample b/config/datatypes_conf.xml.sample
index 5d048b3f48d..afe5bf8f7f1 100644
--- a/config/datatypes_conf.xml.sample
+++ b/config/datatypes_conf.xml.sample
@@ -162,6 +162,7 @@
+
@@ -775,6 +776,7 @@
+
diff --git a/lib/galaxy/datatypes/binary.py b/lib/galaxy/datatypes/binary.py
index 6ada00bde4a..a447c6ba5a5 100644
--- a/lib/galaxy/datatypes/binary.py
+++ b/lib/galaxy/datatypes/binary.py
@@ -1107,6 +1107,66 @@ class Cool(H5):
return "Cool (HDF5) file (%s)." % (nice_size(dataset.get_size()))
+class MCool(H5):
+ """
+ Class describing the multi-resolution cool format (https://github.com/mirnylab/cooler)
+ """
+
+ file_ext = "mcool"
+
+ def sniff(self, filename):
+ """
+ >>> from galaxy.datatypes.sniff import get_test_fname
+ >>> fname = get_test_fname('matrix.mcool')
+ >>> MCool().sniff(fname)
+ True
+ >>> fname = get_test_fname('matrix.cool')
+ >>> MCool().sniff(fname)
+ False
+ >>> fname = get_test_fname('test.mz5')
+ >>> MCool().sniff(fname)
+ False
+ >>> fname = get_test_fname('wiggle.wig')
+ >>> MCool().sniff(fname)
+ False
+ >>> fname = get_test_fname('biom2_sparse_otu_table_hdf5.biom2')
+ >>> MCool().sniff(fname)
+ False
+ """
+
+ MAGIC = "HDF5::Cooler"
+ URL = "https://github.com/mirnylab/cooler"
+
+ if super(MCool, self).sniff(filename):
+ keys0 = ['resolutions']
+ with h5py.File(filename, 'r') as handle:
+ if not all(name in handle.keys() for name in keys0):
+ return False
+ res0 = list(handle['resolutions'].keys())[0]
+ keys = ['chroms', 'bins', 'pixels', 'indexes']
+ fmt = handle['resolutions'][res0].attrs.get('format', None)
+ url = handle['resolutions'][res0].attrs.get('format-url', None)
+ if fmt == MAGIC or url == URL:
+ if not all(name in handle['resolutions'][res0].keys() for name in keys):
+ return False
+ return True
+ return False
+
+ def set_peek(self, dataset, is_multi_byte=False):
+ if not dataset.dataset.purged:
+ dataset.peek = "Multi-resolution Cool (HDF5) file for storing genomic interaction data."
+ dataset.blurb = nice_size(dataset.get_size())
+ else:
+ dataset.peek = 'file does not exist'
+ dataset.blurb = 'file purged from disk'
+
+ def display_peek(self, dataset):
+ try:
+ return dataset.peek
+ except Exception:
+ return "MCool (HDF5) file (%s)." % (nice_size(dataset.get_size()))
+
+
class Scf(Binary):
"""Class describing an scf binary sequence file"""
edam_format = "format_1632"
diff --git a/lib/galaxy/datatypes/test/matrix.mcool b/lib/galaxy/datatypes/test/matrix.mcool
new file mode 100644
index 00000000000..bf42ef345fe
Binary files /dev/null and b/lib/galaxy/datatypes/test/matrix.mcool differ
diff --git a/lib/galaxy/tools/verify/asserts/hdf5.py b/lib/galaxy/tools/verify/asserts/hdf5.py
index f64314fe1ea..c4aae057c9e 100644
--- a/lib/galaxy/tools/verify/asserts/hdf5.py
+++ b/lib/galaxy/tools/verify/asserts/hdf5.py
@@ -24,10 +24,19 @@ def assert_has_h5_attribute(output_bytes, key, value):
def assert_has_h5_keys(output_bytes, keys):
- """ Asserts the specified HDF5 output has exactly the given keys."""
+ """ Asserts the specified HDF5 output has the given keys."""
_assert_h5py()
keys = [k.strip() for k in keys.strip().split(',')]
h5_keys = sorted(keys)
output_temp = io.BytesIO(output_bytes)
- local_keys = sorted(list(h5py.File(output_temp, 'r').keys()))
- assert local_keys == h5_keys, "Not a HDF5 file or H5 keys do not match:\n\t%s\n\t%s" % (local_keys, h5_keys)
+ local_keys = []
+
+ def append_keys(key):
+ local_keys.append(key)
+ return None
+ h5py.File(output_temp, 'r').visit(append_keys)
+ missing = 0
+ for key in h5_keys:
+ if key not in local_keys:
+ missing += 1
+ assert missing == 0, "Not a HDF5 file or H5 keys missing:\n\t%s\n\t%s" % (local_keys, h5_keys)
diff --git a/lib/galaxy/tools/xsd/galaxy.xsd b/lib/galaxy/tools/xsd/galaxy.xsd
index 8fef0b74556..a9c208e62ca 100644
--- a/lib/galaxy/tools/xsd/galaxy.xsd
+++ b/lib/galaxy/tools/xsd/galaxy.xsd
@@ -1669,7 +1669,7 @@ module.
- ``).]]>
+ ``).]]>
diff --git a/test/functional/tools/validation_hdf5.xml b/test/functional/tools/validation_hdf5.xml
index f66fa618835..d3cd9f9175b 100644
--- a/test/functional/tools/validation_hdf5.xml
+++ b/test/functional/tools/validation_hdf5.xml
@@ -13,7 +13,7 @@