Assigns data to this object and builds the Morse-Smale
            Complex
            @ In, X, an m-by-n array of values specifying m
            n-dimensional samples
            @ In, Y, a m vector of values specifying the output
            responses corresponding to the m samples specified by X
            @ In, w, an optional m vector of values specifying the
            weights associated to each of the m samples used. Default of
            None means all points will be equally weighted
            @ In, edges, an optional list of custom edges to use as a
            starting point for pruning, or in place of a computed graph.

def build(self, X, Y, w=None, edges=None):
        """ Assigns data to this object and builds the Morse-Smale
            Complex
            @ In, X, an m-by-n array of values specifying m
            n-dimensional samples
            @ In, Y, a m vector of values specifying the output
            responses corresponding to the m samples specified by X
            @ In, w, an optional m vector of values specifying the
            weights associated to each of the m samples used. Default of
            None means all points will be equally weighted
            @ In, edges, an optional list of custom edges to use as a
            starting point for pruning, or in place of a computed graph.
        """
        super(ContourTree, self).build(X, Y, w, edges)

        # Build the join and split trees that we will merge into the
        # contour tree
        joinTree = MergeTree(debug=self.debug)
        splitTree = MergeTree(debug=self.debug)

        joinTree.build_for_contour_tree(self, True)
        splitTree.build_for_contour_tree(self, False)

        self.augmentedEdges = dict(joinTree.augmentedEdges)
        self.augmentedEdges.update(dict(splitTree.augmentedEdges))

        if self.short_circuit:
            jt = self._construct_nx_tree(joinTree, splitTree)
            st = self._construct_nx_tree(splitTree, joinTree)
        else:
            jt = self._construct_nx_tree(joinTree)
            st = self._construct_nx_tree(splitTree)

        self._process_tree(jt, st)
        self._process_tree(st, jt)

        # Now we have a fully augmented contour tree stored in nodes and
        # edges The rest is some convenience stuff for querying later

        self._identifyBranches()
        self._identifySuperGraph()

        if self.debug:
            sys.stdout.write("Sorting Nodes: ")
            start = time.clock()

        self.sortedNodes = sorted(enumerate(self.Y),
                                  key=operator.itemgetter(1))

        if self.debug:
            end = time.clock()
            sys.stdout.write("%f s\n" % (end - start))