def make_script(self): console.debug_stdoutln(">gnuplots.py->LSQR_vs_TLS_Segments_All_Chains_Plot()") struct_id = self.tlsmd_analysis.struct.structure_id ## generate data and png paths basename = "%s_RESID" % (struct_id) self.set_basename(basename) ## prepare gnuplot script script = _LSQR_VS_TLS_SEGMENTS_ALL_CHAINS_TEMPLATE script = script.replace("<nparts>", str(conf.globalconf.nparts)) script = script.replace("<title>", "Least Squares Residual vs. Number of TLS Segments of %s" % (struct_id)) ## re-use the data files of LSQRvsNTLS from the individual ## graphs; to do this the filenames have to be re-constructed plist = [] for chain in self.tlsmd_analysis.iter_chains(): filename = "%s_CHAIN%s_RESID.txt" % (struct_id, chain.chain_id) x = '"%s" using 1:2 title "Chain %s" lw 3 with linespoints' % (filename, chain.chain_id) plist.append(x) script += "plot " + ",\\\n ".join(plist) + "\n" ## Make a thumbnail (half-size) version for the summary page script += "set term png font '%s,8' size 400,320 linewidth 0.5\n" % conf.GNUPLOT_FONT script += "set output 'summary.png'\n" script += "unset title; set ylabel 'Residual' offset 1; replot\n" console.stdoutln("GNUPLot: Saving summary.png") return script
def __detailed_path(self, V, D, P, T, hop_constraint): """Print out the path from the source vertex (vertex 0) to the destination vertex (end vertex) given the hop_constraint. """ num_vertex = len(D[0]) ## start at the destination vertex curr_v = num_vertex - 1 h = hop_constraint while curr_v >= 0: prev_vertex = P[h,curr_v] vertex_label = V[curr_v].ljust(20) if prev_vertex < 0: prev_vertex_label = "".ljust(20) else: prev_vertex_label = V[prev_vertex].ljust(20) edge = T[h][curr_v] if edge is not None: i, j, cost, frag_range, tlsdict = edge wr = cost / (j - i) edge_label = "(%3d,%3d,%6.3f,%s) %6.3f" % ( i, j, cost, frag_range, wr) else: edge_label = "" console.stdoutln( "%s %3d %10.4f %s %s" % ( vertex_label, h, D[h,curr_v], prev_vertex_label, edge_label)) curr_v = prev_vertex h -= 1
def align_source_target_chains(self): """Performs a sequence alginment folled by a structure alignment of the target chain to the source chain. The coordinates of the target chain is altered. """ alignment_score, chain1_equiv, chain2_equiv, = align_chains(self.chain, self.target_chain) self.srctgt_equiv = chain1_equiv sresult = SuperimposeChains(self.target_chain, self.chain, chain2_equiv, ["CA"]) self.chain.target_chain_sresult = sresult console.stdoutln("Structure Superposition RMSD: %6.2f" % (sresult.rmsd)) for atm in self.target_chain.iter_all_atoms(): atm.align_position = sresult.transform(atm.position) ## residue type mismatches in the sequence alignment of the fragments for frag1 in self.chain.iter_fragments(): try: frag2 = self.srctgt_equiv[frag1] except KeyError: continue if frag1.res_name != frag2.res_name: console.stdoutln("EEK! %s::%s != %s::%s" % ( frag1.fragment_id, frag1.res_name, frag2.fragment_id, frag2.res_name)) return alignment_score
def RecombineIndependentTLSSegments(analysis): console.endln() console.debug_stdoutln(">tlsmd_analysis->RecombineIndependentTLSSegments()") console.stdoutln("TLS SEGMENT RECOMBINATION") for chain in analysis.chains: ## E.g., chain="Segment(1:A, Res(ILE,16,A)...Res(SER,116,A))" cpartition_recombination.ChainPartitionRecombinationOptimization(chain)
def output_png(self): """Runs gnuplot. Expects self.plot_path and self.png_path to be set. """ script0 = self.make_script() ## if a basename is given, then write the GnuPlot script as a file console.stdoutln("GNUPLot: Saving %s" % (self.png_path)) ## set output size l = ['set term png font "%s" %d size %d,%d enhanced' % (self.font_path, self.font_size, self.width, self.height), 'set output "%s"' % (self.png_path), ''] script_png = "\n".join(l) + script0 ## write a gnuplot script open(self.plot_path, "w").write(script_png) ## run gnuplot self.run_gnuplot(script_png) ## XXX: hack svg output if conf.globalconf.use_svg == True: l = ['set term svg size %d %d dynamic fsize 12 enhanced' % (self.width, self.height), 'set output "%s"' % (self.svg_path), ''] script_svg = "\n".join(l) + script0 self.run_gnuplot(script_svg)
def prnt(self): console.stdoutln("TLS Motion Determination (TLSMD) Version %s" % (const.VERSION)) console.endln() console.kvformat("TLS PARAMETER FIT ENGINE", self.tls_model) console.kvformat("MIN_SUBSEGMENT_SIZE", self.min_subsegment_size) console.kvformat("ATOM B-FACTOR WEIGHT_MODEL", self.weight_model) console.kvformat("PROTEIN ATOMS CONSIDERED", self.include_atoms) console.endln()
def calc_include_atom(atm, reject_messages = False): """Filter out atoms from the model which will cause problems or cont contribute to the TLS analysis. """ if atm.position == None: return False if atm.occupancy < 0.1: if reject_messages == True: console.stdoutln("calc_include_atom(%s): rejected because of low occupancy" % (atm)) return False if atm.occupancy > 1.0: atm.occupancy = 1.0 console.stdoutln("calc_include_atom(%s): atom occupancy greator than 1.0; truncating" % (atm)) if numpy.trace(atm.get_U()) <= const.TSMALL: if reject_messages == True: console.stdoutln("calc_include_atom(%s): rejected because of small Uiso magnitude " % (atm)) return False elif conf.globalconf.include_atoms == "MAINCHAIN": if const.MAINCHAIN_ATOM_DICT.has_key(atm.name) is False: if reject_messages == True: console.stdoutln("calc_include_atom(%s): rejected non-mainchain atom" % (atm)) return False return True
def prnt_detailed_paths(self): """Debug """ hops = self.nparts if not self.minimized: return dest_j = len(self.V) - 1 for h in xrange(1, hops + 1): console.endln() console.stdoutln("MINIMIZATON VERTEX PATH FOR %d SEGMENTS" % (h)) console.stdoutln("NODE LABEL HOPS COST PREVIOUS NODE EDGE") self.__detailed_path(self.V, self.D, self.P, self.T, h)
def calc_superposition(self, tls): plist = [] msd = 0.0 segment = tls.segment for frag1 in segment.iter_fragments(): try: frag2 = self.srctgt_equiv[frag1] except KeyError: continue for name in const.SUPER_ATOMS: atm1 = frag1.get_atom(name) atm2 = frag2.get_atom(name) if atm1 == None or atm2 == None: console.stdoutln("EEK! No Equivalent Atom %s" % (atm1)) continue plist.append((atm1.position, atm2.align_position)) d = atm1.position - atm2.align_position msd += numpy.dot(d, d) rmsd_pre_alignment = math.sqrt(msd / len(plist)) tls.rmsd_pre_alignment = rmsd_pre_alignment sresult = Superposition.SuperimposePositions(plist) tls.sresult = sresult rotation = math.degrees(2.0 * math.acos(sresult.Q[0])) if rotation > 180.0: rotation = 360.0 - rotation fragstr = "%s:%s-%s" % (self.chain.chain_id, tls.frag_id1, tls.frag_id2) console.stdoutln( "TLS Group::%20s Num Atoms::%4d RMSD PRE ALIGN::%6.2f RMSD::%6.2f TRANSORM ROTATION::%6.2f" % (fragstr, len(plist), rmsd_pre_alignment, sresult.rmsd, rotation)) ## screw displacement vector vscrew = AtomMath.normalize( numpy.array([sresult.Q[1], sresult.Q[2], sresult.Q[3]], float)) console.stdoutln("superposition rotation vector: %s" % (vscrew)) tls.superposition_vscrew = vscrew * rotation ## fit the isotropic TLS model to the group evals, evecs = numpy.linalg.eig(tls.tls_group.itls_L) for i in (0, 1, 2): eval = evals[i] evec = evecs[i] lname = "L%d_eigen_val" % (i) if (eval * Constants.RAD2DEG2) < 1.0: continue ang = min(calc_angle(evec, vscrew), calc_angle(-evec, vscrew)) console.stdoutln("%s magnitude::%6.2f vector angle::%6.2f" % (lname, eval * Constants.RAD2DEG2, ang))
def prnt_detailed_paths(self): """Debug """ hops = self.nparts if not self.minimized: return dest_j = len(self.V) - 1 for h in xrange(1, hops + 1): console.endln() console.stdoutln("MINIMIZATON VERTEX PATH FOR %d SEGMENTS" % (h)) console.stdoutln( "NODE LABEL HOPS COST PREVIOUS NODE EDGE" ) self.__detailed_path(self.V, self.D, self.P, self.T, h)
def calc_superposition(self, tls): plist = [] msd = 0.0 segment = tls.segment for frag1 in segment.iter_fragments(): try: frag2 = self.srctgt_equiv[frag1] except KeyError: continue for name in SUPER_ATOMS: atm1 = frag1.get_atom(name) atm2 = frag2.get_atom(name) if atm1 == None or atm2 == None: console.stdoutln("EEK! No Equivalent Atom %s" % (atm1)) continue plist.append((atm1.position, atm2.align_position)) d = atm1.position - atm2.align_position msd += numpy.dot(d,d) rmsd_pre_alignment = math.sqrt(msd / len(plist)) tls.rmsd_pre_alignment = rmsd_pre_alignment sresult = Superposition.SuperimposePositions(plist) tls.sresult = sresult rotation = math.degrees(2.0 * math.acos(sresult.Q[0])) if rotation > 180.0: rotation = 360.0 - rotation fragstr = "%s:%s-%s" % (self.chain.chain_id, tls.frag_id1, tls.frag_id2) console.stdoutln( "TLS Group::%20s Num Atoms::%4d RMSD PRE ALIGN::%6.2f RMSD::%6.2f TRANSORM ROTATION::%6.2f" % ( fragstr, len(plist), rmsd_pre_alignment, sresult.rmsd, rotation)) ## screw displacement vector vscrew = AtomMath.normalize(numpy.array([sresult.Q[1],sresult.Q[2],sresult.Q[3]], float)) console.stdoutln("superposition rotation vector: %s" % (vscrew)) tls.superposition_vscrew = vscrew * rotation ## fit the isotropic TLS model to the group evals, evecs = numpy.linalg.eig(tls.tls_group.itls_L) for i in (0,1,2): eval = evals[i] evec = evecs[i] lname = "L%d_eigen_val" % (i) if (eval * Constants.RAD2DEG2) < 1.0: continue ang = min(calc_angle(evec, vscrew), calc_angle(-evec, vscrew)) console.stdoutln("%s magnitude::%6.2f vector angle::%6.2f" % ( lname, eval*Constants.RAD2DEG2, ang))
def IndependentTLSSegmentOptimization(analysis): """Performs the TLS graph minimization on all TLSGraphs. """ for chain in analysis.chains: isopt = independent_segment_opt.ISOptimization( chain, conf.globalconf.min_subsegment_size, conf.globalconf.nparts) isopt.run_minimization() if not isopt.minimized: continue console.endln() console.stdoutln("="*79) console.stdoutln("MINIMIZING CHAIN %s" % (chain)) isopt.prnt_detailed_paths() chain.partition_collection = isopt.construct_partition_collection(conf.globalconf.nparts) chain.partition_collection.struct = analysis.struct
def IsotropicADPDataSmoother(chain, num_smooth = 1): """Experimental data smoothing of temperature factors. """ console.endln() console.stdoutln("SMOOTHING CHAIN %s ADPs" % (chain.chain_id)) console.kvformat("SMOOTH WINDOW", 2 * num_smooth + 1) num_frags = len(chain) smooth_uiso = dict() ifrag_start = num_smooth ifrag_end = num_frags - num_smooth - 1 for ifrag in xrange(ifrag_start, ifrag_end + 1): smooth_frag = chain[ifrag] frag1 = chain[ifrag - num_smooth] frag2 = chain[ifrag + num_smooth] IT, IL, IS, IOrigin = IsotropicFitSegmentOutlierRejection( chain, frag1.fragment_id, frag2.fragment_id) for atm, uiso in TLS.iter_itls_uiso(smooth_frag.iter_all_atoms(), IT, IL, IS, IOrigin): smooth_uiso[atm] = uiso if ifrag == ifrag_start: for i in range(ifrag_start): smooth_frag = chain[i] for atm, uiso in TLS.iter_itls_uiso(smooth_frag.iter_all_atoms(), IT, IL, IS, IOrigin): smooth_uiso[atm] = uiso elif ifrag == ifrag_end: for i in range(ifrag_end + 1, num_frags): smooth_frag = chain[i] for atm, uiso in TLS.iter_itls_uiso(smooth_frag.iter_all_atoms(), IT, IL, IS, IOrigin): smooth_uiso[atm] = uiso for atm, uiso in smooth_uiso.iteritems(): atm.temp_factor = Constants.U2B * uiso atm.U = numpy.identity(3, float) * uiso
def IsotropicADPDataSmoother(chain, num_smooth=1): """Experimental data smoothing of temperature factors """ console.endln() console.stdoutln("SMOOTHING CHAIN %s ADPs" % (chain.chain_id)) conesole.kvformat("SMOOTH WINDOW", 2 * num_smooth + 1) num_frags = len(chain) smooth_uiso = dict() ifrag_start = num_smooth ifrag_end = num_frags - num_smooth - 1 for ifrag in xrange(ifrag_start, ifrag_end + 1): smooth_frag = chain[ifrag] frag1 = chain[ifrag - num_smooth] frag2 = chain[ifrag + num_smooth] IT, IL, IS, IOrigin = IsotropicFitSegmentOutlierRejection( chain, frag1.fragment_id, frag2.fragment_id) for atm, uiso in TLS.iter_itls_uiso(smooth_frag.iter_all_atoms(), IT, IL, IS, IOrigin): smooth_uiso[atm] = uiso if ifrag == ifrag_start: for i in range(ifrag_start): smooth_frag = chain[i] for atm, uiso in TLS.iter_itls_uiso( smooth_frag.iter_all_atoms(), IT, IL, IS, IOrigin): smooth_uiso[atm] = uiso elif ifrag == ifrag_end: for i in range(ifrag_end + 1, num_frags): smooth_frag = chain[i] for atm, uiso in TLS.iter_itls_uiso( smooth_frag.iter_all_atoms(), IT, IL, IS, IOrigin): smooth_uiso[atm] = uiso for atm, uiso in smooth_uiso.iteritems(): atm.temp_factor = Constants.U2B * uiso atm.U = numpy.identity(3, float) * uiso
def IsotropicFitSegmentOutlierRejection(chain, frag_id1, frag_id2): segment = chain[frag_id1:frag_id2] atoms = list(segment.iter_all_atoms()) orig_num_atoms = len(atoms) rejected = 0 while True: tls_analyzer = tlsmdmodule.TLSModelAnalyzer() xlist = atom_selection.chain_to_xmlrpc_list(iter(atoms)) tls_analyzer.set_xmlrpc_chain(xlist) tlsdict = tls_analyzer.isotropic_fit_segment(frag_id1, frag_id2) IT, IL, IS, IOrigin = tls_calcs.isotlsdict2tensors(tlsdict) num_atoms = 0 msd_sum = 0.0 atm_deltab = [] for atm, uiso in TLS.iter_itls_uiso(iter(atoms), IT, IL, IS, IOrigin): num_atoms += 1 deltab = atm.temp_factor - (Constants.U2B * uiso) msd_sum += deltab**2 atm_deltab.append((deltab, atm)) sigma = math.sqrt((msd_sum / num_atoms)) sigma2 = 2.0 * sigma outliers = 0 for deltab, atm in atm_deltab: if abs(deltab) > sigma2: atoms.remove(atm) outliers += 1 rejected += outliers if outliers == 0 or (num_atoms - outliers) < 10: console.stdoutln("SEGMENT %s-%s %d->%d" % (frag_id1, frag_id2, orig_num_atoms, orig_num_atoms - rejected)) return IT, IL, IS, IOrigin
def IsotropicFitSegmentOutlierRejection(chain, frag_id1, frag_id2): segment = chain[frag_id1:frag_id2] atoms = list(segment.iter_all_atoms()) orig_num_atoms = len(atoms) rejected = 0 while True: tls_analyzer = tlsmdmodule.TLSModelAnalyzer() xlist = atom_selection.chain_to_xmlrpc_list(iter(atoms)) tls_analyzer.set_xmlrpc_chain(xlist) tlsdict = tls_analyzer.isotropic_fit_segment(frag_id1, frag_id2) IT, IL, IS, IOrigin = tls_calcs.isotlsdict2tensors(tlsdict) num_atoms = 0 msd_sum = 0.0 atm_deltab = [] for atm, uiso in TLS.iter_itls_uiso(iter(atoms), IT, IL, IS, IOrigin): num_atoms += 1; deltab = atm.temp_factor - (Constants.U2B * uiso) msd_sum += deltab**2 atm_deltab.append((deltab, atm)) sigma = math.sqrt((msd_sum / num_atoms)) sigma2 = 2.0 * sigma outliers = 0 for deltab, atm in atm_deltab: if abs(deltab) > sigma2: atoms.remove(atm) outliers += 1 rejected += outliers if outliers == 0 or (num_atoms - outliers) < 10: console.stdoutln("SEGMENT %s-%s %d->%d" % ( frag_id1, frag_id2, orig_num_atoms, orig_num_atoms - rejected)) return IT, IL, IS, IOrigin
def calc_include_atom(atm, reject_messages=False): """Filter out atoms from the model which will cause problems or can not contribute to the TLS analysis. """ if atm.position == None: return False if atm.occupancy < 0.1: if reject_messages == True: msg = "rejected because of low occupancy" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) return False if atm.occupancy > 1.0: ## FIXME: Does this really work? 2009-07-15 atm.occupancy = 1.0 msg = "atom occupancy greator than 1.0; truncating" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) ## FIXME: Figure out how to keep these .999, 2008-12-23 if atm.occupancy == .999: #atm.occupancy = 1.0 msg = "atom occupancy is .999" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) if numpy.trace(atm.get_U()) <= const.TSMALL: if reject_messages == True: msg = "rejected because of small Uiso magnitude" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) return False elif conf.globalconf.include_atoms == "MAINCHAIN": if const.MAINCHAIN_ATOM_DICT.has_key(atm.name) is False: if reject_messages == True: msg = "rejected non-mainchain atom" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) return False return True
def LoadStructure(struct_source): """Loads Structure, chooses a unique struct_id string. Also, search the REMARK records for TLS group records. If they are found, then add the TLS group ADP magnitude to the B facors of the ATOM records. """ ## determine the argument type if isinstance(struct_source, str): file_path = struct_source console.kvformat("LOADING STRUCTURE", file_path) fobj = open(file_path, "r") elif hasattr(struct_source, "__iter__") and hasattr(struct_source, "seek"): console.kvformat("LOADING STRUCTURE", str(struct_source)) fobj = struct_source else: raise ValueError ## load struct struct = FileIO.LoadStructure(file = fobj, distance_bonds = True) console.kvformat("HEADER", struct.header) console.kvformat("TITLE", struct.title) console.kvformat("EXPERIMENTAL METHOD", struct.experimental_method) ## set the structure ID if conf.globalconf.struct_id is not None: struct_id = conf.globalconf.struct_id else: struct_id = struct.structure_id conf.globalconf.struct_id = struct_id struct.structure_id = struct_id console.endln() ## if there are REFMAC5 TLS groups in the REMARK records of ## the PDB file, then add those in tls_file = TLS.TLSFile() tls_file.set_file_format(TLS.TLSFileFormatPDB()) ## return to the beginning of the file and read the REMARK/TLS records fobj.seek(0) tls_file.load(fobj) if len(tls_file.tls_desc_list) > 0: console.stdoutln("ADDING TLS GROUP Bequiv TO ATOM TEMPERATURE FACTORS") console.stdoutln(" NUM TLS GROUPS: %d" % (len(tls_file.tls_desc_list))) ## assume REFMAC5 groups where Utotal = Utls + Biso(temp_factor) for tls_desc in tls_file.tls_desc_list: tls_group = tls_desc.construct_tls_group_with_atoms(struct) console.stdoutln(" TLS GROUP: %s" % (tls_group.name)) for atm, Utls in tls_group.iter_atm_Utls(): bresi = atm.temp_factor atm.temp_factor = bresi + (Constants.U2B * numpy.trace(Utls) / 3.0) atm.U = (Constants.B2U * bresi * numpy.identity(3, float)) + Utls console.endln() return struct
def calc_include_atom(atm, reject_messages = False): """Filter out atoms from the model which will cause problems or can not contribute to the TLS analysis. """ if atm.position == None: return False if atm.occupancy < 0.1: if reject_messages == True: msg = "rejected because of low occupancy" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) return False if atm.occupancy > 1.0: ## FIXME: Does this really work? 2009-07-15 atm.occupancy = 1.0 msg = "atom occupancy greator than 1.0; truncating" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) ## FIXME: Figure out how to keep these .999, 2008-12-23 if atm.occupancy == .999: #atm.occupancy = 1.0 msg = "atom occupancy is .999" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) if numpy.trace(atm.get_U()) <= const.TSMALL: if reject_messages == True: msg = "rejected because of small Uiso magnitude" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) return False elif conf.globalconf.include_atoms == "MAINCHAIN": if const.MAINCHAIN_ATOM_DICT.has_key(atm.name) is False: if reject_messages == True: msg = "rejected non-mainchain atom" console.stdoutln("calc_include_atom(%s): %s" % (atm, msg)) return False return True
def prnt_detailed_paths(self): """Prints out detailed information on the minimization of each vertex path for n segments with Node Label, Hops, Cost, Previous Node, and Edge. """ hops = self.nparts if not self.minimized: return dest_j = len(self.V) - 1 for h in xrange(1, hops + 1): console.endln() console.stdoutln("MINIMIZATON VERTEX PATH FOR %d SEGMENTS" % (h)) header = "NODE LABEL" + " "*14 # V: "V50[C-TERM]" header += "HOPS" + " "*6 # D: "1" header += "COST" + " "*6 # P: "0.0943" header += "PREVIOUS NODE" + " "*10 # T: "V0[N-TERM]" header += "EDGE" # h: "(0, 50, 0.094,('1', '50')) 0.002" console.stdoutln(header) self.__detailed_path(self.V, self.D, self.P, self.T, h)
def TLSMD_Main(struct_file_path = None, sel_chain_ids = None, html_report_dir = None): ## create the analysis processor and load the structure, select chains analysis = TLSMDAnalysis( struct_file_path = struct_file_path, sel_chain_ids = sel_chain_ids, struct2_file_path = conf.globalconf.target_struct_path, struct2_chain_id = conf.globalconf.target_struct_chain_id) IndependentTLSSegmentOptimization(analysis) RecombineIndependentTLSSegments(analysis) if analysis.struct2_file_path is not None and analysis.struct2_chain_id is not None: SumperimposeHomologousStructure(analysis) if html_report_dir is not None and analysis.num_chains() > 0: FitConstrainedTLSModel(analysis) report = html.HTMLReport(analysis) report.write(html_report_dir) console.stdoutln("="*79) console.stdoutln("TLSMD Exiting Normally")
def IndependentTLSSegmentOptimization(analysis): """Performs the TLS graph minimization on all TLSGraphs. """ for chain in analysis.chains: isopt = independent_segment_opt.ISOptimization( chain, conf.globalconf.min_subsegment_size, conf.globalconf.nparts) ## TODO: Divide this into two CPU times, 2009-12-10 #console.stdoutln("CPU_TIME ->ISOptResidualGraph: %s" % time.clock()) isopt.run_minimization() if not isopt.minimized: continue console.endln() console.stdoutln("="*79) console.debug_stdoutln(">tlsmd_analysis->IndependentTLSSegmentOptimization()") console.stdoutln("MINIMIZING CHAIN %s" % (chain)) isopt.prnt_detailed_paths() chain.partition_collection = isopt.construct_partition_collection(conf.globalconf.nparts) chain.partition_collection.struct = analysis.struct
def SumperimposeHomologousStructure(analysis): """ """ import structcmp target_struct = FileIO.LoadStructure(fil = analysis.struct2_file_path) target_chain = target_struct.get_chain(analysis.struct2_chain_id) if target_chain is None: console.stderrln( "UNABLE TO LOAD TARGET STRUCTURE/CHAIN: %s:%s" % ( target_struct, target_chain)) return analysis.target_chain = target_chain for chain in analysis.iter_chains(): console.endln() console.kvformat("Superimposing Chain", chain.chain_id) hyp = structcmp.TLSConformationPredctionHypothosis(chain, target_chain) for ntls, cpartition in chain.partition_collection.iter_ntls_chain_partitions(): console.endln() console.stdoutln("Number of TLS Segments........: %d" % (ntls)) hyp.add_conformation_prediction_to_chain_partition(cpartition)
def FitConstrainedTLSModel(analysis): """Calculates constrained TLS model for visualization. """ console.endln() console.debug_stdoutln(">tlsmd_analysis->FitConstrainedTLSModel()") console.stdoutln("CALCULATING CONSTRAINED TLS MODEL FOR VISUALIZATION") ## EAM Feb 2008 User job was getting stuck in fit_to_chain() ## Obviously it would be nice to fix the actual error, but at least we would ## like to be able to give it a swift non-fatal kick by sending SIGUSR1 signal.signal(signal.SIGUSR1, SIGUSR1_handler) ## Progress tracking ## - assume this portion of the run occupies 0.1 -> 0.5 of the total time progress = 0.1 for chain in analysis.iter_chains(): console.stdoutln("CHAIN %s" % (chain.chain_id)) for cpartition in chain.partition_collection.iter_chain_partitions(): ## cpartition.chain = "Segment(1:A, Res(MET,1,A)...Res(VAL,50,A))" console.stdoutln("TLS GROUPS: %d" % (cpartition.num_tls_segments())) for tls in cpartition.iter_tls_segments(): try: tls.fit_to_chain(cpartition.chain) ## TODO: Write out data for residual plots. #gp = gnuplots.LSQR_vs_TLS_Segments_Pre_Plot(cpartition.chain) #console.stdoutln("FIT_TO_CHAIN_PATH: %s" % analysis.struct2_file_path) except (RuntimeError, numpy.linalg.linalg.LinAlgError), e: msg = " Runtime error for [%s]: %s, " % ( tls, e) msg += "trying to continue..." console.stdoutln(msg) print console.formatExceptionInfo() pass ## Track progress progress += 0.4/analysis.num_chains() progress_report = open("progress","w+") print >> progress_report, progress ## progress_report.write(progress) progress_report.close()
def FitConstrainedTLSModel(analysis): """ """ console.endln() console.stdoutln("CALCULATING CONSTRAINED TLS MODEL FOR VISUALIZATION") for chain in analysis.iter_chains(): console.stdoutln("CHAIN %s" % (chain.chain_id)) for cpartition in chain.partition_collection.iter_chain_partitions(): console.stdoutln("TLS GROUPS: %d" % (cpartition.num_tls_segments())) for tls in cpartition.iter_tls_segments(): tls.fit_to_chain(cpartition.chain) console.endln()
def calc_include_atom(atm, reject_messages=False): """Filter out atoms from the model which will cause problems or cont contribute to the TLS analysis. """ if atm.position == None: return False if atm.occupancy < 0.1: if reject_messages == True: console.stdoutln( "calc_include_atom(%s): rejected because of low occupancy" % (atm)) return False if atm.occupancy > 1.0: atm.occupancy = 1.0 console.stdoutln( "calc_include_atom(%s): atom occupancy greator than 1.0; truncating" % (atm)) if numpy.trace(atm.get_U()) <= const.TSMALL: if reject_messages == True: console.stdoutln( "calc_include_atom(%s): rejected because of small Uiso magnitude " % (atm)) return False elif conf.globalconf.include_atoms == "MAINCHAIN": if const.MAINCHAIN_ATOM_DICT.has_key(atm.name) is False: if reject_messages == True: console.stdoutln( "calc_include_atom(%s): rejected non-mainchain atom" % (atm)) return False return True
def align_chains(chain1, chain2): """Adds a .equiv attribute to each fragment of the chain referencing the equivalent fragment in the other chain. """ console.stdoutln("Chain Alignment") seq1 = chain1.calc_sequence_one_letter_code() console.stdoutln("Length of Chain 1: %d" % (len(seq1))) seq2 = chain2.calc_sequence_one_letter_code() console.stdoutln("Length of Chain 2: %d" % (len(seq2))) align = pairwise2.align.globalxs(seq1, seq2, -0.5, -0.125) console.stdoutln(align[0]) seq1_align = align[0][0] seq2_align = align[0][1] iter1 = chain1.iter_fragments() iter2 = chain2.iter_fragments() chain1_equiv = {} chain2_equiv = {} for i in xrange(len(seq1_align)): frag1 = None frag2 = None if seq1_align[i] != '-': frag1 = iter1.next() if seq2_align[i] != '-': frag2 = iter2.next() if frag1 and frag2: chain1_equiv[frag1] = frag2 chain2_equiv[frag2] = frag1 return align[0], chain1_equiv, chain2_equiv
def output_png(self): """Runs gnuplot. Expects self.plot_path and self.png_path to be set. """ ## if a basename is given, then write the GnuPlot script as a file script0 = self.make_script() ## this is only for the log file if not re.match(r".*CHAIN.*", self.png_path): console.stdoutln("GNUPLot: Saving %s" % self.png_path) elif re.match(r".*NTLS.*", self.png_path): chain_seg = re.sub(r"^.{1,}_CHAIN([A-Za-z0-9])_NTLS([0-9]{1,2})_.*\.png$", "\\1,\\2", self.png_path) console.stdoutln("[%s] GNUPLot: Saving %s" % (chain_seg, self.png_path)) else: chain_id = re.sub(r"^.{1,}_CHAIN([A-Za-z0-9])_.*\.png$", "\\1", self.png_path) console.stdoutln("[%s,0] GNUPLot: Saving %s" % (chain_id, self.png_path)) ## set output size l = [ 'set term png font "%s,%d" size %d,%d enhanced' % (self.font_path, self.font_size, self.width, self.height), 'set output "%s"' % (self.png_path), "", ] script_png = "\n".join(l) + script0 ## write a gnuplot script open(self.plot_path, "w").write(script_png) ## run gnuplot self.run_gnuplot(script_png) ## XXX: hack svg output if conf.globalconf.use_svg == True: l = [ 'set term svg size %d %d fixed fsize 12 enhanced mouse jsdir "/gnuplot"' % (self.width, self.height), 'set output "%s"' % (self.svg_path), "", ] script_svg = "\n".join(l) + script0 self.run_gnuplot(script_svg)
def ChainPartitionRecombinationOptimization(chain): console.debug_stdoutln( ">cpartition_recombination->ChainPartitionRecombinationOptimization()") visited = {} ntls_best = {} orig_best = {} for ntls, cpartition in chain.partition_collection.iter_ntls_chain_partitions( ): ntls_best[ntls] = cpartition orig_best[ntls] = cpartition ## DEBUG: Example output: #for k,v in cpartition.iteritems(): console.stdoutln("cpartition=%s : %s"%(k,v)) ## ntls_best=[1, 2, 3, 4] ## orig_best=[1, 2, 3, 4] ## ntls_best{KEYS : VALUES}= ## 1 : (A:1-50) ## 2 : (A:1-37)(A:38-50) ## 3 : (A:1-9)(A:21-30)(A:31-50) ## 4 : (A:1-9)(A:21-30)(A:31-37)(A:38-50) ## orig_best{KEYS : VALUES}= ## 1 : (A:1-50) ## 2 : (A:1-37)(A:38-50) ## 3 : (A:1-9)(A:21-30)(A:31-50) ## 4 : (A:1-9)(A:21-30)(A:31-37)(A:38-50) for ntls, cpartition in chain.partition_collection.iter_ntls_chain_partitions( ): if ntls < 2: if float(cpartition.rmsd_b()) < 0.0: ## FIXME: This doesn't work yet, 2009-06-05 ## Why doesn't it? 2010-04-02 msg = "**** STOP! No need to continue. " msg += "Residual is already best for NTLS=%s ****" % ( cpartition.rmsd_b()) console.stdoutln("%s" % msg) break #console.stdoutln("TYPE: [%s] -> type(%s); float(%s)" % ( # cpartition.rmsd_b(), type(cpartition.rmsd_b()), # float(cpartition.rmsd_b()))) console.stdoutln("RMSD-%sc: %s" % (ntls, cpartition.rmsd_b())) console.stdoutln("RESIDUAL-%sc: %s" % (ntls, cpartition.residual())) continue ## No recombination needed for a single ntls group console.stdoutln("=" * 80) ## LOGLINE console.stdoutln("%d INTO %d TO 2" % (ntls, ntls - 1)) ## LOGLINE search_width = 1 search_depth = 1 proot = tree.Tree() proot.cp = cpartition while True: ExtendRecombinationTree(proot, search_depth, search_width) ## NOTE (by Christoph): ## It seems max_depth is always either "1" or "0" (integers) ## E.g., for "4 INTO 3 TO 2", we would have {1,1,1,0} max_depth = proot.depth() best_at_depth = None for depth, ptree in proot.iter_depth_first(): ## NOTE (by Christoph): E.g., ## ptree.cp = "(A:16-26)(A:27-61)(A:62-74; 95-116)(A:75-94)" ## ptree.cp.residual_delta = "0.00150017006854" if depth == max_depth: if best_at_depth is None or \ ptree.cp.residual_delta < best_at_depth.cp.residual_delta: best_at_depth = ptree tmp_ntls = ptree.cp.num_tls_segments() ## (integer value) if not visited.has_key(ptree): visited[ptree] = True if ntls_best.has_key(tmp_ntls): ## E.g., ntls_best[tmp_ntls] = "(A:16-74; 95-116)(A:75-94)" best_rmsd = "%5.2f" % (ntls_best[tmp_ntls].rmsd_b()) else: best_rmsd = "-----" ## E.g., "(A:2-11; 18-23; 39-52; 58-95)(A:12-17; 24-38; 53-57) 5.42( 4.98) 2" console.stdoutln( "%s %5.2f(%s) %d" % (ptree.cp, ptree.cp.rmsd_b(), best_rmsd, tmp_ntls)) ## NOTE: Example output: ## cpartition="(A:1-9)(A:21-30)(A:31-50)" ## cpartition.chain.chain_id="A" ## cpartition.num_tls_segments()="7" ## table.StringTableFromMatrix(cpartition.rmsd_b_mtx)=" ## 1.19667217259 2.44700956714 2.44363045774 ## 2.44700956714 1.90000136951 2.93313261105 ## 2.44363045774 2.93313261105 1.76763623176" ## NOTE: The above are the same values found in ## 'xxxx_CHAINa_NTLSn_RECOMBINATION.txt' files ## segment_ranges = segment_ranges, ## residual = tlsdict["residual"], ## method = tls1.method, ## num_atoms = tlsdict["num_atoms"], ## num_residues = tlsdict["num_residues"]) if ntls_best.has_key(tmp_ntls): if ptree.cp.residual() < ntls_best[tmp_ntls].residual(): ## E.g., ptree.cp="(A:16-61)(A:62-74; 95-116)(A:75-94)" ntls_best[tmp_ntls] = ptree.cp else: ntls_best[tmp_ntls] = ptree.cp ptree = best_at_depth for i in xrange(max_depth - 1): ptree = ptree.parent() proot = ptree if search_depth > max_depth: break ## insert replacement ChainPartitions if conf.globalconf.recombination: for ntls, cpartition in ntls_best.iteritems(): cp = chain.partition_collection.get_chain_partition(ntls) if cp != cpartition: chain.partition_collection.insert_chain_partition(cpartition)
def jmol_animate_html(self, chain, cpartition): """Writes out the HTML page which will display the structure using the JMol Applet. """ basename = "%s_CHAIN%s_NTLS%d_ANIMATE" % (self.struct_id, chain.chain_id, cpartition.num_tls_segments()) html_path = "%s.html" % (basename) pdb_path = "%s.pdb" % (basename) ## generate animation PDB file try: console.stdoutln("TLSAnimate: creating animation PDB file...") tlsa = TLSAnimate(chain, cpartition) tlsa.construct_animation(pdb_path) except TLSAnimateFailure: pass ## create the JMol script using cartoons and consistant ## coloring to represent the TLS groups js = ['load %s;' % (pdb_path), 'select *;', 'cpk off;', 'wireframe off;', 'select protein;', 'trace on;'] ## loop over TLS groups and color for tls in cpartition.iter_tls_segments(): chain_ids = [tlsa.L1_chain.chain_id, tlsa.L2_chain.chain_id, tlsa.L3_chain.chain_id] for chain_id in chain_ids: js.append('select %s;' % (tls.jmol_select())) js.append('color [%d,%d,%d];' % (tls.color.rgbi)) ## select non-protein non-solvent and display js +=['select not protein and not solvent;', 'color CPK;', 'wireframe on;', 'wireframe 0.5;', 'spacefill 80%;', 'spacefill on;', 'anim fps 2;', 'anim mode loop 0 0;', 'anim on;'] ## write the HTML page to render the script in l = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">', '<html>', '<head>', '<title>Chain %s using %d TLS Groups</title>' % (chain.chain_id, cpartition.num_tls_segments()), '<script type="text/javascript" src="%s/Jmol.js">' % (settings.JMOL_DIR), '</script>', '</head>', '<body>', '<script type="text/javascript">', 'jmolInitialize("%s");' % (settings.JMOL_DIR), 'jmolSetAppletColor("white");', 'jmolApplet(%d, "%s");' % (settings.JMOL_SIZE, "".join(js)), '</script>', '</body>', '</html>'] ## manually free memory tlsa = None import gc gc.collect() open(html_path, "w").write("".join(l)) return html_path
def end_chain_timing(chain_id): console.stdoutln("END TIMING CHAIN %s %f" % (chain_id, time.time()))
def raster3d_render_tls_graph_path(self, chain, cpartition): """Render TLS visualizations using Raster3D. """ basename = "%s_CHAIN%s_NTLS%d" % (self.struct_id, chain.chain_id, cpartition.num_tls_segments()) png_path = "%s.png" % (basename) console.stdoutln("Raster3D: rendering %s..." % (basename)) struct_id = self.struct_id driver = R3DDriver.Raster3DDriver() ## XXX: Size hack: some structures have too many chains, ## or are just too large show_chain = {} for chx in self.struct.iter_chains(): if chx.chain_id == chain.chain_id: show_chain[chx.chain_id] = True continue if chx.count_amino_acids() >= 100: show_chain[chx.chain_id] = False continue show_chain[chx.chain_id] = True ## end size hack ## got target chain? if self.tlsmd_analysis.target_chain != None: for atm in self.tlsmd_analysis.target_chain.iter_all_atoms(): atm.orig_position = atm.position atm.position = chain.target_chain_sresult.transform( atm.position) viewer = Viewer.GLViewer() gl_struct = viewer.glv_add_struct(self.struct) ## orient the structure with the super-spiffy orientation algorithm ## which hilights the chain we are examining ori = calc_orientation(self.struct, chain) viewer.glo_update_properties(R=ori["R"], cor=ori["centroid"], zoom=ori["hzoom"], near=ori["near"], far=ori["far"], width=ori["pwidth"], height=ori["pheight"], bg_color="White") ## turn off axes and unit cell visualization gl_struct.glo_update_properties_path("gl_axes/visible", False) gl_struct.glo_update_properties_path("gl_unit_cell/visible", False) ## setup base structural visualization for gl_chain in gl_struct.glo_iter_children(): if not isinstance(gl_chain, Viewer.GLChain): continue ## chain is hidden if show_chain.get(gl_chain.chain.chain_id, False) == False: gl_chain.properties.update(visible=False) continue if gl_chain.chain.chain_id == chain.chain_id: if gl_chain.chain.has_amino_acids(): gl_chain.properties.update(lines=False, trace=True, trace_radius=0.25, trace_color="0.80,0.80,0.80") elif gl_chain.chain.has_nucleic_acids(): gl_chain.properties.update(lines=False, ball_stick=True, ball_stick_radius=0.25, color="0.80,0.80,0.80") else: if gl_chain.chain.has_amino_acids(): gl_chain.properties.update(lines=False, trace=True, trace_radius=0.25, trace_color="0.80,0.80,0.80") elif gl_chain.chain.has_nucleic_acids(): gl_chain.properties.update(hetatm_visible=True, trace=True, trace_radius=0.35, trace_color="0.80,0.80,0.80", ball_stick=True, ball_stick_radius=0.25, color="0.60,0.60,0.70") else: gl_chain.properties.update(visible=True, ball_stick=True, ball_stick_radius=0.25, cpk=False) ## add the TLS group visualizations has_amino_acids = cpartition.chain.has_amino_acids() has_nucleic_acids = cpartition.chain.has_nucleic_acids() for tls in cpartition.iter_tls_segments(): if tls.method != "TLS": continue if self.tlsmd_analysis.target_chain is not None: if tls.rmsd_pre_alignment <= 0.8: continue if (tls.rmsd_pre_alignment - tls.sresult.rmsd) < 0.5: continue tls_name = "TLS_%s" % (tls.filename_label()) gl_tls_group = TLS.GLTLSGroup(oatm_visible=False, side_chain_visible=False, hetatm_visible=True, adp_prob=settings.ADP_PROB, L_axis_scale=2.0, L_axis_radius=0.20, both_phases=True, tls_group=tls.tls_group, tls_info=tls.model_tls_info, tls_name=tls_name, tls_color=tls.color.name) gl_struct.glo_add_child(gl_tls_group) if tls.superposition_vscrew != None: gl_tls_group.properties.update( COR_vector=tls.superposition_vscrew) ## set width of trace according to the group's translationral tensor trace mtls_info = tls.model_tls_info tiso = (mtls_info["Tr1_eigen_val"] + mtls_info["Tr2_eigen_val"] + mtls_info["Tr3_eigen_val"]) / 3.0 ## too big usually for good visualization -- cheat and scale it down radius = 0.30 if has_amino_acids: gl_tls_group.gl_atom_list.properties.update( trace_radius=radius) elif has_nucleic_acids: gl_tls_group.gl_atom_list.properties.update( oatm_visible=True, side_chain_visible=True, trace=True, trace_radius=0.25, ball_stick=True, ball_stick_radius=radius) gl_tls_group.glo_update_properties(time=0.25) ## got target chain? if self.tlsmd_analysis.target_chain is not None: gl_chain = Viewer.GLChain(chain=self.tlsmd_analysis.target_chain) gl_chain.properties.update(oatm_visible=False, side_chain_visible=False, hetatm_visible=True, lines=False, ball_stick=False, trace=True, trace_radius=0.25, trace_color="0.40,0.40,0.40") gl_struct.glo_add_child(gl_chain) driver.glr_set_render_png_path(png_path) viewer.glv_render_one(driver) ## got target chain? if self.tlsmd_analysis.target_chain != None: for atm in self.tlsmd_analysis.target_chain.iter_all_atoms(): atm.position = atm.orig_position del atm.orig_position return "", png_path
def RefineChainPartitionPositions(cpartition): """Refines positions of the partition points of the given ChainPartition instance. """ partitions = ChainPartitionList(cpartition) console.stdoutln(partitions)
def begin_chain_timing(chain_id): console.stdoutln("BEGIN TIMING CHAIN %s %f" % (chain_id, time.time()))
def TLSMD_Main(struct_file_path = None, sel_chain_ids = None, html_report_dir = None): console.cpu_time_stdoutln("->Starting TLSMD analysis: %s" % time.clock()) ## create the analysis processor and load the structure, select chains analysis = TLSMDAnalysis( struct_file_path = struct_file_path, sel_chain_ids = sel_chain_ids, struct2_file_path = conf.globalconf.target_struct_path, struct2_chain_id = conf.globalconf.target_struct_chain_id) console.cpu_time_stdoutln("->LoadStructure: %s" % time.clock()) IndependentTLSSegmentOptimization(analysis) console.cpu_time_stdoutln("->IndependentTLSSegmentOptimization: %s" % ( time.clock())) RecombineIndependentTLSSegments(analysis) console.cpu_time_stdoutln("->RecombineIndependentTLSSegments: %s" % ( time.clock())) if analysis.struct2_file_path is not None and \ analysis.struct2_chain_id is not None: console.stdoutln("SUPERIMPOSING HOMOLOGOUS STRUCTURE") SuperimposeHomologousStructure(analysis) if html_report_dir is not None and analysis.num_chains() > 0: FitConstrainedTLSModel(analysis) ## generate summary page. Allows the user to see some information ## before the analysis is fully complete console.stdoutln("GENERATING SUMMARY PAGE") summary = html.HTMLSummaryReport(analysis) summary.write_summary(html_report_dir) console.cpu_time_stdoutln("->HTMLSummaryReport: %s" % time.clock()) if not conf.globalconf.skip_html: ## generate in-depth HTML report pages console.stdoutln("GENERATING ANALYSIS/REPORT HTML PAGES") report = html.HTMLReport(analysis) report.write(html_report_dir) ## TODO: Figure out a way to gzip all TXT files once TLSMD is done ## with them. 2010-09-24 #import fnmatch #import gzip #abs_report_path = "%s/%s/%s" % ( # conf.TLSMD_WORK_DIR, conf.globalconf.job_id, html_report_dir) #console.stdoutln("GZIP: Attempting to gzip all TXT files in: %s" % abs_report_path) #for path, dirs, files in os.walk(abs_report_path): # console.stdoutln("GZIP: report_dir = %s" % abs_report_path) # for f in files: # if fnmatch.fnmatch(f, '*.txt'): # console.stdoutln("GZIP: found a TXT file: %s" % f) # ## If we find a TXT file, gzip it # f_in = open('%s/%s' % (abs_report_path, f), 'rb') # f_out = gzip.open('%s/%s.gz' % (abs_report_path, f), 'wb') # f_out.writelines(f_in) # f_out.close() # f_in.close() # os.remove(f) console.cpu_time_stdoutln("->TLSMD::Total_time: %s" % time.clock())
def raster3d_render_tls_graph_path(self, chain, cpartition): """Render TLS visualizations using Raster3D. """ basename = "%s_CHAIN%s_NTLS%d" % (self.struct_id, chain.chain_id, cpartition.num_tls_segments()) png_path = "%s.png" % (basename) console.stdoutln( "Raster3D: rendering %s..." % (basename)) struct_id = self.struct_id driver = R3DDriver.Raster3DDriver() ## XXX: Size hack: some structures have too many chains, ## or are just too large show_chain = {} for chx in self.struct.iter_chains(): if chx.chain_id == chain.chain_id: show_chain[chx.chain_id] = True continue if chx.count_amino_acids() >= 100: show_chain[chx.chain_id] = False continue show_chain[chx.chain_id] = True ## end size hack ## got target chain? if self.tlsmd_analysis.target_chain != None: for atm in self.tlsmd_analysis.target_chain.iter_all_atoms(): atm.orig_position = atm.position atm.position = chain.target_chain_sresult.transform(atm.position) viewer = Viewer.GLViewer() gl_struct = viewer.glv_add_struct(self.struct) ## orient the structure with the super-spiffy orientation algorithm ## which hilights the chain we are examining ori = calc_orientation(self.struct, chain) viewer.glo_update_properties( R = ori["R"], cor = ori["centroid"], zoom = ori["hzoom"], near = ori["near"], far = ori["far"], width = ori["pwidth"], height = ori["pheight"], bg_color = "White") ## turn off axes and unit cell visualization gl_struct.glo_update_properties_path("gl_axes/visible", False) gl_struct.glo_update_properties_path("gl_unit_cell/visible", False) ## setup base structural visualization for gl_chain in gl_struct.glo_iter_children(): if not isinstance(gl_chain, Viewer.GLChain): continue ## chain is hidden if show_chain.get(gl_chain.chain.chain_id, False) == False: gl_chain.properties.update(visible = False) continue if gl_chain.chain.chain_id == chain.chain_id: if gl_chain.chain.has_amino_acids(): gl_chain.properties.update( lines = False, trace = True, trace_radius = 0.25, trace_color = "0.80,0.80,0.80") elif gl_chain.chain.has_nucleic_acids(): gl_chain.properties.update( lines = False, ball_stick = True, ball_stick_radius = 0.25, color = "0.80,0.80,0.80") else: if gl_chain.chain.has_amino_acids(): gl_chain.properties.update( lines = False, trace = True, trace_radius = 0.25, trace_color = "0.80,0.80,0.80") elif gl_chain.chain.has_nucleic_acids(): gl_chain.properties.update( hetatm_visible = True, trace = True, trace_radius = 0.35, trace_color = "0.80,0.80,0.80", ball_stick = True, ball_stick_radius = 0.25, color = "0.60,0.60,0.70") else: gl_chain.properties.update( visible = True, ball_stick = True, ball_stick_radius = 0.25, cpk = False) ## add the TLS group visualizations has_amino_acids = cpartition.chain.has_amino_acids() has_nucleic_acids = cpartition.chain.has_nucleic_acids() for tls in cpartition.iter_tls_segments(): if tls.method != "TLS": continue if self.tlsmd_analysis.target_chain is not None: if tls.rmsd_pre_alignment <= 0.8: continue if (tls.rmsd_pre_alignment - tls.sresult.rmsd) < 0.5: continue tls_name = "TLS_%s" % (tls.filename_label()) gl_tls_group = TLS.GLTLSGroup( oatm_visible = False, side_chain_visible = False, hetatm_visible = True, adp_prob = settings.ADP_PROB, L_axis_scale = 2.0, L_axis_radius = 0.20, both_phases = True, tls_group = tls.tls_group, tls_info = tls.model_tls_info, tls_name = tls_name, tls_color = tls.color.name) gl_struct.glo_add_child(gl_tls_group) if tls.superposition_vscrew != None: gl_tls_group.properties.update(COR_vector = tls.superposition_vscrew) ## set width of trace according to the group's translationral tensor trace mtls_info = tls.model_tls_info tiso = (mtls_info["Tr1_eigen_val"] + mtls_info["Tr2_eigen_val"] + mtls_info["Tr3_eigen_val"]) / 3.0 ## too big usually for good visualization -- cheat and scale it down radius = 0.30 if has_amino_acids: gl_tls_group.gl_atom_list.properties.update(trace_radius = radius) elif has_nucleic_acids: gl_tls_group.gl_atom_list.properties.update( oatm_visible = True, side_chain_visible = True, trace = True, trace_radius = 0.25, ball_stick = True, ball_stick_radius = radius) gl_tls_group.glo_update_properties(time = 0.25) ## got target chain? if self.tlsmd_analysis.target_chain is not None: gl_chain = Viewer.GLChain(chain = self.tlsmd_analysis.target_chain) gl_chain.properties.update( oatm_visible = False, side_chain_visible = False, hetatm_visible = True, lines = False, ball_stick = False, trace = True, trace_radius = 0.25, trace_color = "0.40,0.40,0.40") gl_struct.glo_add_child(gl_chain) driver.glr_set_render_png_path(png_path) viewer.glv_render_one(driver) ## got target chain? if self.tlsmd_analysis.target_chain != None: for atm in self.tlsmd_analysis.target_chain.iter_all_atoms(): atm.position = atm.orig_position del atm.orig_position return "", png_path
def RecombineIndependentTLSSegments(analysis): console.endln() console.stdoutln("TLS SEGMENT RECOMBINATION") for chain in analysis.chains: cpartition_recombination.ChainPartitionRecombinationOptimization(chain)
def jmol_animate_html(self, chain, cpartition): """Writes out the HTML page which will display the structure using the JMol Applet. """ basename = "%s_CHAIN%s_NTLS%d_ANIMATE" % ( self.struct_id, chain.chain_id, cpartition.num_tls_segments()) html_path = "%s.html" % (basename) pdb_path = "%s.pdb" % (basename) ## generate animation PDB file try: console.stdoutln("TLSAnimate: creating animation PDB file...") tlsa = TLSAnimate(chain, cpartition) tlsa.construct_animation(pdb_path) except TLSAnimateFailure: pass ## create the JMol script using cartoons and consistant ## coloring to represent the TLS groups js = [ 'load %s;' % (pdb_path), 'select *;', 'cpk off;', 'wireframe off;', 'select protein;', 'trace on;' ] ## loop over TLS groups and color for tls in cpartition.iter_tls_segments(): chain_ids = [ tlsa.L1_chain.chain_id, tlsa.L2_chain.chain_id, tlsa.L3_chain.chain_id ] for chain_id in chain_ids: js.append('select %s;' % (tls.jmol_select())) js.append('color [%d,%d,%d];' % (tls.color.rgbi)) ## select non-protein non-solvent and display js += [ 'select not protein and not solvent;', 'color CPK;', 'wireframe on;', 'wireframe 0.5;', 'spacefill 80%;', 'spacefill on;', 'anim fps 2;', 'anim mode loop 0 0;', 'anim on;' ] ## write the HTML page to render the script in l = [ '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">', '<html>', '<head>', '<title>Chain %s using %d TLS Groups</title>' % (chain.chain_id, cpartition.num_tls_segments()), '<script type="text/javascript" src="%s/Jmol.js">' % (settings.JMOL_DIR), '</script>', '</head>', '<body>', '<script type="text/javascript">', 'jmolInitialize("%s");' % (settings.JMOL_DIR), 'jmolSetAppletColor("white");', 'jmolApplet(%d, "%s");' % (settings.JMOL_SIZE, "".join(js)), '</script>', '</body>', '</html>' ] ## manually free memory tlsa = None import gc gc.collect() open(html_path, "w").write("".join(l)) return html_path
def ChainPartitionRecombinationOptimization(chain): console.debug_stdoutln(">cpartition_recombination->ChainPartitionRecombinationOptimization()") visited = {} ntls_best = {} orig_best = {} for ntls, cpartition in chain.partition_collection.iter_ntls_chain_partitions(): ntls_best[ntls] = cpartition orig_best[ntls] = cpartition ## DEBUG: Example output: #for k,v in cpartition.iteritems(): console.stdoutln("cpartition=%s : %s"%(k,v)) ## ntls_best=[1, 2, 3, 4] ## orig_best=[1, 2, 3, 4] ## ntls_best{KEYS : VALUES}= ## 1 : (A:1-50) ## 2 : (A:1-37)(A:38-50) ## 3 : (A:1-9)(A:21-30)(A:31-50) ## 4 : (A:1-9)(A:21-30)(A:31-37)(A:38-50) ## orig_best{KEYS : VALUES}= ## 1 : (A:1-50) ## 2 : (A:1-37)(A:38-50) ## 3 : (A:1-9)(A:21-30)(A:31-50) ## 4 : (A:1-9)(A:21-30)(A:31-37)(A:38-50) for ntls, cpartition in chain.partition_collection.iter_ntls_chain_partitions(): if ntls < 2: if float(cpartition.rmsd_b()) < 0.0: ## FIXME: This doesn't work yet, 2009-06-05 ## Why doesn't it? 2010-04-02 msg = "**** STOP! No need to continue. " msg += "Residual is already best for NTLS=%s ****" % ( cpartition.rmsd_b()) console.stdoutln("%s" % msg) break #console.stdoutln("TYPE: [%s] -> type(%s); float(%s)" % ( # cpartition.rmsd_b(), type(cpartition.rmsd_b()), # float(cpartition.rmsd_b()))) console.stdoutln("RMSD-%sc: %s" % (ntls, cpartition.rmsd_b())) console.stdoutln("RESIDUAL-%sc: %s" % (ntls, cpartition.residual())) continue ## No recombination needed for a single ntls group console.stdoutln("=" * 80) ## LOGLINE console.stdoutln("%d INTO %d TO 2" % (ntls, ntls - 1)) ## LOGLINE search_width = 1 search_depth = 1 proot = tree.Tree() proot.cp = cpartition while True: ExtendRecombinationTree(proot, search_depth, search_width) ## NOTE (by Christoph): ## It seems max_depth is always either "1" or "0" (integers) ## E.g., for "4 INTO 3 TO 2", we would have {1,1,1,0} max_depth = proot.depth() best_at_depth = None for depth, ptree in proot.iter_depth_first(): ## NOTE (by Christoph): E.g., ## ptree.cp = "(A:16-26)(A:27-61)(A:62-74; 95-116)(A:75-94)" ## ptree.cp.residual_delta = "0.00150017006854" if depth == max_depth: if best_at_depth is None or \ ptree.cp.residual_delta < best_at_depth.cp.residual_delta: best_at_depth = ptree tmp_ntls = ptree.cp.num_tls_segments() ## (integer value) if not visited.has_key(ptree): visited[ptree] = True if ntls_best.has_key(tmp_ntls): ## E.g., ntls_best[tmp_ntls] = "(A:16-74; 95-116)(A:75-94)" best_rmsd = "%5.2f" % (ntls_best[tmp_ntls].rmsd_b()) else: best_rmsd = "-----" ## E.g., "(A:2-11; 18-23; 39-52; 58-95)(A:12-17; 24-38; 53-57) 5.42( 4.98) 2" console.stdoutln("%s %5.2f(%s) %d" % ( ptree.cp, ptree.cp.rmsd_b(), best_rmsd, tmp_ntls)) ## NOTE: Example output: ## cpartition="(A:1-9)(A:21-30)(A:31-50)" ## cpartition.chain.chain_id="A" ## cpartition.num_tls_segments()="7" ## table.StringTableFromMatrix(cpartition.rmsd_b_mtx)=" ## 1.19667217259 2.44700956714 2.44363045774 ## 2.44700956714 1.90000136951 2.93313261105 ## 2.44363045774 2.93313261105 1.76763623176" ## NOTE: The above are the same values found in ## 'xxxx_CHAINa_NTLSn_RECOMBINATION.txt' files ## segment_ranges = segment_ranges, ## residual = tlsdict["residual"], ## method = tls1.method, ## num_atoms = tlsdict["num_atoms"], ## num_residues = tlsdict["num_residues"]) if ntls_best.has_key(tmp_ntls): if ptree.cp.residual() < ntls_best[tmp_ntls].residual(): ## E.g., ptree.cp="(A:16-61)(A:62-74; 95-116)(A:75-94)" ntls_best[tmp_ntls] = ptree.cp else: ntls_best[tmp_ntls] = ptree.cp ptree = best_at_depth for i in xrange(max_depth - 1): ptree = ptree.parent() proot = ptree if search_depth > max_depth: break ## insert replacement ChainPartitions if conf.globalconf.recombination: for ntls, cpartition in ntls_best.iteritems(): cp = chain.partition_collection.get_chain_partition(ntls) if cp != cpartition: chain.partition_collection.insert_chain_partition(cpartition)
def run_minimization(self): """Run the HCSSSP minimization on the self.V, self.E graph, resulting in the creation of the self.D, self.P, and self.T arrays which contain """ chain = self.chain chain_id = self.chain.chain_id min_subsegment_len = self.min_subsegment_len num_vertex = len(chain) + 1 ## choose the TLS Model to fit for the chain fit_method = self.get_fit_method(chain) ## build the vertex labels to reflect the protein structure ## the graph spans vertices = [] for i in xrange(num_vertex): ## add the vertex label for i at Vi if i == 0 : vertex_label = "N-TERM" elif i == num_vertex - 1: vertex_label = "C-TERM" else: vertex_label = "%s{%s:%s}" % ( chain_id, chain[i-1].fragment_id, chain[i].fragment_id) vertex_label = "V%d[%s]" % (i, vertex_label) vertices.append(vertex_label) ## fit chain segments with TLS model and build residual graph to ## minimize total_num_subsegments = calc_num_subsegments(chain.count_fragments(), min_subsegment_len) num_subsegments = 0 pcomplete = 0 pcomplete_old = 0 edges = [] console.stdoutln("=" * 80) console.stdoutln("BUILDING RESIDUAL GRAPH TO MINIMIZE: chain_id=%s" % chain_id) for frag_id1, frag_id2, i, j in iter_chain_subsegment_descs(chain, min_subsegment_len): tlsdict = fit_method(frag_id1, frag_id2) num_subsegments += 1 pcomplete = round(100.0 * num_subsegments / total_num_subsegments) if pcomplete != pcomplete_old: console.stdoutln("(%10d/%10d) %2d%% Complete" % ( num_subsegments, total_num_subsegments, pcomplete)) pcomplete_old = pcomplete if tlsdict == None: console.stderrln("no TLS group %s{%s..%s}" % ( chain_id, frag_id1, frag_id2)) raise SystemExit if tlsdict.has_key("error") is True: continue if not tlsdict.has_key("residual"): console.stderrln("no residual! %s{%s..%s}" % ( chain_id, frag_id1, frag_id2)) raise SystemExit residual = tlsdict["residual"] num_atoms = tlsdict["num_atoms"] num_residues = tlsdict["num_residues"] if residual < 0.0: console.stdoutln("ERROR: Residual is negative!") continue msd = residual / num_residues rmsd = math.sqrt(msd) rmsd_b = rmsd * Constants.U2B chi2 = msd * num_atoms ## XXX: Why is this set to 40? 2010-08-20 if num_atoms < 40: continue cost = residual frag_range = (frag_id1, frag_id2) edge = (i, j, cost, frag_range, tlsdict) edges.append(edge) console.cpu_time_stdoutln("->ResidualGraphMinimized chain_id=%s: %s" % ( chain_id, time.clock())) ## perform the minimization if len(edges) > 0: console.stdoutln("HCSSSP Minimizing: chain_id=%s" % (chain_id)) D, P, T = self.HCSSSP_minimize(vertices, edges, self.nparts) self.minimized = True self.V = vertices self.D = D self.P = P self.T = T else: console.stdoutln("HCSSSP Minimizing: Unable to minimize chain_id=%s" % ( chain_id)) self.minimized = False raise SystemExit ## free memory taken up from edges edges = None gc.collect()
def ChainPartitionRecombinationOptimization(chain): visited = {} ntls_best = {} orig_best = {} for ntls, cpartition in chain.partition_collection.iter_ntls_chain_partitions(): ntls_best[ntls] = cpartition orig_best[ntls] = cpartition for ntls, cpartition in chain.partition_collection.iter_ntls_chain_partitions(): if ntls < 2: continue console.stdoutln("%d INTO %d TO 2" % (ntls, ntls - 1)) search_width = 1 search_depth = 1 proot = tree.Tree() proot.cp = cpartition while True: ExtendRecombinationTree(proot, search_depth, search_width) max_depth = proot.depth() best_at_depth = None for depth, ptree in proot.iter_depth_first(): if depth == max_depth: if best_at_depth is None or ptree.cp.residual_delta < best_at_depth.cp.residual_delta: best_at_depth = ptree tmp_ntls = ptree.cp.num_tls_segments() if not visited.has_key(ptree): visited[ptree] = True if ntls_best.has_key(tmp_ntls): best_rmsd = "%5.2f" % (ntls_best[tmp_ntls].rmsd_b()) else: best_rmsd = "-----" console.stdoutln("%s %5.2f(%s) %d" % (ptree.cp, ptree.cp.rmsd_b(), best_rmsd, tmp_ntls)) if ntls_best.has_key(tmp_ntls): if ptree.cp.residual() < ntls_best[tmp_ntls].residual(): ntls_best[tmp_ntls] = ptree.cp else: ntls_best[tmp_ntls] = ptree.cp ptree = best_at_depth for i in xrange(max_depth - 1): ptree = ptree.parent() proot = ptree if search_depth > max_depth: break ## insert replacement ChainPartitions if conf.globalconf.recombination: for ntls, cpartition in ntls_best.iteritems(): cp = chain.partition_collection.get_chain_partition(ntls) if cp != cpartition: chain.partition_collection.insert_chain_partition(cpartition)