def _update(self):
        """parse design file and fill class attributes.

        Call this function whenever self.table changes.
        """

        # remove all entries that should not be included
        self.table = self.table[self.table["include"] != 0]

        # define attributes
        self.conditions = self.table['group'].tolist()
        self.pairs = self.table['pair'].tolist()
        # TS - use OrderedDict to retain order in unique
        self.groups = (list(collections.OrderedDict.fromkeys(
            self.conditions)))
        self.samples = self.table.index.tolist()

        # TS, adapted from JJ code for DESeq2 design tables:
        # if additional columns present, pass to 'factors'
        if len(self.table.columns) > 3:
            self.factors = self.table.iloc[:, 3:]
        else:
            self.factors = None

        # Test if replicates exist, i.e at least one group has multiple samples
        # TS - does this need to be extended to check whether replicates exist
        # for each group?
        max_per_group = max([self.conditions.count(x) for x in self.groups])
        self.has_replicates = max_per_group >= 2

        # Test if pairs exist:
        npairs = len(set(self.pairs))
        has_pairs = npairs == 2

        # ..if so, at least two samples are required per pair
        if has_pairs:
            min_per_pair = min([self.pairs.count(x) for x in set(self.pairs)])
            self.has_pairs = min_per_pair >= 2
        else:
            self.has_pairs = False
dataset/ETHPy150Open CGATOxford/cgat/CGAT/Expression.py/ExperimentalDesign._update/original