def initialize(ind): # ind = parameter index where match should occur spec = "x : ~y : E\ny : x : E\nz : x : E" network = DSGRN.Network(spec) pg = DSGRN.ParameterGraph(network) dgs = [DSGRN.DomainGraph(pg.parameter(p)) for p in range(pg.size())] sgs = [DSGRN.SearchGraph(dg) for dg in dgs] return network, sgs[ind]
def check_Morsegraphs(spec): net = DSGRN.Network(spec) pg = DSGRN.ParameterGraph(net) test = {} for pi in range(pg.size()): param = pg.parameter(pi) dg = DSGRN.DomainGraph(param) md = DSGRN.MorseDecomposition(dg.digraph()) mg = DSGRN.MorseGraph(md, dg) test[pi] = ast.literal_eval(mg.annotation(0).stringify())[0] return test
def PathMatches_with_count(network, posets, domain, stablefc): ''' Count the number of pattern matches in the domain graph and/or stable full cycles. :param network: DSGRN network object. :param posets: The partially ordered sets that are to be matched at each epsilon in DSGRN format. :param domain: True or False, search over whole domain graph. :param stablefc: True or False search over stable full cycles only. :return: dictionary of results ''' if len(posets) > 1: totalDom= {"all": {str(eps[0]) : set() for eps in posets[next(iter(posets))]} } totalFC = {"all": {str(eps[0]) : set() for eps in posets[next(iter(posets))]} } numDomMatch = { tsfile : {str(eps[0]) : 0 for eps in poset_list} for tsfile,poset_list in posets.items()} numFCMatch = { tsfile : {str(eps[0]) : 0 for eps in poset_list} for tsfile,poset_list in posets.items()} numFC = 0 paramgraph = DSGRN.ParameterGraph(network) for paramind in range(paramgraph.size()): FC = False domaingraph = DSGRN.DomainGraph(paramgraph.parameter(paramind)) for tsfile, poset_list in posets.items(): for (eps, (events, event_ordering)) in poset_list: patterngraph = DSGRN.PatternGraph(DSGRN.PosetOfExtrema(network,events,event_ordering)) if stablefc: stabmatch, newFC = stableFC_check(domaingraph,patterngraph) if newFC and not FC: numFC +=1 FC = True if stabmatch: numFCMatch[tsfile][str(eps)]+=1 if len(posets) > 1: totalFC["all"][str(eps)].add(paramind) if stabmatch and domain: numDomMatch[tsfile][str(eps)] += 1 if len(posets) > 1: totalDom["all"][str(eps)].add(paramind) elif not stabmatch and domain: dommatch = domain_check(domaingraph, patterngraph) if dommatch: numDomMatch[tsfile][str(eps)] += 1 if len(posets) > 1: totalDom["all"][str(eps)].add(paramind) if domain and not stablefc: dommatch = domain_check(domaingraph,patterngraph) if dommatch: numDomMatch[tsfile][str(eps)]+=1 if len(posets) > 1: totalDom["all"][str(eps)].add(paramind) dommatches = {tsfile : [(float(eps),count,paramgraph.size()) for eps,count in edict.items()] for tsfile,edict in numDomMatch.items()} fcmatches = {tsfile : [(float(eps),count,numFC,paramgraph.size()) for eps,count in edict.items()] for tsfile,edict in numFCMatch.items()} if len(posets)>1: dommatches.update({"all": [(float(eps),len(totalDom["all"][eps]),paramgraph.size()) for eps in totalDom["all"]]}) fcmatches.update({"all" : [(float(eps),len(totalFC["all"][eps]),numFC,paramgraph.size()) for eps in totalFC["all"]]}) return dommatches,fcmatches
def test1(): network_spec = "A : A + B\nB : (B)(~A)(~C)\nC : A + C" network = DSGRN.Network(network_spec) hex_codes = ["000", "0000", "00"] orders = [[0, 1, 2], [0, 1], [0, 1]] param = build.construct_parameter(network, hex_codes, orders) pg = DSGRN.ParameterGraph(network) pi = pg.index(param) assert (pi == 0) mg1 = DSGRN.MorseGraph(DSGRN.DomainGraph(param)).stringify() mg2 = DSGRN.MorseGraph(DSGRN.DomainGraph(pg.parameter(pi))).stringify() assert (mg1 == mg2) hex_codes = ["000", "FC00", "C0"] orders = [[0, 2, 1], [0, 1], [1, 0]] param = build.construct_parameter(network, hex_codes, orders) pg = DSGRN.ParameterGraph(network) pi = pg.index(param) assert (pi == 2000000) mg1 = DSGRN.MorseGraph(DSGRN.DomainGraph(param)).stringify() mg2 = DSGRN.MorseGraph(DSGRN.DomainGraph(pg.parameter(pi))).stringify() assert (mg1 == mg2)
def query(networks, resultsdir, params): ''' :param networks: list of network specification strings in DSGRN format :param resultsdir: path to directory where results file(s) will be stored :param params: dictionary containing the key "bounds". bounds is a dictionary of variable names common to all network specifications with a range of values assigned to each. Example: {"X1":[2,2],"X2":[1,1],"X3":[0,1]}. The integer ranges are the matching conditions for an FP. For example, if there are four variables X1, X2, X3, X4 in the network spec, the FP (2,1,0,*) would be a match for any value of *. :return: Writes count of parameters with an FP match to a dictionary keyed by network spec, which is dumped to a json file. ''' bounds = dict(params["bounds"]) def is_FP(annotation): return annotation.startswith("FP") def is_FP_match(bounds_ind, annotation): digits = [ int(s) for s in annotation.replace(",", "").split() if s.isdigit() ] return all( digits[k] >= bounds_ind[k][0] and digits[k] <= bounds_ind[k][1] for k in bounds_ind) resultsdict = {} for net in networks: count = 0 network = DSGRN.Network() network.assign(net) bounds_ind = {network.index(str(k)): bounds[k] for k in bounds} parametergraph = DSGRN.ParameterGraph(network) for p in range(parametergraph.size()): parameter = parametergraph.parameter(p) dg = DSGRN.DomainGraph(parameter) md = DSGRN.MorseDecomposition(dg.digraph()) mg = DSGRN.MorseGraph(dg, md) stable_FP_annotations = [ mg.annotation(i)[0] for i in range(0, mg.poset().size()) if is_FP(mg.annotation(i)[0]) and len(mg.poset().children(i)) == 0 ] if any([is_FP_match(bounds_ind, a) for a in stable_FP_annotations]): count += 1 resultsdict[net] = [count, parametergraph.size()] rname = os.path.join(resultsdir, "query_results.json") if os.path.exists(rname): os.rename(rname, rname + ".old") json.dump(resultsdict, open(rname, 'w'))
def DSGRN_Computation(parameter): ''' Get DSGRN annotations for all Morse sets that are fixed points. :param parameter: DSGRN.Parameter object :return: list of DSGRN annotations ''' dg = DSGRN.DomainGraph(parameter) mg = DSGRN.MorseGraph(dg) return [ mg.annotation(i)[0] for i in range(0, mg.poset().size()) if is_FP(mg.annotation(i)[0]) and len(mg.poset().children(i)) == 0 ]
def DatabaseJSON(network, param_indices=None, verts_colors=None, eq_cells=False, thres_type=''): if network.size() not in [2, 3]: print('Only available for dimensions 2 and 3!') return parameter_graph = DSGRN.ParameterGraph(network) # Use all parameter indices if None if param_indices == None: param_indices = range(parameter_graph.size()) network_json_data = network_json(network) cell_complex_json_data = cubical_complex_json(network) param_graph_json_data = parameter_graph_json(parameter_graph, param_indices, verts_colors, thres_type) dynamics_database = [] # Dynamics database for par_index in param_indices: # Compute DSGRN dynamics parameter = parameter_graph.parameter(par_index) domain_graph = DSGRN.DomainGraph(parameter) morse_decomposition = DSGRN.MorseDecomposition(domain_graph.digraph()) morse_graph = DSGRN.MorseGraph(domain_graph, morse_decomposition) morse_graph_json_data = morse_graph_json(morse_graph) morse_sets_json_data = morse_sets_json(network, morse_graph, morse_decomposition) stg_json_data = state_transition_graph_json(network, domain_graph) if eq_cells: # Include equilibrium cells if true eq_cells_json_data = equilibrium_cells_json( parameter, morse_sets_json_data["morse_sets"]) else: eq_cells_json_data = {"equilibrium_cells": []} # Dynamics data for this parameter dynamics_json_data = { "parameter": par_index, "morse_graph": morse_graph_json_data["morse_graph"], "morse_sets": morse_sets_json_data["morse_sets"], "equilibrium_cells": eq_cells_json_data["equilibrium_cells"], "stg": stg_json_data["stg"] } dynamics_database.append(dynamics_json_data) morse_graph_database = { "network": network_json_data["network"], "complex": cell_complex_json_data["complex"], "parameter_graph": param_graph_json_data["parameter_graph"], "dynamics_database": dynamics_database } return morse_graph_database
def PathMatchInDomainGraph(paramgraph, patterngraph, count): ''' Search for path matches anywhere in the domain graph. :return: Integer count of parameters if count = True; if count = False return True if at least one match, False otherwise. ''' numparams = 0 for paramind in range(paramgraph.size()): domaingraph = DSGRN.DomainGraph(paramgraph.parameter(paramind)) searchgraph = DSGRN.SearchGraph(domaingraph) matchinggraph = DSGRN.MatchingGraph(searchgraph, patterngraph) if DSGRN.PathMatch(matchinggraph): if count: numparams += 1 else: return True return numparams if count else False
def CycleMatchInDomainGraph(paramgraph, patterngraph, count): ''' Search for cycle matches anywhere in the domain graph. :return: Integer count of parameters if count = True; if count = False return True if at least one match, False otherwise. ''' # TODO: In order for cycle matches to work correctly, the last extremum on each time series with an odd number of extrema must be removed numparams = 0 for paramind in range(paramgraph.size()): domaingraph = DSGRN.DomainGraph(paramgraph.parameter(paramind)) searchgraph = DSGRN.SearchGraph(domaingraph) matchinggraph = DSGRN.MatchingGraph(searchgraph, patterngraph) if DSGRN.CycleMatch(matchinggraph): if count: numparams += 1 else: return True return numparams if count else False
def findAllOrderedExtrema_Morsesets(networkfile=None,networkspec=None): if networkfile: network = DSGRN.Network(networkfile) elif networkspec: network = DSGRN.Network() network.assign(networkspec) else: raise ValueError("No input network.") names = [network.name(i) for i in range(network.size())] paramgraph = DSGRN.ParameterGraph(network) paths = set([]) start = time.time() for paramind in range(paramgraph.size()): if time.time()-start >= 2: print("{} / {} parameters analyzed\n".format(paramind,paramgraph.size())) start = time.time() domaingraph = DSGRN.DomainGraph(paramgraph.parameter(paramind)) morsedecomposition = DSGRN.MorseDecomposition(domaingraph.digraph()) morsegraph = DSGRN.MorseGraph() morsegraph.assign(domaingraph,morsedecomposition) poset = morsedecomposition.poset() for i in range(0,morsedecomposition.poset().size()): ms = morsedecomposition.morseset(i) if len(ms) > 1 and morsegraph.annotation(i)[0] == "FC" and len(poset.children(i)) == 0: morseedges = [ (j,a) for j in ms for a in domaingraph.digraph().adjacencies(j) if a in ms ] digraph = makeNXDigraph(domaingraph,ms,morseedges) print("Nodes: {}".format(digraph.number_of_nodes())) print("Edges: {}".format(digraph.size())) cycles = findCycles(digraph) print("Have cycles.") k = 0 for c in cycles: k+=1 print("Number cycles: {}".format(k)) sys.exit() # debugging try-except block try: C = max(len(c)-1 for c in cycles) if C > len(ms): print("morse set: {}, max cycle: {}".format(len(ms),C)) raise ValueError("Nodes in cycle exceeds nodes in Morse set.") except: pass extrema = orderedExtrema(names,cycles) paths = removeCyclicPermutations(extrema,paths) print(paths) sys.stdout.flush() return set(paths)
def compute_query(network_specs, spec_index): start_time = time.time() net_spec = network_specs[spec_index] net_spec_str = NetworkSpecStr(net_spec) network = DSGRN.Network(net_spec_str) parameter_graph = DSGRN.ParameterGraph(network) ipsc_parameters = [] day8_parameters = [] both_parameters = [] for parameter_index in range(0, parameter_graph.size()): parameter = parameter_graph.parameter(parameter_index) domain_graph = DSGRN.DomainGraph(parameter) morse_decomposition = DSGRN.MorseDecomposition(domain_graph.digraph()) morse_graph = DSGRN.MorseGraph(domain_graph, morse_decomposition) morse_nodes = range(0, morse_graph.poset().size()) has_ipsc_FP = any( is_ipsc_fixed_point(node, morse_graph) for node in morse_nodes) has_day8_FP = any( is_day8_fixed_point(node, morse_graph) for node in morse_nodes) if has_ipsc_FP: ipsc_parameters.append(parameter_index) if has_day8_FP: day8_parameters.append(parameter_index) if has_ipsc_FP and has_day8_FP: both_parameters.append(parameter_index) num_pars = parameter_graph.size() num_ipsc_pars = len(ipsc_parameters) num_day8_pars = len(day8_parameters) num_both_pars = len(both_parameters) end_time = time.time() tot_time = end_time - start_time net_spec_fname = 'net_spec_' + str(spec_index) + '.txt' with open(net_spec_fname, 'w') as outfile: outfile.write(' '.join(str(k) for k in net_spec) + '\n') results = (num_pars, num_ipsc_pars, num_day8_pars, num_both_pars, tot_time) results_fname = 'results_' + str(spec_index) + '.txt' with open(results_fname, 'w') as outfile: outfile.write(' '.join(str(x) for x in results) + '\n')
def check_FC(N, tup): k, netspec = tup count = 0 network = DSGRN.Network(netspec) parametergraph = DSGRN.ParameterGraph(network) for p in range(parametergraph.size()): parameter = parametergraph.parameter(p) dg = DSGRN.DomainGraph(parameter) md = DSGRN.MorseDecomposition(dg.digraph()) mg = DSGRN.MorseGraph(dg, md) stable_FC_annotations = [ mg.annotation(i)[0] for i in range(0, mg.poset().size()) if is_FC(mg.annotation(i)[0]) and len(mg.poset().children(i)) == 0 ] if len(stable_FC_annotations) > 0: count += 1 print("Network {} of {} complete".format(k + 1, N)) sys.stdout.flush() return netspec, (count, parametergraph.size())
def PathMatches_without_count(network, posets, domain, stablefc): ''' Test for the existence of at least one pattern match in the domain graph and/or stable full cycles. :param network: DSGRN network object. :param posets: The partially ordered sets that are to be matched at each epsilon in DSGRN format. :param domain: True or False, search over whole domain graph. :param stablefc: True or False search over stable full cycles only. :return: dictionary of results ''' def format(numDomMatch,numFCMatch): dommatches = {tsfile: [(float(eps), b, paramgraph.size()) for eps, b in edict.items()] for tsfile, edict in numDomMatch.items()} fcmatches = {tsfile: [(float(eps), b, paramgraph.size()) for eps, b in edict.items()] for tsfile, edict in numFCMatch.items()} return dommatches, fcmatches numDomMatch = { tsfile : {str(eps[0]) : False for eps in poset_list} for tsfile,poset_list in posets.items()} numFCMatch = { tsfile : {str(eps[0]) : False for eps in poset_list} for tsfile,poset_list in posets.items()} paramgraph = DSGRN.ParameterGraph(network) for paramind in range(paramgraph.size()): domaingraph = DSGRN.DomainGraph(paramgraph.parameter(paramind)) for tsfile, poset_list in posets.items(): for (eps, (events, event_ordering)) in poset_list: patterngraph = DSGRN.PatternGraph(DSGRN.PosetOfExtrema(network,events,event_ordering)) if domain and not numDomMatch[tsfile][str(eps)]: dommatch = domain_check(domaingraph,patterngraph) if dommatch: numDomMatch[tsfile][str(eps)] = True if stablefc and not numFCMatch[tsfile][str(eps)]: stabmatch, newFC = stableFC_check(domaingraph,patterngraph) if stabmatch: numFCMatch[tsfile][str(eps)] = True b = True for tsfile,poset_list in posets.items(): b = bool(b*all([numDomMatch[tsfile][str(eps[0])] for eps in poset_list])) b = bool(b*all([numFCMatch[tsfile][str(eps[0])] for eps in poset_list])) if b: return format(numDomMatch,numFCMatch) return format(numDomMatch,numFCMatch)
def get_matching_truthtables(parametergraph, truthtables, N): params = [[] for _ in range(len(truthtables))] bar = progressbar.ProgressBar(max_value=N) for p in range(N): bar.update(p) parameter = parametergraph.parameter(p) dg = DSGRN.DomainGraph(parameter) md = DSGRN.MorseDecomposition(dg.digraph()) mg = DSGRN.MorseGraph(dg, md) stable_FP_annotations = [ mg.annotation(i)[0] for i in range(0, mg.poset().size()) if is_FP(mg.annotation(i)[0]) and len(mg.poset().children(i)) == 0 ] for k, states in enumerate(truthtables): if all( any([is_FP_match(v, a) for a in stable_FP_annotations]) for v in states): params[k].append(p) bar.finish() return params
def CycleMatchInStableMorseSet(paramgraph, patterngraph, count): ''' Search for cycle matches in stable Morse sets only. :return: Integer count of parameters if count = True; if count = False return True if at least one match, False otherwise. ''' # TODO: In order for cycle matches to work correctly, the last extremum on each time series with an odd number of extrema must be removed numparams = 0 for paramind in range(paramgraph.size()): domaingraph = DSGRN.DomainGraph(paramgraph.parameter(paramind)) morsedecomposition = DSGRN.MorseDecomposition(domaingraph.digraph()) morsegraph = DSGRN.MorseGraph(domaingraph, morsedecomposition) for i in range(0, morsedecomposition.poset().size()): if morsegraph.annotation(i)[0] in ["FC", "XC"] and len( morsedecomposition.poset().children(i)) == 0: searchgraph = DSGRN.SearchGraph(domaingraph, i) matchinggraph = DSGRN.MatchingGraph(searchgraph, patterngraph) if DSGRN.CycleMatch(matchinggraph): if count: numparams += 1 break else: return True return numparams if count else False
# sampling a special parameter node sampler = DSGRN.ParameterSampler(EMT_network) sampler.sample(special_parameternode) isFP = lambda morse_node: morse_graph.annotation(morse_node)[0].startswith('FP' ) monostable_FP_parameters = [] bistable_FP_parameters = [] multistable_FP_parameters = [] good_candidate = [] for par_index in range(10): # parameter_graph_EMT.size() parameter = parameter_graph_EMT.parameter(par_index) domain_graph = DSGRN.DomainGraph(parameter) morse_graph = DSGRN.MorseGraph(domain_graph) morse_nodes = range(morse_graph.poset().size()) num_stable_FP = sum(1 for node in morse_nodes if isFP(node)) if num_stable_FP == 1: monostable_FP_parameters.append(par_index) adjacent_nodes = parameter_graph_EMT.adjacencies(par_index) for adjacent in adjacent_nodes: parameter_adjacent = parameter_graph_EMT.parameter(adjacent) domain_graph_adjacent = DSGRN.DomainGraph(parameter_adjacent) morse_graph = DSGRN.MorseGraph(domain_graph_adjacent) morse_nodes_adjacent = range(morse_graph.poset().size()) num_stable_FP_adjacent = sum(1 for node in morse_nodes_adjacent if isFP(node)) if num_stable_FP_adjacent == 2: good_candidate.append((par_index, adjacent))
def DSGRN_Computation(parameter): dg = DSGRN.DomainGraph(parameter) md = DSGRN.MorseDecomposition(dg.digraph()) mg = DSGRN.MorseGraph(dg, md) return [mg.annotation(i)[0] for i in range(0, mg.poset().size()) if is_FP(mg.annotation(i)[0]) and len(mg.poset( ).children(i)) == 0]
def AnalyzeParameter(self, parameterindex): parameter = self.parametergraph.parameter(parameterindex) dg = DSGRN.DomainGraph(parameter) md = DSGRN.MorseDecomposition(dg.digraph()) mg = DSGRN.MorseGraph(dg, md) return mg