├── README.md └── coot_trimmings.py /README.md: -------------------------------------------------------------------------------- 1 | # coot-trimmings 2 | Python customizations for the macromolecular model building software Coot. 3 | 4 | Copy python file (`coot_trimmings.py`) to the `~/.coot-preferences/` directory (hidden dir, copy on command line, e.g `cp coot_trimmings.py ~/.coot-preferences/`) and restart coot. 5 | 6 | You should see a new menu ("Custom") and a bunch of new key bindings, as well as a couple of new toolbar buttons (e.g. "sequence context"). 7 | 8 | (If you see an errror like ` ^ SyntaxError: invalid syntax`, you have downloaded the webpage rather than the actual Python script. Make sure you clicked "download raw file" when downloading.) 9 | 10 | (*NOTE: There are some non-default settings (e.g. I don't like using the scroll-wheel for changing map contours) which I like but you may not! Check the bottom of this readme for details and tweak as you prefer.*) 11 | 12 | Email me if you run into any trouble (olibclarke at gmail dot com). 13 | 14 | I haven't tested most of these on WinCoot, or on older versions of Coot. Most testing done with Coot 0.8.8 or later (_Not yet tested with Coot 1.x!_). 15 | 16 | Also, many of the functions here haven't been tested on molecules with insertion codes. If this is important to you, let me know and I'll fix. 17 | 18 | # Custom keybindings 19 | Ordered approximately by interestingness/usefulness. YMMV. 20 | 21 | NEW "G": Toggle display of the active map between a local mesh and a global surface. 22 | 23 | NEW "L": Set contour level of scrollable map in sigma by entering a new value. 24 | 25 | NEW "Y"/"T": Cycle phi/psi angles of terminal residue. Useful when manually building in conjunction with "y" 26 | 27 | "M": Mutate active residue by entered single letter code (case-insensitive). 28 | 29 | "?": Display only active model; If only active model displayed, cycle display of models. 30 | 31 | "~": Display only active map; If only active map displayed, cycle display of maps. 32 | 33 | "\`": Toggle display of all maps. 34 | 35 | "/": Toggle display of all models. 36 | 37 | "]"/"[": Cycle representation mode forward/back for active model. 38 | 39 | "}"/"{": Cycle symmetry representation mode forward/back for active model. 40 | 41 | "R": Cycle through rotamers for active residue. 42 | 43 | "H": Toggle hide/display of modelling toolbar. 44 | 45 | "h": Place helix here, with H-bond restraints added. 46 | 47 | "Tab": Clear pending picks. 48 | 49 | "!"..."(": Set active map contour to 1,2,3...9 sigma. 50 | 51 | ">"/"<": Next/previous residue. 52 | 53 | "Q": Save and overwrite active model (makes backup in case of accidents). 54 | 55 | "A": Real space refine zone (click start and end of zone) 56 | 57 | "Z": Clear distances and labels. 58 | 59 | "P": Place atom at pointer. 60 | 61 | "q": Pepflip active residue. 62 | 63 | "a": Auto-refine zone of 10 residues centered on active residue. 64 | 65 | "J": Jiggle fit active residue. 66 | 67 | "D": Toggle display of environment distances. 68 | 69 | "X": Delete active residue. 70 | 71 | "K": Kill sidechain of active residue. 72 | 73 | "k": Fill sidechain of active residue. 74 | 75 | "w": Place water without refinement. 76 | 77 | "W": Place water with refinement. 78 | 79 | "y": Add terminal residue. 80 | 81 | "r": Refine three residues centered on active residue. 82 | 83 | "V": Undo symmetry view. 84 | 85 | "z": Undo for active model. 86 | 87 | "x": Redo for active model. 88 | 89 | "O": Go to equivalent residue on NCS master chain. 90 | 91 | "|":/"\_": Increase/decrease active map level by 0.5 sigma. 92 | 93 | # Custom menu items 94 | (Very incomplete list - these are some highlights) 95 | 96 | ## _Display_ 97 | * Colour by rotamer probability/missing atomsl; hydrophobics/polars; +ve/-ve charge; entered subset of residues 98 | * Highlight chainbreaks with dotted lines; red >50 residues, orange 15-50 residues missing, gray <15 residues missing 99 | * Color active segment (covalently connected polymer segment). 100 | * Open current view in UCSF chimera (requires chimera in PATH): Hopefully does what it says on the box, including changing view and display of maps. Useful as a starting point for making density figures. 101 | 102 | ## _Renumber_ 103 | * Renumber active chain by current res: Adjusts sequence numbering of chain so that active residue matches entered number. 104 | * Renumber active segment (contiguous stretch of sequence, bounded by chain breaks) by current res: Adjusts sequence numbering of segment so that active residue matches entered number. Checks for overlapping numbering. 105 | 106 | ## _Settings_ 107 | * Auto-scale B-factor coloring 108 | * Change default B for new residues to mean B of active model. 109 | 110 | ## _Build_ 111 | * Forced addition of terminal residue: adds residue, ignoring map, for when you disagree with Coot's assessment of residue placeability. 112 | * Rebuild backbone: Uses db_mainchain to rebuild the selected zone based on similar sequence fragments in a database of high resolution structures. 113 | * Make alkyl chain of length n: Makes alkyl chain and jiggle-fits to map. Useful for preliminary modelling of lipids/detergents. 114 | * Grow helix, grow strand etc. Grows selected helix/strand by entered number of residues assuming ideal geometry. 115 | 116 | ## _Mutate_ 117 | * Mutate range to ALA 118 | * Mutate range to UNK 119 | * Mutate Mets to MSE and vice-versa 120 | * Mutate active chain to template sequence: Mutates active chain to sequence pasted into textbox, assuming numbering the same - i.e. first residue in pasted sequence is residue 1 in numbering scheme of model. Filters non-sequence (e.g. formatting) characters from pasted sequence. Once sequence is pasted once, it is remembered after, to speed up multiple register adjustments. 121 | 122 | ## _Copy_ 123 | * Cut/copy chain, segment, selected fragment, etc. 124 | 125 | ## _Delete_ 126 | * Delete active chain 127 | * Delete active segment 128 | * Delete sidechains in range 129 | * Delete hydrogens in active molecule 130 | 131 | ## _Merge_ 132 | * Merge two molecules or chains by clicking. 133 | 134 | ## _Maps_ 135 | * Sharpen by entered B-factor. Absolute not relative; 0 always returns to original map. (MTZ only!) 136 | * Change hi-res-limit for map; creates low-pass filtered version of active map (MTZ only!) 137 | * Go to center of active map. 138 | * Set refinement map to active (scrollable) map. 139 | 140 | 141 | 142 | # Toolbar buttons 143 | * Measure distance 144 | * Toggle display of symmetry copies 145 | * Sequence context (displays local sequence before/after active residue) 146 | * Accept RSR (forces acceptance of current real space refine results) 147 | 148 | # Non-default setttings 149 | 150 | `set_symmetry_colour(255,35,0)` 151 | 152 | Makes sym copies brighter (yellow), rather than grey. 153 | 154 | 155 | `set_refine_max_residues(100)` 156 | 157 | Increases max number of residues included in a refinement. 158 | 159 | `set_rotamer_search_mode(ROTAMERSEARCHLOWRES)` 160 | 161 | Use "backrub" rotamers (better at low res). 162 | 163 | 164 | `set_refine_ramachandran_angles(1)` 165 | 166 | Turn ramachandran restraints on by default during real space refinement 167 | 168 | 169 | `set_map_sampling_rate(2.0)` 170 | 171 | Increase map sampling a bit for nicer looking maps. 172 | 173 | 174 | `allow_duplicate_sequence_numbers()` 175 | 176 | So Coot doesn't choke on the occasional entry in the PDB which has duplicate residue numbers. 177 | 178 | 179 | `set_add_terminal_residue_n_phi_psi_trials(1000)` 180 | 181 | Increase number of trials when adding a terminal residue 182 | 183 | 184 | `set_refinement_drag_elasticity(0.5)` 185 | 186 | Change RSR back to old "rubber-banding" behaviour. 187 | 188 | 189 | `set_matrix(20.0)` 190 | 191 | Change refinement weighting to be more appropriarte for low res (more weighting on geometry). 192 | 193 | 194 | `set_smooth_scroll_flag(0)` 195 | 196 | Make scrolling faster. 197 | 198 | 199 | `set_active_map_drag_flag(0)` 200 | 201 | Update mag after dragging - better for large map radius. 202 | 203 | 204 | `set_show_environment_distances(0) 205 | set_show_environment_distances_bumps(0) 206 | set_show_environment_distances_h_bonds(1)` 207 | 208 | Don't show environment distances by default, and only show H-bonds when shown. 209 | 210 | 211 | `set_environment_distances_distance_limits(2.1,3.2)` 212 | 213 | Set distance limits for environment distances. 214 | 215 | 216 | `set_map_radius(20)` 217 | 218 | Set default map radius. 219 | 220 | 221 | `set_default_temperature_factor_for_new_atoms(50.0)` 222 | 223 | Increase default B for new atoms. 224 | 225 | 226 | `set_add_terminal_residue_do_post_refine(1) 227 | set_terminal_residue_do_rigid_body_refine(0)` 228 | 229 | Post-refine when adding term res and don't rigid body fit (better for low res). 230 | 231 | 232 | `set_mutate_auto_fit_do_post_refine(1)` 233 | 234 | Real-space refine after mutating residue. 235 | 236 | 237 | `set_scroll_by_wheel_mouse(0)` 238 | 239 | Turn scroll-wheel adjustment of contouring off - better for trackpads, large maps. 240 | 241 | 242 | `set_symmetry_size(30)` 243 | 244 | Set default symmetry radius to 30 Å. 245 | 246 | 247 | `set_nomenclature_errors_on_read("ignore")` 248 | 249 | Turn off nomenclature errors, because they are annoying and omnipresent. 250 | 251 | -------------------------------------------------------------------------------- /coot_trimmings.py: -------------------------------------------------------------------------------- 1 | #Oli's Coot customizations: 2 | #Usage: Copy to ~/.coot-preferences 3 | #When Coot is restarted, a new "Custom" menu will appear, with some new shortcuts for various model-building tasks. 4 | #Also there will be a bunch of new keyboard shortcuts - check "Extensions...Settings...Key bindings" for details. 5 | 6 | #****Settings**** 7 | #Make symmetry copies a brighter color 8 | set_symmetry_colour(255,35,0) 9 | 10 | #turn off scrolling to change contour (for trackpads) 11 | set_scroll_by_wheel_mouse(0) 12 | 13 | #Consider clashes when autofitting rotamers. 14 | set_auto_fit_best_rotamer_clash_flag(1) 15 | 16 | #Increase the default limit for the max number of residues to refine 17 | set_refine_max_residues(100) 18 | 19 | #Sets "Backrub" rotamers as default (best at low res) 20 | set_rotamer_search_mode(ROTAMERSEARCHLOWRES) 21 | 22 | #Use ramachandran restraints in real space refinement 23 | set_refine_ramachandran_angles(1) 24 | 25 | #Use finer map sampling 26 | set_map_sampling_rate(3.0) 27 | 28 | #Allow duplicate sequence numbers (otherwise some PDBs won't load) 29 | try: 30 | allow_duplicate_sequence_numbers() 31 | except NameError: 32 | print("Your coot is a bit old... consider upgrading...") 33 | #Increase number of trials for add terminal residue 34 | set_add_terminal_residue_n_phi_psi_trials(1000) 35 | 36 | #set default refinement weighting for low resolution 37 | set_matrix(20.0) 38 | 39 | #Make scrolling faster 40 | set_smooth_scroll_flag(0) 41 | 42 | #Update map after dragging - improves speed with large map radius 43 | set_active_map_drag_flag(0) 44 | 45 | #Default to not showing environment distances, and only showing h-bonds if shown 46 | set_show_environment_distances(0) 47 | set_show_environment_distances_bumps(0) 48 | set_show_environment_distances_h_bonds(1) 49 | 50 | #Set distance limits for environment distances 51 | set_environment_distances_distance_limits(2.1,3.2) 52 | 53 | #Set default map radius 54 | set_map_radius(20) 55 | set_map_radius_em(20) 56 | 57 | #Set default bond thickness 58 | set_default_bond_thickness(3) 59 | 60 | #Use variable width bonds 61 | try: 62 | set_use_variable_bond_thickness(1) 63 | set_default_bond_thickness(7) 64 | except: 65 | print("Your coot is a bit old... consider upgrading...") 66 | 67 | #Increase default B for new atoms 68 | set_default_temperature_factor_for_new_atoms(50.0) 69 | 70 | #Post-refine when adding term res and don't rigid body fit (better for low res) 71 | set_add_terminal_residue_do_post_refine(1) 72 | set_terminal_residue_do_rigid_body_refine(0) 73 | 74 | #real space refine after mutating residue 75 | set_mutate_auto_fit_do_post_refine(1) 76 | 77 | #Set symmetry radius to 30 A 78 | set_symmetry_size(30) 79 | 80 | #Ignore nomenclature errors 81 | set_nomenclature_errors_on_read("ignore") 82 | 83 | #****Modules**** 84 | add_module_cryo_em_gui() 85 | add_module_refine() 86 | #add_module_restraints() 87 | add_module_carbohydrate_gui() 88 | 89 | #****Keybindings and toolbar buttons**** 90 | # Measure distance shortcut 91 | coot_toolbar_button("Measure distance", 92 | "do_distance_define()", icon_name="geom.svg") 93 | 94 | #Toggle display of symmetry copies 95 | coot_toolbar_button("Sym?", 96 | "set_show_symmetry_master(not get_show_symmetry())", 97 | icon_name="cell+symm.svg") 98 | 99 | 100 | 101 | #place helix with prosmart alpha helix restraints and depict in rainbow 102 | add_key_binding("Place helix here","h", 103 | lambda: place_helix_with_restraints()) 104 | 105 | #Toggle display of modelling toolbar (assumes initial state is shown) 106 | add_key_binding("Toggle toolbar display","H", 107 | lambda: toggle_toolbar_display()) 108 | 109 | #Toggle global display of map 110 | add_key_binding("Toggle global view of map","G", 111 | lambda: toggle_global_map_view()) 112 | 113 | 114 | #Quicksave active mol (overwrite orig) 115 | add_key_binding("Save and overwrite active model","Q", 116 | lambda: quicksave_active()) 117 | 118 | #Refine zond (click two atoms) 119 | add_key_binding("Refine zone","A", 120 | lambda: refine_residues_click()) 121 | 122 | #Bring up place atom at pointer dialog 123 | add_key_binding("Place atom at pointer","P", 124 | lambda: place_atom_at_pointer()) 125 | 126 | 127 | #Flip peptide. 128 | add_key_binding("Flip peptide","q", 129 | lambda: pepflip_active_residue()) 130 | 131 | #place helix with prosmart alpha helix restraints and depict in rainbow 132 | add_key_binding("Auto refine zone","a", 133 | lambda: auto_refine(10)) 134 | 135 | #Jiggle fit active res 136 | add_key_binding("Jiggle Fit","J", 137 | lambda: using_active_atom(fit_to_map_by_random_jiggle,"aa_imol","aa_chain_id","aa_res_no","aa_ins_code",1000,0.1)) 138 | 139 | #Clear pending picks 140 | add_key_binding("Clear Pending Picks","Tab", 141 | lambda: clear_pending_picks()) 142 | 143 | #Toggle environment distances 144 | add_key_binding("Toggle environment distances","D", 145 | lambda: toggle_env_dist()) 146 | 147 | #Delete active residue 148 | add_key_binding("Delete this residue","X", 149 | lambda: using_active_atom(delete_residue,"aa_imol","aa_chain_id","aa_res_no","aa_ins_code")) 150 | 151 | #Delete sidechain 152 | add_key_binding("Kill Sidechain","K", 153 | lambda: using_active_atom(delete_residue_sidechain,"aa_imol","aa_chain_id","aa_res_no","aa_ins_code",0)) 154 | 155 | #Fill sidechain 156 | add_key_binding("Fill Sidechain","k", 157 | lambda: using_active_atom(fill_partial_residue,"aa_imol","aa_chain_id","aa_res_no","aa_ins_code")) 158 | 159 | #place water without refinement 160 | add_key_binding("Add Water","w", 161 | lambda: place_typed_atom_at_pointer("Water")) 162 | 163 | #place water with refinement 164 | add_key_binding("Add Water +","W", 165 | lambda: [place_typed_atom_at_pointer("Water"),sphere_refine(),accept_moving_atoms()]) 166 | 167 | #add terminal residue 168 | add_key_binding("Add terminal residue","y", 169 | lambda: add_term_shortcut()) 170 | 171 | #add terminal residue 172 | add_key_binding("Cycle terminus phi","Y", 173 | lambda: cycle_residue_phi()) 174 | 175 | #add terminal residue 176 | add_key_binding("cycle terminus psi","T", 177 | lambda: cycle_residue_psi()) 178 | 179 | 180 | #Refine active residue 181 | add_key_binding("Refine Triple","r", 182 | lambda: key_binding_refine_triple()) 183 | 184 | #Undo Symm view 185 | add_key_binding("Undo Symmetry View", "V", 186 | lambda: undo_symmetry_view()) 187 | 188 | #Cycle through rotamers for active reidue with 'R" 189 | add_key_binding("Cycle rotamers","R", 190 | lambda: cycle_rotamers()) 191 | 192 | #Undo function for keybinding. Undoes last change to active mol. 193 | add_key_binding("Undo","z", 194 | lambda: undo_visible()) 195 | 196 | #Redo function for keybinding. redoes last change to active mol. 197 | add_key_binding("Redo","x", 198 | lambda: redo_visible()) 199 | 200 | 201 | add_key_binding("Cycle representation mode forward","[", 202 | lambda: cycle_rep_up(active_residue()[0],cycle_rep_flag.get(active_residue()[0],0))) 203 | 204 | add_key_binding("Cycle representation mode back","]", 205 | lambda: cycle_rep_down(active_residue()[0],cycle_rep_flag.get(active_residue()[0],0))) 206 | 207 | add_key_binding("Cycle symm representation mode forward","{", 208 | lambda: cycle_symm_up(active_residue()[0],cycle_symm_flag.get(active_residue()[0],0))) 209 | 210 | add_key_binding("Cycle symm representation mode back","}", 211 | lambda: cycle_symm_down(active_residue()[0],cycle_symm_flag.get(active_residue()[0],0))) 212 | 213 | add_key_binding("Toggle map display","`", 214 | lambda: toggle_map_display()) 215 | 216 | add_key_binding("Toggle mol display","/", 217 | lambda: toggle_mol_display()) 218 | 219 | #Clear distances/labels 220 | add_key_binding("Clear distances and labels","Z", 221 | lambda: clear_distances_and_labels()) 222 | 223 | #Shortcut to set map level in sigma (useful for EM maps) 224 | add_key_binding("Set map contour in sigma","L", 225 | lambda: set_map_level_quickly()) 226 | 227 | #Show local sequence context for active residue 228 | coot_toolbar_button("Sequence context", 229 | "sequence_context()", icon_name="") 230 | 231 | 232 | #Force accept real space refinemnt 233 | coot_toolbar_button("Accept RSR", 234 | "accept_regularizement()", icon_name="") 235 | 236 | #mutate active residue to entered residue code (upper or lower case single-letter) 237 | add_key_binding("Mutate by single letter code","M", 238 | lambda: mutate_by_entered_code()) 239 | 240 | 241 | #Bind next_res() and prev_res() to ">" and "<" 242 | add_key_binding("Next residue in chain",">", 243 | lambda: next_res()) 244 | add_key_binding("Prev residue in chain","<", 245 | lambda: prev_res()) 246 | 247 | #The nine key bindings elow allow easy setting of map 248 | #level by rmsd - shift + any single digit integer 249 | #sets the currently scrollable map to that level 250 | # in rmsd. Useful when on a laptop with touchpad, 251 | #when changing the contour using the scrollwheel is 252 | #not practical and using +/- is too slow. 253 | add_key_binding("Map to 1 sigma","!", 254 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),1)) 255 | 256 | add_key_binding("Map to 2 sigma","@", 257 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),2)) 258 | 259 | add_key_binding("Map to 3 sigma","#", 260 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),3)) 261 | 262 | add_key_binding("Map to 4 sigma","$", 263 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),4)) 264 | 265 | add_key_binding("Map to 5 sigma","%", 266 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),5)) 267 | 268 | add_key_binding("Map to 6 sigma","^", 269 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),6)) 270 | 271 | add_key_binding("Map to 7 sigma","&", 272 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),7)) 273 | 274 | add_key_binding("Map to 8 sigma","*", 275 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),8)) 276 | 277 | add_key_binding("Map to 9 sigma","(", 278 | lambda: set_contour_level_in_sigma(scroll_wheel_map(),9)) 279 | 280 | add_key_binding("Map plus 0.5 sigma","|", 281 | lambda: step_map_coarse_up(scroll_wheel_map())) 282 | 283 | add_key_binding("Map minus 0.5 sigma","_", 284 | lambda: step_map_coarse_down(scroll_wheel_map())) 285 | 286 | #Undisplay all models except the active one. 287 | #If only one model is displayed, cycle through 288 | #all available models. 289 | 290 | add_key_binding("Display only the active model","?", 291 | lambda: display_only_active()) 292 | 293 | 294 | 295 | #Undisplay all maps except the active one. 296 | #If only one map is displayed, cycle through 297 | #all available models. 298 | add_key_binding("Display only the active map","~", 299 | lambda: display_only_active_map()) 300 | 301 | #Go to equivalent residue on ncs master chain 302 | 303 | def goto_ncs_master(): 304 | mol_id=active_residue()[0] 305 | resno=active_residue()[2] 306 | atom_name=active_residue()[4] 307 | ncs_ch_id=ncs_master_chain_id(mol_id) 308 | set_go_to_atom_molecule(mol_id) 309 | set_go_to_atom_chain_residue_atom_name(ncs_ch_id,resno,atom_name) 310 | add_key_binding("Go to NCS master chain","O", 311 | lambda: goto_ncs_master()) 312 | 313 | 314 | #****Misc. functions (for keybindings and scripting**** 315 | def display_only_active_map(): 316 | active_map=scroll_wheel_map() 317 | if not scroll_wheel_map() in map_molecule_list(): 318 | for map_id in map_molecule_list(): 319 | if (map_is_displayed(map_id)==1) and (map_id!=active_map): 320 | set_scroll_wheel_map(map_id) 321 | set_scrollable_map(map_id) 322 | else: 323 | set_scroll_wheel_map(map_molecule_list()[0]) 324 | set_scrollable_map(map_molecule_list()[0]) 325 | active_map=scroll_wheel_map() 326 | if not map_is_displayed(active_map): 327 | set_map_displayed(active_map,1) 328 | displayed_maps_count=0 329 | for map_id in map_molecule_list(): 330 | displayed_maps_count=displayed_maps_count+map_is_displayed(map_id) 331 | if (map_is_displayed(map_id)==1) and (map_id!=active_map): 332 | set_map_displayed(map_id,0) 333 | if map_is_displayed(map_id): 334 | displayed_map=map_id 335 | if displayed_maps_count==1: 336 | index_displayed=map_molecule_list().index(active_map) 337 | try: 338 | next_map=map_molecule_list()[index_displayed+1] 339 | except IndexError: 340 | next_map=map_molecule_list()[0] 341 | set_map_displayed(active_map,0) 342 | set_map_displayed(next_map,1) 343 | set_scroll_wheel_map(next_map) 344 | set_scrollable_map(next_map) 345 | for map_id in map_molecule_list(): 346 | if map_is_displayed(map_id): 347 | set_scrollable_map(map_id) 348 | set_scroll_wheel_map(map_id) #New 349 | 350 | def hide_active_mol(): 351 | mol_id=active_residue()[0] 352 | set_mol_displayed(mol_id,0) 353 | 354 | def display_only_active(): 355 | try: 356 | mol_id_active=active_residue()[0] 357 | except: 358 | mol_id_active=model_molecule_list()[0] 359 | displayed_mols_count=0 360 | for mol_id in model_molecule_list(): 361 | displayed_mols_count=displayed_mols_count+mol_is_displayed(mol_id) 362 | if (mol_is_displayed(mol_id)==1) and (mol_id!=mol_id_active): 363 | set_mol_displayed(mol_id,0) 364 | elif (mol_is_displayed(mol_id)==0) and (mol_id==mol_id_active): 365 | set_mol_displayed(mol_id,1) 366 | if mol_is_displayed(mol_id): 367 | displayed_mol=mol_id 368 | if displayed_mols_count==1: 369 | index_displayed=model_molecule_list().index(mol_id_active) 370 | try: 371 | next_mol=model_molecule_list()[index_displayed+1] 372 | except IndexError: 373 | next_mol=model_molecule_list()[0] 374 | set_mol_displayed(displayed_mol,0) 375 | set_mol_displayed(next_mol,1) 376 | 377 | def step_map_coarse_up(mol_id): 378 | current_level=get_contour_level_in_sigma(mol_id) 379 | if (current_level >= 0.5) and (current_level <= 10.0): 380 | new_level=current_level+0.5 381 | elif (current_level<0.5): 382 | new_level=0.5 383 | elif (current_level>10.0): 384 | new_level=10.0 385 | set_contour_level_in_sigma(mol_id,new_level) 386 | 387 | def step_map_coarse_down(mol_id): 388 | current_level=get_contour_level_in_sigma(mol_id) 389 | if (current_level >= 0.5) and (current_level <= 10.0): 390 | new_level=current_level-0.5 391 | elif (current_level<0.5): 392 | new_level=0.5 393 | elif (current_level>10.0): 394 | new_level=10.0 395 | set_contour_level_in_sigma(mol_id,new_level) 396 | 397 | map_global_view_cycle_var=1 398 | def toggle_global_map_view(): 399 | global map_global_view_cycle_var 400 | map_id=scroll_wheel_map() 401 | current_colour=get_map_colour(map_id) 402 | default_colour=[0.19999998807907104, 0.38333338499069214, 0.699999988079071] 403 | default_radius=20.0 404 | new_colour=[0.4156862795352936, 0.6705882549285889, 0.886274516582489] 405 | current_radius=get_map_radius() 406 | max_radius=map_cell(map_id)[0]/2 407 | if (map_global_view_cycle_var==1) and (map_is_difference_map(map_id)==0): 408 | set_draw_solid_density_surface(map_id,1) 409 | set_draw_map_standard_lines(map_id,0) 410 | set_flat_shading_for_solid_density_surface(0) 411 | set_map_colour(map_id,new_colour[0],new_colour[1],new_colour[2]) 412 | set_map_radius(max_radius) 413 | map_global_view_cycle_var=0 414 | elif (map_global_view_cycle_var==0) and (map_is_difference_map(map_id)==0): 415 | set_draw_solid_density_surface(map_id,0) 416 | set_draw_map_standard_lines(map_id,1) 417 | set_map_colour(map_id,default_colour[0],default_colour[1],default_colour[2]) 418 | set_map_radius(default_radius) 419 | map_global_view_cycle_var=1 420 | 421 | 422 | #Go to next residue in current polymer chain. 423 | def next_res(): 424 | mol_id=active_residue()[0] 425 | ch_id=active_residue()[1] 426 | resn=active_residue()[2] 427 | atom_name=active_residue()[4] 428 | sn=get_sn_from_resno(mol_id,ch_id,resn) 429 | next_sn=sn+1 430 | next_res=seqnum_from_serial_number(mol_id,"%s"%(ch_id),next_sn) 431 | set_go_to_atom_molecule(mol_id) 432 | if (next_res!=-10000 and is_protein_chain_p(mol_id,ch_id)==1): 433 | set_go_to_atom_chain_residue_atom_name(ch_id,next_res,atom_name) 434 | elif (next_res!=-10000 and is_nucleotide_chain_p(mol_id,ch_id)==1): 435 | set_go_to_atom_chain_residue_atom_name(ch_id,next_res,atom_name) 436 | 437 | #Go to previous residue in current polymer chain. 438 | def prev_res(): 439 | mol_id=active_residue()[0] 440 | ch_id=active_residue()[1] 441 | resn=active_residue()[2] 442 | atom_name=active_residue()[4] 443 | sn=get_sn_from_resno(mol_id,ch_id,resn) 444 | if (sn>=1): 445 | sn=sn-1 446 | prev_res=seqnum_from_serial_number(mol_id,"%s"%(ch_id),sn) 447 | set_go_to_atom_molecule(mol_id) 448 | if (prev_res!=-10000 and is_protein_chain_p(mol_id,ch_id)==1): 449 | set_go_to_atom_chain_residue_atom_name(ch_id,prev_res,atom_name) 450 | elif (prev_res!=-10000 and is_nucleotide_chain_p(mol_id,ch_id)==1): 451 | set_go_to_atom_chain_residue_atom_name(ch_id,prev_res,atom_name) 452 | 453 | def mutate_by_entered_code(): 454 | def mutate_single_letter(X): 455 | entry=str(X).upper() 456 | mol_id=active_residue()[0] 457 | ch_id=active_residue()[1] 458 | resno=active_residue()[2] 459 | ins_code=active_residue()[3] 460 | resname=residue_name(mol_id,ch_id,resno,ins_code) 461 | map_id=imol_refinement_map() 462 | aa_dic={'A':'ALA','R':'ARG','N':'ASN','D':'ASP','C':'CYS','E':'GLU','Q':'GLN','G':'GLY','H':'HIS','I':'ILE','L':'LEU','K':'LYS','M':'MET','F':'PHE','P':'PRO','S':'SER','T':'THR','W':'TRP','Y':'TYR','V':'VAL'} 463 | nt_list=['A','C','T','G','U'] 464 | if (resname in aa_dic.values()) and (aa_dic.get(entry,0)!=0): 465 | mutate(mol_id,ch_id,resno,ins_code,aa_dic.get(entry,0)) 466 | elif (resname in nt_list) and (entry in nt_list): 467 | mutate_base(mol_id,ch_id,resno,ins_code,entry) 468 | else: 469 | info_dialog("Invalid target residue! Must be protein or nucleic acid, and entered code must be single letter.") 470 | generic_single_entry("New residue? (single letter code)","A","Mutate by single-letter code",mutate_single_letter) 471 | 472 | def set_map_level_quickly(): 473 | if scroll_wheel_map()!=-1 and map_is_displayed(scroll_wheel_map())!=0: 474 | current_map_level=get_contour_level_in_sigma(scroll_wheel_map()) 475 | current_map_level="{0:.2f}".format(current_map_level) 476 | def set_map_level_quickly(X): 477 | try: 478 | map_level=float(X) 479 | map_id=scroll_wheel_map() 480 | set_contour_level_in_sigma(map_id, map_level) 481 | except ValueError: 482 | info_dialog("Has to be a number!") 483 | generic_single_entry("New map level in sigma/RMS?",current_map_level,"Set map level",set_map_level_quickly) 484 | else: 485 | info_dialog("You need a (scrollable, displayed) map!") 486 | 487 | def sequence_context(): 488 | mol_id=active_residue()[0] 489 | ch_id=active_residue()[1] 490 | resnum=active_residue()[2] 491 | ins_code=active_residue()[3] 492 | resname=residue_name(mol_id,ch_id,resnum,ins_code) 493 | def get_aa_code(resnum): 494 | mol_id=active_residue()[0] 495 | ch_id=active_residue()[1] 496 | ins_code=active_residue()[3] 497 | if residue_name(mol_id,ch_id,resnum,ins_code): 498 | aa_code=three_letter_code2single_letter(residue_name(mol_id,ch_id,resnum,ins_code)) 499 | if (len(residue_name(mol_id,ch_id,resnum,ins_code))==1): 500 | aa_code=residue_name(mol_id,ch_id,resnum,ins_code) 501 | if (residue_name(mol_id,ch_id,resnum,ins_code)!="ALA") and (aa_code=="A") and (len(residue_name(mol_id,ch_id,resnum,ins_code))!=1): 502 | aa_code="X" 503 | else: 504 | aa_code="-" 505 | return aa_code 506 | current_res=get_aa_code(resnum) 507 | minus_context="" 508 | for i in range(1,10): 509 | aa_code=str(get_aa_code(resnum-i)) 510 | minus_context=aa_code + minus_context 511 | plus_context="" 512 | for i in range(1,10): 513 | aa_code=str(get_aa_code(resnum+i)) 514 | plus_context=plus_context + aa_code 515 | final_string="Residue: " + resname + " " + str(resnum) +" Sequence context: ..." + minus_context + "[" + current_res + "]" + plus_context + "..." 516 | info_dialog(final_string) 517 | 518 | #Toggle display of active map 519 | map_disp_flag={0:0} 520 | map_disp_flag_cycle=0 521 | def toggle_map_display(): 522 | global map_disp_flag 523 | global map_disp_flag_cycle 524 | if map_disp_flag_cycle==0: 525 | for map_id in map_molecule_list(): 526 | disp_value=map_is_displayed(map_id) 527 | map_disp_flag[map_id]=disp_value 528 | if disp_value==1: 529 | set_map_displayed(map_id,0) #If any maps are displayed, undisplay them. 530 | map_disp_flag_cycle=1 531 | elif map_disp_flag_cycle==1: 532 | disp_counter=0 533 | for map_id in map_molecule_list(): 534 | if map_id not in map_disp_flag: #if the map wasn't present in the previous cycle, assign a disp_value for it 535 | disp_value=map_is_displayed(map_id) 536 | map_disp_flag[map_id]=disp_value 537 | if map_disp_flag[map_id]==1: 538 | set_map_displayed(map_id,1) #Redisplay any maps that were displayed on the previous cycle. 539 | disp_counter=disp_counter+map_disp_flag[map_id] #test 540 | if disp_counter==0: #If no maps were displayed in the prior cycle, display all maps. 541 | for map_id in map_molecule_list(): 542 | set_map_displayed(map_id,1) 543 | map_disp_flag_cycle=0 544 | 545 | #Toggle display of modelling toolbar (assumes it is shown by default) 546 | toolbar_toggle_var=0 547 | def toggle_toolbar_display(): 548 | global toolbar_toggle_var 549 | if toolbar_toggle_var==0: 550 | hide_modelling_toolbar() 551 | toolbar_toggle_var=1 552 | elif toolbar_toggle_var==1: 553 | show_modelling_toolbar() 554 | toolbar_toggle_var=0 555 | 556 | #Open displayed models and maps in Chimera, set map levels and view 557 | def open_in_chimera(): 558 | if find_exe("chimera"): #If chimera exists do stuff, else raise an error 559 | import subprocess 560 | pwd=os.getcwd() #Dir from which coot was launched 561 | cofr=rotation_centre() #3-membered list [x,y,z] 562 | make_directory_maybe("coot-chimera") #Put coot droppings here 563 | coot_chimera_path=pwd+"/coot-chimera/" 564 | check_path=coot_chimera_path+"chimera_launcher.cmd" #Chimera run script that will be written later 565 | check_path2=coot_chimera_path+"matrix.txt" #Orientation matrix for chimera input 566 | view_number=add_view_here("tmp") 567 | # initial_zoom=zoom_factor() #Coot's zoom factor. 100 is the initial state, zooming out gets larger, in gets smaller. 568 | # reset_view() 569 | zoom=zoom_factor() 570 | # go_to_view_number(view_number,1) 571 | # scale_factor=initial_zoom/base_zoom 572 | # chimera_scale=base_zoom/initial_zoom 573 | chimera_scale=100.0/zoom #Approx - breaks down when initial views upon loading mol in Coot or Chimera are different 574 | coot_slab_thickness=(0.071*zoom)+2.8612 #Empirically estimated 575 | chimera_clip_val=coot_slab_thickness/2.0 #Dist from cofr to clip plane (symmetric) 576 | map_radius=get_map_radius() #We'll use this to export a map_radius sized fragment 577 | if os.path.isfile(check_path): #if chimera script exists, delete it. 578 | os.remove(check_path) 579 | if os.path.isfile(check_path2): #same for matrix.txt 580 | os.remove(check_path2) 581 | map_list=map_molecule_list() 582 | mol_list=model_molecule_list() 583 | disp_mol_list=[] 584 | disp_map_list=[] 585 | for mol_id in model_molecule_list(): 586 | if mol_is_displayed(mol_id): 587 | disp_mol_list.append(mol_id) 588 | for map_id in map_molecule_list(): 589 | if map_is_displayed(mol_id): 590 | disp_map_list.append(map_id) 591 | print("disp model list",disp_mol_list) 592 | print("disp map list",disp_map_list) 593 | set_graphics_window_size(1000,1000) 594 | matrix_list=view_matrix() #9-membered list of rotation matrix elements. 595 | with open(check_path2,"a") as matrix_file: #Write orientation matrix (specify first pdb as model, then use matrixcopy to apply to all others). Translation vector in last column is 0,0,0 because we will take care of that separately. 596 | matrix_file.write("Model {model_id}.0\n".format(model_id=disp_mol_list[0])) 597 | matrix_file.write("\t {a} {b} {c} 0.0\n".format(a=matrix_list[0],b=matrix_list[1],c=matrix_list[2])) 598 | matrix_file.write("\t {a} {b} {c} 0.0\n".format(a=matrix_list[3],b=matrix_list[4],c=matrix_list[5])) 599 | matrix_file.write("\t {a} {b} {c} 0.0\n".format(a=matrix_list[6],b=matrix_list[7],c=matrix_list[8])) 600 | with open(check_path,"a") as cmd_file: #Start writing stuff to chimera launch script. 601 | for mol_id in model_molecule_list(): 602 | if mol_is_displayed(mol_id): 603 | file_name=coot_chimera_path+"mol_{mol_id}.pdb".format(mol_id=mol_id) 604 | write_pdb_file(mol_id,file_name) 605 | path_to_file=file_name 606 | model_id=mol_id 607 | cmd_file.write("open #{model_id} {mol}\n".format(model_id=model_id,mol=path_to_file)) 608 | cmd_file.write("color gold #{model_id}; color byhet #{model_id}; sel #{model_id}; namesel tmp; ~ribbon tmp; ~disp tmp; sel tmp&@CA&protein; repr stick sel; disp sel; sel tmp&~protein; repr stick sel; disp sel; setattr m stickScale 1.0 tmp; sel side chain/base.without CA/C1'&tmp; repr stick sel; disp sel; setattr b radius 0.1 sel; color byhet tmp; sel @CA|@CB; namesel tmp2; sel tmp&tmp2; repr stick sel; setattr b radius 0.1 sel; sel @CD,N&:pro&tmp; disp sel; repr stick sel; setattr b radius 0.1 sel; ~sel; disp ~protein\n".format(model_id=model_id)) 609 | cmd_file.write("matrixset matrix.txt\n") 610 | cmd_file.write("matrixcopy #{mol_id0} #{mol_id}\n".format(mol_id0=disp_mol_list[0],mol_id=model_id)) 611 | map_id0=mol_id 612 | for map_id in map_molecule_list(): 613 | if map_is_displayed(map_id): 614 | map_level=get_contour_level_absolute(map_id) 615 | if map_is_difference_map(map_id): 616 | model_id=map_id0+map_id #make sure that the assigned model number of each map is unique and does not overlap with those of pdbs. 617 | if map_id==0: 618 | model_id=model_id+1 619 | file_name=coot_chimera_path+"diff_map_{model_id}.mrc".format(model_id=model_id) 620 | path_to_file=file_name 621 | export_map_fragment(map_id,cofr[0],cofr[1],cofr[2],map_radius,file_name) 622 | cmd_file.write("open #{model_id} {diff_map} \n".format(model_id=model_id,diff_map=path_to_file)) 623 | cmd_file.write("volume #{model_id} capfaces false style mesh meshlighting false squaremesh false color \"#08882eefa222\" step 1 ; sop cap off ; set depthCue ; set dcStart 0.2 ; set dcEnd 1 ; background solid white ; set showcofr ; cofr view ; clip on; volume #{model_id} level -{map_level} color #da1200000000 level {map_level} color #0000bda00000 \n".format(model_id=model_id,map_level=map_level)) 624 | cmd_file.write("matrixset matrix.txt\n") 625 | cmd_file.write("matrixcopy #{mol_id0} #{model_id}\n".format(mol_id0=disp_mol_list[0],model_id=model_id)) 626 | else: 627 | model_id=map_id0+map_id 628 | if map_id==0: 629 | model_id=model_id+1 630 | file_name=coot_chimera_path+"map_{model_id}.mrc".format(model_id=model_id) 631 | export_map_fragment(map_id,cofr[0],cofr[1],cofr[2],map_radius,file_name) 632 | path_to_file=file_name 633 | cmd_file.write("open #{model_id} {map} \n".format(model_id=model_id,map=path_to_file)) 634 | cmd_file.write("volume #{model_id} capfaces false style mesh meshlighting false squaremesh false color \"#08882eefa222\" step 1 ; sop cap off ; set depthCue ; set dcStart 0.2 ; set dcEnd 1 ; background solid white ; set showcofr ; cofr view ; clip on; volume #{model_id} level {map_level} \n".format(model_id=model_id,map_level=map_level)) 635 | cmd_file.write("matrixset matrix.txt\n") 636 | cmd_file.write("matrixcopy #{mol_id0} #{model_id}\n".format(mol_id0=disp_mol_list[0],model_id=model_id)) 637 | cmd_file.write("~sel; set projection orthographic; clip off; cofr {x},{y},{z} coordinatesystem #{mol_id0}; ac mc; center sel; cofr view; cofr fixed; clip hither {clipval} fromCenter true; clip yon -{clipval} fromCenter true; cofr view; clip on; ~set showcofr; del sel; scale {chimera_scale}; windowsize 1000 1000; scene ca_and_sidechains save; disp; scene all_atoms save; scene ca_and_sidechains reset; windowsize 1000 1000".format(x=cofr[0],y=cofr[1],z=cofr[2],mol_id0=disp_mol_list[0],chimera_scale=chimera_scale,clipval=chimera_clip_val)) 638 | #line above applies translation and scale obtained from coot rotation center and zoom_factor 639 | chimera_exe=find_exe("chimera") 640 | info_dialog("Opening in Chimera...\nOrientation should be right but you will probably need to \nadjust the scale and clipping to get the same view as in Coot. \n If you can't see anything, try zooming out.") 641 | subprocess.Popen(["chimera",check_path]) 642 | else: 643 | info_dialog("Sorry, you need UCSF Chimera installed and accessible from the terminal for this to work!") 644 | #This works okay, though adjustment of zoom and clipping still not ideal. 645 | #would it be possible to add a subprocess.communicate() to use Coot as a controller for Chimera? 646 | #Hmmm 647 | #Doesn't work when attempting to open second set of maps loaded, when first set is undisplayed... Fixed! (I think) 648 | 649 | 650 | #Colour active segment 651 | def colour_active_segment(): 652 | mol_id=active_residue()[0] 653 | segments=segment_list(mol_id) 654 | res_here=active_residue()[2] 655 | ins_code=active_residue()[3] 656 | ch_id=active_residue()[1] 657 | colour_list=[] 658 | blank_list=[] 659 | segment_colour=34 660 | blank_colour=0 661 | for seg in segments: 662 | if (res_here>=seg[2]) and (res_here<=seg[3]) and (ch_id==seg[1]): 663 | res_start=seg[2] 664 | res_end=seg[3] 665 | ch_id=seg[1] 666 | for res in range(res_start,res_end+1): 667 | res_color_spec=[([ch_id,res,""],segment_colour)] 668 | colour_list=colour_list+res_color_spec 669 | else: 670 | res_start=seg[2] 671 | res_end=seg[3] 672 | ch_id_here=seg[1] 673 | for res in range(res_start,res_end+1): 674 | blank_color_spec=[([ch_id_here,res,""],blank_colour)] 675 | blank_list=blank_list+blank_color_spec 676 | clear_user_defined_atom_colours(mol_id) 677 | set_user_defined_atom_colour_by_residue_py(mol_id,colour_list) 678 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_list) 679 | graphics_to_user_defined_atom_colours_representation(mol_id) 680 | 681 | 682 | def color_emringer_outliers(mol_id,map_id): 683 | if find_exe("phenix.emringer"): 684 | import subprocess 685 | import sys 686 | mmtbx_path=find_exe("phenix")[:-16]+"modules/cctbx_project/" 687 | sys.path.insert(0,mmtbx_path) 688 | import mmtbx 689 | import cPickle as pickle 690 | pwd=os.getcwd() 691 | model_name=molecule_name(mol_id) 692 | map_name=molecule_name(map_id) 693 | make_directory_maybe("coot-emringer") 694 | coot_emringer_path=pwd+"/coot-emringer/" 695 | output_file_name=coot_emringer_path+"mol_{mol_id}_cablam_output.txt".format(mol_id=mol_id) 696 | p=subprocess.Popen("phenix.emringer {model_name} {map_name}".format(model_name=model_name,map_name=map_name),shell=True) 697 | p.communicate() 698 | emringer_outlier_list=[] 699 | emringer_outlier_color=30 700 | emringer_outlier_pkl=pwd+"/"+molecule_name_stub(mol_id,2)+"_emringer_plots/Outliers.pkl" 701 | outlier_string=str(pickle.load(open(emringer_outlier_pkl,"rb"))) 702 | with open(output_file_name,"a") as outlier_file: 703 | outlier_file.write(outlier_string) 704 | with open(output_file_name) as f: 705 | emringer_output = [x.strip('\n') for x in f.readlines()] #make a list of lines in cablam output file, stripping newlines 706 | for line in emringer_output: 707 | line_list=line.split() 708 | if len(line_list)>=5: 709 | ch_id=str(line_list[2]) # string.split() defaults to splitting by spaces and making into a list 710 | print("ch_id:",ch_id) 711 | resid=int(line_list[1]) #If second column has trailing letters (as it will if there is an insertion code) then strip them 712 | print("resid",resid) 713 | ins_id="" 714 | emringer_outlier_color_spec=[([ch_id,resid,ins_id],emringer_outlier_color)] 715 | emringer_outlier_list=emringer_outlier_list+emringer_outlier_color_spec 716 | print("outlier_list",emringer_outlier_list) 717 | try: 718 | set_user_defined_atom_colour_by_residue_py(mol_id,emringer_outlier_list) 719 | graphics_to_user_defined_atom_colours_representation(mol_id) 720 | except NameError: 721 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 722 | pass 723 | else: 724 | info_dialog("Sorry, you need phenix.cablam_validate, sed and awk installed and accessible from the terminal for this to work!") 725 | 726 | def color_by_cablam2(mol_id): 727 | if find_exe("phenix.cablam_validate") and find_exe("awk") and find_exe("sed"): 728 | import subprocess 729 | pwd=os.getcwd() #dir where coot was launched 730 | make_directory_maybe("coot-cablam") #Put coot droppings here 731 | coot_cablam_path=pwd+"/coot-cablam/" 732 | file_name=molecule_name(mol_id) 733 | file_name_output=coot_cablam_path+"mol_{mol_id}_cablam_output.txt".format(mol_id=mol_id) #this file will have info on cablam outliers 734 | # write_pdb_file(mol_id,file_name) # write a copy of the active mol to the cablam dir 735 | p=subprocess.Popen("phenix.cablam_validate {file_name} outlier_cutoff=0.01 | tail -n +2 | awk '{{FS=\":\"}} {{print $1,$2,$5}}' | sed 's/CaBLAM Outlier/1/g' | sed 's/CaBLAM Disfavored/2/g' | sed 's/CA Geom Outlier/3/g' | sed 's/try alpha helix/4/g' | sed 's/try beta sheet/5/g' | sed 's/try three-ten/6/g' | sed 's/[0123456789-]/ &/' > {file_name_output}".format(file_name=file_name,file_name_output=file_name_output),shell=True) 736 | p.communicate() #wait for cablam to finish 737 | cablam_outlier_list=[] 738 | cablam_beta_list=[] 739 | cablam_alpha_list=[] 740 | cablam_3_10_list=[] 741 | cablam_disfavored_list=[] 742 | cablam_outlier_colour=30 743 | cablam_disfavored_colour=27 744 | cablam_alpha_colour=10 745 | cablam_beta_colour=39 746 | cablam_3_10_colour=15 747 | cablam_ca_geom_colour=10 748 | blank_colour=0 749 | outlier_flag=0 750 | with open(file_name_output) as f: 751 | cablam_output = [x.strip('\n') for x in f.readlines()] #make a list of lines in cablam output file, stripping newlines 752 | for line in cablam_output: 753 | line_list=line.split() 754 | if len(line_list)>=3: 755 | ch_id=line_list[0] # string.split() defaults to splitting by spaces and making into a list 756 | resid=int(line_list[1].rstrip('abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')) #If second column has trailing letters (as it will if there is an insertion code) then strip them 757 | ins_id=str(line_list[1].lstrip('0123456789')) #If second column has trailing characters, these correspond to the insertion code. Strip leading numbers. 758 | resname=line_list[2] 759 | if len(line_list)>3: 760 | outlier_flag=int(line_list[3]) #1 is Cablam outlier 2 is cablam disfavored, and 3 is ca geom outlier 761 | if outlier_flag==1: #CaBLAM outliers 762 | cablam_outlier_colour_spec=[([ch_id,resid,ins_id],cablam_outlier_colour)] 763 | cablam_outlier_list=cablam_outlier_list+cablam_outlier_colour_spec 764 | elif outlier_flag==2: #CaBLAM disfavored 765 | cablam_outlier_colour_spec=[([ch_id,resid,ins_id],cablam_disfavored_colour)] 766 | cablam_outlier_list=cablam_outlier_list+cablam_outlier_colour_spec 767 | elif outlier_flag==3: #CaBLAM disfavored 768 | cablam_outlier_colour_spec=[([ch_id,resid,ins_id],cablam_ca_geom_colour)] 769 | cablam_outlier_list=cablam_outlier_list+cablam_outlier_colour_spec 770 | elif outlier_flag==4: #alpha 771 | cablam_outlier_colour_spec=[([ch_id,resid,ins_id],cablam_alpha_colour)] 772 | cablam_outlier_list=cablam_outlier_list+cablam_outlier_colour_spec 773 | elif outlier_flag==5: #beta 774 | cablam_outlier_colour_spec=[([ch_id,resid,ins_id],cablam_beta_colour)] 775 | cablam_outlier_list=cablam_outlier_list+cablam_outlier_colour_spec 776 | elif outlier_flag==6: #3-10 helix 777 | cablam_outlier_colour_spec=[([ch_id,resid,ins_id],cablam_3_10_colour)] 778 | cablam_outlier_list=cablam_outlier_list+cablam_outlier_colour_spec 779 | else: 780 | cablam_outlier_colour_spec=[([ch_id,resid,ins_id],blank_colour)] 781 | cablam_outlier_list=cablam_outlier_list+cablam_outlier_colour_spec 782 | else: 783 | cablam_outlier_colour_spec=[([ch_id,resid,ins_id],blank_colour)] 784 | cablam_outlier_list=cablam_outlier_list+cablam_outlier_colour_spec 785 | # os.remove(file_name) 786 | os.remove(file_name_output) 787 | try: 788 | set_user_defined_atom_colour_by_residue_py(mol_id,cablam_outlier_list) 789 | graphics_to_user_defined_atom_colours_representation(mol_id) 790 | info_dialog("CaBLAM coloring scheme (predicted SS and outliers): \n \n Teal = alpha \n \n Green = 3-10 \n \n Purple = beta \n \n Yellow = Ca geometry outlier \n \n Orange = CaBLAM disfavored (5% cutoff) \n \n Red = CaBLAM outlier (1% cutoff)") 791 | except NameError: 792 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 793 | pass 794 | else: 795 | info_dialog("Sorry, you need phenix.cablam_validate, sed and awk installed and accessible from the terminal for this to work!") 796 | 797 | def color_by_rama(mol_id): 798 | if find_exe("phenix.ramalyze") and find_exe("awk") and find_exe("sed"): 799 | import subprocess 800 | pwd=os.getcwd() #dir where coot was launched 801 | make_directory_maybe("coot-ramalyze") #Put coot droppings here 802 | coot_ramalyze_path=pwd+"/coot-ramalyze/" 803 | file_name=molecule_name(mol_id) 804 | file_name_output=coot_ramalyze_path+"mol_{mol_id}_ramalyze_output.txt".format(mol_id=mol_id) #this file will have info on ramalyze outliers 805 | # write_pdb_file(mol_id,file_name) # write a copy of the active mol to the ramalyze dir 806 | p=subprocess.Popen("phenix.ramalyze {file_name} outliers_only=true rama_potential=emsley | awk '{{FS=\":\"}} {{print $1}}' | sed 's/[0123456789-]/ &/' | awk '{{if (NF==3) print}}' > {file_name_output}".format(file_name=file_name,file_name_output=file_name_output),shell=True) 807 | p.communicate() #wait for ramalyze to finish 808 | ramalyze_outlier_list=[] 809 | ramalyze_outlier_colour=34 810 | blank_res_list=[] 811 | blank_colour=0 812 | for ch_id in chain_ids(mol_id): 813 | sn_max=chain_n_residues(ch_id,mol_id) 814 | for sn in range(0,sn_max+1): 815 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 816 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 817 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 818 | blank_res_list=blank_res_list+residue_to_color 819 | with open(file_name_output) as f: 820 | ramalyze_output = [x.strip('\n') for x in f.readlines()] #make a list of lines in ramalyze output file, stripping newlines 821 | for line in ramalyze_output: 822 | line_list=line.split() 823 | ch_id=line_list[0] # string.split() defaults to splitting by spaces and making into a list 824 | resid=int(line_list[1].rstrip('abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')) #If second column has trailing letters (as it will if there is an insertion code) then strip them 825 | ins_id=str(line_list[1].lstrip('0123456789')) #If second column has trailing characters, these correspond to the insertion code. Strip leading numbers. 826 | resname=line_list[2] 827 | ramalyze_outlier_colour_spec=[([ch_id,resid,ins_id],ramalyze_outlier_colour)] 828 | ramalyze_outlier_list=ramalyze_outlier_list+ramalyze_outlier_colour_spec 829 | # os.remove(file_name) 830 | os.remove(file_name_output) 831 | try: 832 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_res_list) 833 | set_user_defined_atom_colour_by_residue_py(mol_id,ramalyze_outlier_list) 834 | graphics_to_user_defined_atom_colours_representation(mol_id) 835 | except NameError: 836 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 837 | pass 838 | else: 839 | info_dialog("Sorry, you need phenix.ramalyze, sed and awk installed and accessible from the terminal for this to work!") 840 | 841 | def color_by_cc(mol_id): 842 | if find_exe("phenix.model_map_cc") and find_exe("awk") and find_exe("sed") and find_exe("grep") and imol_refinement_map()!=-1 and space_group(imol_refinement_map())=="P 1": 843 | import subprocess 844 | pwd=os.getcwd() #dir where coot was launched 845 | make_directory_maybe("coot-cc") #Put coot droppings here 846 | coot_cc_path=pwd+"/coot-cc/" 847 | pdb_name=molecule_name(mol_id) 848 | map_id=int(imol_refinement_map()) 849 | map_name=molecule_name(map_id) 850 | # write_pdb_file(mol_id,pdb_name) # write a copy of the active mol to the cc dir 851 | if not (map_name.endswith(".ccp4") or map_name.endswith(".mrc") or map_name.endswith(".map")): 852 | map_name=coot_cc_path+"mol_{mol_id}.ccp4".format(mol_id=mol_id) 853 | export_map(map_id,map_name) 854 | file_name_output=coot_cc_path+"mol_{mol_id}_cc_output.txt".format(mol_id=mol_id) #this file will have info on cc outliers 855 | p=subprocess.Popen("phenix.model_map_cc {pdb_name} {map_name} resolution=4.0 | awk '{{if (NF==7) print}}' | grep chain > {file_name_output}".format(pdb_name=pdb_name,map_name=map_name,file_name_output=file_name_output),shell=True) 856 | p.communicate() #wait for cc to finish 857 | cc_list=[] 858 | with open(file_name_output) as f: 859 | cc_output = [x.strip('\n') for x in f.readlines()] #make a list of lines in cc output file, stripping newlines 860 | for line in cc_output: 861 | line_list=line.split() 862 | ch_id=line_list[2] # string.split() defaults to splitting by spaces and making into a list 863 | resid=int(line_list[4].rstrip('abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')) #If second column has trailing letters (as it will if there is an insertion code) then strip them 864 | ins_id=str(line_list[4].lstrip('0123456789')) #If second column has trailing characters, these correspond to the insertion code. Strip leading numbers. 865 | cc=float(line_list[6]) 866 | if cc<0.0: 867 | cc=0.0 868 | cc_colour=int((1.0-cc)*31+2) 869 | print("cc=",cc,"color=",cc_colour) 870 | cc_colour_spec=[([ch_id,resid,ins_id],cc_colour)] 871 | cc_list=cc_list+cc_colour_spec 872 | try: 873 | set_user_defined_atom_colour_by_residue_py(mol_id,cc_list) 874 | graphics_to_user_defined_atom_colours_representation(mol_id) 875 | except NameError: 876 | info_dialog("You need a newer Coot - custom coloring is only in r6188 and later, sorry.") 877 | pass 878 | else: 879 | info_dialog("Sorry, you need phenix.model_map_cc, sed and awk installed and accessible from the terminal for this to work! Also, needs to be P1 map right now, sorry.") 880 | 881 | 882 | #Set refinement map to currently scrollable map 883 | def set_map_to_scrollable_map(): 884 | if map_molecule_list()!=[]: 885 | set_imol_refinement_map(scroll_wheel_map()) 886 | else: 887 | info_dialog("You need a map for this to work.") 888 | 889 | #Toggle display of active model 890 | mol_disp_flag={0:0} 891 | mol_disp_flag_cycle=0 892 | def toggle_mol_display(): 893 | global mol_disp_flag 894 | global mol_disp_flag_cycle 895 | if mol_disp_flag_cycle==0: 896 | for mol_id in model_molecule_list(): 897 | mol_disp_value=mol_is_displayed(mol_id) 898 | mol_disp_flag[mol_id]=mol_disp_value 899 | if mol_disp_value==1: 900 | set_mol_displayed(mol_id,0) 901 | mol_disp_flag_cycle=1 902 | elif mol_disp_flag_cycle==1: 903 | disp_counter=0 904 | for mol_id in model_molecule_list(): 905 | if mol_id not in mol_disp_flag: 906 | disp_value=mol_is_displayed(mol_id) 907 | mol_disp_flag[mol_id]=disp_value 908 | if mol_disp_flag[mol_id]==1: 909 | set_mol_displayed(mol_id,1) 910 | disp_counter=disp_counter+mol_disp_flag[mol_id] 911 | if disp_counter==0: 912 | for mol_id in model_molecule_list(): 913 | set_mol_displayed(mol_id,1) 914 | mol_disp_flag_cycle=0 915 | 916 | #Cycle representation mode forward/back 917 | cycle_rep_flag={0:0} 918 | def cycle_rep_up(mol_id,flag): 919 | global cycle_rep_flag 920 | cycle_rep_flag[mol_id]=flag 921 | if cycle_rep_flag[mol_id]==0: 922 | graphics_to_ca_plus_ligands_representation(mol_id) 923 | cycle_rep_flag[mol_id]=1 924 | elif cycle_rep_flag[mol_id]==1: 925 | graphics_to_ca_plus_ligands_and_sidechains_representation(mol_id) 926 | cycle_rep_flag[mol_id]=2 927 | elif cycle_rep_flag[mol_id]==2: 928 | graphics_to_rainbow_representation(mol_id) 929 | cycle_rep_flag[mol_id]=3 930 | elif cycle_rep_flag[mol_id]==3: 931 | graphics_to_bonds_representation(mol_id) 932 | cycle_rep_flag[mol_id]=4 933 | elif cycle_rep_flag[mol_id]==4: 934 | try: 935 | graphics_to_user_defined_atom_colours_representation(mol_id) 936 | cycle_rep_flag[mol_id]=5 937 | except NameError: 938 | cycle_rep_flag[mol_id]=0 939 | elif cycle_rep_flag[mol_id]==5: 940 | try: 941 | graphics_to_user_defined_atom_colours_all_atoms_representation(mol_id) 942 | cycle_rep_flag[mol_id]=0 943 | except NameError: 944 | cycle_rep_flag[mol_id]=0 945 | 946 | # def add_partial_water(): 947 | # place_typed_atom_at_pointer("Water") 948 | # refine_active_residue() 949 | # mol_id=active_residue()[0] 950 | # ch_id=active_residue()[1] 951 | # resno=active_residue()[2] 952 | # ins_code=active_residue()[3] 953 | # atom_name=active_residue()[4] 954 | # alt_conf="" 955 | # set_atom_attribute(mol_id,ch_id,resno,ins_code,atom_name,alt_conf,"occ",0.5) 956 | # add_key_binding("Add partial water","w", 957 | # lambda: add_partial_water()) 958 | 959 | # def delete_alt_confs(): 960 | # mol_id=active_residue()[0] 961 | # for ch_id in chain_ids(mol_id): 962 | # for resn in (first_residue(mol_id,ch_id),last_residue(mol_id,ch_id)+1): 963 | # residue_inf=residue_info(mol_id,ch_id,resn,"") 964 | 965 | 966 | def cycle_rep_down(mol_id,flag): 967 | global cycle_rep_flag 968 | cycle_rep_flag[mol_id]=flag 969 | if cycle_rep_flag[mol_id]==3: 970 | graphics_to_ca_plus_ligands_and_sidechains_representation(mol_id) 971 | cycle_rep_flag[mol_id]=2 972 | elif cycle_rep_flag[mol_id]==2: 973 | graphics_to_ca_plus_ligands_representation(mol_id) 974 | cycle_rep_flag[mol_id]=1 975 | elif cycle_rep_flag[mol_id]==1: 976 | try: 977 | graphics_to_user_defined_atom_colours_all_atoms_representation(mol_id) 978 | cycle_rep_flag[mol_id]=0 979 | except NameError: 980 | cycle_rep_flag[mol_id]=5 981 | elif cycle_rep_flag[mol_id]==0: 982 | try: 983 | graphics_to_user_defined_atom_colours_representation(mol_id) 984 | cycle_rep_flag[mol_id]=5 985 | except NameError: 986 | cycle_rep_flag[mol_id]=5 987 | elif cycle_rep_flag[mol_id]==5: 988 | graphics_to_bonds_representation(mol_id) 989 | cycle_rep_flag[mol_id]=4 990 | elif cycle_rep_flag[mol_id]==4: 991 | graphics_to_rainbow_representation(mol_id) 992 | cycle_rep_flag[mol_id]=3 993 | 994 | 995 | #Refine triple (Paul) 996 | def key_binding_refine_triple(): 997 | active_atom = active_residue() 998 | if not active_atom: 999 | print("No active atom") 1000 | else: 1001 | imol = active_atom[0] 1002 | residue_spec = atom_spec_to_residue_spec(active_atom) 1003 | N_terminal_residue_spec = [residue_spec_to_chain_id(residue_spec), 1004 | residue_spec_to_res_no(residue_spec)-1, 1005 | residue_spec_to_ins_code(residue_spec)] 1006 | C_terminal_residue_spec = [residue_spec_to_chain_id(residue_spec), 1007 | residue_spec_to_res_no(residue_spec)+1, 1008 | residue_spec_to_ins_code(residue_spec)] 1009 | spec_list = [N_terminal_residue_spec, residue_spec, C_terminal_residue_spec] 1010 | refine_residues(imol, spec_list) 1011 | 1012 | #Cycle symmetry represntation mode forward/back 1013 | cycle_symm_flag={0:0} 1014 | def cycle_symm_up(mol_id,flag): 1015 | global cycle_symm_flag 1016 | cycle_symm_flag[mol_id]=flag 1017 | if cycle_symm_flag[mol_id]==0: 1018 | get_show_symmetry() 1019 | set_show_symmetry_master(1) 1020 | symmetry_as_calphas(mol_id,1) 1021 | cycle_symm_flag[mol_id]=1 1022 | elif cycle_symm_flag[mol_id]==1: 1023 | get_show_symmetry() 1024 | set_show_symmetry_master(1) 1025 | symmetry_as_calphas(mol_id,0) 1026 | set_symmetry_whole_chain(mol_id,1) 1027 | cycle_symm_flag[mol_id]=2 1028 | elif cycle_symm_flag[mol_id]==2: 1029 | get_show_symmetry() 1030 | set_show_symmetry_master(1) 1031 | symmetry_as_calphas(mol_id,0) 1032 | set_symmetry_whole_chain(mol_id,0) 1033 | cycle_symm_flag[mol_id]=3 1034 | elif cycle_symm_flag[mol_id]==3: 1035 | get_show_symmetry() 1036 | set_show_symmetry_master(0) 1037 | cycle_symm_flag[mol_id]=0 1038 | def cycle_symm_down(mol_id,flag): 1039 | global cycle_symm_flag 1040 | cycle_symm_flag[mol_id]=flag 1041 | if cycle_symm_flag[mol_id]==3: 1042 | get_show_symmetry() 1043 | set_show_symmetry_master(1) 1044 | symmetry_as_calphas(mol_id,0) 1045 | set_symmetry_whole_chain(mol_id,1) 1046 | cycle_symm_flag[mol_id]=2 1047 | elif cycle_symm_flag[mol_id]==2: 1048 | get_show_symmetry() 1049 | set_show_symmetry_master(1) 1050 | symmetry_as_calphas(mol_id,1) 1051 | cycle_symm_flag[mol_id]=1 1052 | elif cycle_symm_flag[mol_id]==1: 1053 | get_show_symmetry() 1054 | set_show_symmetry_master(0) 1055 | cycle_symm_flag[mol_id]=0 1056 | elif cycle_symm_flag[mol_id]==0: 1057 | get_show_symmetry() 1058 | set_show_symmetry_master(1) 1059 | symmetry_as_calphas(mol_id,0) 1060 | set_symmetry_whole_chain(mol_id,0) 1061 | cycle_symm_flag[mol_id]=3 1062 | 1063 | def undo_visible(): 1064 | set_undo_molecule(active_residue()[0]) 1065 | apply_undo() 1066 | 1067 | def redo_visible(): 1068 | set_undo_molecule(active_residue()[0]) 1069 | apply_redo() 1070 | 1071 | #Cycle rotamers for active residue 1072 | rotamer_number=0 1073 | def cycle_rotamers(): 1074 | global rotamer_number 1075 | mol_id=active_residue()[0] 1076 | ch_id=active_residue()[1] 1077 | res_here=active_residue()[2] 1078 | ins_code="" 1079 | alt_conf="" 1080 | n_rots=n_rotamers(mol_id, ch_id, res_here, ins_code)-1 1081 | turn_off_backup(mol_id) 1082 | update_go_to_atom_from_current_position() 1083 | if rotamer_number>=n_rots: 1084 | rotamer_number=0 1085 | set_residue_to_rotamer_number(mol_id,ch_id,res_here,ins_code,alt_conf,rotamer_number) 1086 | else: 1087 | rotamer_number=rotamer_number+1 1088 | set_residue_to_rotamer_number(mol_id,ch_id,res_here,ins_code,alt_conf,rotamer_number) 1089 | turn_on_backup(mol_id) 1090 | 1091 | #Toggle environment distances 1092 | def toggle_env_dist(): 1093 | if show_environment_distances_state()==1: 1094 | set_show_environment_distances(0) 1095 | else: 1096 | set_show_environment_distances(1) 1097 | 1098 | #Check if residue is in a polymer by comparing resname to list 1099 | def is_polymer_residue(mol_id,ch_id,sn): 1100 | valid_resnames=['A','C','T','G','U','ALA','UNK','ARG','ASN','ASP','CYS','GLU','GLN','GLY','HIS','ILE','LEU','LYS','MET','MSE','PHE','PRO','SER','THR','TRP','TYR','VAL'] 1101 | resname=resname_from_serial_number(mol_id,ch_id,sn) 1102 | if resname in valid_resnames: 1103 | return 1 1104 | else: 1105 | return 0 1106 | 1107 | #Return last residue in polymer 1108 | def last_polymer_residue(mol_id,ch_id): 1109 | if ((valid_model_molecule_qm(mol_id)) and (ch_id in chain_ids(mol_id))): 1110 | if not is_solvent_chain_qm(mol_id,ch_id): 1111 | n=chain_n_residues(ch_id,mol_id)-1 1112 | valid_resnames=['A','C','T','G','U','ALA','UNK','ARG','ASN','ASP','CYS','GLU','GLN','GLY','HIS','ILE','LEU','LYS','MET','MSE','PHE','PRO','SER','THR','TRP','TYR','VAL'] 1113 | while resname_from_serial_number(mol_id,"%s"%(ch_id),n) not in valid_resnames: 1114 | n=n-1 1115 | result=seqnum_from_serial_number(mol_id,"%s"%(ch_id),n) 1116 | return result 1117 | else: 1118 | return -1 1119 | 1120 | def first_polymer_residue(mol_id,ch_id): 1121 | if ((valid_model_molecule_qm(mol_id)) and (ch_id in chain_ids(mol_id))): 1122 | if not is_solvent_chain_qm(mol_id,ch_id): 1123 | n=0 1124 | valid_resnames=['A','C','T','G','U','ALA','UNK','ARG','ASN','ASP','CYS','GLU','GLN','GLY','HIS','ILE','LEU','LYS','MET','MSE','PHE','PRO','SER','THR','TRP','TYR','VAL'] 1125 | while resname_from_serial_number(mol_id,"%s"%(ch_id),n) not in valid_resnames: 1126 | n=n+1 1127 | result=seqnum_from_serial_number(mol_id,"%s"%(ch_id),n) 1128 | return result 1129 | else: 1130 | return -1 1131 | 1132 | 1133 | #Return last res (polymer or not) 1134 | def last_residue(mol_id,ch_id): 1135 | n=chain_n_residues(ch_id,mol_id)-1 1136 | result=seqnum_from_serial_number(mol_id,"%s"%(ch_id),n) 1137 | return result 1138 | 1139 | #Return first res (polymer or not) 1140 | def first_residue(mol_id,ch_id): 1141 | result=seqnum_from_serial_number(mol_id,"%s"%(ch_id),0) 1142 | return result 1143 | 1144 | #Check if chain is polymer 1145 | def is_polymer(mol_id,ch_id): 1146 | a=is_protein_chain_p(mol_id,"%s"%(ch_id)) 1147 | b=is_nucleotide_chain_p(mol_id,"%s"%(ch_id)) 1148 | if (a==1) or (b==1): 1149 | result=1 1150 | else: 1151 | result=0 1152 | return result 1153 | 1154 | #Check if residue is last in polymer 1155 | def is_last_polymer_residue_sn(mol_id,ch_id,sn): 1156 | if ((valid_model_molecule_qm(mol_id)) and (ch_id in chain_ids(mol_id))): 1157 | if not is_solvent_chain_qm(mol_id,ch_id): 1158 | valid_resnames=['A','C','T','G','U','ALA','UNK','ARG','ASN','ASP','CYS','GLU','GLN','GLY','HIS','ILE','LEU','LYS','MET','MSE','PHE','PRO','SER','THR','TRP','TYR','VAL'] 1159 | if (resname_from_serial_number(mol_id,"%s"%(ch_id),sn) in valid_resnames) and (resname_from_serial_number(mol_id,"%s"%(ch_id),sn+1) not in valid_resnames): 1160 | return 1 1161 | else: 1162 | return -1 1163 | 1164 | #get serial number from resnum 1165 | def get_sn_from_resno(mol_id,ch_id,resno): 1166 | sn=chain_n_residues(ch_id,mol_id)-1 1167 | sn2=0 1168 | resno_out="" 1169 | resno_out_2="" 1170 | if resno>last_residue(mol_id,ch_id) or resno=2): 1211 | return 1 1212 | else: 1213 | return 0 1214 | else: 1215 | return 0 1216 | 1217 | 1218 | #check if res is at C-term side of break in mid chain 1219 | def is_term_type_mc_sn(mol_id,ch_id,sn): 1220 | if sn in range(1,chain_n_residues(ch_id,mol_id)): 1221 | resn_here=seqnum_from_serial_number(mol_id,ch_id,sn) 1222 | if (is_polymer_residue(mol_id,ch_id,sn)==1) and (is_polymer_residue(mol_id,ch_id,sn+1)==1): 1223 | resn_next=seqnum_from_serial_number(mol_id,ch_id,sn+1) 1224 | diff_next=resn_next-resn_here 1225 | if (diff_next>=2): 1226 | return 1 1227 | else: 1228 | return 0 1229 | else: 1230 | return 0 1231 | else: 1232 | return 0 1233 | 1234 | #check if res is at N-term side of break in mid chain 1235 | def is_term_type_mn(mol_id,ch_id,resno): 1236 | sn=get_sn_from_resno(mol_id,ch_id,resno) 1237 | if type(sn) is int: 1238 | if sn in range(1,chain_n_residues(ch_id,mol_id)) and (is_polymer_residue(mol_id,ch_id,sn)==1): 1239 | resn_here=resno 1240 | resn_prev=seqnum_from_serial_number(mol_id,ch_id,sn-1) 1241 | diff_prev=resn_here-resn_prev 1242 | if (diff_prev>=2): 1243 | return 1 1244 | else: 1245 | return 0 1246 | else: 1247 | return 0 1248 | else: 1249 | return 0 1250 | 1251 | def is_term_type_mn_sn(mol_id,ch_id,sn): 1252 | if sn in range(1,chain_n_residues(ch_id,mol_id)): 1253 | resn_here=seqnum_from_serial_number(mol_id,ch_id,sn) 1254 | if (is_polymer_residue(mol_id,ch_id,sn)==1): 1255 | resn_prev=seqnum_from_serial_number(mol_id,ch_id,sn-1) 1256 | diff_prev=resn_here-resn_prev 1257 | if (diff_prev>=2): 1258 | return 1 1259 | else: 1260 | return 0 1261 | else: 1262 | return 0 1263 | else: 1264 | return 0 1265 | 1266 | 1267 | def first_residue_in_seg(mol_id,ch_id,resno): 1268 | sn_here=get_sn_from_resno(mol_id,ch_id,resno) 1269 | sn=sn_here 1270 | while is_term_type_mn_sn(mol_id,ch_id,sn)==0 and sn>0 and seqnum_from_serial_number(mol_id,ch_id,sn-1)!=-10000 and is_polymer_residue(mol_id,ch_id,sn-1)==1: 1271 | sn=sn-1 1272 | res_start=seqnum_from_serial_number(mol_id,ch_id,sn) 1273 | return res_start 1274 | 1275 | def last_residue_in_seg(mol_id,ch_id,resno): 1276 | sn_here=get_sn_from_resno(mol_id,ch_id,resno) 1277 | sn=sn_here 1278 | while is_term_type_mc_sn(mol_id,ch_id,sn)==0 and seqnum_from_serial_number(mol_id,ch_id,sn+1)!=-10000 and is_polymer_residue(mol_id,ch_id,sn+1)==1: 1279 | sn=sn+1 1280 | res_end=seqnum_from_serial_number(mol_id,ch_id,sn) 1281 | return res_end 1282 | 1283 | 1284 | #Get serial number of active residue 1285 | def sn_of_active_res(): 1286 | sn=0 1287 | resn_to_match=active_residue()[2] 1288 | mol_id=active_residue()[0] 1289 | ch_id=active_residue()[1] 1290 | current_resn=seqnum_from_serial_number(mol_id,"%s"%(ch_id),sn) 1291 | while (current_resn!=resn_to_match): 1292 | sn=sn+1 1293 | current_resn=seqnum_from_serial_number(mol_id,"%s"%(ch_id),sn) 1294 | return sn 1295 | 1296 | #Get monomer and delete hydrogens 1297 | def get_monomer_no_H(mon): 1298 | get_monomer(mon) 1299 | delete_hydrogens(molecule_number_list()[-1]) 1300 | 1301 | #Return list of segments in active mol 1302 | def segment_list(mol_id): 1303 | sn=0 1304 | list_out=[] 1305 | for ch_id in chain_ids(mol_id): 1306 | while is_polymer_residue(mol_id,ch_id,sn+1)==1: 1307 | if sn==0: 1308 | res_start=seqnum_from_serial_number(mol_id,ch_id,sn) 1309 | while is_term_type_mc_sn(mol_id,ch_id,sn)==0 and seqnum_from_serial_number(mol_id,ch_id,sn+1)!=-10000 and is_polymer_residue(mol_id,ch_id,sn+1)==1: 1310 | sn=sn+1 1311 | res_end=seqnum_from_serial_number(mol_id,ch_id,sn) 1312 | list_out.append([mol_id,ch_id,res_start,res_end]) 1313 | else: 1314 | while is_term_type_mn_sn(mol_id,ch_id,sn)==0: 1315 | sn=sn+1 1316 | res_start=seqnum_from_serial_number(mol_id,ch_id,sn) 1317 | while is_term_type_mc_sn(mol_id,ch_id,sn)==0 and seqnum_from_serial_number(mol_id,ch_id,sn+1)!=-10000 and is_polymer_residue(mol_id,ch_id,sn+1)==1: 1318 | sn=sn+1 1319 | res_end=seqnum_from_serial_number(mol_id,ch_id,sn) 1320 | list_out.append([mol_id,ch_id,res_start,res_end]) 1321 | sn=0 1322 | return list_out 1323 | 1324 | def segment_list_chain(mol_id,ch_id): 1325 | sn=0 1326 | list_out=[] 1327 | while is_polymer_residue(mol_id,ch_id,sn+1)==1: 1328 | if sn==0: 1329 | res_start=seqnum_from_serial_number(mol_id,ch_id,sn) 1330 | while is_term_type_mc_sn(mol_id,ch_id,sn)==0 and seqnum_from_serial_number(mol_id,ch_id,sn+1)!=-10000 and is_polymer_residue(mol_id,ch_id,sn+1)==1: 1331 | sn=sn+1 1332 | res_end=seqnum_from_serial_number(mol_id,ch_id,sn) 1333 | list_out.append([mol_id,ch_id,res_start,res_end]) 1334 | else: 1335 | while is_term_type_mn_sn(mol_id,ch_id,sn)==0: 1336 | sn=sn+1 1337 | res_start=seqnum_from_serial_number(mol_id,ch_id,sn) 1338 | while is_term_type_mc_sn(mol_id,ch_id,sn)==0 and seqnum_from_serial_number(mol_id,ch_id,sn+1)!=-10000 and is_polymer_residue(mol_id,ch_id,sn+1)==1: 1339 | sn=sn+1 1340 | res_end=seqnum_from_serial_number(mol_id,ch_id,sn) 1341 | list_out.append([mol_id,ch_id,res_start,res_end]) 1342 | return list_out 1343 | 1344 | 1345 | #rigid body refine zone here +/- n+1, then real space refine zone here +/-n 1346 | def auto_refine(n): 1347 | mol_id=active_residue()[0] 1348 | ch_id=active_residue()[1] 1349 | resno=active_residue()[2] 1350 | altloc=active_residue()[5] 1351 | res_start=resno 1352 | res_end=resno 1353 | i=0 1354 | fpr=first_polymer_residue(mol_id,ch_id) 1355 | lpr=last_polymer_residue(mol_id,ch_id) 1356 | while not (is_term_type_mn(mol_id,ch_id,res_start) or res_start==fpr or i==n): 1357 | res_start=res_start-1 1358 | i=i+1 1359 | i=0 1360 | while not (is_term_type_mc(mol_id,ch_id,res_end) or res_end==lpr or i==n): 1361 | res_end=res_end+1 1362 | i=i+1 1363 | rigid_body_refine_zone(res_start,res_end,ch_id,mol_id) 1364 | accept_regularizement() 1365 | refine_zone(mol_id,ch_id,res_start,res_end,altloc) 1366 | 1367 | 1368 | #**** "Custom menu item functions **** 1369 | #Deletes active chain 1370 | def delete_chain(): 1371 | active_chain_id=active_residue()[1] 1372 | active_mol_id=active_residue()[0] 1373 | turn_off_backup(active_mol_id) 1374 | while (is_polymer(active_mol_id,active_chain_id)==1) or ( 1375 | is_solvent_chain_p(active_mol_id,active_chain_id)!=-1): 1376 | first_res=first_residue(active_mol_id,active_chain_id) 1377 | last_res=last_residue(active_mol_id,active_chain_id) 1378 | delete_residue_range(active_mol_id,active_chain_id,first_res,last_res) 1379 | turn_on_backup(active_mol_id) 1380 | 1381 | #Fits all polymer chains to map 1382 | def rigid_fit_all_chains(): 1383 | mol_id=active_residue()[0] 1384 | turn_off_backup(mol_id) 1385 | for ch_id in chain_ids(mol_id): #Rigid body refine each chain 1386 | if is_polymer(mol_id,ch_id)==1: 1387 | rigid_body_refine_by_atom_selection(mol_id, "//%s//"%(ch_id)) 1388 | accept_regularizement() 1389 | turn_on_backup(mol_id) 1390 | 1391 | #Fits active chain to map 1392 | def rigid_fit_active_chain(): 1393 | mol_id=active_residue()[0] 1394 | ch_id=active_residue()[1] 1395 | rigid_body_refine_by_atom_selection(mol_id, "//%s//"%(ch_id)) 1396 | 1397 | #Copies active chain 1398 | def copy_active_chain(): 1399 | mol_id=active_residue()[0] 1400 | ch_id=active_residue()[1] 1401 | new_molecule_by_atom_selection(mol_id, "//%s//"%(ch_id)) 1402 | 1403 | #Cuts active chain 1404 | def cut_active_chain(): 1405 | mol_id=active_residue()[0] 1406 | ch_id=active_residue()[1] 1407 | new_molecule_by_atom_selection(mol_id, "//%s//"%(ch_id)) 1408 | turn_off_backup(mol_id) 1409 | while (is_polymer(mol_id,ch_id)==1) or (is_solvent_chain_p(mol_id,ch_id)!=-1): 1410 | first_res=first_residue(mol_id,ch_id) 1411 | last_res=last_residue(mol_id,ch_id) 1412 | delete_residue_range(mol_id,ch_id,first_res,last_res) 1413 | turn_on_backup(mol_id) 1414 | 1415 | #Faster rigid body fit (not relevant for smaller ranges, but much faster for larger ranges) 1416 | def fast_rigid_fit(res_start,res_end,ch_id,mol_id): 1417 | if (mol_id in model_molecule_number_list()) and (ch_id in chain_ids(mol_id)): 1418 | turn_off_backup(mol_id) 1419 | ins_code="" 1420 | sn_max=chain_n_residues(ch_id,mol_id)-1 1421 | res_min=seqnum_from_serial_number(mol_id,ch_id,0) 1422 | res_max=seqnum_from_serial_number(mol_id,ch_id,sn_max) 1423 | if res_start>res_end: 1424 | res_start,res_end=res_end,res_start 1425 | while not residue_exists_qm(mol_id,ch_id,res_start,ins_code) and res_start<=res_max: 1426 | res_start=res_start+1 1427 | while not residue_exists_qm(mol_id,ch_id,res_end,ins_code) and res_end>=res_min: 1428 | res_end=res_end-1 1429 | if res_start<=res_end: 1430 | new_molecule_by_atom_selection(mol_id, "//{ch_id}/{res_start}-{res_end}/".format(ch_id=ch_id,res_start=res_start,res_end=res_end)) 1431 | mol_id_new=model_molecule_number_list()[-1] 1432 | rigid_body_refine_by_atom_selection(mol_id_new,"/ /") 1433 | accept_regularizement() 1434 | delete_residue_range(mol_id,ch_id,res_start,res_end) #delete copied range from original mol 1435 | merge_molecules([mol_id_new],mol_id) #Merge fit segment back into original mol 1436 | change_chain_id_with_result(mol_id,chain_ids(mol_id)[-1],ch_id,1,res_start,res_end) #Merge chains 1437 | close_molecule(mol_id_new) 1438 | turn_on_backup(mol_id) 1439 | else: 1440 | info_dialog("The specified chain or molecule does not exist!") 1441 | 1442 | #Copy active segment 1443 | def copy_active_segment(): 1444 | mol_id=active_residue()[0] 1445 | segments=segment_list(mol_id) 1446 | res_here=active_residue()[2] 1447 | ch_id=active_residue()[1] 1448 | for seg in segments: 1449 | if (res_here>=seg[2]) and (res_here<=seg[3]) and (ch_id==seg[1]): 1450 | res_start=seg[2] 1451 | res_end=seg[3] 1452 | ch_id=seg[1] 1453 | new_molecule_by_atom_selection(mol_id, "//{ch_id}/{res_start}-{res_end}/".format(ch_id=ch_id,res_start=res_start,res_end=res_end)) 1454 | 1455 | #Cut active segment 1456 | def cut_active_segment(): 1457 | mol_id=active_residue()[0] 1458 | segments=segment_list(mol_id) 1459 | res_here=active_residue()[2] 1460 | ch_id=active_residue()[1] 1461 | for seg in segments: 1462 | if (res_here>=seg[2]) and (res_here<=seg[3]) and (ch_id==seg[1]): 1463 | res_start=seg[2] 1464 | res_end=seg[3] 1465 | ch_id=seg[1] 1466 | new_molecule_by_atom_selection(mol_id, "//{ch_id}/{res_start}-{res_end}/".format(ch_id=ch_id,res_start=res_start,res_end=res_end)) 1467 | delete_residue_range(mol_id,ch_id,res_start,res_end) 1468 | 1469 | #Delete active segment 1470 | def delete_active_segment(): 1471 | mol_id=active_residue()[0] 1472 | segments=segment_list(mol_id) 1473 | res_here=active_residue()[2] 1474 | ch_id=active_residue()[1] 1475 | for seg in segments: 1476 | if (res_here>=seg[2]) and (res_here<=seg[3]) and (ch_id==seg[1]): 1477 | res_start=seg[2] 1478 | res_end=seg[3] 1479 | ch_id=seg[1] 1480 | delete_residue_range(mol_id,ch_id,res_start,res_end) 1481 | 1482 | 1483 | #Jiggle-fits active chain to map 1484 | def jiggle_fit_active_chain(): 1485 | if (imol_refinement_map()==-1): 1486 | info_dialog("You must set a refinement map!") 1487 | else: 1488 | mol_id=active_residue()[0] 1489 | ch_id=active_residue()[1] 1490 | fit_chain_to_map_by_random_jiggle(mol_id,ch_id,1000,0.1) 1491 | 1492 | #Jiggle-fit active chain to B-smoothed map 1493 | def jiggle_fit_active_chain_smooth(): 1494 | if (imol_refinement_map()==-1): 1495 | info_dialog("You must set a refinement map!") 1496 | else: 1497 | sharpen(imol_refinement_map(),200) 1498 | mol_id=active_residue()[0] 1499 | ch_id=active_residue()[1] 1500 | fit_chain_to_map_by_random_jiggle(mol_id,ch_id,1000,0.1) 1501 | sharpen(imol_refinement_map(),0) 1502 | 1503 | #Jiggle-fits active chain to map (more thorough) 1504 | def jiggle_fit_active_chain_slow(): 1505 | if (imol_refinement_map()==-1): 1506 | info_dialog("You must set a refinement map!") 1507 | else: 1508 | mol_id=active_residue()[0] 1509 | ch_id=active_residue()[1] 1510 | score_string="" 1511 | for scale_fac in range(1,1000,100): 1512 | scale_fac2=scale_fac/10.0 1513 | score=fit_chain_to_map_by_random_jiggle(mol_id,ch_id,100,scale_fac2) 1514 | score_string=score_string+"scale:"+str(scale_fac2)+"score:"+str(score) 1515 | print(score_string) 1516 | 1517 | #Fits all polymer chains to map 1518 | def jiggle_fit_all_chains(): 1519 | if (imol_refinement_map()==-1): 1520 | info_dialog("You must set a refinement map!") 1521 | else: 1522 | mol_id=active_residue()[0] 1523 | turn_off_backup(mol_id) 1524 | for ch_id in chain_ids(mol_id): #Rigid body refine each chain 1525 | if is_polymer(mol_id,ch_id)==1: 1526 | fit_chain_to_map_by_random_jiggle(mol_id,ch_id,1000,0.1) 1527 | accept_regularizement() 1528 | turn_on_backup(mol_id) 1529 | 1530 | #Jiggle-fit current molecule to map 1531 | def jiggle_fit_active_mol(): 1532 | if (imol_refinement_map()==-1): 1533 | info_dialog("You must set a refinement map!") 1534 | else: 1535 | mol_id=active_residue()[0] 1536 | fit_molecule_to_map_by_random_jiggle(mol_id,1000,0.1) 1537 | 1538 | #Clear labels and distances 1539 | def clear_distances_and_labels(): 1540 | remove_all_atom_labels() 1541 | clear_simple_distances() 1542 | 1543 | #Delete hydrogens from active molecule 1544 | def delete_h_active(): 1545 | mol_id=active_residue()[0] 1546 | delete_hydrogens(mol_id) 1547 | 1548 | #click the start and end point, then fit the gap between them with polyala 1549 | def fit_polyala_gui(): 1550 | def fit_polyala(res1,res2): 1551 | length=abs(res1[3]-res2[3])-1 1552 | loop_seq=length*"A" 1553 | fit_gap(res1[1],res1[2],res1[3],res2[3],loop_seq,1) 1554 | user_defined_click(2,fit_polyala) 1555 | 1556 | # Try to rebuild with db_mainchain after fit_gap? 1557 | # def fit_polyala_gui2(): 1558 | # def fit_polyala(res1,res2): 1559 | # length=abs(res1[3]-res2[3])-1 1560 | # loop_seq=length*"A" 1561 | # fit_gap(res1[1],res1[2],res1[3],res2[3],loop_seq,1) 1562 | # db_mainchain? 1563 | # user_defined_click(2,fit_polyala) 1564 | 1565 | #Rebuild backbone in selected zone 1566 | def rebuild_backbone_wrapper(): 1567 | def rebuild_backbone(res1,res2): 1568 | if res1[1]==res2[1] and res1[2]==res2[2]: #if residues in same mol and chain 1569 | mol_id=res1[1] 1570 | ch_id=res1[2] 1571 | resid1=res1[3] 1572 | resid2=res2[3] 1573 | if resid1!=resid2: 1574 | if resid2=seg[2]) and (resid1<=seg[3]) and (ch_id==seg[1]): 1612 | res_start=seg[2] 1613 | res_end=seg[3] 1614 | ch_id=seg[1] 1615 | turn_off_backup(mol_id) 1616 | if res_start!=res_end: 1617 | reverse_direction_of_fragment(mol_id,ch_id,res_start) 1618 | new_mol_id=db_mainchain(mol_id,ch_id,res_start,res_end,"forwards") 1619 | accept_regularizement() 1620 | res1_rsr=first_residue(new_mol_id,ch_id) 1621 | res2_rsr=last_residue(new_mol_id,ch_id) 1622 | #need to mutate each residue to appropriate sidechain and kill sidechain 1623 | #get target seq with aa_code=three_letter_code2single_letter(residue_name(mol_id,ch_id,resnum,ins_code)) 1624 | #mutate_residue_range 1625 | #delete_sidechain_range 1626 | target_seq="" 1627 | for res in range(res1_rsr,res2_rsr+1): 1628 | aa_code=three_letter_code2single_letter(residue_name(new_mol_id,ch_id,res,"")) 1629 | target_seq=target_seq+aa_code 1630 | print("target seq:",target_seq) 1631 | mutate_residue_range(new_mol_id,ch_id,res1_rsr,res2_rsr,target_seq) 1632 | delete_sidechain_range(new_mol_id,ch_id,res1_rsr,res2_rsr) 1633 | for res in range(res1_rsr,res2_rsr+1): 1634 | if residue_name(new_mol_id,ch_id,res,"")=="PRO": 1635 | target_seq="P" 1636 | mutate_residue_range(new_mol_id,ch_id,res,res,target_seq) 1637 | #cut out orginal region and merge in new fragment? 1638 | delete_residue_range(mol_id,ch_id,res_start,res_end) 1639 | merge_molecules([new_mol_id],mol_id) 1640 | turn_off_backup(mol_id) 1641 | user_defined_click(1,rebuild_backbone_reverse) 1642 | 1643 | def fit_this_segment(): 1644 | if (imol_refinement_map()==-1): 1645 | info_dialog("You must set a refinement map!") 1646 | else: 1647 | mol_id=active_residue()[0] 1648 | segments=segment_list(mol_id) 1649 | res_here=active_residue()[2] 1650 | ch_id=active_residue()[1] 1651 | for seg in segments: 1652 | if (res_here>=seg[2]) and (res_here<=seg[3]) and (ch_id==seg[1]): 1653 | res_start=seg[2] 1654 | res_end=seg[3] 1655 | ch_id=seg[1] 1656 | turn_off_backup(mol_id) 1657 | set_refinement_immediate_replacement(1) 1658 | rigid_body_refine_zone(res_start,res_end,ch_id,mol_id) 1659 | accept_regularizement() 1660 | set_refinement_immediate_replacement(0) 1661 | turn_on_backup(mol_id) 1662 | 1663 | 1664 | #Real space refine for keyboard shortcut 1665 | def refine_click(): 1666 | def refine_click_a(res1,res2): 1667 | mol_id_1=res1[1] 1668 | mol_id_2=res2[1] 1669 | ch_id_1=res1[2] 1670 | ch_id_2=res2[2] 1671 | resno_1=res1[3] 1672 | resno_2=res2[3] 1673 | alt_conf_1=res1[4] 1674 | alt_conf_2=res2[4] 1675 | if resno_2>=resno_1: 1676 | refine_zone(mol_id_1,ch_id_1,resno_1,resno_2,alt_conf_1) 1677 | else: 1678 | refine_zone(mol_id_1,ch_id_1,resno_2,resno_1,alt_conf_1) 1679 | user_defined_click(2,refine_click_a) 1680 | 1681 | #Use refine residues rather than refine zone because refine_residues knows about disulfides etc. 1682 | def refine_residues_click(): 1683 | def refine_residues_click_a(res1,res2): 1684 | mol_id_1=res1[1] 1685 | mol_id_2=res2[1] 1686 | ch_id_1=res1[2] 1687 | ch_id_2=res2[2] 1688 | resno_1=res1[3] 1689 | resno_2=res2[3] 1690 | ins_code_1=res1[6] 1691 | ins_code_2=res2[6] 1692 | if (mol_id_1==mol_id_2) and (ch_id_1==ch_id_2): 1693 | if resno_1>=resno_2: 1694 | resno_1,resno_2=resno_2,resno_1 #Swap res numbers if wrong way round 1695 | res_list=[] 1696 | for resn in range(resno_1,resno_2+1): 1697 | res_triple=[ch_id_1,resn,ins_code_1] #Does not account for varying ins code. Should be able to fix using residues_matching_criteria(), e.g.: 1698 | #residues_matching_criteria(0, lambda chain_id,resno,ins_code,serial: True), except substitute a test func for true 1699 | #that evaluates to true if resno, mol id and ch_id match, and returns ins_code (third item in output triple) 1700 | res_list.append(res_triple) #append rather than adding, bc making list of lists 1701 | refine_residues(mol_id_1,res_list) 1702 | print(res_list) 1703 | else: 1704 | info_dialog("Sorry, start and end residues must be in same mol and chain!") 1705 | user_defined_click(2,refine_residues_click_a) 1706 | 1707 | def refine_residues_range(mol_id,ch_id,resno_1,resno_2,ins_code_1): 1708 | if resno_1>=resno_2: 1709 | resno_1,resno_2=resno_2,resno_1 #Swap res numbers if wrong way round 1710 | res_list=[] 1711 | for resn in range(resno_1,resno_2+1): 1712 | res_triple=[ch_id,resn,ins_code_1] #Does not account for varying ins code. Should be able to fix using residues_matching_criteria(), e.g.: 1713 | #residues_matching_criteria(0, lambda chain_id,resno,ins_code,serial: True), except substitute a test func for true 1714 | #that evaluates to true if resno, mol id and ch_id match, and returns ins_code (third item in output triple) 1715 | res_list.append(res_triple) #append rather than adding, bc making list of lists 1716 | refine_residues(mol_id,res_list) 1717 | 1718 | 1719 | 1720 | #refine range, plus everything in contact with it 1721 | def refine_residues_sphere_click(): 1722 | def refine_residues_sphere_click_a(res1,res2): 1723 | mol_id_1=res1[1] 1724 | mol_id_2=res2[1] 1725 | ch_id_1=res1[2] 1726 | ch_id_2=res2[2] 1727 | resno_1=res1[3] 1728 | resno_2=res2[3] 1729 | ins_code_1=res1[6] 1730 | ins_code_2=res2[6] 1731 | if (mol_id_1==mol_id_2) and (ch_id_1==ch_id_2) and (imol_refinement_map!=-1): 1732 | if resno_1>=resno_2: 1733 | resno_1,resno_2=resno_2,resno_1 #Swap res numbers if wrong way round 1734 | res_list=[] 1735 | nearby_residues=[] 1736 | for resn in range(resno_1,resno_2+1): 1737 | res_triple=[ch_id_1,resn,ins_code_1] #Does not account for varying ins code. Should be able to fix using residues_matching_criteria(), e.g.: 1738 | #residues_matching_criteria(0, lambda chain_id,resno,ins_code,serial: True), except substitute a test func for true 1739 | #that evaluates to true if resno, mol id and ch_id match, and returns ins_code (third item in output triple) 1740 | res_list.append(res_triple) #append rather than adding, bc making list of lists 1741 | for resn in range(resno_1+1,resno_2-1): 1742 | res_triple=[ch_id_1,resn,ins_code_1] #Does not account for varying ins code. Should be able to fix using residues_matching_criteria(), e.g.: 1743 | new_nearby_residues=residues_near_residue(mol_id_1,res_triple,5) 1744 | nearby_residues.extend(new_nearby_residues) 1745 | if len(res_list)<=2: 1746 | for resn in range(resno_1,resno_2+1): 1747 | res_triple=[ch_id_1,resn,ins_code_1] #Does not account for varying ins code. Should be able to fix using residues_matching_criteria(), e.g.: 1748 | new_nearby_residues=residues_near_residue(mol_id_1,res_triple,5) 1749 | nearby_residues.extend(new_nearby_residues) 1750 | res_list=res_list+nearby_residues 1751 | print(res_list) 1752 | res_list=[list(x) for x in set(tuple(x) for x in res_list)] #Uniquifies list of lists 1753 | print("hopefully unique:",res_list) 1754 | refine_residues(mol_id_1,res_list) 1755 | print(res_list) 1756 | else: 1757 | info_dialog("Sorry, start and end residues must be in same mol and chain! And you need to have a refinement map.") 1758 | user_defined_click(2,refine_residues_sphere_click_a) 1759 | 1760 | #Python version of sphere refine from here: 1761 | #https://www.mail-archive.com/coot@jiscmail.ac.uk/msg01463.html 1762 | def sphere_refine_active(radius): 1763 | from types import ListType 1764 | active_atom = active_residue() 1765 | if (not active_atom): 1766 | add_status_bar_text("No active residue") 1767 | else: 1768 | imol = active_atom[0] 1769 | chain_id = active_atom[1] 1770 | res_no = active_atom[2] 1771 | ins_code = active_atom[3] 1772 | atom_name = active_atom[4] 1773 | alt_conf = active_atom[5] 1774 | centred_residue = active_atom[1:4] 1775 | other_residues = residues_near_residue(imol, centred_residue, radius) 1776 | all_residues = [centred_residue] 1777 | if (type(other_residues) is ListType): 1778 | all_residues += other_residues 1779 | print "imol: %s residues: %s" %(imol, all_residues) 1780 | refine_residues(imol, all_residues) 1781 | 1782 | def stepped_sphere_refine(mol_id,ch_id): 1783 | turn_off_backup(mol_id) 1784 | set_refinement_immediate_replacement(1) 1785 | valid_resnames=['A','C','T','G','U','ALA','UNK','ARG','ASN','ASP','CYS','GLU','GLN','GLY','HIS','ILE','LEU','LYS','MET','MSE','PHE','PRO','SER','THR','TRP','TYR','VAL'] 1786 | if is_polymer(mol_id,ch_id): 1787 | first_res=first_residue(mol_id,ch_id) 1788 | last_res=last_residue(mol_id,ch_id) 1789 | if is_protein_chain_p(mol_id,ch_id): 1790 | for res in range(first_res,last_res+1): 1791 | res_exist_flag=does_residue_exist_p(mol_id,ch_id,res,"") 1792 | resname=residue_name(mol_id,ch_id,res,"") 1793 | if (res_exist_flag==1) and (resname in valid_resnames): 1794 | set_go_to_atom_chain_residue_atom_name(ch_id,res," CA ") 1795 | sphere_refine_active(7) 1796 | accept_regularizement() 1797 | elif is_nucleotide_chain_p(mol_id,ch_id): 1798 | for res in range(first_res,last_res+1): 1799 | res_exist_flag=does_residue_exist_p(mol_id,ch_id,res,"") 1800 | resname=residue_name(mol_id,ch_id,res,"") 1801 | if (res_exist_flag==1) and (resname in valid_resnames): 1802 | set_go_to_atom_chain_residue_atom_name(ch_id,res," P ") 1803 | sphere_refine_active(7) 1804 | accept_regularizement() 1805 | set_refinement_immediate_replacement(0) 1806 | turn_on_backup(mol_id) 1807 | info_dialog("Refinement finished - all done!") 1808 | 1809 | 1810 | #Stepped v of cylinder refine: 1811 | #get mol from active residue 1812 | #for ch_id in mol: 1813 | #cylinder_refine four res segments, with two res overlap 1814 | #ignore breaks? 1815 | #what about waters? 1816 | 1817 | 1818 | #Copy fragment (click start and end) 1819 | def copy_frag_by_click(): 1820 | def copy_frag(res1,res2): 1821 | mol_id_1=res1[1] 1822 | mol_id_2=res2[1] 1823 | ch_id_1=res1[2] 1824 | ch_id_2=res2[2] 1825 | resno_1=res1[3] 1826 | resno_2=res2[3] 1827 | if (mol_id_1==mol_id_2) and (ch_id_1==ch_id_2): 1828 | if resno_1>resno_2: 1829 | atom_sel="//%s/%s-%s" %(ch_id_1,resno_2,resno_1) 1830 | new_molecule_by_atom_selection(mol_id_1,atom_sel) 1831 | elif resno_2>resno_1: 1832 | atom_sel="//%s/%s-%s" %(ch_id_1,resno_1,resno_2) 1833 | new_molecule_by_atom_selection(mol_id_1,atom_sel) 1834 | else: 1835 | atom_sel="//%s/%s" %(ch_id_1,resno_2) 1836 | new_molecule_by_atom_selection(mol_id_1,atom_sel) 1837 | else: 1838 | info_dialog("Start and end residues must be in the same molecule and chain!") 1839 | user_defined_click(2,copy_frag) 1840 | 1841 | #Cut fragment (click start and end) 1842 | def cut_frag_by_click(): 1843 | def cut_frag(res1,res2): 1844 | mol_id_1=res1[1] 1845 | mol_id_2=res2[1] 1846 | ch_id_1=res1[2] 1847 | ch_id_2=res2[2] 1848 | resno_1=res1[3] 1849 | resno_2=res2[3] 1850 | if (mol_id_1==mol_id_2) and (ch_id_1==ch_id_2): 1851 | turn_off_backup(mol_id_1) 1852 | if resno_1>resno_2: 1853 | atom_sel="//%s/%s-%s" %(ch_id_1,resno_2,resno_1) 1854 | new_molecule_by_atom_selection(mol_id_1,atom_sel) 1855 | delete_residue_range(mol_id_1,ch_id_1,resno_2,resno_1) 1856 | elif resno_2>resno_1: 1857 | atom_sel="//%s/%s-%s" %(ch_id_1,resno_1,resno_2) 1858 | new_molecule_by_atom_selection(mol_id_1,atom_sel) 1859 | delete_residue_range(mol_id_1,ch_id_1,resno_1,resno_2) 1860 | else: 1861 | atom_sel="//%s/%s" %(ch_id_1,resno_2) 1862 | new_molecule_by_atom_selection(mol_id_1,atom_sel) 1863 | delete_residue_range(mol_id_1,ch_id_1,resno_2) 1864 | turn_on_backup(mol_id_1) 1865 | else: 1866 | info_dialog("Start and end residues must be in the same molecule and chain!") 1867 | user_defined_click(2,cut_frag) 1868 | 1869 | 1870 | #Delete sidechain range (click start and end) 1871 | def delete_sidechain_range_by_click_a(): 1872 | def delete_sidechain_range_by_click_b(res1,res2): 1873 | if (res1[1]!=res2[1]) or (res1[2]!=res2[2]) or (res1[3]==res2[3]): 1874 | info_dialog("Start and end points must be in the same mol and chain!") 1875 | else: 1876 | if (res1[3] > res2[3]): 1877 | res_start=res2[3]-1 1878 | res_end=res1[3]+1 1879 | else: 1880 | res_start=res1[3]-1 1881 | res_end=res2[3]+1 1882 | mol_id=res1[1] 1883 | ch_id=res1[2] 1884 | turn_off_backup(mol_id) 1885 | delete_sidechain_range(mol_id,ch_id,res_start,res_end) 1886 | turn_on_backup(mol_id) 1887 | user_defined_click(2,delete_sidechain_range_by_click_b) 1888 | 1889 | #Mutate range to poly-unk 1890 | def mutate_residue_range_by_click_a(): 1891 | def mutate_residue_range_by_click_b(res1,res2): 1892 | if (res1[1]!=res2[1]) or (res1[2]!=res2[2]) or (res1[3]==res2[3]): 1893 | info_dialog("Start and end points must be in the same mol and chain!") 1894 | else: 1895 | if (res1[3] > res2[3]): 1896 | res_start=res2[3] 1897 | res_end=res1[3] 1898 | n=res_end-res_start+1 1899 | else: 1900 | res_start=res1[3] 1901 | res_end=res2[3] 1902 | n=res_end-res_start+1 1903 | mol_id=res1[1] 1904 | ch_id=res1[2] 1905 | target_seq=n*"A" 1906 | turn_off_backup(mol_id) 1907 | mutate_residue_range(mol_id,ch_id,res_start,res_end,target_seq) 1908 | for n in range(res_start,res_end+1): 1909 | set_residue_name(mol_id,ch_id,n,"","UNK") 1910 | turn_on_backup(mol_id) 1911 | user_defined_click(2,mutate_residue_range_by_click_b) 1912 | 1913 | #Mutate range to polyala 1914 | def mutate_residue_range_by_click_ala_a(): 1915 | def mutate_residue_range_by_click_ala_b(res1,res2): 1916 | if (res1[1]!=res2[1]) or (res1[2]!=res2[2]) or (res1[3]==res2[3]): 1917 | info_dialog("Start and end points must be in the same mol and chain!") 1918 | else: 1919 | if (res1[3] > res2[3]): 1920 | res_start=res2[3] 1921 | res_end=res1[3] 1922 | n=res_end-res_start+1 1923 | else: 1924 | res_start=res1[3] 1925 | res_end=res2[3] 1926 | n=res_end-res_start+1 1927 | mol_id=res1[1] 1928 | ch_id=res1[2] 1929 | target_seq=n*"A" 1930 | turn_off_backup(mol_id) 1931 | mutate_residue_range(mol_id,ch_id,res_start,res_end,target_seq) 1932 | for n in range(res_start,res_end+1): 1933 | set_residue_name(mol_id,ch_id,n,"","ALA") 1934 | turn_on_backup(mol_id) 1935 | user_defined_click(2,mutate_residue_range_by_click_ala_b) 1936 | 1937 | #Merge two fragments 1938 | def merge_fragments(): 1939 | def merge_2_fragments(res1,res2): 1940 | mol_daughter=[res2[1]] 1941 | mol_ref=res1[1] 1942 | merge_molecules(mol_daughter,mol_ref) 1943 | toggle_display_mol(mol_ref) 1944 | toggle_display_mol(mol_ref) 1945 | user_defined_click(2,merge_2_fragments) 1946 | 1947 | #Force addition of residue - useful when 1948 | #Coot says "No acceptable position found" 1949 | # but density is clear. 1950 | def force_add_terminal_residue(): 1951 | def force_addition(res1): 1952 | mol_id=res1[1] 1953 | ch_id=res1[2] 1954 | res_no=res1[3] 1955 | res_type="auto" 1956 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 1957 | res_type,-57.82,-47) 1958 | if residue_exists_qm(mol_id,ch_id,res_no+1,res1[4]): 1959 | set_b_factor_residue_range(mol_id,ch_id,res_no+1,res_no+1,default_new_atoms_b_factor()) 1960 | elif residue_exists_qm(mol_id,ch_id,res_no-1,res1[4]): 1961 | set_b_factor_residue_range(mol_id,ch_id,res_no-1,res_no-1,default_new_atoms_b_factor()) 1962 | sort_residues(mol_id) 1963 | user_defined_click(1,force_addition) 1964 | 1965 | def force_add_terminal_residue_noclick(mol_id,ch_id,res_no): 1966 | res_type="auto" 1967 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 1968 | res_type,-57.82,-47) 1969 | if residue_exists_qm(mol_id,ch_id,res_no+1,""): 1970 | set_b_factor_residue_range(mol_id,ch_id,res_no+1,res_no+1,default_new_atoms_b_factor()) 1971 | elif residue_exists_qm(mol_id,ch_id,res_no-1,""): 1972 | set_b_factor_residue_range(mol_id,ch_id,res_no-1,res_no-1,default_new_atoms_b_factor()) 1973 | sort_residues(mol_id) 1974 | 1975 | def force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,res_no,phi,psi): 1976 | res_type="auto" 1977 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 1978 | res_type,float(phi),float(psi)) 1979 | if residue_exists_qm(mol_id,ch_id,res_no+1,""): 1980 | set_b_factor_residue_range(mol_id,ch_id,res_no+1,res_no+1,default_new_atoms_b_factor()) 1981 | elif residue_exists_qm(mol_id,ch_id,res_no-1,""): 1982 | set_b_factor_residue_range(mol_id,ch_id,res_no-1,res_no-1,default_new_atoms_b_factor()) 1983 | sort_residues(mol_id) 1984 | 1985 | def force_add_terminal_residue_noclick_strand(mol_id,ch_id,res_no): 1986 | res_type="auto" 1987 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 1988 | res_type,-139,135) 1989 | if residue_exists_qm(mol_id,ch_id,res_no+1,""): 1990 | set_b_factor_residue_range(mol_id,ch_id,res_no+1,res_no+1,default_new_atoms_b_factor()) 1991 | elif residue_exists_qm(mol_id,ch_id,res_no-1,""): 1992 | set_b_factor_residue_range(mol_id,ch_id,res_no-1,res_no-1,default_new_atoms_b_factor()) 1993 | sort_residues(mol_id) 1994 | 1995 | #Paul 1996 | def key_binding_terminal_spin(): 1997 | active_atom = active_residue() 1998 | if not active_atom: 1999 | print("No active atom") 2000 | else: 2001 | imol = active_atom[0] 2002 | residue_spec = atom_spec_to_residue_spec(active_atom) 2003 | print ('spin_N {} {} {}'.format(imol, residue_spec, 120)) 2004 | spin_N_py(imol, residue_spec, 120) 2005 | 2006 | #This works, but should alter to be more flexible. ideally, have one key to tweak phi, one to tweak psi. 2007 | #Will need two global cycle variables - residue_phi_cycle and residue_psi_cycle - as well as two variables to keep the current value of phi and psi. 2008 | residue_phi_cycle=0 2009 | residue_psi_cycle=0 2010 | current_phi=-60 2011 | current_psi=-50 2012 | #should chamnge this to incorporate measurement of starting phi/psi using get_torsion (and maybe setting using set_torsion?) 2013 | #get_torsion(0,["A",2393,""," C ",""], ["A",2394,"", " N ", ""], ["A", 2394, "", " CA ", ""], ["A", 2394, "", " C ",""]) 2014 | #set_torsion(imol, chain_id, res_no, ins_code_alt_conf, atom_name_1,atom_name_2, atom_name_3, atom_name_4) 2015 | def cycle_residue_phi(): 2016 | global residue_phi_cycle 2017 | global current_phi 2018 | global current_psi 2019 | res_type="auto" 2020 | mol_id=active_residue()[0] 2021 | ch_id=active_residue()[1] 2022 | resn=active_residue()[2] 2023 | atom_name=active_residue()[4] 2024 | set_go_to_atom_molecule(mol_id) 2025 | ins_code="" 2026 | first_in_seg=first_residue_in_seg(mol_id,ch_id,resn) 2027 | last_in_seg=last_residue_in_seg(mol_id,ch_id,resn) 2028 | delta_first=abs(first_in_seg-resn) 2029 | delta_last=abs(last_in_seg-resn) 2030 | set_new_atom_b_fac_to_mean() 2031 | if delta_first<=delta_last: 2032 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2033 | if (residue_phi_cycle==0): 2034 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2035 | phi=-180 2036 | psi=current_psi 2037 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2038 | sort_residues(mol_id) 2039 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2040 | residue_phi_cycle=1 2041 | elif (residue_phi_cycle==1): 2042 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2043 | phi=-150 2044 | psi=current_psi 2045 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2046 | sort_residues(mol_id) 2047 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2048 | residue_phi_cycle=2 2049 | elif (residue_phi_cycle==2): 2050 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2051 | phi=-120 2052 | psi=current_psi 2053 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2054 | sort_residues(mol_id) 2055 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2056 | residue_phi_cycle=3 2057 | elif (residue_phi_cycle==3): 2058 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2059 | phi=-90 2060 | psi=current_psi 2061 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2062 | sort_residues(mol_id) 2063 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2064 | residue_phi_cycle=4 2065 | elif (residue_phi_cycle==4): 2066 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2067 | phi=-60 2068 | psi=current_psi 2069 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2070 | sort_residues(mol_id) 2071 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2072 | residue_phi_cycle=5 2073 | elif (residue_phi_cycle==5): 2074 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2075 | phi=-30 2076 | psi=current_psi 2077 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2078 | sort_residues(mol_id) 2079 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2080 | residue_phi_cycle=6 2081 | elif (residue_phi_cycle==6): 2082 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2083 | phi=0 2084 | psi=current_psi 2085 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2086 | sort_residues(mol_id) 2087 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2088 | residue_phi_cycle=7 2089 | elif (residue_phi_cycle==7): 2090 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2091 | phi=30 2092 | psi=current_psi 2093 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2094 | sort_residues(mol_id) 2095 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2096 | residue_phi_cycle=8 2097 | elif (residue_phi_cycle==8): 2098 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2099 | phi=60 2100 | psi=current_psi 2101 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2102 | sort_residues(mol_id) 2103 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2104 | residue_phi_cycle=9 2105 | elif (residue_phi_cycle==9): 2106 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2107 | phi=90 2108 | psi=current_psi 2109 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2110 | sort_residues(mol_id) 2111 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2112 | residue_phi_cycle=10 2113 | elif (residue_phi_cycle==10): 2114 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2115 | phi=120 2116 | psi=current_psi 2117 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2118 | sort_residues(mol_id) 2119 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2120 | residue_phi_cycle=0 2121 | else: 2122 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2123 | if (residue_phi_cycle==0): 2124 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2125 | phi=-180 2126 | psi=current_psi 2127 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2128 | sort_residues(mol_id) 2129 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2130 | residue_phi_cycle=1 2131 | elif (residue_phi_cycle==1): 2132 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2133 | phi=-150 2134 | psi=current_psi 2135 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2136 | sort_residues(mol_id) 2137 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2138 | residue_phi_cycle=2 2139 | elif (residue_phi_cycle==2): 2140 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2141 | phi=-120 2142 | psi=current_psi 2143 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2144 | sort_residues(mol_id) 2145 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2146 | residue_phi_cycle=3 2147 | elif (residue_phi_cycle==3): 2148 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2149 | phi=-90 2150 | psi=current_psi 2151 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2152 | sort_residues(mol_id) 2153 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2154 | residue_phi_cycle=4 2155 | elif (residue_phi_cycle==4): 2156 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2157 | phi=-60 2158 | psi=current_psi 2159 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2160 | sort_residues(mol_id) 2161 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2162 | residue_phi_cycle=5 2163 | elif (residue_phi_cycle==5): 2164 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2165 | phi=-30 2166 | psi=current_psi 2167 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2168 | sort_residues(mol_id) 2169 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2170 | residue_phi_cycle=6 2171 | elif (residue_phi_cycle==6): 2172 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2173 | phi=0 2174 | psi=current_psi 2175 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2176 | sort_residues(mol_id) 2177 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2178 | residue_phi_cycle=7 2179 | elif (residue_phi_cycle==7): 2180 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2181 | phi=30 2182 | psi=current_psi 2183 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2184 | sort_residues(mol_id) 2185 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2186 | residue_phi_cycle=8 2187 | elif (residue_phi_cycle==8): 2188 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2189 | phi=60 2190 | psi=current_psi 2191 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2192 | sort_residues(mol_id) 2193 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2194 | residue_phi_cycle=9 2195 | elif (residue_phi_cycle==9): 2196 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2197 | phi=90 2198 | psi=current_psi 2199 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2200 | sort_residues(mol_id) 2201 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2202 | residue_phi_cycle=10 2203 | elif (residue_phi_cycle==10): 2204 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2205 | phi=120 2206 | psi=current_psi 2207 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2208 | sort_residues(mol_id) 2209 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2210 | residue_phi_cycle=0 2211 | current_phi=phi 2212 | def cycle_residue_psi(): 2213 | global residue_psi_cycle 2214 | global current_phi 2215 | global current_psi 2216 | res_type="auto" 2217 | mol_id=active_residue()[0] 2218 | ch_id=active_residue()[1] 2219 | resn=active_residue()[2] 2220 | atom_name=active_residue()[4] 2221 | set_go_to_atom_molecule(mol_id) 2222 | ins_code="" 2223 | first_in_seg=first_residue_in_seg(mol_id,ch_id,resn) 2224 | last_in_seg=last_residue_in_seg(mol_id,ch_id,resn) 2225 | delta_first=abs(first_in_seg-resn) 2226 | delta_last=abs(last_in_seg-resn) 2227 | set_new_atom_b_fac_to_mean() 2228 | if delta_first<=delta_last: 2229 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2230 | if (residue_psi_cycle==0): 2231 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2232 | phi=current_phi 2233 | psi=-180 2234 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2235 | sort_residues(mol_id) 2236 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2237 | residue_psi_cycle=1 2238 | elif (residue_psi_cycle==1): 2239 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2240 | phi=current_phi 2241 | psi=-150 2242 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2243 | sort_residues(mol_id) 2244 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2245 | residue_psi_cycle=2 2246 | elif (residue_psi_cycle==2): 2247 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2248 | phi=current_phi 2249 | psi=-120 2250 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2251 | sort_residues(mol_id) 2252 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2253 | residue_psi_cycle=3 2254 | elif (residue_psi_cycle==3): 2255 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2256 | phi=current_phi 2257 | psi=-90 2258 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2259 | sort_residues(mol_id) 2260 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2261 | residue_psi_cycle=4 2262 | elif (residue_psi_cycle==4): 2263 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2264 | phi=current_phi 2265 | psi=-60 2266 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2267 | sort_residues(mol_id) 2268 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2269 | residue_psi_cycle=5 2270 | elif (residue_psi_cycle==5): 2271 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2272 | phi=current_phi 2273 | psi=-30 2274 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2275 | sort_residues(mol_id) 2276 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2277 | residue_psi_cycle=6 2278 | elif (residue_psi_cycle==6): 2279 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2280 | phi=current_phi 2281 | psi=0 2282 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2283 | sort_residues(mol_id) 2284 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2285 | residue_psi_cycle=7 2286 | elif (residue_psi_cycle==7): 2287 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2288 | phi=current_phi 2289 | psi=30 2290 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2291 | sort_residues(mol_id) 2292 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2293 | residue_psi_cycle=8 2294 | elif (residue_psi_cycle==8): 2295 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2296 | phi=current_phi 2297 | psi=60 2298 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2299 | sort_residues(mol_id) 2300 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2301 | residue_psi_cycle=9 2302 | elif (residue_psi_cycle==9): 2303 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2304 | phi=current_phi 2305 | psi=90 2306 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2307 | sort_residues(mol_id) 2308 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2309 | residue_psi_cycle=10 2310 | elif (residue_psi_cycle==10): 2311 | delete_residue(mol_id,ch_id,first_in_seg,ins_code) 2312 | phi=current_phi 2313 | psi=120 2314 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,first_in_seg+1,phi,psi) 2315 | sort_residues(mol_id) 2316 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 2317 | residue_psi_cycle=0 2318 | else: 2319 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2320 | if (residue_psi_cycle==0): 2321 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2322 | phi=current_phi 2323 | psi=-180 2324 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2325 | sort_residues(mol_id) 2326 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2327 | residue_psi_cycle=1 2328 | elif (residue_psi_cycle==1): 2329 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2330 | phi=current_phi 2331 | psi=-150 2332 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2333 | sort_residues(mol_id) 2334 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2335 | residue_psi_cycle=2 2336 | elif (residue_psi_cycle==2): 2337 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2338 | phi=current_phi 2339 | psi=-120 2340 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2341 | sort_residues(mol_id) 2342 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2343 | residue_psi_cycle=3 2344 | elif (residue_psi_cycle==3): 2345 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2346 | phi=current_phi 2347 | psi=-90 2348 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2349 | sort_residues(mol_id) 2350 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2351 | residue_psi_cycle=4 2352 | elif (residue_psi_cycle==4): 2353 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2354 | phi=current_phi 2355 | psi=-60 2356 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2357 | sort_residues(mol_id) 2358 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2359 | residue_psi_cycle=5 2360 | elif (residue_psi_cycle==5): 2361 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2362 | phi=current_phi 2363 | psi=-30 2364 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2365 | sort_residues(mol_id) 2366 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2367 | residue_psi_cycle=6 2368 | elif (residue_psi_cycle==6): 2369 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2370 | phi=current_phi 2371 | psi=0 2372 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2373 | sort_residues(mol_id) 2374 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2375 | residue_psi_cycle=7 2376 | elif (residue_psi_cycle==7): 2377 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2378 | phi=current_phi 2379 | psi=30 2380 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2381 | sort_residues(mol_id) 2382 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2383 | residue_psi_cycle=8 2384 | elif (residue_psi_cycle==8): 2385 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2386 | phi=current_phi 2387 | psi=60 2388 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2389 | sort_residues(mol_id) 2390 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2391 | residue_psi_cycle=9 2392 | elif (residue_psi_cycle==9): 2393 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2394 | phi=current_phi 2395 | psi=90 2396 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2397 | sort_residues(mol_id) 2398 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2399 | residue_psi_cycle=10 2400 | elif (residue_psi_cycle==10): 2401 | delete_residue(mol_id,ch_id,last_in_seg,ins_code) 2402 | phi=current_phi 2403 | psi=120 2404 | force_add_terminal_residue_noclick_phi_psi(mol_id,ch_id,last_in_seg-1,phi,psi) 2405 | sort_residues(mol_id) 2406 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 2407 | residue_psi_cycle=0 2408 | current_psi=psi 2409 | 2410 | 2411 | def add_term_shortcut_force(): 2412 | mol_id=active_residue()[0] 2413 | ch_id=active_residue()[1] 2414 | resn=active_residue()[2] 2415 | atom_name=active_residue()[4] 2416 | set_go_to_atom_molecule(mol_id) 2417 | first_in_seg=first_residue_in_seg(mol_id,ch_id,resn) 2418 | last_in_seg=last_residue_in_seg(mol_id,ch_id,resn) 2419 | delta_first=abs(first_in_seg-resn) 2420 | delta_last=abs(last_in_seg-resn) 2421 | set_new_atom_b_fac_to_mean() 2422 | if delta_first<=delta_last: 2423 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,"CA") 2424 | force_add_terminal_residue_noclick(mol_id,ch_id,first_in_seg) 2425 | sort_residues(mol_id) 2426 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg-1,"CA") 2427 | else: 2428 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,"CA") 2429 | force_add_terminal_residue_noclick(mol_id,ch_id,last_in_seg) 2430 | sort_residues(mol_id) 2431 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg+1,"CA") 2432 | 2433 | 2434 | 2435 | #Grow helix from selected terminus 2436 | def grow_helix(): 2437 | def grow_helix_post_click(res1): 2438 | def grow_helix_enter_resn(n): 2439 | mol_id=res1[1] 2440 | ch_id=res1[2] 2441 | res_no=res1[3] 2442 | res_no_0=res_no 2443 | for i in range(1,(int(n)+1)): 2444 | res_type="auto" 2445 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 2446 | res_type,-57.82,-47) 2447 | sort_residues(mol_id) 2448 | if (res_no==(first_residue_in_seg(mol_id,ch_id,res_no)+1)): 2449 | res_no=res_no-1 2450 | elif (res_no==(last_residue_in_seg(mol_id,ch_id,res_no)-1)): 2451 | res_no=res_no+1 2452 | set_b_factor_residue_range(mol_id,ch_id,res_no_0,res_no,default_new_atoms_b_factor()) 2453 | generic_single_entry("How many residues for helix?", 2454 | "10","Grow helix",grow_helix_enter_resn) 2455 | user_defined_click(1,grow_helix_post_click) 2456 | 2457 | #Grow strand from selected terminus 2458 | def grow_strand(): 2459 | def grow_strand_post_click(res1): 2460 | def grow_strand_enter_resn(n): 2461 | mol_id=res1[1] 2462 | ch_id=res1[2] 2463 | res_no=res1[3] 2464 | res_no_0=res_no 2465 | for i in range(1,(int(n)+1)): 2466 | res_type="auto" 2467 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 2468 | res_type,-139,135) 2469 | sort_residues(mol_id) 2470 | if (res_no==(first_residue_in_seg(mol_id,ch_id,res_no)+1)): 2471 | res_no=res_no-1 2472 | elif (res_no==(last_residue_in_seg(mol_id,ch_id,res_no)-1)): 2473 | res_no=res_no+1 2474 | set_b_factor_residue_range(mol_id,ch_id,res_no_0,res_no,default_new_atoms_b_factor()) 2475 | generic_single_entry("How many residues for strand?", 2476 | "10","Grow strand",grow_strand_enter_resn) 2477 | user_defined_click(1,grow_strand_post_click) 2478 | 2479 | #Grow para strand from selected terminus 2480 | def grow_parallel_strand(): 2481 | def grow_parallel_strand_post_click(res1): 2482 | def grow_parallel_strand_enter_resn(n): 2483 | mol_id=res1[1] 2484 | ch_id=res1[2] 2485 | res_no=res1[3] 2486 | for i in range(1,(int(n)+1)): 2487 | res_type="auto" 2488 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 2489 | res_type,-119,113) 2490 | sort_residues(mol_id) 2491 | if (res_no==(first_residue_in_seg(mol_id,ch_id,res_no)+1)): 2492 | res_no=res_no-1 2493 | elif (res_no==(last_residue_in_seg(mol_id,ch_id,res_no)-1)): 2494 | res_no=res_no+1 2495 | generic_single_entry("How many residues for parallel strand?", 2496 | "10","Grow parallel strand",grow_parallel_strand_enter_resn) 2497 | user_defined_click(1,grow_parallel_strand_post_click) 2498 | 2499 | #Grow 3-10 helix from selected terminus 2500 | def grow_helix_3_10(): 2501 | def grow_helix_post_click(res1): 2502 | def grow_helix_enter_resn(n): 2503 | mol_id=res1[1] 2504 | ch_id=res1[2] 2505 | res_no=res1[3] 2506 | for i in range(1,(int(n)+1)): 2507 | res_type="auto" 2508 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 2509 | res_type,-49,-26) 2510 | sort_residues(mol_id) 2511 | if (res_no==(first_residue_in_seg(mol_id,ch_id,res_no)+1)): 2512 | res_no=res_no-1 2513 | elif (res_no==(last_residue_in_seg(mol_id,ch_id,res_no)-1)): 2514 | res_no=res_no+1 2515 | generic_single_entry("How many residues for helix?", 2516 | "10","Grow 3-10 helix",grow_helix_enter_resn) 2517 | user_defined_click(1,grow_helix_post_click) 2518 | 2519 | #Renumbers the active chain (from active_residue()). User enters new starting residue number. 2520 | def renumber_by_first_res(): 2521 | def renum_chain(new_num): 2522 | new_num=int(new_num) 2523 | mol_id=active_residue()[0] 2524 | ch_id=active_residue()[1] 2525 | first_res=first_residue(mol_id,ch_id) 2526 | last_res=last_residue(mol_id,ch_id) 2527 | offset=new_num-first_res 2528 | renumber_residue_range(mol_id,ch_id,first_res,last_res,int(offset)) 2529 | delete_all_extra_restraints(mol_id) 2530 | set_show_extra_restraints(mol_id,0) 2531 | set_show_extra_restraints(mol_id,1) 2532 | generic_single_entry("New number for first residue in this chain?", 2533 | str(seqnum_from_serial_number(active_residue()[0], 2534 | "%s"%(active_residue()[1]),0)),"Renumber",renum_chain) 2535 | 2536 | #Renumbers the active chain (from active_residue()). User enters new last residue number. 2537 | def renumber_by_last_res(): 2538 | def renum_chain(new_num): 2539 | new_num=int(new_num) 2540 | mol_id=active_residue()[0] 2541 | ch_id=active_residue()[1] 2542 | first_res=first_residue(mol_id,ch_id) 2543 | last_res=last_residue(mol_id,ch_id) 2544 | offset=new_num-last_res 2545 | renumber_residue_range(mol_id,ch_id,first_res,last_res,int(offset)) 2546 | delete_all_extra_restraints(mol_id) 2547 | set_show_extra_restraints(mol_id,0) 2548 | set_show_extra_restraints(mol_id,1) 2549 | generic_single_entry("New number for last residue in this chain?", 2550 | str(seqnum_from_serial_number(active_residue()[0], 2551 | "%s"%(active_residue()[1]), 2552 | (chain_n_residues(active_residue()[1],active_residue()[0])-1))),"Renumber",renum_chain) 2553 | 2554 | #Renumbers the active chain (from active_residue()). User enters new active residue number. 2555 | def renumber_by_active_res(): 2556 | def renum_chain(new_num): 2557 | new_num=int(new_num) 2558 | mol_id=active_residue()[0] 2559 | ch_id=active_residue()[1] 2560 | current_num=active_residue()[2] 2561 | first_res=first_residue(mol_id,ch_id) 2562 | last_res=last_residue(mol_id,ch_id) 2563 | offset=new_num-current_num 2564 | renumber_residue_range(mol_id,ch_id,first_res,last_res,int(offset)) 2565 | delete_all_extra_restraints(mol_id) 2566 | set_show_extra_restraints(mol_id,0) 2567 | set_show_extra_restraints(mol_id,1) 2568 | generic_single_entry("New number for this residue?", 2569 | str(active_residue()[2]),"Renumber",renum_chain) 2570 | 2571 | #Renumber from N-term to current residue 2572 | def renumber_n_term_segment(): 2573 | def renumber_n_term_segment_entry(new_resn): 2574 | mol_id=active_residue()[0] 2575 | ch_id=active_residue()[1] 2576 | resn=active_residue()[2] 2577 | first_res=seqnum_from_serial_number(mol_id,"%s"%(ch_id),0) 2578 | offset=int(new_resn)-resn 2579 | renumber_residue_range(mol_id,ch_id,first_res,resn,offset) 2580 | delete_all_extra_restraints(mol_id) 2581 | set_show_extra_restraints(mol_id,0) 2582 | set_show_extra_restraints(mol_id,1) 2583 | generic_single_entry("New residue number?", 2584 | str(active_residue()[2]),"Renumber",renumber_n_term_segment_entry) 2585 | 2586 | #Renumber from current residue to C-term 2587 | def renumber_c_term_segment(): 2588 | def renumber_c_term_segment_entry(new_resn): 2589 | mol_id=active_residue()[0] 2590 | ch_id=active_residue()[1] 2591 | resn=active_residue()[2] 2592 | def last_residue(mol_id,ch_id): 2593 | n=chain_n_residues(ch_id,mol_id)-1 2594 | result=seqnum_from_serial_number(mol_id,"%s"%(ch_id),n) 2595 | return result 2596 | last_res=last_residue(mol_id,ch_id) 2597 | offset=int(new_resn)-resn 2598 | renumber_residue_range(mol_id,ch_id,resn,last_res,offset) 2599 | delete_all_extra_restraints(mol_id) 2600 | set_show_extra_restraints(mol_id,0) 2601 | set_show_extra_restraints(mol_id,1) 2602 | generic_single_entry("New residue number?", 2603 | str(active_residue()[2]),"Renumber",renumber_c_term_segment_entry) 2604 | 2605 | #Sharpen or blur map. Slider jerky on large maps. 2606 | def sharpen_by_entered_factor(): 2607 | if (scroll_wheel_map()==-1): 2608 | info_dialog("You need a map!") 2609 | else: 2610 | def sharpen_by_entry(B): 2611 | B=float(B) 2612 | sharpen(scroll_wheel_map(),B) 2613 | generic_single_entry("New B-factor for map?", 2614 | "-100","Sharpen/Blur",sharpen_by_entry) 2615 | 2616 | #Reload map with different hi-res limit 2617 | def change_hires_limit(): 2618 | if (scroll_wheel_map()==-1): 2619 | info_dialog("You need a map!") 2620 | else: 2621 | def change_hires_by_entry(new_res): 2622 | mol=scroll_wheel_map() 2623 | new_res=float(new_res) 2624 | mtz_file=map_parameters(mol)[0] 2625 | F_col=map_parameters(mol)[1] 2626 | PHI_col=map_parameters(mol)[2] 2627 | make_and_draw_map_with_reso_with_refmac_params(mtz_file,F_col,PHI_col,"",0,0,0,"Fobs:None-specified", 2628 | "SigF:None-specified","RFree:None-specified",0,0,1,1000.0,new_res) 2629 | close_molecule(mol) 2630 | generic_single_entry("New high-res limit for map?", 2631 | "5.0","Change high resolution limit for active map",change_hires_by_entry) 2632 | 2633 | def change_hires_limit_copy(): 2634 | if (scroll_wheel_map()==-1): 2635 | info_dialog("You need a map!") 2636 | else: 2637 | def change_hires_by_entry(new_res): 2638 | mol=scroll_wheel_map() 2639 | new_res=float(new_res) 2640 | mtz_file=map_parameters(mol)[0] 2641 | F_col=map_parameters(mol)[1] 2642 | PHI_col=map_parameters(mol)[2] 2643 | make_and_draw_map_with_reso_with_refmac_params(mtz_file,F_col,PHI_col,"",0,0,0,"Fobs:None-specified", 2644 | "SigF:None-specified","RFree:None-specified",0,0,1,1000.0,new_res) 2645 | generic_single_entry("New high-res limit for map?", 2646 | "5.0","Make low pass filtered copy of active map",change_hires_by_entry) 2647 | 2648 | #Mutate mets to MSE 2649 | def mutate_all_mets_to_mse(): 2650 | mol_id=active_residue()[0] 2651 | turn_off_backup(mol_id) 2652 | for ch_id in chain_ids(mol_id): 2653 | for resn in range(0,chain_n_residues(ch_id,mol_id)): 2654 | if (resname_from_serial_number(mol_id,ch_id,resn)=="MET"): 2655 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 2656 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,resn)) 2657 | delete_residue_with_full_spec(mol_id,1,ch_id,seqnum,ins_id,"B") 2658 | delete_residue_with_full_spec(mol_id,1,ch_id,seqnum,ins_id,"C") 2659 | mutate(mol_id,ch_id,seqnum,ins_id,"MSE") 2660 | map_id=imol_refinement_map() 2661 | if (map_id!=-1): 2662 | auto_fit_best_rotamer(seqnum,"",ins_id,ch_id,mol_id,map_id,1,0.01) 2663 | turn_on_backup(mol_id) 2664 | 2665 | #Mutate MSEs to MET 2666 | def mutate_all_mse_to_met(): 2667 | mol_id=active_residue()[0] 2668 | turn_off_backup(mol_id) 2669 | for ch_id in chain_ids(mol_id): 2670 | for resn in range(0,chain_n_residues(ch_id,mol_id)): 2671 | if (resname_from_serial_number(mol_id,ch_id,resn)=="MSE"): 2672 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 2673 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,resn)) 2674 | delete_residue_with_full_spec(mol_id,1,ch_id,seqnum,ins_id,"B") 2675 | delete_residue_with_full_spec(mol_id,1,ch_id,seqnum,ins_id,"C") 2676 | mutate(mol_id,ch_id,seqnum,ins_id,"MET") 2677 | map_id=imol_refinement_map() 2678 | if (map_id!=-1): 2679 | auto_fit_best_rotamer(seqnum,"",ins_id,ch_id,mol_id,map_id,1,0.01) 2680 | turn_on_backup(mol_id) 2681 | 2682 | #Shorten loop by one residue 2683 | def shorten_loop(): 2684 | active_atom=active_residue() 2685 | mol_id=active_atom[0] 2686 | ch_id=active_atom[1] 2687 | resn=active_atom[2] 2688 | ins_code=active_atom[3] 2689 | delete_residue(mol_id,ch_id,resn,ins_code) 2690 | first_res=seqnum_from_serial_number(mol_id,"%s"%(ch_id),0) 2691 | renumber_residue_range(mol_id,ch_id,first_res,resn,1) 2692 | delete_all_extra_restraints(mol_id) 2693 | set_show_extra_restraints(mol_id,0) 2694 | set_show_extra_restraints(mol_id,1) 2695 | r1=resn-1 2696 | r2=resn+2 2697 | set_refinement_immediate_replacement(1) 2698 | refine_zone(mol_id,ch_id,r1,r2,"") 2699 | accept_regularizement() 2700 | set_refinement_immediate_replacement(0) 2701 | 2702 | #Lengthen loop by one residue 2703 | def lengthen_loop(): 2704 | active_atom=active_residue() 2705 | mol_id=active_atom[0] 2706 | ch_id=active_atom[1] 2707 | resn=active_atom[2] 2708 | first_res=seqnum_from_serial_number(mol_id,"%s"%(ch_id),0) 2709 | renumber_residue_range(mol_id,ch_id,first_res,resn,-1) 2710 | delete_all_extra_restraints(mol_id) 2711 | set_show_extra_restraints(mol_id,0) 2712 | set_show_extra_restraints(mol_id,1) 2713 | r1=resn-1 2714 | r2=resn 2715 | set_refinement_immediate_replacement(1) 2716 | fit_gap(mol_id,ch_id,r1,r2,"A",1) 2717 | accept_regularizement() 2718 | set_refinement_immediate_replacement(0) 2719 | 2720 | #Get fractional coordinates of active atom. Useful when inspecting heavy atom sites. 2721 | def get_fract_coords(): 2722 | a=active_residue() 2723 | x_cart=atom_specs(a[0],a[1],a[2],a[3],a[4],a[5])[3] 2724 | y_cart=atom_specs(a[0],a[1],a[2],a[3],a[4],a[5])[4] 2725 | z_cart=atom_specs(a[0],a[1],a[2],a[3],a[4],a[5])[5] 2726 | mol_id=active_residue()[0] 2727 | cell_a=cell(mol_id)[0] 2728 | cell_b=cell(mol_id)[1] 2729 | cell_c=cell(mol_id)[2] 2730 | cell_alpha=math.radians(cell(mol_id)[3]) 2731 | cell_beta=math.radians(cell(mol_id)[4]) 2732 | cell_gamma=math.radians(cell(mol_id)[5]) 2733 | cos_alpha_star=(math.cos(cell_beta)*math.cos(cell_gamma)-math.cos(cell_alpha))/(math.sin(cell_beta)*math.sin(cell_gamma)) 2734 | sin_alpha_star=math.sqrt(1-cos_alpha_star**2) 2735 | z_fract=z_cart/(cell_c*math.sin(cell_beta)*sin_alpha_star) 2736 | y_fract=(y_cart-(-1*cell_c*math.sin(cell_beta)*cos_alpha_star)*z_fract)/(cell_b*math.sin(cell_gamma)) 2737 | x_fract=(x_cart-(cell_b*math.cos(cell_gamma))*y_fract-(cell_c*math.cos(cell_beta))*z_fract)/cell_a 2738 | x_y_z_string=str("("+str("%.3f" % x_fract)+","+str("%.3f" % y_fract)+","+str("%.3f" % z_fract)+")") 2739 | info_dialog("The fractional coordinates of the active atom are: %s"%(x_y_z_string)) 2740 | 2741 | #Go to center of scroll wheel map. 2742 | def goto_center_of_map(): 2743 | if (scroll_wheel_map()==-1): 2744 | info_dialog("You need a map!") 2745 | else: 2746 | mol_id=scroll_wheel_map() 2747 | a=float(cell(mol_id)[0]) 2748 | b=float(cell(mol_id)[1]) 2749 | c=float(cell(mol_id)[2]) 2750 | x=a*0.5 2751 | y=b*0.5 2752 | z=c*0.5 2753 | set_rotation_centre(x,y,z) 2754 | 2755 | #Make a button list for inserting common monomers 2756 | def pick_common_monomers(): 2757 | get_ddm=["DDM", lambda func: get_monomer_no_H("LMT")] 2758 | get_dm=["DM", lambda func: get_monomer_no_H("DMU")] 2759 | get_bog=["OG", lambda func: get_monomer_no_H("HSH")] 2760 | get_ldao=["LDAO", lambda func: get_monomer_no_H("LDA")] 2761 | get_mpg=["Monoolein", lambda func: get_monomer_no_H("MPG")] 2762 | get_glycerol=["Glycerol", lambda func: get_monomer_no_H("GOL")] 2763 | get_eg=["Ethylene glycol", lambda func: get_monomer_no_H("EDO")] 2764 | get_acetate=["Acetate", lambda func: get_monomer_no_H("ACT")] 2765 | get_dmso=["DMSO", lambda func: get_monomer_no_H("DMS")] 2766 | get_tris=["Tris", lambda func: get_monomer_no_H("TAM")] 2767 | get_hepes=["HEPES", lambda func: get_monomer_no_H("EPE")] 2768 | get_mes=["MES", lambda func: get_monomer_no_H("MES")] 2769 | get_cac=["Cacodylate", lambda func: get_monomer_no_H("CAD")] 2770 | get_peg=["PEG", lambda func: get_monomer_no_H("1PE")] 2771 | get_popg=["POPG (lipid)", lambda func: get_monomer_no_H("LHG")] 2772 | get_pe=["PE (lipid)", lambda func: get_monomer_no_H("PEF")] 2773 | get_pc=["PC (lipid)", lambda func: get_monomer_no_H("PLC")] 2774 | get_ps=["PS (lipid)", lambda func: get_monomer_no_H("PSF")] 2775 | get_ps=["PI(3,4)P2 (lipid)", lambda func: get_monomer_no_H("52N")] 2776 | get_chs=["Cholesterol hemisuccinate", lambda func: get_monomer_no_H("Y01")] 2777 | get_chl=["Cholesterol", lambda func: get_monomer_no_H("CLR")] 2778 | button_list=[get_acetate,get_eg,get_glycerol,get_dmso,get_ddm,get_dm,get_bog,get_ldao,get_mpg,get_tris,get_hepes,get_mes,get_cac,get_peg,get_popg,get_pe,get_pc,get_ps,get_chs,get_chl] 2779 | generic_button_dialog("Common small molecules",button_list) 2780 | 2781 | #Switch all models to CA representation 2782 | def all_mols_to_ca(): 2783 | for mol_id in molecule_number_list(): 2784 | graphics_to_ca_plus_ligands_representation(mol_id) 2785 | 2786 | #Set b-factor color scaling based on mean B of active mol 2787 | def autoscale_b_factor(): 2788 | mol_id=active_residue()[0] 2789 | mean_b=average_temperature_factor(mol_id) 2790 | scale_fac=50/mean_b 2791 | set_b_factor_bonds_scale_factor(mol_id,scale_fac) 2792 | graphics_to_b_factor_representation(mol_id) 2793 | 2794 | #Color molecule by rotamer and missing atom outliers 2795 | def color_rotamer_outliers_and_missing_atoms(mol_id): 2796 | missing_atoms_list=[] 2797 | missing_atoms_colour=2 2798 | rotamer_outlier_list=[] 2799 | rotamer_outlier_colour=34 2800 | blank_colour=0 2801 | for x in missing_atom_info(mol_id): 2802 | missing_atoms_spec=[(x,missing_atoms_colour)] 2803 | missing_atoms_list=missing_atoms_list+missing_atoms_spec 2804 | for ch_id in chain_ids(mol_id): 2805 | first_res=first_residue(mol_id,ch_id) 2806 | last_res=last_residue(mol_id,ch_id) 2807 | for resn in range(first_res,last_res): 2808 | if residue_exists_qm(mol_id,ch_id,resn,""): 2809 | rot_prob=rotamer_score(mol_id,ch_id,resn,"","") 2810 | if rot_prob<0.5 and rot_prob>0.0: 2811 | rotamer_outlier_spec=[([ch_id,resn,""],rotamer_outlier_colour)] 2812 | rotamer_outlier_list=rotamer_outlier_list+rotamer_outlier_spec 2813 | else: 2814 | rotamer_outlier_spec=[([ch_id,resn,""],blank_colour)] 2815 | rotamer_outlier_list=rotamer_outlier_list+rotamer_outlier_spec 2816 | try: 2817 | set_user_defined_atom_colour_by_residue_py(mol_id,rotamer_outlier_list) 2818 | set_user_defined_atom_colour_by_residue_py(mol_id,missing_atoms_list) 2819 | graphics_to_user_defined_atom_colours_representation(mol_id) 2820 | except NameError: 2821 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 2822 | pass 2823 | 2824 | 2825 | #Colors subset of protein residues red, provided by user as string of single-letter ids. 2826 | def color_protein_residue_subset(): 2827 | def color_from_string(X): 2828 | entry=str(X).upper() #capitalize 2829 | mol_id=active_residue()[0] 2830 | aa_dic={'A':'ALA','R':'ARG','N':'ASN','D':'ASP','C':'CYS','E':'GLU','Q':'GLN','G':'GLY','H':'HIS','I':'ILE','L':'LEU','K':'LYS','M':'MET','F':'PHE','P':'PRO','S':'SER','T':'THR','W':'TRP','Y':'TYR','V':'VAL','X':'UNK'} 2831 | highlight_colour=34 #red 2832 | blank_colour=0 #light grey 2833 | residue_list=[] 2834 | resname_list=[] 2835 | for char in entry: 2836 | if (aa_dic.get(char,0)!=0): #make a list of 3-letter resnames from user supplied string by checking aa_dic 2837 | resname=[(aa_dic.get(char,0))] 2838 | resname_list=resname_list+resname 2839 | for ch_id in chain_ids(mol_id): 2840 | sn_max=chain_n_residues(ch_id,mol_id) 2841 | for sn in range(0,sn_max+1): 2842 | resname_here=resname_from_serial_number(mol_id,ch_id,sn) 2843 | for resname in resname_list: 2844 | if resname==resname_here: 2845 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2846 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2847 | residue_to_color=[([ch_id,resn,ins_id],highlight_colour)] 2848 | residue_list=residue_list+residue_to_color 2849 | if resname_here not in resname_list: 2850 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2851 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2852 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 2853 | residue_list=residue_list+residue_to_color 2854 | try: 2855 | set_user_defined_atom_colour_by_residue_py(mol_id,residue_list) 2856 | graphics_to_user_defined_atom_colours_representation(mol_id) 2857 | except NameError: 2858 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 2859 | pass 2860 | generic_single_entry("Residues to color? Single letter code (e.g. DE or de will color Asp/Glu)","A","Color entered residue types!",color_from_string) 2861 | 2862 | def color_polars_and_hphobs(mol_id): 2863 | hphob_list=["CYS","ILE","LEU","VAL","TYR","MET","PHE","TRP","ALA"] 2864 | polar_list=["SER","ASN","GLN","HIS","ARG","LYS","GLU","ASP","THR"] 2865 | #based these on Moon&Fleming PNAS 2011 and MacCallum TIBS 2011 2866 | #Gly/Pro colored differently because they are conformationally "special" residues 2867 | polar_colour=5 #light blue 2868 | hphob_colour=28 #orange 2869 | gly_colour=34 #magenta 2870 | pro_colour=15 #green 2871 | blank_colour=0 #light gray 2872 | polar_res_list=[] 2873 | hphob_res_list=[] 2874 | gly_res_list=[] 2875 | pro_res_list=[] 2876 | blank_res_list=[] 2877 | for ch_id in chain_ids(mol_id): 2878 | sn_max=chain_n_residues(ch_id,mol_id) 2879 | for sn in range(0,sn_max+1): 2880 | resname_here=resname_from_serial_number(mol_id,ch_id,sn) 2881 | if resname_here in polar_list: 2882 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2883 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2884 | residue_to_color=[([ch_id,resn,ins_id],polar_colour)] 2885 | polar_res_list=polar_res_list+residue_to_color 2886 | elif resname_here in hphob_list: 2887 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2888 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2889 | residue_to_color=[([ch_id,resn,ins_id],hphob_colour)] 2890 | hphob_res_list=hphob_res_list+residue_to_color 2891 | elif resname_here=="GLY": 2892 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2893 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2894 | residue_to_color=[([ch_id,resn,ins_id],gly_colour)] 2895 | gly_res_list=gly_res_list+residue_to_color 2896 | elif resname_here=="PRO": 2897 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2898 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2899 | residue_to_color=[([ch_id,resn,ins_id],pro_colour)] 2900 | pro_res_list=pro_res_list+residue_to_color 2901 | else: 2902 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2903 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2904 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 2905 | blank_res_list=blank_res_list+residue_to_color 2906 | try: 2907 | set_user_defined_atom_colour_by_residue_py(mol_id,polar_res_list) 2908 | set_user_defined_atom_colour_by_residue_py(mol_id,hphob_res_list) 2909 | set_user_defined_atom_colour_by_residue_py(mol_id,gly_res_list) 2910 | set_user_defined_atom_colour_by_residue_py(mol_id,pro_res_list) 2911 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_res_list) 2912 | graphics_to_user_defined_atom_colours_representation(mol_id) 2913 | except NameError: 2914 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 2915 | pass 2916 | 2917 | def color_by_charge(mol_id): 2918 | pos_list=["ARG","LYS","HIS"] 2919 | neg_list=["GLU","ASP"] 2920 | pos_colour=4 2921 | neg_colour=31 2922 | blank_colour=0 2923 | pos_res_list=[] 2924 | neg_res_list=[] 2925 | blank_res_list=[] 2926 | for ch_id in chain_ids(mol_id): 2927 | sn_max=chain_n_residues(ch_id,mol_id) 2928 | for sn in range(0,sn_max+1): 2929 | resname_here=resname_from_serial_number(mol_id,ch_id,sn) 2930 | if resname_here in pos_list: 2931 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2932 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2933 | residue_to_color=[([ch_id,resn,ins_id],pos_colour)] 2934 | pos_res_list=pos_res_list+residue_to_color 2935 | elif resname_here in neg_list: 2936 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2937 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2938 | residue_to_color=[([ch_id,resn,ins_id],neg_colour)] 2939 | neg_res_list=neg_res_list+residue_to_color 2940 | else: 2941 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2942 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2943 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 2944 | blank_res_list=blank_res_list+residue_to_color 2945 | try: 2946 | set_user_defined_atom_colour_by_residue_py(mol_id,pos_res_list) 2947 | set_user_defined_atom_colour_by_residue_py(mol_id,neg_res_list) 2948 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_res_list) 2949 | graphics_to_user_defined_atom_colours_representation(mol_id) 2950 | except NameError: 2951 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 2952 | pass 2953 | 2954 | def uncolor_other_chains(): 2955 | mol_id=active_residue()[0] 2956 | ch_id_here=active_residue()[1] 2957 | blank_colour=0 2958 | blank_res_list=[] 2959 | for ch_id in chain_ids(mol_id): 2960 | sn_max=chain_n_residues(ch_id,mol_id) 2961 | if ch_id!=ch_id_here: 2962 | for sn in range(0,sn_max+1): 2963 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2964 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2965 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 2966 | blank_res_list=blank_res_list+residue_to_color 2967 | try: 2968 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_res_list) 2969 | graphics_to_user_defined_atom_colours_representation(mol_id) 2970 | except NameError: 2971 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 2972 | pass 2973 | 2974 | def color_active_chain(): 2975 | mol_id=active_residue()[0] 2976 | ch_id_here=active_residue()[1] 2977 | blank_colour=0 2978 | chain_colour=22 #yellow 2979 | blank_res_list=[] 2980 | chain_res_list=[] 2981 | for ch_id in chain_ids(mol_id): 2982 | sn_max=chain_n_residues(ch_id,mol_id) 2983 | if ch_id!=ch_id_here: 2984 | for sn in range(0,sn_max+1): 2985 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2986 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2987 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 2988 | blank_res_list=blank_res_list+residue_to_color 2989 | if ch_id==ch_id_here: 2990 | for sn in range(0,sn_max+1): 2991 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 2992 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 2993 | residue_to_color=[([ch_id,resn,ins_id],chain_colour)] 2994 | chain_res_list=chain_res_list+residue_to_color 2995 | try: 2996 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_res_list) 2997 | set_user_defined_atom_colour_by_residue_py(mol_id,chain_res_list) 2998 | graphics_to_user_defined_atom_colours_representation(mol_id) 2999 | except NameError: 3000 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 3001 | pass 3002 | 3003 | def color_active_chain_by_num(chain_colour): 3004 | mol_id=active_residue()[0] 3005 | ch_id_here=active_residue()[1] 3006 | blank_colour=0 3007 | blank_res_list=[] 3008 | chain_res_list=[] 3009 | for ch_id in chain_ids(mol_id): 3010 | sn_max=chain_n_residues(ch_id,mol_id) 3011 | if ch_id!=ch_id_here: 3012 | for sn in range(0,sn_max+1): 3013 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 3014 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 3015 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 3016 | blank_res_list=blank_res_list+residue_to_color 3017 | if ch_id==ch_id_here: 3018 | for sn in range(0,sn_max+1): 3019 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 3020 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 3021 | residue_to_color=[([ch_id,resn,ins_id],chain_colour)] 3022 | chain_res_list=chain_res_list+residue_to_color 3023 | try: 3024 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_res_list) 3025 | set_user_defined_atom_colour_by_residue_py(mol_id,chain_res_list) 3026 | graphics_to_user_defined_atom_colours_representation(mol_id) 3027 | except NameError: 3028 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 3029 | pass 3030 | 3031 | def color_protein_na(mol_id): 3032 | blank_colour=0 3033 | protein_colour=22 #yellow 3034 | na_colour=31 3035 | protein_res_list=[] 3036 | na_res_list=[] 3037 | blank_res_list=[] 3038 | for ch_id in chain_ids(mol_id): 3039 | sn_max=chain_n_residues(ch_id,mol_id) 3040 | if is_nucleotide_chain_p(mol_id,ch_id): 3041 | for sn in range(0,sn_max+1): 3042 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 3043 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 3044 | residue_to_color=[([ch_id,resn,ins_id],na_colour)] 3045 | na_res_list=na_res_list+residue_to_color 3046 | if is_protein_chain_p(mol_id,ch_id): 3047 | for sn in range(0,sn_max+1): 3048 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 3049 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 3050 | residue_to_color=[([ch_id,resn,ins_id],protein_colour)] 3051 | protein_res_list=protein_res_list+residue_to_color 3052 | else: 3053 | for sn in range(0,sn_max+1): 3054 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 3055 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 3056 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 3057 | blank_res_list=blank_res_list+residue_to_color 3058 | try: 3059 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_res_list) 3060 | set_user_defined_atom_colour_by_residue_py(mol_id,protein_res_list) 3061 | set_user_defined_atom_colour_by_residue_py(mol_id,na_res_list) 3062 | graphics_to_user_defined_atom_colours_representation(mol_id) 3063 | except NameError: 3064 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 3065 | pass 3066 | 3067 | 3068 | def color_waters(mol_id): 3069 | water_colour=31 3070 | blank_colour=0 3071 | water_list=[] 3072 | blank_res_list=[] 3073 | for ch_id in chain_ids(mol_id): 3074 | sn_max=chain_n_residues(ch_id,mol_id) 3075 | for sn in range(0,sn_max+1): 3076 | resname_here=resname_from_serial_number(mol_id,ch_id,sn) 3077 | if resname_here=="HOH": 3078 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 3079 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 3080 | residue_to_color=[([ch_id,resn,ins_id],water_colour)] 3081 | water_list=water_list+residue_to_color 3082 | else: 3083 | resn=seqnum_from_serial_number(mol_id,ch_id,sn) 3084 | ins_id=str(insertion_code_from_serial_number(mol_id,ch_id,sn)) 3085 | residue_to_color=[([ch_id,resn,ins_id],blank_colour)] 3086 | blank_res_list=blank_res_list+residue_to_color 3087 | try: 3088 | set_user_defined_atom_colour_by_residue_py(mol_id,water_list) 3089 | set_user_defined_atom_colour_by_residue_py(mol_id,blank_res_list) 3090 | graphics_to_user_defined_atom_colours_all_atoms_representation(mol_id) 3091 | except NameError: 3092 | info_dialog("You need a newer Coot - custom coloring is only in r6174 and later, sorry.") 3093 | pass 3094 | 3095 | 3096 | #Mutate active chain to entered sequence 3097 | default_seq="MAAAA" 3098 | def mutate_by_resnum(): 3099 | def enter_seq(seq): 3100 | global default_seq 3101 | seq=str(seq).upper() 3102 | seq.replace(" ", "") 3103 | seq_dic={} 3104 | len_seq=len(seq) 3105 | n=0 3106 | nmax=len_seq+1 3107 | aa_dic={'A':'ALA','R':'ARG','N':'ASN','D':'ASP','C':'CYS','E':'GLU', 3108 | 'Q':'GLN','G':'GLY','H':'HIS','I':'ILE','L':'LEU','K':'LYS','M':'MET', 3109 | 'F':'PHE','P':'PRO','S':'SER','T':'THR','W':'TRP','Y':'TYR','V':'VAL'} 3110 | clean_seq='' 3111 | while (n 3163 | # 3164 | # org.pdb.query.simple.SequenceQuery 3165 | # {sequence} 3166 | # 0.00001 3167 | # blast 3168 | # 50 3169 | # 3170 | # """.format(sequence=seq) 3171 | # 3172 | # print "query:\n", queryText 3173 | # print "querying PDB...\n" 3174 | # req = urllib2.Request(url, data=queryText) 3175 | # f = urllib2.urlopen(req) 3176 | # result = f.read() 3177 | # if result: 3178 | # print "Found number of PDB entries:", result.count('\n') 3179 | # print result 3180 | # else: 3181 | # print "Failed to retrieve results" 3182 | 3183 | #Highlight various items with ball-and-stick and lines 3184 | def highlight_chain_breaks(): 3185 | mol_id=active_residue()[0] 3186 | clear_ball_and_stick(mol_id) 3187 | turn_off_backup(mol_id) 3188 | obj_number=generic_object_with_name("chain_breaks_{mol_id}".format(mol_id=mol_id)) 3189 | generic_object_clear(obj_number) 3190 | protein_resnames=['ALA','UNK','ARG','ASN','ASP','CYS','GLU','GLN','GLY','HIS','ILE','LEU','LYS','MET','MSE','PHE','PRO','SER','THR','TRP','TYR','VAL'] 3191 | na_resnames=['A','C','T','G','U'] 3192 | missing_segments_list=[] 3193 | for ch_id in chain_ids(mol_id): 3194 | for resn in range(0,chain_n_residues(ch_id,mol_id)): 3195 | resname=resname_from_serial_number(mol_id,ch_id,resn) 3196 | print(resname) 3197 | if (resname in protein_resnames): 3198 | if ((is_term_type_mc_sn(mol_id,ch_id,resn)==1) or (is_term_type_mn_sn(mol_id,ch_id,resn)==1)): 3199 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3200 | # sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/CA" 3201 | # make_ball_and_stick(mol_id,sel_string,0,0.5,1 3202 | if (is_term_type_mn_sn(mol_id,ch_id,resn)==1): 3203 | x_mn=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-3] 3204 | y_mn=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-2] 3205 | z_mn=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-1] 3206 | x_mid=(x_mn+x_here)/2 3207 | y_mid=(y_mn+y_here)/2 3208 | z_mid=(z_mn+z_here)/2 3209 | res_missing=seqnum-seqnum_from_serial_number(mol_id,ch_id,resn-1) 3210 | #formula: sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) 3211 | distance=((x_here-x_mn)**2+(y_here-y_mn)**2+(z_here-z_mn)**2)**0.5 3212 | print("distance",distance) 3213 | distance_per_residue=distance/res_missing 3214 | print("per residue distance",distance_per_residue) 3215 | label_string="{ch_id} {res_start}...{res_end} ({res_missing} missing residues)".format(ch_id=ch_id,res_start=seqnum_from_serial_number(mol_id,ch_id,resn-1),res_end=seqnum,res_missing=res_missing) 3216 | if distance_per_residue>3.8: 3217 | label_string="MIND THE GAP! {ch_id} {res_start}...{res_end} ({res_missing} missing residues for {distance:6.1f} A)".format(ch_id=ch_id,res_start=seqnum_from_serial_number(mol_id,ch_id,resn-1),res_end=seqnum,res_missing=res_missing,distance=distance) 3218 | if res_missing >=50: 3219 | label_string="!!! {ch_id} {res_start}...{res_end} ({res_missing} missing residues)".format(ch_id=ch_id,res_start=seqnum_from_serial_number(mol_id,ch_id,resn-1),res_end=seqnum,res_missing=res_missing) 3220 | list_entry=[label_string,x_mid,y_mid,z_mid] 3221 | missing_segments_list.append(list_entry) 3222 | if res_missing <=15: 3223 | gap_color="gray" 3224 | elif (res_missing > 15) and (res_missing<50): 3225 | gap_color="orange" 3226 | else: 3227 | gap_color="red" 3228 | if distance_per_residue>3.8: 3229 | gap_color="cyan" 3230 | line_width=4 3231 | dash_density=3 3232 | to_generic_object_add_dashed_line(obj_number,gap_color,line_width,dash_density,x_here,y_here,z_here,x_mn,y_mn,z_mn) 3233 | #if res_missing>=20: 3234 | # place_text(str(res_missing),x_mid,y_mid,z_mid,1) 3235 | else: #By definition we always pass through here first (need to hit a term_type_mc befor term_type_mn) 3236 | x_here=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-3] 3237 | y_here=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-2] 3238 | z_here=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-1] 3239 | if (resn==0): 3240 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3241 | sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/CA" 3242 | make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3243 | if (is_last_polymer_residue_sn(mol_id,ch_id,resn)==1): 3244 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3245 | sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/CA" 3246 | make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3247 | if (resname in na_resnames): 3248 | if ((is_term_type_mc_sn(mol_id,ch_id,resn)==1) or (is_term_type_mn_sn(mol_id,ch_id,resn)==1)): 3249 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3250 | # sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/CA" 3251 | # make_ball_and_stick(mol_id,sel_string,0,0.5,1 3252 | if (is_term_type_mn_sn(mol_id,ch_id,resn)==1): 3253 | x_mn=atom_specs(mol_id,ch_id,seqnum,"","P","")[-3] 3254 | y_mn=atom_specs(mol_id,ch_id,seqnum,"","P","")[-2] 3255 | z_mn=atom_specs(mol_id,ch_id,seqnum,"","P","")[-1] 3256 | x_mid=(x_mn+x_here)/2 3257 | y_mid=(y_mn+y_here)/2 3258 | z_mid=(z_mn+z_here)/2 3259 | res_missing=seqnum-seqnum_from_serial_number(mol_id,ch_id,resn-1) 3260 | #formula: sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) 3261 | distance=((x_here-x_mn)**2+(y_here-y_mn)**2+(z_here-z_mn)**2)**0.5 3262 | distance_per_residue=distance/res_missing 3263 | label_string="{ch_id} {res_start}...{res_end} ({res_missing} missing residues)".format(ch_id=ch_id,res_start=seqnum_from_serial_number(mol_id,ch_id,resn-1),res_end=seqnum,res_missing=res_missing) 3264 | if distance_per_residue>5.9: 3265 | label_string="MIND THE GAP! {ch_id} {res_start}...{res_end} ({res_missing} missing residues for {distance:6.1f} A)".format(ch_id=ch_id,res_start=seqnum_from_serial_number(mol_id,ch_id,resn-1),res_end=seqnum,res_missing=res_missing,distance=distance) 3266 | if res_missing >=50: 3267 | label_string="!!! {ch_id} {res_start}...{res_end} ({res_missing} missing residues)".format(ch_id=ch_id,res_start=seqnum_from_serial_number(mol_id,ch_id,resn-1),res_end=seqnum,res_missing=res_missing) 3268 | list_entry=[label_string,x_mid,y_mid,z_mid] 3269 | missing_segments_list.append(list_entry) 3270 | if res_missing <=15: 3271 | gap_color="gray" 3272 | elif (res_missing > 15) and (res_missing<50): 3273 | gap_color="orange" 3274 | else: 3275 | gap_color="red" 3276 | if distance_per_residue>5.9: 3277 | gap_color="cyan" 3278 | line_width=4 3279 | dash_density=3 3280 | to_generic_object_add_dashed_line(obj_number,gap_color,line_width,dash_density,x_here,y_here,z_here,x_mn,y_mn,z_mn) 3281 | #if res_missing>=20: 3282 | # place_text(str(res_missing),x_mid,y_mid,z_mid,1) 3283 | else: #By definition we always pass through here first (need to hit a term_type_mc befor term_type_mn) 3284 | x_here=atom_specs(mol_id,ch_id,seqnum,"","P","")[-3] 3285 | y_here=atom_specs(mol_id,ch_id,seqnum,"","P","")[-2] 3286 | z_here=atom_specs(mol_id,ch_id,seqnum,"","P","")[-1] 3287 | if (resn==0): 3288 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3289 | sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/P" 3290 | make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3291 | if (is_last_polymer_residue_sn(mol_id,ch_id,resn)==1): 3292 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3293 | sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/P" 3294 | make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3295 | set_display_generic_object(obj_number,1) 3296 | try: 3297 | attach_generic_object_to_molecule(obj_number, mol_id) 3298 | except NameError: 3299 | info_dialog("attach_generic_object_to_molecule is only present in Coot r6057 and later, sorry.") 3300 | pass 3301 | turn_on_backup(mol_id) 3302 | interesting_things_gui("Missing segments",missing_segments_list) 3303 | 3304 | 3305 | def highlight_all_chain_breaks(): 3306 | protein_resnames=['ALA','UNK','ARG','ASN','ASP','CYS','GLU','GLN','GLY','HIS','ILE','LEU','LYS','MET','MSE','PHE','PRO','SER','THR','TRP','TYR','VAL'] 3307 | na_resnames=['A','C','T','G','U'] 3308 | for mol_id in model_molecule_list(): 3309 | clear_ball_and_stick(mol_id) 3310 | turn_off_backup(mol_id) 3311 | obj_number=generic_object_with_name("chain_breaks_{mol_id}".format(mol_id=mol_id)) 3312 | generic_object_clear(obj_number) 3313 | for ch_id in chain_ids(mol_id): 3314 | for resn in range(0,chain_n_residues(ch_id,mol_id)): 3315 | resname=resname_from_serial_number(mol_id,ch_id,resn) 3316 | print(resname) 3317 | if (resname in protein_resnames): 3318 | if ((is_term_type_mc_sn(mol_id,ch_id,resn)==1) or (is_term_type_mn_sn(mol_id,ch_id,resn)==1)): 3319 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3320 | # sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/CA" 3321 | # make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3322 | if (is_term_type_mn_sn(mol_id,ch_id,resn)==1): 3323 | x_mn=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-3] 3324 | y_mn=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-2] 3325 | z_mn=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-1] 3326 | x_mid=(x_mn+x_here)/2 3327 | y_mid=(y_mn+y_here)/2 3328 | z_mid=(z_mn+z_here)/2 3329 | res_missing=seqnum-seqnum_from_serial_number(mol_id,ch_id,resn-1) 3330 | #formula: sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) 3331 | distance=((x_here-x_mn)**2+(y_here-y_mn)**2+(z_here-z_mn)**2)**0.5 3332 | distance_per_residue=distance/res_missing 3333 | if res_missing <=15: 3334 | gap_color="gray" 3335 | elif (res_missing > 15) and (res_missing<50): 3336 | gap_color="orange" 3337 | else: 3338 | gap_color="red" 3339 | if distance_per_residue>3.8: 3340 | gap_color="cyan" 3341 | line_width=4 3342 | dash_density=3 3343 | to_generic_object_add_dashed_line(obj_number,gap_color,line_width,dash_density,x_here,y_here,z_here,x_mn,y_mn,z_mn) 3344 | #res_missing=seqnum-seqnum_from_serial_number(mol_id,ch_id,resn-1) 3345 | #if res_missing>=20: 3346 | # place_text(str(res_missing),x_mid,y_mid,z_mid,1) 3347 | else: #By definition we always pass through here first (need to hit a term_type_mc befor term_type_mn) 3348 | x_here=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-3] 3349 | y_here=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-2] 3350 | z_here=atom_specs(mol_id,ch_id,seqnum,"","CA","")[-1] 3351 | if (resn==0): 3352 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3353 | sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/CA" 3354 | make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3355 | if (is_last_polymer_residue_sn(mol_id,ch_id,resn)==1): 3356 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3357 | sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/CA" 3358 | make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3359 | if (resname in na_resnames): 3360 | if ((is_term_type_mc_sn(mol_id,ch_id,resn)==1) or (is_term_type_mn_sn(mol_id,ch_id,resn)==1)): 3361 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3362 | if (is_term_type_mn_sn(mol_id,ch_id,resn)==1): 3363 | x_mn=atom_specs(mol_id,ch_id,seqnum,"","P","")[-3] 3364 | y_mn=atom_specs(mol_id,ch_id,seqnum,"","P","")[-2] 3365 | z_mn=atom_specs(mol_id,ch_id,seqnum,"","P","")[-1] 3366 | x_mid=(x_mn+x_here)/2 3367 | y_mid=(y_mn+y_here)/2 3368 | z_mid=(z_mn+z_here)/2 3369 | res_missing=seqnum-seqnum_from_serial_number(mol_id,ch_id,resn-1) 3370 | #formula: sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) 3371 | distance=((x_here-x_mn)**2+(y_here-y_mn)**2+(z_here-z_mn)**2)**0.5 3372 | distance_per_residue=distance/res_missing 3373 | if res_missing <=15: 3374 | gap_color="gray" 3375 | elif (res_missing > 15) and (res_missing<50): 3376 | gap_color="orange" 3377 | else: 3378 | gap_color="red" 3379 | if distance_per_residue>5.9: 3380 | gap_color="cyan" 3381 | line_width=4 3382 | dash_density=3 3383 | to_generic_object_add_dashed_line(obj_number,gap_color,line_width,dash_density,x_here,y_here,z_here,x_mn,y_mn,z_mn) 3384 | #if res_missing>=20: 3385 | # place_text(str(res_missing),x_mid,y_mid,z_mid,1) 3386 | else: #By definition we always pass through here first (need to hit a term_type_mc befor term_type_mn) 3387 | x_here=atom_specs(mol_id,ch_id,seqnum,"","P","")[-3] 3388 | y_here=atom_specs(mol_id,ch_id,seqnum,"","P","")[-2] 3389 | z_here=atom_specs(mol_id,ch_id,seqnum,"","P","")[-1] 3390 | if (resn==0): 3391 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3392 | sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/P" 3393 | make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3394 | if (is_last_polymer_residue_sn(mol_id,ch_id,resn)==1): 3395 | seqnum=seqnum_from_serial_number(mol_id,ch_id,resn) 3396 | sel_string="//"+str(ch_id)+"/"+str(seqnum)+"/P" 3397 | make_ball_and_stick(mol_id,sel_string,0,0.5,1) 3398 | set_display_generic_object(obj_number,1) 3399 | try: 3400 | attach_generic_object_to_molecule(obj_number, mol_id) 3401 | except NameError: 3402 | info_dialog("attach_generic_object_to_molecule is only present in Coot r6057 and later, sorry.") 3403 | pass 3404 | turn_on_backup(mol_id) 3405 | 3406 | def local_hbonds_and_baddies(): 3407 | mol_id=active_residue()[0] 3408 | probe_local_sphere(mol_id,5) 3409 | undisplay_list=["wide contact","close contact"] 3410 | display_list=["bad overlap","H-bonds","small overlap"] 3411 | for obj_name in undisplay_list: 3412 | obj_number=generic_object_with_name(obj_name) 3413 | generic_object_clear(obj_number) 3414 | for obj_name in display_list: 3415 | obj_number=generic_object_with_name(obj_name) 3416 | set_display_generic_object(obj_number,1) 3417 | try: 3418 | attach_generic_object_to_molecule(obj_number, mol_id) 3419 | except NameError: 3420 | info_dialog("attach_generic_object_to_molecule is only present in Coot r6057 and later, sorry.") 3421 | pass 3422 | 3423 | def global_hbonds_and_baddies(): 3424 | mol_id=active_residue()[0] 3425 | probe(mol_id) 3426 | close_molecule(model_molecule_list()[-1]) 3427 | undisplay_list=["wide contact","close contact","H-bonds","small overlap"] 3428 | display_list=["bad overlap"] 3429 | for obj_name in undisplay_list: 3430 | obj_number=generic_object_with_name(obj_name) 3431 | generic_object_clear(obj_number) 3432 | for obj_name in display_list: 3433 | obj_number=generic_object_with_name(obj_name) 3434 | set_display_generic_object(obj_number,1) 3435 | try: 3436 | attach_generic_object_to_molecule(obj_number, mol_id) 3437 | except NameError: 3438 | info_dialog("attach_generic_object_to_molecule is only present in Coot r6057 and later, sorry.") 3439 | pass 3440 | 3441 | def clear_dots(): 3442 | undisplay_list=["wide contact","close contact", "small overlap","bad overlap","H-bonds","H-bond","big-overlap","close-contact","small-overlap","wide-contact","clashes"] 3443 | for obj_name in undisplay_list: 3444 | obj_number=generic_object_with_name(obj_name) 3445 | generic_object_clear(obj_number) 3446 | 3447 | #Make an alkyl chain of entered length and autofit to map if available 3448 | def make_alkyl_chain(): 3449 | def make_alkyl_chain_length_n(n): 3450 | smiles_string=int(int(n)+1)*"c" 3451 | new_molecule_by_smiles_string("",smiles_string,force_libcheck=True) 3452 | delete_hydrogens(molecule_number_list()[-1]) 3453 | mol_id=molecule_number_list()[-1] 3454 | ch_id="A" 3455 | res_no=1 3456 | ins_code="" 3457 | altloc="" 3458 | new_residue_name="CXC" 3459 | set_residue_name(mol_id,ch_id,res_no,ins_code,new_residue_name) 3460 | delete_atom(mol_id,ch_id,res_no,ins_code," C ",altloc) 3461 | prodrg_ify(mol_id,ch_id,res_no,ins_code) 3462 | close_molecule(molecule_number_list()[-1]) 3463 | close_molecule(molecule_number_list()[-1]) 3464 | if imol_refinement_map()!=-1: 3465 | fit_chain_to_map_by_random_jiggle(mol_id,ch_id,1000,0.1) 3466 | generic_single_entry("How many carbons do you want in the chain?", 3467 | "10","Make alkyl chain",make_alkyl_chain_length_n) 3468 | 3469 | #Place helix and add helix restraints 3470 | def place_helix_with_restraints(): 3471 | size_initial=len(model_molecule_number_list()) 3472 | if place_helix_here(): 3473 | size_after=len(model_molecule_number_list()) 3474 | size_diff=size_after-size_initial 3475 | for i in range(1,size_diff+1): 3476 | mol_id=model_molecule_number_list()[-i] 3477 | set_b_factor_molecule(mol_id,default_new_atoms_b_factor()) 3478 | graphics_to_rainbow_representation(mol_id) 3479 | ch_id="" 3480 | res1=seqnum_from_serial_number(mol_id,ch_id,0) 3481 | res2=last_polymer_residue(mol_id,ch_id) 3482 | for resn in range(res1,res2-2): 3483 | add_extra_bond_restraint(mol_id, 3484 | ch_id, resn , "", " O ", "", 3485 | ch_id, resn + 3, "", " N ", "", 3486 | 3.3, 0.1) 3487 | if (resn + 4 <= res2): 3488 | add_extra_bond_restraint(mol_id, 3489 | ch_id, resn , "", " O ", "", 3490 | ch_id, resn + 4, "", " N ", "", 3491 | 2.9, 0.05) 3492 | 3493 | #Make new helix (don't fit) 3494 | def place_new_helix(): 3495 | def place_new_helix_entry(n): 3496 | get_monomer_no_H("ALA") 3497 | mol_id=model_molecule_list()[-1] 3498 | ch_id=chain_ids(mol_id)[0] 3499 | res_no=1 3500 | ins_code="" 3501 | altloc="" 3502 | delete_atom(mol_id,ch_id,1,ins_code," OXT",altloc) 3503 | res_type="auto" 3504 | for i in range(1,int(n)): 3505 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 3506 | res_type,-57.82,-47) 3507 | res_no=res_no+1 3508 | generic_single_entry("How many residues for helix?", 3509 | "10","Place helix",place_new_helix_entry) 3510 | 3511 | #Make new strand (don't fit) 3512 | def place_new_strand(): 3513 | def place_new_strand_entry(n): 3514 | get_monomer_no_H("ALA") 3515 | mol_id=model_molecule_list()[-1] 3516 | ch_id=chain_ids(mol_id)[0] 3517 | res_no=1 3518 | ins_code="" 3519 | altloc="" 3520 | delete_atom(mol_id,ch_id,1,ins_code," OXT",altloc) 3521 | res_type="auto" 3522 | for i in range(1,int(n)): 3523 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 3524 | res_type,-139,135) 3525 | res_no=res_no+1 3526 | generic_single_entry("How many residues for strand?", 3527 | "10","Place strand",place_new_strand_entry) 3528 | 3529 | #Make new 3-10 helix (don't fit) 3530 | def place_new_3_10_helix(): 3531 | def place_new_3_10_helix_entry(n): 3532 | get_monomer_no_H("ALA") 3533 | mol_id=model_molecule_list()[-1] 3534 | ch_id=chain_ids(mol_id)[0] 3535 | res_no=1 3536 | ins_code="" 3537 | altloc="" 3538 | delete_atom(mol_id,ch_id,1,ins_code," OXT",altloc) 3539 | res_type="auto" 3540 | for i in range(1,int(n)): 3541 | add_terminal_residue_using_phi_psi(mol_id,ch_id,res_no, 3542 | res_type,-49,-26) 3543 | res_no=res_no+1 3544 | generic_single_entry("How many residues for 3-10 helix?", 3545 | "10","Place 3-10 helix",place_new_3_10_helix_entry) 3546 | 3547 | #Merge two chains (throw error msg if they overlap in numbering) 3548 | #This needs fixing - says selections overlap in cases where sel1 has one segment on either side from sel2 3549 | #Fixed now, I think. 3550 | def merge_chains(): 3551 | def merge_chains_by_click(res1,res2): 3552 | mol_id_1=res1[1] 3553 | mol_id_2=res2[1] 3554 | ch_id_1=res1[2] 3555 | ch_id_2=res2[2] 3556 | first_res_sel1=first_residue(mol_id_1,ch_id_1) 3557 | last_res_sel1=last_residue(mol_id_1,ch_id_1) 3558 | first_res_sel2=first_residue(mol_id_2,ch_id_2) 3559 | last_res_sel2=last_residue(mol_id_2,ch_id_2) 3560 | size_2=abs(last_res_sel2-first_res_sel2) 3561 | size_1=abs(last_res_sel1-first_res_sel1) 3562 | if (mol_id_1!=mol_id_2) or (ch_id_1==ch_id_2): 3563 | info_dialog("No can do, chains must be in the same mol and have non-overlapping ranges!") 3564 | elif (mol_id_1==mol_id_2) and (ch_id_1!=ch_id_2) and (size_1<=size_2): 3565 | out=change_chain_id_with_result(mol_id_1,ch_id_1,ch_id_2,1,first_res_sel1,last_res_sel1) 3566 | if out[0]==0: 3567 | info_dialog(out[1]) 3568 | elif (mol_id_1==mol_id_2) and (ch_id_1!=ch_id_2) and (size_2=seg[2]) and (current_num<=seg[3]): 3597 | res_start=seg[2] 3598 | res_end=seg[3] 3599 | ch_id=seg[1] 3600 | if res_endfirst_res: 3603 | seg_prev=new_seg_list[seg_count-2] 3604 | offset=new_num-current_num 3605 | if ((((res_start==first_res) or (res_start+offset)>seg_prev[3])) and (((res_end==last_res) or (res_end+offset)=seg[2]) and (res_here<=seg[3]) and (ch_id==seg[1]): 3644 | res_start=seg[2] 3645 | res_end=seg[3] 3646 | ch_id=seg[1] 3647 | turn_off_backup(mol_id) 3648 | set_refinement_immediate_replacement(1) 3649 | rigid_body_refine_zone(res_start,res_end,ch_id,mol_id) 3650 | accept_regularizement() 3651 | set_refinement_immediate_replacement(0) 3652 | turn_on_backup(mol_id) 3653 | 3654 | #Set default b-fac for new atoms to mean B for active mol 3655 | def set_new_atom_b_fac_to_mean(): 3656 | mol_id=active_residue()[0] 3657 | mean_b=average_temperature_factor(mol_id) 3658 | set_default_temperature_factor_for_new_atoms(mean_b) 3659 | 3660 | 3661 | #Shortcut for adding terminal residue (to bind to key) 3662 | def add_term_shortcut(): 3663 | if imol_refinement_map()!=-1: 3664 | mol_id=active_residue()[0] 3665 | ch_id=active_residue()[1] 3666 | resn=active_residue()[2] 3667 | atom_name=active_residue()[4] 3668 | first_in_seg=first_residue_in_seg(mol_id,ch_id,resn) 3669 | last_in_seg=last_residue_in_seg(mol_id,ch_id,resn) 3670 | delta_first=abs(first_in_seg-resn) 3671 | delta_last=abs(last_in_seg-resn) 3672 | set_new_atom_b_fac_to_mean() 3673 | if delta_first<=delta_last: 3674 | set_go_to_atom_molecule(mol_id) 3675 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 3676 | add_terminal_residue(mol_id,ch_id,first_in_seg,"auto",1) 3677 | sort_residues(mol_id) 3678 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg-1,atom_name) 3679 | else: 3680 | set_go_to_atom_molecule(mol_id) 3681 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 3682 | add_terminal_residue(mol_id,ch_id,last_in_seg,"auto",1) 3683 | sort_residues(mol_id) 3684 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg+1,atom_name) 3685 | else: 3686 | info_dialog("You must set a refinement map!") 3687 | 3688 | def add_term_shortcut_force(): 3689 | mol_id=active_residue()[0] 3690 | ch_id=active_residue()[1] 3691 | resn=active_residue()[2] 3692 | atom_name=active_residue()[4] 3693 | set_go_to_atom_molecule(mol_id) 3694 | first_in_seg=first_residue_in_seg(mol_id,ch_id,resn) 3695 | last_in_seg=last_residue_in_seg(mol_id,ch_id,resn) 3696 | delta_first=abs(first_in_seg-resn) 3697 | delta_last=abs(last_in_seg-resn) 3698 | set_new_atom_b_fac_to_mean() 3699 | if delta_first<=delta_last: 3700 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 3701 | force_add_terminal_residue_noclick(mol_id,ch_id,first_in_seg) 3702 | sort_residues(mol_id) 3703 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg-1,atom_name) 3704 | else: 3705 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 3706 | force_add_terminal_residue_noclick(mol_id,ch_id,last_in_seg) 3707 | sort_residues(mol_id) 3708 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg+1,atom_name) 3709 | 3710 | def add_term_shortcut_force_strand(): 3711 | mol_id=active_residue()[0] 3712 | ch_id=active_residue()[1] 3713 | resn=active_residue()[2] 3714 | atom_name=active_residue()[4] 3715 | set_go_to_atom_molecule(mol_id) 3716 | first_in_seg=first_residue_in_seg(mol_id,ch_id,resn) 3717 | last_in_seg=last_residue_in_seg(mol_id,ch_id,resn) 3718 | delta_first=abs(first_in_seg-resn) 3719 | delta_last=abs(last_in_seg-resn) 3720 | set_new_atom_b_fac_to_mean() 3721 | if delta_first<=delta_last: 3722 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg,atom_name) 3723 | force_add_terminal_residue_noclick_strand(mol_id,ch_id,first_in_seg) 3724 | sort_residues(mol_id) 3725 | set_go_to_atom_chain_residue_atom_name(ch_id,first_in_seg-1,atom_name) 3726 | else: 3727 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg,atom_name) 3728 | force_add_terminal_residue_noclick_strand(mol_id,ch_id,last_in_seg) 3729 | sort_residues(mol_id) 3730 | set_go_to_atom_chain_residue_atom_name(ch_id,last_in_seg+1,atom_name) 3731 | 3732 | #Add h-bond restraints to active mol with Prosmart 3733 | def run_prosmart_self(): 3734 | """ 3735 | target is my molecule, ref is the homologous (high-res) model 3736 | 3737 | extra arg: include_side_chains=False 3738 | """ 3739 | imol_target=active_residue()[0] 3740 | dir_stub = "coot-ccp4" 3741 | prosmart_dir="ProSMART_Output" 3742 | make_directory_maybe(dir_stub) 3743 | make_directory_maybe(prosmart_dir) 3744 | target_pdb_file_name = os.path.join(dir_stub, 3745 | molecule_name_stub(imol_target, 0).replace(" ", "_") + \ 3746 | "-prosmart.pdb") 3747 | prosmart_out = os.path.join("ProSMART_Output", 3748 | molecule_name_stub(imol_target, 0).replace(" ", "_") + \ 3749 | "-prosmart.txt") 3750 | 3751 | write_pdb_file(imol_target, target_pdb_file_name) 3752 | prosmart_exe = find_exe("prosmart") 3753 | if prosmart_exe: 3754 | l = ["-p1", target_pdb_file_name, 3755 | "-h","-self_restrain","-bond_max","4.0","-bond_override", "2","-o",prosmart_dir] 3756 | popen_command(prosmart_exe, 3757 | l, 3758 | [], 3759 | os.path.join(dir_stub, "prosmart.log"), 3760 | False) 3761 | if (not os.path.isfile(prosmart_out)): 3762 | print "file not found", prosmart_out 3763 | else: 3764 | print "Reading ProSMART restraints from", prosmart_out 3765 | add_refmac_extra_restraints(imol_target, prosmart_out) 3766 | delete_extra_restraints_worse_than(imol_target,4) 3767 | 3768 | #Fix all atoms in active residue 3769 | def fix_active_residue(): 3770 | ar=active_residue() #ar[0] is mol_id, 1 is ch_id, 2 is resnum, 3 is ins code, 4 is atom name (CA) and 5 is alt conf 3771 | residue_info_list=residue_info(ar[0],ar[1],ar[2],ar[3]) 3772 | atom_list=[] 3773 | for item in residue_info_list: # residue item is list of list of lists. first item in first list of each list in the list is the atom name :-) 3774 | atom_name=item[0][0] 3775 | atom_info=[ar[1],ar[2],ar[3],atom_name,ar[5]] #Make a list of chain id, res number, ins code, atom name and alt conf. Not sure if alt conf and ins code are right way around here... 3776 | atom_list.append(atom_info) 3777 | mark_multiple_atoms_as_fixed(ar[0],atom_list,1) 3778 | 3779 | #Save and overwrite active model: 3780 | def quicksave_active(): 3781 | import shutil 3782 | mol_id=active_residue()[0] 3783 | filename=molecule_name(mol_id) 3784 | filename_bak=filename+".bak" 3785 | shutil.copy(filename,filename_bak) 3786 | save_coordinates(mol_id,filename) 3787 | info_dialog("Saved {filename} (molecule {mol_id}). \n If this was an accident, you can find a backup of the original file here: \n {filename_bak}".format(filename=filename,mol_id=mol_id,filename_bak=filename_bak)) 3788 | 3789 | #Refresh model from file (if changed externally for example) 3790 | def reload_model(): 3791 | mol_id=active_residue()[0] 3792 | filename=molecule_name(mol_id) 3793 | clear_and_update_model_molecule_from_file(mol_id,filename) 3794 | 3795 | #Copy changes from active chain to NCS equivalents. 3796 | def copy_ncs_chain_from_active(): 3797 | mol_id=active_residue()[0] 3798 | ch_id=active_residue()[1] 3799 | turn_off_backup(mol_id) 3800 | ncs_control_change_ncs_master_to_chain_id(mol_id,ch_id) 3801 | copy_from_ncs_master_to_others(mol_id,ch_id) 3802 | turn_on_backup(mol_id) 3803 | 3804 | def return_seq_as_string(mol_id,ch_id): 3805 | seq='' 3806 | for sn in range(0,chain_n_residues(ch_id,mol_id)): 3807 | resno=seqnum_from_serial_number(mol_id,ch_id,sn) 3808 | ins_code=insertion_code_from_serial_number(mol_id,ch_id,sn) 3809 | residue_name_3_letter=residue_name(mol_id,ch_id,resno,ins_code) 3810 | aa_code=three_letter_code2single_letter(residue_name_3_letter) 3811 | if (len(residue_name(mol_id,ch_id,resno,ins_code))==1): 3812 | aa_code=residue_name_3_letter 3813 | if (residue_name(mol_id,ch_id,resno,ins_code)!="ALA") and (aa_code=="A") and (len(residue_name(mol_id,ch_id,resno,ins_code))!=1): 3814 | aa_code="X" 3815 | seq=seq+aa_code 3816 | return seq 3817 | 3818 | stereo_gif_counter=1 3819 | def make_rot_gif(): 3820 | if find_exe("convert"): 3821 | global stereo_gif_counter 3822 | import subprocess 3823 | pwd=os.getcwd() 3824 | set_rotation_center_size(0) 3825 | set_draw_axes(0) 3826 | rotate_y_scene(1,-2) 3827 | screendump_image("{pwd}/pair1_tmp.ppm".format(pwd=pwd)) 3828 | rotate_y_scene(1,1) 3829 | screendump_image("{pwd}/pair2_tmp.ppm".format(pwd=pwd)) 3830 | rotate_y_scene(1,1) 3831 | screendump_image("{pwd}/pair3_tmp.ppm".format(pwd=pwd)) 3832 | rotate_y_scene(1,1) 3833 | screendump_image("{pwd}/pair4_tmp.ppm".format(pwd=pwd)) 3834 | rotate_y_scene(1,1) 3835 | screendump_image("{pwd}/pair5_tmp.ppm".format(pwd=pwd)) 3836 | rotate_y_scene(1,-2) 3837 | p=subprocess.Popen("convert -scale 500 -normalize -fuzz 5% -delay 8 -loop 0 -layers Optimize {pwd}/pair1_tmp.ppm {pwd}/pair2_tmp.ppm {pwd}/pair3_tmp.ppm {pwd}/pair4_tmp.ppm {pwd}/pair5_tmp.ppm {pwd}/pair4_tmp.ppm {pwd}/pair3_tmp.ppm {pwd}/pair2_tmp.ppm {pwd}/stereo_density_{stereo_gif_counter}.gif".format(pwd=pwd,stereo_gif_counter=stereo_gif_counter),shell=True) 3838 | p.communicate() 3839 | stereo_gif_counter=stereo_gif_counter+1 3840 | os.remove("{pwd}/pair1_tmp.ppm".format(pwd=pwd)) 3841 | os.remove("{pwd}/pair2_tmp.ppm".format(pwd=pwd)) 3842 | os.remove("{pwd}/pair3_tmp.ppm".format(pwd=pwd)) 3843 | os.remove("{pwd}/pair4_tmp.ppm".format(pwd=pwd)) 3844 | os.remove("{pwd}/pair5_tmp.ppm".format(pwd=pwd)) 3845 | set_rotation_center_size(0.1) 3846 | set_draw_axes(1) 3847 | else: 3848 | info_dialog("You need Imagemagick to use this!") 3849 | 3850 | 3851 | def find_sequence_in_current_chain(subseq): 3852 | subseq=subseq.upper() 3853 | mol_id=active_residue()[0] 3854 | ch_id=active_residue()[1] 3855 | seq=return_seq_as_string(mol_id,ch_id) 3856 | index=0 3857 | sn_list=[] 3858 | interesting_list=[] 3859 | while index < len(seq): 3860 | try: 3861 | index=seq.index(subseq,index) 3862 | except ValueError: 3863 | break 3864 | sn_list.append(index) 3865 | if index==-1: 3866 | break 3867 | index=index+len(subseq) 3868 | if len(sn_list)==1: 3869 | sn_start=sn_list[0] 3870 | resno=seqnum_from_serial_number(mol_id,ch_id,sn_start) 3871 | ins_code=insertion_code_from_serial_number(mol_id,ch_id,sn_start) 3872 | alt_conf=residue_alt_confs(mol_id,ch_id,resno,ins_code)[0] 3873 | print("sn_start",sn_start) 3874 | try: 3875 | x=atom_specs(mol_id,ch_id,resno,ins_code,"CA",alt_conf)[-3] 3876 | y=atom_specs(mol_id,ch_id,resno,ins_code,"CA",alt_conf)[-2] 3877 | z=atom_specs(mol_id,ch_id,resno,ins_code,"CA",alt_conf)[-1] 3878 | except TypeError: 3879 | x=atom_specs(mol_id,ch_id,resno,ins_code,"P",alt_conf)[-3] 3880 | y=atom_specs(mol_id,ch_id,resno,ins_code,"P",alt_conf)[-2] 3881 | z=atom_specs(mol_id,ch_id,resno,ins_code,"P",alt_conf)[-1] 3882 | set_rotation_centre(x,y,z) 3883 | elif len(sn_list)==0: 3884 | info_dialog("Sequence not found!") 3885 | elif len(sn_list)>1: 3886 | count=0 3887 | for sn in sn_list: 3888 | count=count+1 3889 | resno=seqnum_from_serial_number(mol_id,ch_id,sn) 3890 | ins_code=insertion_code_from_serial_number(mol_id,ch_id,sn) 3891 | alt_conf=residue_alt_confs(mol_id,ch_id,resno,ins_code)[0] 3892 | print("sn_start",sn) 3893 | try: 3894 | x=atom_specs(mol_id,ch_id,resno,ins_code,"CA",alt_conf)[-3] 3895 | y=atom_specs(mol_id,ch_id,resno,ins_code,"CA",alt_conf)[-2] 3896 | z=atom_specs(mol_id,ch_id,resno,ins_code,"CA",alt_conf)[-1] 3897 | except TypeError: 3898 | x=atom_specs(mol_id,ch_id,resno,ins_code,"P",alt_conf)[-3] 3899 | y=atom_specs(mol_id,ch_id,resno,ins_code,"P",alt_conf)[-2] 3900 | z=atom_specs(mol_id,ch_id,resno,ins_code,"P",alt_conf)[-1] 3901 | list_entry=[str(resno),x,y,z] 3902 | interesting_list.append(list_entry) 3903 | print("interesting list",interesting_list) 3904 | print("interesting list",interesting_list) 3905 | interesting_things_gui("Matches to entered sequence",interesting_list) 3906 | 3907 | def find_sequence_with_entry(): 3908 | generic_single_entry("Enter sequence fragment to find", 3909 | "MAAAA","Find sequence in active chain",find_sequence_in_current_chain) 3910 | 3911 | 3912 | def user_defined_add_arbitrary_length_bond_restraint(bond_length=2.0): 3913 | def make_restr(text_list, continue_qm): 3914 | s = "Now click on 2 atoms to define the additional bond restraint" 3915 | add_status_bar_text(s) 3916 | dist = text_list[0] 3917 | try: 3918 | bl = float(dist) 3919 | except: 3920 | bl = False 3921 | add_status_bar_text("Must define a number for the bond length") 3922 | if bl: 3923 | def make_restr_dist(*args): 3924 | atom_spec_1 = args[0] 3925 | atom_spec_2 = args[1] 3926 | imol = atom_spec_1[1] 3927 | print "BL DEBUG:: imol: %s spec 1: %s and 2: %s" %(imol, atom_spec_1, atom_spec_2) 3928 | add_extra_bond_restraint(imol, atom_spec_1[2], atom_spec_1[3], atom_spec_1[4], atom_spec_1[5], atom_spec_1[6], atom_spec_2[2], atom_spec_2[3], atom_spec_2[4], atom_spec_2[5], atom_spec_2[6], bl, 0.035) 3929 | user_defined_click(2, make_restr_dist) 3930 | if continue_qm: 3931 | user_defined_add_arbitrary_length_bond_restraint(bl) 3932 | def stay_open(*args): 3933 | pass 3934 | #generic_single_entry("Add a User-defined extra distance restraint", 3935 | # "2.0", 3936 | # "OK...", 3937 | # lambda text: make_restr(text)) 3938 | generic_multiple_entries_with_check_button( 3939 | [["Add a User-defined extra distance restraint", 3940 | str(bond_length)]], 3941 | ["Stay open?", lambda active_state: stay_open(active_state)], 3942 | "OK...", 3943 | lambda text, stay_open_qm: make_restr(text, stay_open_qm)) 3944 | 3945 | 3946 | 3947 | 3948 | 3949 | 3950 | 3951 | #Test post manipulation background func 3952 | # import time, threading 3953 | # def background_func(): 3954 | # threading.Timer(0.01, post_manip_background).start() 3955 | # if condition: 3956 | # do something 3957 | # post_manip_background() 3958 | 3959 | # def post_manipulation_script(imol, mode): 3960 | # print "BL DEBUG:: imol and mode", imol, mode 3961 | # if (mode == DELETED): 3962 | # print "BL DEBUG:: deleted something in mol ", imol 3963 | # return 1 3964 | # 3965 | # def post_manipulation_script2(imol, mode): 3966 | # print "BL DEBUG:: imol and mode", imol, mode 3967 | # if (mode == MUTATED): 3968 | # print "BL DEBUG:: moved something in mol ", imol 3969 | # return 1 3970 | 3971 | #****Make and arrange menus**** 3972 | 3973 | menu=coot_menubar_menu("Custom") 3974 | 3975 | #make submenus 3976 | 3977 | submenu_display=gtk.Menu() 3978 | menuitem_2=gtk.MenuItem("Display...") 3979 | menuitem_2.set_submenu(submenu_display) 3980 | menu.append(menuitem_2) 3981 | menuitem_2.show() 3982 | 3983 | 3984 | submenu_fit=gtk.Menu() 3985 | menuitem_3=gtk.MenuItem("Fit...") 3986 | menuitem_3.set_submenu(submenu_fit) 3987 | menu.append(menuitem_3) 3988 | menuitem_3.show() 3989 | 3990 | 3991 | submenu_renumber=gtk.Menu() 3992 | menuitem_4=gtk.MenuItem("Renumber...") 3993 | menuitem_4.set_submenu(submenu_renumber) 3994 | menu.append(menuitem_4) 3995 | menuitem_4.show() 3996 | 3997 | submenu_settings=gtk.Menu() 3998 | menuitem_5=gtk.MenuItem("Settings...") 3999 | menuitem_5.set_submenu(submenu_settings) 4000 | menu.append(menuitem_5) 4001 | menuitem_5.show() 4002 | 4003 | submenu_build=gtk.Menu() 4004 | menuitem_6=gtk.MenuItem("Build...") 4005 | menuitem_6.set_submenu(submenu_build) 4006 | menu.append(menuitem_6) 4007 | menuitem_6.show() 4008 | 4009 | submenu_mutate=gtk.Menu() 4010 | menuitem_7=gtk.MenuItem("Mutate...") 4011 | menuitem_7.set_submenu(submenu_mutate) 4012 | menu.append(menuitem_7) 4013 | menuitem_7.show() 4014 | 4015 | submenu_copy=gtk.Menu() 4016 | menuitem_8=gtk.MenuItem("Copy...") 4017 | menuitem_8.set_submenu(submenu_copy) 4018 | menu.append(menuitem_8) 4019 | menuitem_8.show() 4020 | 4021 | submenu_delete=gtk.Menu() 4022 | menuitem_9=gtk.MenuItem("Delete...") 4023 | menuitem_9.set_submenu(submenu_delete) 4024 | menu.append(menuitem_9) 4025 | menuitem_9.show() 4026 | 4027 | submenu_merge=gtk.Menu() 4028 | menuitem_10=gtk.MenuItem("Merge...") 4029 | menuitem_10.set_submenu(submenu_merge) 4030 | menu.append(menuitem_10) 4031 | menuitem_10.show() 4032 | 4033 | submenu_maps=gtk.Menu() 4034 | menuitem_11=gtk.MenuItem("Maps...") 4035 | menuitem_11.set_submenu(submenu_maps) 4036 | menu.append(menuitem_11) 4037 | menuitem_11.show() 4038 | 4039 | #**** Populate submenus **** 4040 | #"Display..." 4041 | 4042 | add_simple_coot_menu_menuitem(submenu_display, "All Molecules use \"C-alpha\" Symmetry", lambda func: map(lambda imol: valid_model_molecule_qm(imol) and symmetry_as_calphas(imol, 1), molecule_number_list())) 4043 | 4044 | add_simple_coot_menu_menuitem(submenu_display, "Toggle Symmetry", 4045 | lambda func: set_show_symmetry_master(not get_show_symmetry())) 4046 | 4047 | add_simple_coot_menu_menuitem(submenu_display, "Clear labels and distances", 4048 | lambda func: clear_distances_and_labels()) 4049 | 4050 | add_simple_coot_menu_menuitem(submenu_display, 4051 | "Switch all mols to CA representation",lambda func: all_mols_to_ca()) 4052 | 4053 | add_simple_coot_menu_menuitem(submenu_display, 4054 | "Color active mol by rotamer prob (outliers magenta) and missing atoms (blue)", lambda func: color_rotamer_outliers_and_missing_atoms(active_residue()[0])) 4055 | 4056 | add_simple_coot_menu_menuitem(submenu_display, 4057 | "Color active mol by hydrophobics (orange), polars (blue), glys (magenta) and pros (green)", lambda func: color_polars_and_hphobs(active_residue()[0])) 4058 | 4059 | add_simple_coot_menu_menuitem(submenu_display, 4060 | "Color active mol by charge (+ve blue, -ve red)", lambda func: color_by_charge(active_residue()[0])) 4061 | 4062 | add_simple_coot_menu_menuitem(submenu_display, 4063 | "Uncolor other chains in active mol", lambda func: uncolor_other_chains()) 4064 | 4065 | add_simple_coot_menu_menuitem(submenu_display, 4066 | "Color active chain", lambda func: color_active_chain()) 4067 | 4068 | add_simple_coot_menu_menuitem(submenu_display, 4069 | "Color active segment", lambda func: colour_active_segment()) 4070 | 4071 | add_simple_coot_menu_menuitem(submenu_display, 4072 | "Color by protein/nucleic acid", lambda func: color_protein_na(active_residue()[0])) 4073 | 4074 | 4075 | add_simple_coot_menu_menuitem(submenu_display, 4076 | "Color waters", lambda func: color_waters(active_residue()[0])) 4077 | 4078 | add_simple_coot_menu_menuitem(submenu_display, "Colour entered subset of protein residues for active mol", lambda func: color_protein_residue_subset()) 4079 | 4080 | add_simple_coot_menu_menuitem(submenu_display, 4081 | "Color active mol by CaBLAM outliers (blue) (needs phenix)", lambda func: color_by_cablam2(active_residue()[0])) 4082 | 4083 | add_simple_coot_menu_menuitem(submenu_display, 4084 | "Color active mol by EMringer outliers (red) (needs phenix)", lambda func: color_emringer_outliers(active_residue()[0],scroll_wheel_map())) 4085 | 4086 | add_simple_coot_menu_menuitem(submenu_display, 4087 | "Color active mol by ramachandran outliers (blue) (needs phenix)", lambda func: color_by_rama(active_residue()[0])) 4088 | 4089 | add_simple_coot_menu_menuitem(submenu_display, 4090 | "Color active mol by map/model-CC at 4 A (Slow, needs phenix, P1 only)", lambda func: color_by_cc(active_residue()[0])) 4091 | 4092 | add_simple_coot_menu_menuitem(submenu_display, "Highlight chain breaks in active mol", lambda func: highlight_chain_breaks()) 4093 | 4094 | add_simple_coot_menu_menuitem(submenu_display, "Highlight chain breaks in all mols", lambda func: highlight_all_chain_breaks()) 4095 | 4096 | add_simple_coot_menu_menuitem(submenu_display, "Open current view in UCSF Chimera. Experimental!", lambda func: open_in_chimera()) 4097 | 4098 | add_simple_coot_menu_menuitem(submenu_display, "Show local probe dots (H-bonds, VdW and baddies only)", lambda func: local_hbonds_and_baddies()) 4099 | 4100 | add_simple_coot_menu_menuitem(submenu_display, "Show global probe dots (bad overlaps only)", lambda func: global_hbonds_and_baddies()) 4101 | 4102 | add_simple_coot_menu_menuitem(submenu_display, "Clear probe dots", lambda func: clear_dots()) 4103 | 4104 | add_simple_coot_menu_menuitem(submenu_display, "Find sequence in active chain", lambda func: find_sequence_with_entry()) 4105 | 4106 | add_simple_coot_menu_menuitem(submenu_display, "Make stereo-wiggle GIF of current scenre (Needs ImageMagick!)", lambda func: make_rot_gif()) 4107 | 4108 | 4109 | 4110 | #"Fit..." 4111 | add_simple_coot_menu_menuitem(submenu_fit, "Fit all chains to map", 4112 | lambda func: rigid_fit_all_chains()) 4113 | 4114 | add_simple_coot_menu_menuitem(submenu_fit, "Stepped sphere refine active chain", 4115 | lambda func: stepped_sphere_refine(active_residue()[0],active_residue()[1])) 4116 | 4117 | add_simple_coot_menu_menuitem(submenu_fit, "Fit current chain to map", 4118 | lambda func: rigid_fit_active_chain()) 4119 | 4120 | add_simple_coot_menu_menuitem(submenu_fit, 4121 | "Jiggle-fit current chain to map (Slow!)", lambda func: jiggle_fit_active_chain()) 4122 | 4123 | add_simple_coot_menu_menuitem(submenu_fit, 4124 | "Jiggle-fit current chain to B-smoothed map (Slow!)", lambda func: jiggle_fit_active_chain_smooth()) 4125 | 4126 | add_simple_coot_menu_menuitem(submenu_fit, "Jiggle-fit all chains to map (very slow!)", 4127 | lambda func: jiggle_fit_all_chains()) 4128 | 4129 | add_simple_coot_menu_menuitem(submenu_fit, 4130 | "Jiggle-fit current mol to map (Slow!)", lambda func: jiggle_fit_active_mol()) 4131 | 4132 | add_simple_coot_menu_menuitem(submenu_fit, 4133 | "Fit polyala loop (click start and end)", lambda func: fit_polyala_gui()) 4134 | 4135 | add_simple_coot_menu_menuitem(submenu_fit, "Fit all segments", lambda func: rigid_body_fit_segments()) 4136 | 4137 | add_simple_coot_menu_menuitem(submenu_fit, "Fit this segment", lambda func: fit_this_segment()) 4138 | 4139 | add_simple_coot_menu_menuitem(submenu_fit, 4140 | "Prosmart self restrain active mol",lambda func: run_prosmart_self()) 4141 | 4142 | add_simple_coot_menu_menuitem(submenu_fit, 4143 | "Cylinder refine (click start and end of range)",lambda func: refine_residues_sphere_click()) 4144 | 4145 | add_simple_coot_menu_menuitem(submenu_fit, "Add distance restraint (click two atoms)",lambda func: user_defined_add_arbitrary_length_bond_restraint(bond_length=2.0)) 4146 | 4147 | #"Renumber..." 4148 | 4149 | add_simple_coot_menu_menuitem(submenu_renumber, "Renumber active chain by first res", 4150 | lambda func: renumber_by_first_res()) 4151 | 4152 | add_simple_coot_menu_menuitem(submenu_renumber, 4153 | "Renumber active chain by last res", lambda func: renumber_by_last_res()) 4154 | 4155 | add_simple_coot_menu_menuitem(submenu_renumber, 4156 | "Renumber active chain by current res", lambda func: renumber_by_active_res()) 4157 | 4158 | add_simple_coot_menu_menuitem(submenu_renumber,"Renumber from N-term to active residue", 4159 | lambda func: renumber_n_term_segment()) 4160 | 4161 | add_simple_coot_menu_menuitem(submenu_renumber,"Renumber from active residue to C-term", 4162 | lambda func: renumber_c_term_segment()) 4163 | 4164 | add_simple_coot_menu_menuitem(submenu_renumber, "Renumber segment by active res", lambda func: renumber_seg_by_active_res()) 4165 | 4166 | 4167 | #"Settings..." 4168 | 4169 | add_simple_coot_menu_menuitem(submenu_settings, 4170 | "Auto-scale B-factor coloring for active mol",lambda func: autoscale_b_factor()) 4171 | 4172 | add_simple_coot_menu_menuitem(submenu_settings, 4173 | "Set Bfac for new atoms to mean B for active mol",lambda func: set_new_atom_b_fac_to_mean()) 4174 | 4175 | 4176 | #"Build..." 4177 | add_simple_coot_menu_menuitem(submenu_build, 4178 | "Forced addition of terminal residue (click terminus)", 4179 | lambda func: force_add_terminal_residue()) 4180 | 4181 | add_simple_coot_menu_menuitem(submenu_build, 4182 | "Grow helix (click terminus)", 4183 | lambda func: grow_helix()) 4184 | 4185 | add_simple_coot_menu_menuitem(submenu_build, 4186 | "Grow strand (click terminus)", 4187 | lambda func: grow_strand()) 4188 | 4189 | add_simple_coot_menu_menuitem(submenu_build, 4190 | "Grow parallel strand (click terminus)", 4191 | lambda func: grow_parallel_strand()) 4192 | 4193 | add_simple_coot_menu_menuitem(submenu_build, 4194 | "Grow 3-10 helix (click terminus)", 4195 | lambda func: grow_helix_3_10()) 4196 | 4197 | add_simple_coot_menu_menuitem(submenu_build, 4198 | "Shorten loop by one residue", lambda func: shorten_loop()) 4199 | 4200 | add_simple_coot_menu_menuitem(submenu_build, 4201 | "Lengthen loop by one residue", lambda func: lengthen_loop()) 4202 | 4203 | add_simple_coot_menu_menuitem(submenu_build, 4204 | "Get fractional coordinates of active atom",lambda func: get_fract_coords()) 4205 | 4206 | add_simple_coot_menu_menuitem(submenu_build, 4207 | "Common monomers",lambda func: pick_common_monomers()) 4208 | 4209 | add_simple_coot_menu_menuitem(submenu_build, "Make alkyl chain of length n", lambda func: make_alkyl_chain()) 4210 | 4211 | add_simple_coot_menu_menuitem(submenu_build, "Make alpha helix of length n", lambda func: place_new_helix()) 4212 | 4213 | add_simple_coot_menu_menuitem(submenu_build, "Make 3-10 helix of length n", lambda func: place_new_3_10_helix()) 4214 | 4215 | add_simple_coot_menu_menuitem(submenu_build, "Rebuild backbone (click start,end)", lambda func: rebuild_backbone_wrapper()) 4216 | 4217 | add_simple_coot_menu_menuitem(submenu_build, "Rebuild and reverse backbone of segment (click segment)", lambda func: rebuild_backbone_reverse_wrapper()) 4218 | 4219 | 4220 | 4221 | 4222 | 4223 | #"Mutate... 4224 | 4225 | add_simple_coot_menu_menuitem(submenu_mutate, 4226 | "Mutate range to UNK (click start and end)", lambda func: mutate_residue_range_by_click_a()) 4227 | 4228 | add_simple_coot_menu_menuitem(submenu_mutate, 4229 | "Mutate range to ALA (click start and end)", lambda func: mutate_residue_range_by_click_ala_a()) 4230 | 4231 | add_simple_coot_menu_menuitem(submenu_mutate, "Mutate all Mets to MSE", lambda func: mutate_all_mets_to_mse()) 4232 | 4233 | add_simple_coot_menu_menuitem(submenu_mutate, "Mutate all MSEs to Met", lambda func: mutate_all_mse_to_met()) 4234 | 4235 | add_simple_coot_menu_menuitem(submenu_mutate, 4236 | "Mutate active chain to template sequence (numbering must match sequence!)", lambda func: mutate_by_resnum()) 4237 | 4238 | #"Copy..." 4239 | add_simple_coot_menu_menuitem(submenu_copy, "Copy current chain", 4240 | lambda func: copy_active_chain()) 4241 | 4242 | add_simple_coot_menu_menuitem(submenu_copy, "Cut current chain", 4243 | lambda func: cut_active_chain()) 4244 | 4245 | add_simple_coot_menu_menuitem(submenu_copy, "Copy active segment", lambda func: copy_active_segment()) 4246 | 4247 | add_simple_coot_menu_menuitem(submenu_copy, "Cut active segment", lambda func: cut_active_segment()) 4248 | 4249 | add_simple_coot_menu_menuitem(submenu_copy, 4250 | "Copy fragment (click start and end)", lambda func: copy_frag_by_click()) 4251 | 4252 | add_simple_coot_menu_menuitem(submenu_copy, 4253 | "Cut fragment (click start and end)", lambda func: cut_frag_by_click()) 4254 | 4255 | add_simple_coot_menu_menuitem(submenu_copy, 4256 | "Copy active chain to NCS equivs", lambda func: copy_ncs_chain_from_active()) 4257 | 4258 | 4259 | #"Delete..." 4260 | add_simple_coot_menu_menuitem(submenu_delete, 4261 | "Delete active chain", lambda func: delete_chain()) 4262 | 4263 | add_simple_coot_menu_menuitem(submenu_delete, "Delete active segment", lambda func: delete_active_segment()) 4264 | 4265 | 4266 | add_simple_coot_menu_menuitem(submenu_delete, 4267 | "Delete hydrogens from molecule", lambda func: delete_h_active()) 4268 | 4269 | add_simple_coot_menu_menuitem(submenu_delete, 4270 | "Delete sidechains in range (click start and end)", lambda func: delete_sidechain_range_by_click_a()) 4271 | 4272 | #"Merge..." 4273 | 4274 | add_simple_coot_menu_menuitem(submenu_merge, 4275 | "Merge two mols (click two; 2nd into 1st)", lambda func: merge_fragments()) 4276 | 4277 | add_simple_coot_menu_menuitem(submenu_merge, "Merge chains (click two; 2nd into 1st)", lambda func: merge_chains()) 4278 | 4279 | 4280 | #"Maps..." 4281 | add_simple_coot_menu_menuitem(submenu_maps, 4282 | "Sharpen (enter B-factor)",lambda func: sharpen_by_entered_factor()) 4283 | 4284 | add_simple_coot_menu_menuitem(submenu_maps, 4285 | "Change hi-res limit for map",lambda func: change_hires_limit_copy()) 4286 | 4287 | add_simple_coot_menu_menuitem(submenu_maps, 4288 | "Go to center of scrollable map",lambda func: goto_center_of_map()) 4289 | 4290 | add_simple_coot_menu_menuitem(submenu_maps, 4291 | "Set refinement map to scrollable map",lambda func: set_map_to_scrollable_map()) 4292 | --------------------------------------------------------------------------------