from __future__ import absolute_import
import os
from .validate import ValidationError
from .base import HubComponent
from .genome import Genome
from .genomes_file import GenomesFile
[docs]
class GroupDefinition(object):
[docs]
def __init__(self, name, label=None, priority=1, default_is_closed=0):
"""
Represents a group of tracks in a trackhub.
Instances of this class are provided to an assembly.
Parameters
----------
name : str
Name for the group (e.g., "map").
label : str
The label that will be displayed (e.g., "Mapping")
priority : int
Orders this track group with the other track groups
default_is_closed : 0 | 1
Determines if this track group is expanded or closed by default.
Values to use are 0 or 1
"""
self.name = str(name)
if label is None:
label = name
self.label = str(label)
self.priority = int(priority)
if default_is_closed in (0, 1):
self.default_is_closed = default_is_closed
else:
raise ValueError("default_is_closed must be 1 or 0")
def __str__(self):
s = [
"name %s" % self.name,
"label %s" % self.label,
"priority %s" % self.priority,
"defaultIsClosed %d" % self.default_is_closed,
]
return "\n".join(s) + "\n"
[docs]
class GroupsFile(HubComponent):
[docs]
def __init__(self, groups, filename=None):
"""
Represents the groups file on disk, used for assembly hubs.
Parameters
----------
groups : list
List of GroupDefinition objects
filename : str
Filename to use, relative to the top-level hub. If None, default is
to use "<genome>/groups.txt"
"""
HubComponent.__init__(self)
self.groups = []
self.add_groups(groups)
self._filename = filename
[docs]
def add_groups(self, groups):
"""
Add a list of GroupDefinition objects.
Parameters
----------
groups : list
List of GroupDefinition objects.
"""
self.groups.extend(groups)
def __str__(self):
"""
Render groups.txt file.
"""
return "\n".join(g.__str__() for g in self.groups)
@property
def genomes_file(self):
genomes_file, level = self.root(GenomesFile)
if level is None:
return None
if level != -2:
raise ValueError("GenomesFile is level %s, not -2" % level)
return genomes_file
@property
def genome(self):
genome, level = self.root(Genome)
if level is None:
return None
if level != -1:
raise ValueError("Genome is level %s, not -1" % level)
return genome
@property
def filename(self):
if self._filename is not None:
return self._filename
if self.genome is None:
return None
if self.genomes_file is None:
return None
else:
return os.path.join(
os.path.dirname(self.genomes_file.filename),
self.genome.genome,
"groups.txt",
)
@filename.setter
def filename(self, fn):
self._filename = fn
[docs]
def validate(self):
if self.genome is None:
raise ValidationError(
"GroupsFile object must be attached to an Genome instance "
"or subclass"
)
pass
def _render(self, staging="staging"):
"""
Renders the children GroupDefinition objects to file
"""
rendered_filename = os.path.join(staging, self.filename)
self.makedirs(rendered_filename)
fout = open(rendered_filename, "w")
fout.write(str(self))
fout.close()
return fout.name