Allow for the printing of nested GenObjects
        :param metadata: Nested dictionary containing the metadata. Will be further populated by this method
        :param attr: Current attribute being evaluated. Must be a GenObject e.g. sample.general
        :param datastore: The dictionary of the current attribute. Will be converted to nested dictionaries
        :return: Updated nested metadata dictionary with all GenObjects safely converted to dictionaries

def nested_genobject(self, metadata, attr, datastore):
        """
        Allow for the printing of nested GenObjects
        :param metadata: Nested dictionary containing the metadata. Will be further populated by this method
        :param attr: Current attribute being evaluated. Must be a GenObject e.g. sample.general
        :param datastore: The dictionary of the current attribute. Will be converted to nested dictionaries
        :return: Updated nested metadata dictionary with all GenObjects safely converted to dictionaries
        """
        # Iterate through all the key: value pairs of the current datastore[attr] datastore
        # e.g. reverse_reads <accessoryFunctions.accessoryFunctions.GenObject object at 0x7fe153b725f8>
        for key, value in sorted(datastore[attr].datastore.items()):
            # If the type(value) is a GenObject, then JSON serialization will not work
            if 'GenObject' in str(type(value)):
                # Initialise the nested attribute: key nested dictionary within the metadata dictionary
                # e.g. attr: 100_100, key: reverse_reads
                metadata[attr][key] = dict()
                # Iterate through the nested keys and nested values within the value datastore
                # e.g. nested_key: length, nested_value: 100
                for nested_key, nested_datastore in sorted(value.datastore.items()):
                    # Create an additional dictionary layer within the metadata dictionary
                    metadata[attr][key][nested_key] = dict()
                    # If the type(nested_datastore) is a GenObject, recursively run this method to update the
                    # metadata dictionary, supply the newly created nested dictionary: metadata[attr][key] as
                    # the input metadata dictionary, the nested key as the input attribute, and the datastore of
                    # value as the input datastore
                    # e.g. key: 100_100,
                    # datastore: <accessoryFunctions.accessoryFunctions.GenObject object at 0x7fc526001e80>
                    if 'GenObject' in str(type(nested_datastore)):
                        metadata[attr][key].update(
                            self.nested_genobject(metadata[attr][key], nested_key, value.datastore))
                    # If the nested datastore is not a GenObject, populate the nested metadata dictionary with
                    # the attribute, key, nested key, and nested datastore
                    # e.g. attr: 100_100, key: reverse_reads, nested_key: length, nested_datastore: 100
                    else:
                        metadata[attr][key][nested_key] = nested_datastore
            # Non-GenObjects can (usually) be added to the metadata dictionary without issues
            else:
                try:
                    if key not in self.unwanted_keys:
                        metadata[attr][key] = value
                except AttributeError:
                    print('dumperror', attr)
        # Return the metadata
        return metadata