def scaling_callback_animation(callbackresults, alpha, Bstar_inv, ncra, ncca, num_vertices, num_edges, TG, template, g, cfiles): frames = [] frames_append = frames.append for l in callbackresults: X, fX = l uc_params = X[0:6] rc_a, rc_b, rc_c, rc_alpha, rc_beta, rc_gamma = uc_params rc_covars = np.array(X[6:]) rc_covars = rc_covars.reshape(ncra, ncca) rc_Alpha = np.r_[alpha[0:num_edges - num_vertices + 1, :], rc_covars] rc_omega_plus = np.dot(Bstar_inv, rc_Alpha) rc_coords = omega2coords(TG, rc_omega_plus, uc_params, num_vertices, template, g, cfiles) ax_rc = rc_a ay_rc = 0.0 az_rc = 0.0 bx_rc = rc_b * np.cos(rc_gamma * pi / 180.0) by_rc = rc_b * np.sin(rc_gamma * pi / 180.0) bz_rc = 0.0 cx_rc = rc_c * np.cos(rc_beta * pi / 180.0) cy_rc = (rc_c * rc_b * np.cos(rc_alpha * pi / 180.0) - bx_rc * cx_rc) / by_rc cz_rc = (rc_c**2.0 - cx_rc**2.0 - cy_rc**2.0)**0.5 rc_unit_cell = np.asarray([[ax_rc, ay_rc, az_rc], [bx_rc, by_rc, bz_rc], [cx_rc, cy_rc, cz_rc]]).T frames_append([rc_coords, rc_unit_cell]) return frames
sc_omega_plus = np.dot(Bstar_inv, sc_Alpha) ax = sc_a ay = 0.0 az = 0.0 bx = sc_b * np.cos(sc_gamma * pi / 180.0) by = sc_b * np.sin(sc_gamma * pi / 180.0) bz = 0.0 cx = sc_c * np.cos(sc_beta * pi / 180.0) cy = (sc_c * sc_b * np.cos(sc_alpha * pi / 180.0) - bx * cx) / by cz = (sc_c**2.0 - cx**2.0 - cy**2.0)**0.5 sc_unit_cell = np.asarray([[ax, ay, az], [bx, by, bz], [cx, cy, cz]]).T scaled_coords = omega2coords( TG, sc_omega_plus, (sc_a, sc_b, sc_c, sc_alpha, sc_beta, sc_gamma), num_vertices, template, g, WRITE_CHECK_FILES) nvecs, evecs = scaled_node_and_edge_vectors( scaled_coords, sc_omega_plus, sc_unit_cell, ea_dict) placed_nodes, node_bonds = place_nodes( nvecs, CHARGES, ORIENTATION_DEPENDENT_NODES) placed_edges, edge_bonds = place_edges(evecs, CHARGES, len(placed_nodes)) if RECORD_CALLBACK: vnames = '_'.join([v.split('.')[0] for v in v_set]) if len(ea) <= 5: enames = '_'.join([e[0:-4] for e in ea]) else:
def run_template(template): print() print('=========================================================================================================') print('template :',template) print('=========================================================================================================') print() cat_count = 0 for net in ct2g(template): cat_count += 1 TG, start, unit_cell, TVT, TET, TNAME, a, b, c, ang_alpha, ang_beta, ang_gamma, max_le, catenation = net TVT = sorted(TVT, key=lambda x:x[0], reverse=True) TET = sorted(TET, reverse=True) node_cns = [(cncalc(node, 'nodes', ONE_ATOM_NODE_CN), node) for node in os.listdir('nodes')] print('Number of vertices = ', len(TG.nodes())) print('Number of edges = ', len(TG.edges())) print() if PRINT: print('There are', len(TG.nodes()), 'vertices in the voltage graph:') print() v = 0 for node in TG.nodes(): v += 1 print(v,':',node) node_dict = TG.node[node] print('type : ', node_dict['type']) print('cartesian coords : ', node_dict['ccoords']) print('fractional coords : ', node_dict['fcoords']) print('degree : ', node_dict['cn'][0]) print() print('There are', len(TG.edges()), 'edges in the voltage graph:') print() for edge in TG.edges(data=True,keys=True): edge_dict = edge[3] ind = edge[2] print(ind,':',edge[0],edge[1]) print('length : ',edge_dict['length']) print('type : ',edge_dict['type']) print('label : ',edge_dict['label']) print('positive direction :',edge_dict['pd']) print('cartesian coords : ',edge_dict['ccoords']) print('fractional coords : ',edge_dict['fcoords']) print() vas = vertex_assign(TG, TVT, node_cns, unit_cell, ONE_ATOM_NODE_CN, USER_SPECIFIED_NODE_ASSIGNMENT, SYMMETRY_TOL, ALL_NODE_COMBINATIONS) CB,CO = cycle_cocyle(TG) for va in vas: if len(va) == 0: print('At least one vertex does not have a building block with the correct number of connection sites.') print('Moving to the next template...') print() continue if len(CB) != (len(TG.edges()) - len(TG.nodes()) + 1): print('The cycle basis is incorrect.') print('The number of cycles in the cycle basis does not equal the rank of the cycle space.') print('Moving to the next tempate...') continue num_edges = len(TG.edges()) Bstar, alpha = Bstar_alpha(CB,CO,TG,num_edges) if PRINT: print('B* (top) and alpha (bottom) for the barycentric embedding are:') print() for i in Bstar: print(i) print() for i in alpha: print(i) print() num_vertices = len(TG.nodes()) if COMBINATORIAL_EDGE_ASSIGNMENT: eas = list(itertools.product([e for e in os.listdir('edges')], repeat = len(TET))) else: edge_files = sorted([e for e in os.listdir('edges')]) eas = [] i = 0 while len(eas) < len(TET): eas.append(edge_files[i]) i += 1 if i == len(edge_files): i = 0 eas = [eas] g = 0 for va in vas: node_elems = [bbelems(i[1], 'nodes') for i in va] metals = [[i for i in j if i in metal_elements] for j in node_elems] metals = list(set([i for j in metals for i in j])) v_set = [('v' + str(vname_dict[re.sub('[0-9]','',i[0])]), i[1]) for i in va] v_set = sorted(list(set(v_set)), key=lambda x: x[0]) v_set = [v[0] + '-' + v[1] for v in v_set] print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') print('vertex assignment : ',v_set) print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') print() if SINGLE_METAL_MOFS_ONLY and len(metals) != 1: print(v_set, 'contains no metals or multiple metal elements, no cif will be written') print() continue for v in va: for n in TG.nodes(data=True): if v[0] == n[0]: n[1]['cifname'] = v[1] for ea in eas: g += 1 print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') print('edge assignment : ',ea) print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') print() type_assign = dict((k,[]) for k in sorted(TET, reverse=True)) for k,m in zip(TET,ea): type_assign[k] = m for e in TG.edges(data=True): ty = e[2]['type'] for k in type_assign: if ty == k or (ty[1],ty[0]) == k: e[2]['cifname'] = type_assign[k] ea_dict = assign_node_vecs2edges(TG, unit_cell, SYMMETRY_TOL) all_SBU_coords = SBU_coords(TG, ea_dict, CONNECTION_SITE_BOND_LENGTH) sc_a, sc_b, sc_c, sc_alpha, sc_beta, sc_gamma, sc_covar, Bstar_inv, max_length, callbackresults, ncra, ncca, scaling_data = scale(all_SBU_coords,a,b,c,ang_alpha,ang_beta,ang_gamma,max_le,num_vertices,Bstar,alpha,num_edges,FIX_UC,SCALING_ITERATIONS,PRE_SCALE,SCALING_CONVERGENCE_TOLERANCE,SCALING_STEP_SIZE) print('*******************************************') print('The scaled unit cell parameters are : ') print('*******************************************') print('a :', np.round(sc_a, 5)) print('b :', np.round(sc_b, 5)) print('c :', np.round(sc_c, 5)) print('alpha:', np.round(sc_alpha, 5)) print('beta :', np.round(sc_beta, 5)) print('gamma:', np.round(sc_gamma, 5)) print() for sc, name in zip((sc_a, sc_b, sc_c), ('a', 'b', 'c')): cflag = False if sc < 1.0: print('unit cell parameter', name, 'has collapsed during scaling!') print('try re-running with', name, 'fixed, with a larger value for PRE_SCALE, or with a higher SCALING_CONVERGENCE_TOLERANCE') print('no cif will be written') cflag = True if cflag: continue scaled_params = [sc_a,sc_b,sc_c,sc_alpha,sc_beta,sc_gamma] sc_Alpha = np.r_[alpha[0:num_edges-num_vertices+1,:], sc_covar] sc_omega_plus = np.dot(Bstar_inv, sc_Alpha) ax = sc_a ay = 0.0 az = 0.0 bx = sc_b * np.cos(sc_gamma * pi/180.0) by = sc_b * np.sin(sc_gamma * pi/180.0) bz = 0.0 cx = sc_c * np.cos(sc_beta * pi/180.0) cy = (sc_c * sc_b * np.cos(sc_alpha * pi/180.0) - bx * cx) / by cz = (sc_c ** 2.0 - cx ** 2.0 - cy ** 2.0) ** 0.5 sc_unit_cell = np.asarray([[ax,ay,az],[bx,by,bz],[cx,cy,cz]]).T scaled_coords = omega2coords(start, TG, sc_omega_plus, (sc_a,sc_b,sc_c,sc_alpha,sc_beta,sc_gamma), num_vertices, template, g, WRITE_CHECK_FILES) nvecs,evecs = scaled_node_and_edge_vectors(scaled_coords, sc_omega_plus, sc_unit_cell, ea_dict) placed_nodes, node_bonds = place_nodes(nvecs, CHARGES, ORIENTATION_DEPENDENT_NODES) placed_edges, edge_bonds = place_edges(evecs, CHARGES, len(placed_nodes)) if RECORD_CALLBACK: vnames = '_'.join([v.split('.')[0] for v in v_set]) if len(ea) <= 5: enames = '_'.join([e[0:-4] for e in ea]) else: enames = str(len(ea)) + '_edges' prefix = template[0:-4] + '_' + vnames + '_' + enames frames = scaling_callback_animation(callbackresults, alpha, Bstar_inv, ncra, ncca, num_vertices, num_edges, TG, template, g, False) write_scaling_callback_animation(frames, prefix) animate_objective_minimization(callbackresults, prefix) if PLACE_EDGES_BETWEEN_CONNECTION_POINTS: placed_edges = adjust_edges(placed_edges, placed_nodes, sc_unit_cell) placed_all = placed_nodes + placed_edges bonds_all = node_bonds + edge_bonds if WRITE_CHECK_FILES: write_check_cif(template, placed_nodes, placed_edges, g, scaled_params, sc_unit_cell) if SINGLE_ATOM_NODE or NODE_TO_NODE: placed_all,bonds_all = remove_Fr(placed_all,bonds_all) print('computing X-X bonds...') print() print('*******************************************') print('Bond formation : ') print('*******************************************') fixed_bonds, nbcount, bond_check = bond_connected_components(placed_all, bonds_all, sc_unit_cell, max_length, BOND_TOL, TRACE_BOND_MAKING, NODE_TO_NODE, EXPANSIVE_BOND_SEARCH, ONE_ATOM_NODE_CN) print('there were ', nbcount, ' X-X bonds formed') if bond_check: print('bond check passed') bond_check_code = '' else: print('bond check failed, attempting distance search bonding...') fixed_bonds, nbcount = distance_search_bond(placed_all, bonds_all, sc_unit_cell, 2.5, TRACE_BOND_MAKING) bond_check_code = '_BOND_CHECK' print('there were', nbcount, 'X-X bonds formed') print() if CHARGES: fc_placed_all, netcharge, onetcharge, rcb = fix_charges(placed_all) else: fc_placed_all = placed_all fixed_bonds = fix_bond_sym(fixed_bonds, placed_all, sc_unit_cell) if CHARGES: print('*******************************************') print('Charge information : ') print('*******************************************') print('old net charge :', np.round(onetcharge, 5)) print('rescaling magnitude :', np.round(rcb, 5)) remove_net = choice(range(len(fc_placed_all))) fc_placed_all[remove_net][4] -= np.round(netcharge, 4) print('new net charge (after rescaling):', np.sum([li[4] for li in fc_placed_all])) print() vnames = '_'.join([v.split('.')[0] for v in v_set]) if len(ea) <= 5: enames = [] for e in [e[0:-4] for e in ea]: if e not in enames: enames.append(e) enames = '_'.join(enames) else: enames = str(len(ea)) + '_edges' if catenation: cifname = template[0:-4] + '_' + vnames + '_' + enames + bond_check_code + '_' + 'CAT' + str(cat_count) + '.cif' else: cifname = template[0:-4] + '_' + vnames + '_' + enames + bond_check_code + '.cif' if WRITE_CIF: print('writing cif...') print() if len(cifname) > 255: cifname = cifname[0:241]+'_truncated.cif' write_cif(fc_placed_all, fixed_bonds, scaled_params, sc_unit_cell, cifname, CHARGES) if catenation and MERGE_CATENATED_NETS: print('merging catenated cifs...') cat_cifs = glob.glob('output_cifs/*_CAT*.cif') for comb in itertools.combinations(cat_cifs, cat_count): builds = [name[0:-9] for name in comb] print(set(builds)) if len(set(builds)) == 1: pass else: continue merge_catenated_cifs(comb, CHARGES) for cif in cat_cifs: os.remove(cif)