Package mmLib :: Module mmCIFBuilder
[hide private]
[frames] | no frames]

Source Code for Module mmLib.mmCIFBuilder

  1  ## Copyright 2002-2010 by PyMMLib Development Group (see AUTHORS file) 
  2  ## This code is part of the PyMMLib distribution and governed by 
  3  ## its license.  Please see the LICENSE file that should have been 
  4  ## included as part of this package. 
  5  """Convert a Structure object into its mmCIFFile description. 
  6  """ 
  7  ## Python 
  8  import copy 
  9   
 10  ## pymmlib 
 11  import ConsoleOutput 
 12  import mmCIF 
 13  import StructureBuilder 
 14  import Structure 
 15   
 16   
17 -def setmaps_cif(smap, skey, dmap, dkey):
18 """For string converisons, treat [?.] as blank. 19 """ 20 if smap.has_key_lower(skey): 21 x = smap.getitem_lower(skey) 22 if x in ('', '?', '.'): 23 return False 24 dmap[dkey] = str(x) 25 return True 26 return False
27 28
29 -def setmapi_cif(smap, skey, dmap, dkey):
30 """For integer converisons, treat [?.] as blank. 31 """ 32 if smap.has_key_lower(skey): 33 x = smap.getitem_lower(skey) 34 if x in ('', '?', '.'): 35 return False 36 try: 37 dmap[dkey] = int(x) 38 except ValueError: 39 return False 40 return True 41 return False
42 43
44 -def setmapf_cif(smap, skey, dmap, dkey):
45 """For float converisons, treat [?.] as blank. 46 """ 47 if smap.has_key_lower(skey): 48 x = smap.getitem_lower(skey) 49 if x in ('', '?', '.'): 50 return False 51 try: 52 dmap[dkey] = float(x) 53 except ValueError: 54 return False 55 return True 56 return False
57 58
59 -class mmCIFStructureBuilder(StructureBuilder.StructureBuilder):
60 """Builds a new Structure object by loading an mmCIF file. 61 """ 62
63 - def read_start(self, filobj):
64 ## parse the mmCIF file 65 self.cif_file = mmCIF.mmCIFFile() 66 self.cif_file.load_file(filobj) 67 68 ## for an mmCIF file for a structure, assume the first data item 69 ## contains the structure; if there is no data in the mmCIF 70 ## file, halt 71 try: 72 self.cif_data = self.cif_file[0] 73 except IndexError: 74 self.halt = True 75 return 76 77 self.set_atom_site_data_columns() 78 79 ## maintain a map of atom_site.id -> atm 80 self.atom_site_id_map = {}
81
82 - def set_atom_site_auth(self):
83 """Read atom_site.auth_ labels for atom definitions. 84 """ 85 self.atom_id = "auth_atom_id" 86 self.alt_id = "auth_alt_id" 87 self.comp_id = "auth_comp_id" 88 self.seq_id = "auth_seq_id" 89 self.asym_id = "auth_asym_id" 90 self.ptnr1_atom_id = "ptnr1_auth_atom_id" 91 self.ptnr1_comp_id = "ptnr1_auth_comp_id" 92 self.ptnr1_asym_id = "ptnr1_auth_asym_id" 93 self.ptnr1_seq_id = "ptnr1_auth_seq_id" 94 self.ptnr2_atom_id = "ptnr2_auth_atom_id" 95 self.ptnr2_comp_id = "ptnr2_auth_comp_id" 96 self.ptnr2_asym_id = "ptnr2_auth_asym_id" 97 self.ptnr2_seq_id = "ptnr2_auth_seq_id"
98
99 - def set_atom_site_label(self):
100 """Read atom_site.label_ items for atom definitions. 101 """ 102 self.atom_id = "label_atom_id" 103 self.alt_id = "label_alt_id" 104 self.comp_id = "label_comp_id" 105 self.seq_id = "label_seq_id" 106 self.asym_id = "label_asym_id" 107 self.ptnr1_atom_id = "ptnr1_label_atom_id" 108 self.ptnr1_comp_id = "ptnr1_label_comp_id" 109 self.ptnr1_asym_id = "ptnr1_label_asym_id" 110 self.ptnr1_seq_id = "ptnr1_label_seq_id" 111 self.ptnr2_atom_id = "ptnr2_label_atom_id" 112 self.ptnr2_comp_id = "ptnr2_label_comp_id" 113 self.ptnr2_asym_id = "ptnr2_label_asym_id" 114 self.ptnr2_seq_id = "ptnr2_label_seq_id"
115
117 """Choose to use atom_site.auth_ labels, or atom_site.label_ 118 """ 119 try: 120 atom_site_table = self.cif_data["atom_site"] 121 except KeyError: 122 return 123 124 ## count the number of columns which exist for the auth_ style 125 ## columns and label_ style columns 126 auth_cols = ["auth_atom_id", "auth_comp_id", "auth_seq_id", "auth_asym_id"] 127 label_cols = ["label_atom_id", "label_comp_id", "label_seq_id", "label_asym_id"] 128 129 auth_count = 0 130 for col in auth_cols: 131 if col in atom_site_table.columns: 132 auth_count += 1 133 134 label_count = 0 135 for col in label_cols: 136 if col in atom_site_table.columns: 137 label_count += 1 138 139 if auth_count >= label_count: 140 self.set_atom_site_auth() 141 else: 142 self.set_atom_site_label()
143
144 - def read_atoms(self):
145 try: 146 atom_site_table = self.cif_data["atom_site"] 147 except KeyError: 148 ConsoleOutput.warning("read_atoms: atom_site table not found") 149 return 150 151 try: 152 aniso_table = self.cif_data["atom_site_anisotrop"] 153 except KeyError: 154 aniso_table = None 155 else: 156 aniso_dict = aniso_table.row_index_dict("id") 157 158 for atom_site in atom_site_table: 159 try: 160 atom_site_id = atom_site["id"] 161 except KeyError: 162 ConsoleOutput.warning("unable to find id for atom_site row") 163 continue 164 165 atm_map = {} 166 167 setmaps_cif(atom_site, self.atom_id, atm_map, "name") 168 setmaps_cif(atom_site, self.alt_id, atm_map, "alt_loc") 169 setmaps_cif(atom_site, self.comp_id, atm_map, "res_name") 170 setmaps_cif(atom_site, self.seq_id, atm_map, "fragment_id") 171 setmaps_cif(atom_site, self.asym_id, atm_map, "chain_id") 172 173 setmaps_cif(atom_site, "label_entity_id", atm_map, "label_entity_id") 174 setmaps_cif(atom_site, "label_asym_id", atm_map, "label_asym_id") 175 setmaps_cif(atom_site, "label_seq_id", atm_map, "label_seq_id") 176 setmaps_cif(atom_site, "type_symbol", atm_map, "element") 177 setmapf_cif(atom_site, "cartn_x", atm_map, "x") 178 setmapf_cif(atom_site, "cartn_y", atm_map, "y") 179 setmapf_cif(atom_site, "cartn_z", atm_map, "z") 180 setmapf_cif(atom_site, "occupancy", atm_map, "occupancy") 181 setmapf_cif(atom_site, "b_iso_or_equiv", atm_map, "temp_factor") 182 setmapf_cif(atom_site, "cartn_x_esd", atm_map, "sig_x") 183 setmapf_cif(atom_site, "cartn_y_esd", atm_map, "sig_y") 184 setmapf_cif(atom_site, "cartn_z_esd", atm_map, "sig_z") 185 setmapf_cif(atom_site, "occupancy_esd", atm_map, "sig_occupancy") 186 187 setmapf_cif(atom_site, "b_iso_or_equiv_esd", 188 atm_map, "sig_temp_factor") 189 190 setmapi_cif(atom_site, "pdbx_pdb_model_num", 191 atm_map, "model_id") 192 193 if aniso_table is not None: 194 try: 195 aniso = aniso_dict[atom_site_id] 196 except KeyError: 197 ConsoleOutput.warning("unable to find aniso row for atom") 198 else: 199 setmapf_cif(aniso, "u[1][1]", atm_map, "u11") 200 setmapf_cif(aniso, "u[2][2]", atm_map, "u22") 201 setmapf_cif(aniso, "u[3][3]", atm_map, "u33") 202 setmapf_cif(aniso, "u[1][2]", atm_map, "u12") 203 setmapf_cif(aniso, "u[1][3]", atm_map, "u13") 204 setmapf_cif(aniso, "u[2][3]", atm_map, "u23") 205 206 setmapf_cif(aniso, "u[1][1]_esd", atm_map, "sig_u12") 207 setmapf_cif(aniso, "u[2][2]_esd", atm_map, "sig_u22") 208 setmapf_cif(aniso, "u[3][3]_esd", atm_map, "sig_u33") 209 setmapf_cif(aniso, "u[1][2]_esd", atm_map, "sig_u12") 210 setmapf_cif(aniso, "u[1][3]_esd", atm_map, "sig_u13") 211 setmapf_cif(aniso, "u[2][3]_esd", atm_map, "sig_u23") 212 213 atm = self.load_atom(atm_map) 214 self.atom_site_id_map[atom_site_id] = atm
215
216 - def read_metadata(self):
217 self.read_structure_id() 218 219 ## copy selected mmCIF tables to the structure's mmCIF database 220 skip_tables = ["atom_site", 221 "atom_site_anisotrop", 222 "atom_sites_alt"] 223 224 for table in self.cif_data: 225 print "DEBUG: %s" % table 226 if table.name not in skip_tables: 227 self.struct.cifdb.add_table(table) 228 229 self.read_sequence() 230 231 ## read unit cell table 232 self.read_unit_cell() 233 234 ## read bond information 235 self.read_struct_conn()
236
237 - def read_sequence(self):
238 """Read the sequence. 239 """
240
241 - def read_structure_id(self):
242 """Read the PDB ID. 243 """ 244 try: 245 entry_id = self.cif_data["entry"]["id"] 246 except KeyError: 247 pass 248 else: 249 self.load_structure_id(entry_id)
250
251 - def read_unit_cell(self):
252 """Load unit cell and symmetry tables. 253 """ 254 ucell_map = {} 255 256 try: 257 entry_id = self.cif_data["entry"]["id"] 258 cell_table = self.cif_data["cell"] 259 symmetry_table = self.cif_data["symmetry"] 260 except KeyError: 261 return 262 263 cell = cell_table.get_row1("entry_id", entry_id) 264 if cell is not None: 265 setmapf_cif(cell, "length_a", ucell_map, "a") 266 setmapf_cif(cell, "length_b", ucell_map, "b") 267 setmapf_cif(cell, "length_c", ucell_map, "c") 268 setmapf_cif(cell, "angle_alpha", ucell_map, "alpha") 269 setmapf_cif(cell, "angle_beta", ucell_map, "beta") 270 setmapf_cif(cell, "angle_gamma", ucell_map, "gamma") 271 setmapi_cif(cell, "z_pdb", ucell_map, "z") 272 273 symm = symmetry_table.get_row1("entry_id", entry_id) 274 if symm is not None: 275 setmaps_cif(symm, "space_group_name_H-M", ucell_map, "space_group") 276 277 self.load_unit_cell(ucell_map)
278
279 - def read_struct_conn(self):
280 """Read bond information form the struct_conn and struct_conn_type 281 sections. 282 """ 283 ## only read these types of bonds for now 284 bond_type_list = [ 285 "covale", # covalent bond 286 "metalc", # metal coordination 287 "disulf", # disulfide bridge 288 "saltbr", # ionic interaction 289 "covale_base", # covalent modification of a nucleotide base 290 "covale_sugar", # covalent modification of a nucleotide sugar 291 "covale_phosphate", # covalent modification of a nucleotide phosphate 292 ] 293 294 try: 295 atom_site = self.cif_data["atom_site"] 296 except KeyError: 297 ConsoleOutput.warning("read_struct_conn: atom_site table not found") 298 return 299 300 try: 301 struct_conn_table = self.cif_data["struct_conn"] 302 except KeyError: 303 ConsoleOutput.warning("read_struct_conn: struct_conn table not found") 304 return 305 306 bond_map = {} 307 308 for row in struct_conn_table: 309 conn_type = row.get("conn_type_id") 310 if conn_type not in bond_type_list: 311 continue 312 313 # Always use label_ values since they are mandatory 314 asym_id1 = row.get("ptnr1_label_asym_id") 315 seq_id1 = row.get("ptnr1_label_seq_id") 316 comp_id1 = row.get("ptnr1_label_comp_id") 317 atom_id1 = row.get("ptnr1_label_atom_id") 318 auth_asym_id1 = row.get("ptnr1_auth_asym_id") 319 auth_seq_id1 = row.get("ptnr1_auth_seq_id") 320 auth_comp_id1 = row.get("ptnr1_auth_comp_id") 321 symm1 = row.get("ptnr1_symmetry") 322 323 asym_id2 = row.get("ptnr2_label_asym_id") 324 seq_id2 = row.get("ptnr2_label_seq_id") 325 comp_id2 = row.get("ptnr2_label_comp_id") 326 atom_id2 = row.get("ptnr2_label_atom_id") 327 auth_asym_id2 = row.get("ptnr2_auth_asym_id") 328 auth_seq_id2 = row.get("ptnr2_auth_seq_id") 329 auth_comp_id2 = row.get("ptnr2_auth_comp_id") 330 symm2 = row.get("ptnr2_symmetry") 331 332 ## check for these special mmCIF tokens 333 if conn_type == "disulf": 334 atom_id1 = atom_id2 = "SG" 335 336 as1 = atom_site.get_row( 337 ("label_asym_id", asym_id1), 338 ("label_seq_id", seq_id1), 339 ("label_comp_id", comp_id1), 340 ("auth_asym_id", auth_asym_id1), 341 ("auth_seq_id", auth_seq_id1), 342 ("auth_comp_id", auth_comp_id1), 343 ("label_atom_id", atom_id1)) 344 345 as2 = atom_site.get_row( 346 ("label_asym_id", asym_id2), 347 ("label_seq_id", seq_id2), 348 ("label_comp_id", comp_id2), 349 ("auth_asym_id", auth_asym_id2), 350 ("auth_seq_id", auth_seq_id2), 351 ("auth_comp_id", auth_comp_id2), 352 ("label_atom_id", atom_id2)) 353 354 if not as1 or not as2: 355 ConsoleOutput.warning("read_struct_conn: atom not found id: " + \ 356 row.get("id","[No ID]")) 357 358 ConsoleOutput.warning("atm1: asym=%s seq=%s comp=%s atom=%s symm=%s" % ( 359 asym_id1, seq_id1, comp_id1, atom_id1, symm1)) 360 361 ConsoleOutput.warning("atm2: asym=%s seq=%s comp=%s atom=%s symm=%s" % ( 362 asym_id2, seq_id2, comp_id2, atom_id2, symm2)) 363 364 continue 365 366 try: 367 atm1 = self.atom_site_id_map[as1["id"]] 368 atm2 = self.atom_site_id_map[as2["id"]] 369 except KeyError: 370 ConsoleOutput.warning("read_struct_conn: atom_site_id_map incorrect id: " + \ 371 row.get("id", "[No ID]")) 372 373 ConsoleOutput.warning("atm1: asym=%s seq=%s comp=%s atom=%s symm=%s" % ( 374 asym_id1, seq_id1, comp_id1, atom_id1, symm1)) 375 376 ConsoleOutput.warning("atm2: asym=%s seq=%s comp=%s atom=%s symm=%s" % ( 377 asym_id2, seq_id2, comp_id2, atom_id2, symm2)) 378 379 continue 380 381 if id(atm1) < id(atm2): 382 bnd = (atm1, atm2) 383 else: 384 bnd = (atm2, atm1) 385 386 try: 387 bond_map[bnd]["bond_type"] = conn_type 388 except KeyError: 389 bond_map[bnd] = {"bond_type": conn_type} 390 391 if symm1: 392 bond_map[bnd]["symop1"] = symm1 393 if symm2: 394 bond_map[bnd]["symop2"] = symm2 395 396 ## load the bonds 397 self.load_bonds(bond_map)
398
399 - def read_struct_conf(self):
400 """Reads the struct_conf table getting information on alpha 401 helicies and turns in the structure. 402 """ 403 try: 404 struct_conf = self.cif_data["struct_conf"] 405 except KeyError: 406 return 407 408 ## iterate over struct_conf and create the helix_list 409 helix_list = [] 410 411 for row in struct_conf: 412 ## check for required fields 413 try: 414 row["id"] 415 row["conf_type_id"] 416 except KeyError: 417 continue 418 419 ## if this is a alpha helix 420 if row["conf_type_id"].startswith("HELIX"): 421 helix = {"helix_id": row["id"], 422 "helix_class": row["conf_type_id"]}
423 424 425 CIF_BUILD_TABLES = { 426 "entry": ["id"], 427 428 "entity": [ 429 "id", "type", "ndb_description"], 430 431 "cell": [ 432 "entry_id", "length_a", "length_b", "length_c", 433 "angle_alpha", "angle_beta", "angle_gamma", "PDB_Z"], 434 435 "symmetry": [ 436 "entry_id", "space_group_name_H-M", "cell_setting", 437 "Int_Tables_number"], 438 439 "entity_poly": [ 440 "entity_id", "ndb_chain_id", "ndb_seq_one_letter_code"], 441 442 "audit_author": ["name"], 443 444 "atom_site": [ 445 "group_PDB", "id", "type_symbol", "label_entity_id", "label_asym_id", 446 "label_seq_id", "label_comp_id", "label_alt_id", "label_atom_id", 447 "Cartn_x", "Cartn_y", "Cartn_z", "occupancy", "B_iso_or_equiv", 448 "Cartn_x_esd", "Cartn_y_esd", "Cartn_z_esd", "occupancy_esd", 449 "B_iso_or_equiv_esd", "auth_asym_id", "auth_seq_id", "auth_comp_id", 450 "auth_alt_id", "auth_atom_id", "pdbx_PDB_model_num"], 451 452 "atom_site_anisotrop": [ 453 "id", "type_symbol", "label_entity_id", "U[1][1]", "U[1][2]", 454 "U[1][3]", "U[2][2]", "U[2][3]", "U[3][3]", "U[1][1]_esd", 455 "U[1][2]_esd", "U[1][3]_esd", "U[2][2]_esd", "U[2][3]_esd", 456 "U[3][3]_esd", "pdbx_auth_seq_id", "pdbx_auth_comp_id", 457 "pdbx_auth_asym_id", "pdbx_auth_atom_id"] 458 } 459 460 461
462 -class mmCIFFileBuilder(object):
463 """Builds a mmCIF file from a Structure object. 464 """
465 - def __init__(self, struct, cif_file):
466 self.struct = struct 467 self.entry_id = self.struct.structure_id 468 self.cif_data = cif_file.new_data(self.entry_id) 469 470 ## entity handling 471 ## entity_desc list 472 self.entity_list = [] 473 ## Fragment -> entity_desc 474 self.entity_frag_dict = {} 475 ## res_name -> entity_desc 476 self.entity_res_name_dict = {} 477 478 ## these tables need to be formed from the atom structure 479 self.add__entry() 480 self.add__entity() 481 self.add__entity_poly() 482 self.add__cell() 483 self.add__symmetry() 484 self.add__atom_site()
485
486 - def get_table(self, name):
487 """Returns the self.cif_data[name] mmCIFTable, or it creates 488 it and adds it to self.cif_data if it does not exist. 489 """ 490 table = self.cif_data.get_table(name) 491 if table is not None: 492 return table 493 494 columns = copy.deepcopy(CIF_BUILD_TABLES[name]) 495 table = self.cif_data.new_table(name, columns) 496 return table
497
498 - def get_entity_desc_from_id(self, entity_id):
499 for entity_desc in self.entity_list: 500 if entity_desc["id"]==entity_id: 501 return entity_desc 502 return None
503
504 - def get_entity_desc_from_sequence(self, sequence):
505 for entity_desc in self.entity_list: 506 if entity_desc.has_key("sequence") and entity_desc["sequence"] == sequence: 507 return entity_desc 508 return None
509
510 - def add__entry(self):
511 """Add the _entry table. 512 """ 513 entry = self.get_table("entry") 514 row = entry.new_row() 515 row["id"] = self.entry_id
516
517 - def add__entity(self):
518 """Adds the entity table. The entity names are faked here, since 519 it is really not clear to us how the names are chosen by the PDB. 520 """ 521 ## maps fragment -> entity_id 522 entity = self.get_table("entity") 523 524 ## ADD BIO-POLYMERS 525 ## list of polymer entities (entity_id, sequence1) 526 527 cur_entity_id = 1 528 529 for chain in self.struct.iter_all_chains(): 530 531 ## if the chain is a bio-polymer, it is one entity; come up 532 ## with a name from its sequence and add it to the 533 ## entity map 534 if chain.count_standard_residues() < 3: 535 continue 536 537 ## calculate sequence and compare the sequence to chains 538 ## already added so we can re-use the entity ID 539 sequence = chain.sequence.one_letter_code() 540 541 entity_desc = self.get_entity_desc_from_sequence(sequence) 542 543 ## ADD POLYMER TO CURRENT ENTITY 544 if entity_desc is not None: 545 entity_desc["chains"].append(chain) 546 entity_desc["chain_ids"].append(chain.chain_id) 547 548 ## NEW ENTITY 549 else: 550 ## figure out what type of biopolymer this is 551 if (chain.count_amino_acids() / len(chain)) > 0.5: 552 details = "%d residue polypeptide" % (chain.count_amino_acids()) 553 poly_type = "polypeptide(L)" 554 555 elif (chain.count_nucleic_acids() / len(chain)) > 0.5: 556 details = "%d residue DNA/RNA" % (chain.count_nucleic_acids()) 557 poly_type = "polydeoxyribonucleotide" 558 559 else: 560 details = "unknown polymer" 561 poly_type = "other" 562 563 ## new entity description 564 entity_desc = { 565 "id": cur_entity_id, 566 "chains": [chain], 567 "chain_ids": [chain.chain_id], 568 "polymer": True, 569 "poly_type": poly_type, 570 "sequence": sequence, 571 "details": details } 572 self.entity_list.append(entity_desc) 573 574 row = entity.new_row() 575 row["id"] = entity_desc["id"] 576 row["type"] = "polymer" 577 row["ndb_description"] = details 578 579 ## incriment entity_id 580 cur_entity_id = cur_entity_id + 1 581 582 ## loop over all residues and map the frag->entity_desc 583 for frag in chain.iter_standard_residues(): 584 self.entity_frag_dict[frag] = entity_desc 585 586 587 ## ADD HET ATOMS (Water, metal) 588 for chain in self.struct.iter_all_chains(): 589 for frag in chain.iter_fragments(): 590 591 ## any fragments already assigned to a entity by the 592 ## polymer section above should be skipped 593 if self.entity_frag_dict.has_key(frag): 594 continue 595 596 ## already assigned a entity_id for this fragment_id 597 if self.entity_res_name_dict.has_key(frag.res_name): 598 self.entity_frag_dict[frag] = self.entity_res_name_dict[frag.res_name] 599 continue 600 601 ## we need to assign a entity_id for this fragment_id 602 ## and add a row for it in the entity table 603 if frag.is_water(): 604 type = "water" 605 details = "" 606 else: 607 type = "non-polymer" 608 details = frag.res_name 609 610 row = entity.new_row() 611 row["id"] = cur_entity_id 612 row["type"] = "non-polymer" 613 row["ndb_description"] = frag.res_name 614 615 entity_desc = { 616 "id": cur_entity_id, 617 "polymer": False, 618 "res_name": frag.res_name } 619 620 self.entity_res_name_dict[frag.res_name] = entity_desc 621 self.entity_frag_dict[frag] = entity_desc 622 623 ## incriment entity_id 624 cur_entity_id = cur_entity_id + 1
625
626 - def add__entity_poly(self):
627 """Adds the _entity_poly table. 628 """ 629 entity_poly = self.get_table("entity_poly") 630 631 for entity_desc in self.entity_list: 632 if entity_desc["polymer"]==False: 633 continue 634 635 row = entity_poly.new_row() 636 637 row["entity_id"] = entity_desc["id"] 638 row["ndb_chain_id"] = ",".join(entity_desc["chain_ids"]) 639 row["ndb_seq_one_letter_code"] = entity_desc["sequence"]
640
641 - def add__cell(self):
642 """Adds the _cell table. 643 """ 644 try: 645 unit_cell = self.struct.unit_cell 646 except AttributeError: 647 return 648 649 cell = self.get_table("cell") 650 row = cell.new_row() 651 652 row["entry_id"] = self.entry_id 653 row["length_a"] = unit_cell.a 654 row["length_b"] = unit_cell.b 655 row["length_c"] = unit_cell.c 656 row["angle_alpha"] = unit_cell.calc_alpha_deg() 657 row["angle_beta"] = unit_cell.calc_beta_deg() 658 row["angle_gamma"] = unit_cell.calc_gamma_deg()
659
660 - def add__symmetry(self):
661 """Adds the _symmetry table. 662 """ 663 try: 664 space_group = self.struct.unit_cell.space_group 665 except AttributeError: 666 return 667 668 symmetry = self.get_table("symmetry") 669 row = symmetry.new_row() 670 671 row["entry_id"] = self.entry_id 672 row["space_group_name_H-M"] = space_group.pdb_name 673 row["Int_Tables_number"] = space_group.number
674
675 - def add__atom_site(self):
676 """Adds the _atom_site table. 677 """ 678 atom_site = self.get_table("atom_site") 679 atom_id = 0 680 681 for chain in self.struct.iter_all_chains(): 682 label_seq_id = 0 683 684 for frag in chain.iter_fragments(): 685 label_seq_id += 1 686 entity_desc = self.entity_frag_dict[frag] 687 688 for atm in frag.iter_all_atoms(): 689 atom_id += 1 690 691 row = atom_site.new_row() 692 row["id"] = atom_id 693 694 self.set_atom_site_row(row, atm, entity_desc, label_seq_id)
695
696 - def set_atom_site_row(self, asrow, atm, entity_desc, label_seq_id):
697 """Add atom_site coordinate row. 698 """ 699 if entity_desc["polymer"]==True: 700 asrow["group_PDB"] = "ATOM" 701 asrow["label_asym_id"] = atm.chain_id 702 703 else: 704 asrow["group_PDB"] = "HETATM" 705 706 asrow["label_entity_id"] = entity_desc["id"] 707 asrow["label_atom_id"] = atm.name 708 asrow["label_alt_id"] = atm.alt_loc 709 asrow["label_comp_id"] = atm.res_name 710 asrow["label_seq_id"] = label_seq_id 711 712 asrow["auth_atom_id"] = atm.name 713 asrow["auth_alt_id"] = atm.alt_loc 714 asrow["auth_comp_id"] = atm.res_name 715 asrow["auth_seq_id"] = atm.fragment_id 716 asrow["auth_asym_id"] = atm.chain_id 717 718 asrow["type_symbol"] = atm.element 719 asrow["pdbx_PDB_model_num"] = atm.model_id 720 721 if atm.occupancy is not None: 722 asrow["occupancy"] = atm.occupancy 723 724 if atm.temp_factor is not None: 725 asrow["B_iso_or_equiv"] = atm.temp_factor 726 727 if atm.position is not None: 728 if atm.position[0] is not None: 729 asrow["Cartn_x"] = atm.position[0] 730 if atm.position[1] is not None: 731 asrow["Cartn_y"] = atm.position[1] 732 if atm.position[2] is not None: 733 asrow["Cartn_z"] = atm.position[2] 734 735 if atm.sig_position is not None: 736 if atm.sig_position[0] is not None: 737 asrow["Cartn_x_esd"] = atm.sig_position[0] 738 if atm.sig_position[1] is not None: 739 asrow["Cartn_y_esd"] = atm.sig_position[1] 740 if atm.sig_position[2] is not None: 741 asrow["Cartn_z_esd"] = atm.sig_position[2] 742 743 if atm.sig_occupancy is not None: 744 asrow["occupancy_esd"] = atm.sig_occupancy 745 746 if atm.sig_temp_factor is not None: 747 asrow["B_iso_or_equiv_esd"] = atm.sig_temp_factor 748 749 if atm.U is not None: 750 aniso = self.get_table("atom_site_anisotrop") 751 anrow = aniso.new_row() 752 753 anrow["id"] = asrow["id"] 754 anrow["type_symbol"] = asrow["type_symbol"] 755 anrow["label_entity_id"] = asrow["label_entity_id"] 756 anrow["pdbx_auth_seq_id"] = asrow["auth_seq_id"] 757 anrow["pdbx_auth_comp_id"] = asrow["auth_comp_id"] 758 anrow["pdbx_auth_asym_id"] = asrow["auth_asym_id"] 759 anrow["pdbx_auth_atom_id"] = asrow["auth_atom_id"] 760 anrow["pdbx_auth_alt_id"] = asrow["auth_alt_id"] 761 762 if atm.U[0,0] is not None: 763 anrow["U[1][1]"] = atm.U[0,0] 764 if atm.U[1,1] is not None: 765 anrow["U[2][2]"] = atm.U[1,1] 766 if atm.U[2,2] is not None: 767 anrow["U[3][3]"] = atm.U[2,2] 768 if atm.U[0,1] is not None: 769 anrow["U[1][2]"] = atm.U[0,1] 770 if atm.U[0,2] is not None: 771 anrow["U[1][3]"] = atm.U[0,2] 772 if atm.U[1,2] is not None: 773 anrow["U[2][3]"] = atm.U[1,2] 774 775 if atm.sig_U is not None: 776 if atm.sig_U[0,0] is not None: 777 anrow["U[1][1]_esd"] = atm.sig_U[0,0] 778 if atm.sig_U[1,1] is not None: 779 anrow["U[2][2]_esd"] = atm.sig_U[1,1] 780 if atm.sig_U[2,2] is not None: 781 anrow["U[3][3]_esd"] = atm.sig_U[2,2] 782 if atm.sig_U[0,1] is not None: 783 anrow["U[1][2]_esd"] = atm.sig_U[0,1] 784 if atm.sig_U[0,2] is not None: 785 anrow["U[1][3]_esd"] = atm.sig_U[0,2] 786 if atm.sig_U[1,2] is not None: 787 anrow["U[2][3]_esd"] = atm.sig_U[1,2]
788