<commit_before>#!/usr/bin/env python

#Copyright (C) 2011 by <NAME>
#
#Released under the MIT license, see LICENSE.txt

""" Schedule jobs based on the dependencies between their associated
events.  These dependencies are based 1, on the phylogeny and 2,
on outgroups.  The input is a DAG, the output is a TREE 

"""

import os
import xml.etree.ElementTree as ET
import sys
import math
import copy
import networkx as NX

from optparse import OptionParser


from cactus.progressive.multiCactusProject import MultiCactusProject
from cactus.progressive.multiCactusTree import MultiCactusTree
from cactus.progressive.experimentWrapper import ExperimentWrapper

class Schedule:
    def __init__(self):
        # input graph
        self.inGraph = None
        # output tree
        self.depTree = None
    
    # read the experiments, compute the dependency dag
    def loadProject(self, mcProject):
        self.inGraph = NX.DiGraph()
        globTree = mcProject.mcTree
        leafEvents = [globTree.getName(i) for i in globTree.getLeaves()]
        for name, expPath in mcProject.expMap.items():
            exp = ExperimentWrapper(ET.parse(expPath).getroot())
            tree = exp.getTree()
            for leaf in tree.getLeaves():
                # we don't add edges for leaves (in the global tree)
                # as they are input sequences and do not form dependencies
                # (it would be clever to maybe do the same with existing
                # references when --overwrite is not specified but for now
                # we just do the leaves)
                leafName = tree.getName(leaf)
                if leafName not in leafEvents:
                    self.inGraph.add_edge(name, leafName)
        assert NX.is_directed_acyclic_graph(self.inGraph)
    
    # break all the cycles in reverse topological order
    def compute(self):
        self.depTree = self.inGraph.copy()
        tsort = NX.topological_sort(self.depTree)
        tsort.reverse()
        for node in tsort:
            parents = [i[0] for i in self.depTree.in_edges(node)]
            if len(parents) > 1:
                chosenParentIndex = min([tsort.index(i) for i in parents])
                chosenParent = tsort[chosenParentIndex]
                for parent in parents:
                    if parent != chosenParent:
                        self.depTree.remove_edge(parent, node)<commit_msg>add nodes to dependency graph even if they have no children (this prevents assert to be triggered for empty graphs)<commit_after>#!/usr/bin/env python

#Copyright (C) 2011 by <NAME>
#
#Released under the MIT license, see LICENSE.txt

""" Schedule jobs based on the dependencies between their associated
events.  These dependencies are based 1, on the phylogeny and 2,
on outgroups.  The input is a DAG, the output is a TREE 

"""

import os
import xml.etree.ElementTree as ET
import sys
import math
import copy
import networkx as NX

from optparse import OptionParser


from cactus.progressive.multiCactusProject import MultiCactusProject
from cactus.progressive.multiCactusTree import MultiCactusTree
from cactus.progressive.experimentWrapper import ExperimentWrapper

class Schedule:
    def __init__(self):
        # input graph
        self.inGraph = None
        # output tree
        self.depTree = None
    
    # read the experiments, compute the dependency dag
    def loadProject(self, mcProject):
        self.inGraph = NX.DiGraph()
        globTree = mcProject.mcTree
        leafEvents = [globTree.getName(i) for i in globTree.getLeaves()]
        for name, expPath in mcProject.expMap.items():
            exp = ExperimentWrapper(ET.parse(expPath).getroot())
            tree = exp.getTree()
            self.inGraph.add_node(name)
            for leaf in tree.getLeaves():
                # we don't add edges for leaves (in the global tree)
                # as they are input sequences and do not form dependencies
                # (it would be clever to maybe do the same with existing
                # references when --overwrite is not specified but for now
                # we just do the leaves)
                leafName = tree.getName(leaf)
                if leafName not in leafEvents:
                    self.inGraph.add_edge(name, leafName)
        assert NX.is_directed_acyclic_graph(self.inGraph)
    
    # break all the cycles in reverse topological order
    def compute(self):
        self.depTree = self.inGraph.copy()
        tsort = NX.topological_sort(self.depTree)
        tsort.reverse()
        for node in tsort:
            parents = [i[0] for i in self.depTree.in_edges(node)]
            if len(parents) > 1:
                chosenParentIndex = min([tsort.index(i) for i in parents])
                chosenParent = tsort[chosenParentIndex]
                for parent in parents:
                    if parent != chosenParent:
                        self.depTree.remove_edge(parent, node)
{'fraction_non_alphanumeric': 0.06977687626774848, 'fraction_numerical': 0.0032454361054766734, 'mean_word_length': 2.3250168577208363, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4590535', 'n_tokens_mistral': 1377, 'n_tokens_neox': 1320, 'n_words': 467}