migrate dotfiles to chezmoi

This commit is contained in:
Daniel Bauer
2025-07-06 16:21:42 +02:00
parent 20a061820e
commit 25e0d0460b
76 changed files with 77 additions and 9533 deletions

1
.chezmoiignore Normal file
View File

@@ -0,0 +1 @@
README.md

1
.gitignore vendored
View File

@@ -1 +0,0 @@
./pymolrc/*pyc

View File

@@ -1,8 +1,9 @@
# dotfiles for linux/wsl
# My dotfiles
clone to `.dotfiles`.
Set up on new machin:
Start by installing the base configuration via `./install.sh`.
Then choose relevant configuration bundles with `./dotfiles.sh bundname`
(i.e. `./dotfiles.sh gui`)
```bash
sh -c "$(curl -fsLS get.chezmoi.io)"
chezmoi init --apply dnlbauer
```

View File

@@ -1,59 +0,0 @@
#!/bin/bash
# adapted from: https://github.com/jez/dotfiles/blob/master/util/auto-update.sh
# Number of seconds to wait before printing a reminder
UPDATE_THRESHOLD="604800" # 1 week
check_for_updates() {
[ ! -e $HOME/.dotfiles_update ] && touch $HOME/.dotfiles_update
# Initialize for when we have no GNU date available
last_check=0
time_now=0
# Darwin uses BSD, check for gdate, else use date
if [[ $(uname) = "Darwin" && -n $(which gdate) ]]; then
last_login=$(gdate -r ~/.dotfiles_update +%s)
time_now=$(gdate +%s)
else
# Ensure this is GNU grep
if [ -n "$(date --version 2> /dev/null | grep GNU)" ]; then
last_login=$(date -r ~/.dotfiles_update +%s)
time_now=$(date +%s)
fi
fi
time_since_check=$((time_now - last_login))
if [ "$time_since_check" -ge "$UPDATE_THRESHOLD" ]; then
echo $time_since_check
else
echo 0
fi
}
update() {
# Record that we've update
touch $HOME/.dotfiles_update
# Update dotfiles repo
cd ~/.dotfiles/
echo "Checking for updates..."
git fetch --quiet origin
if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/master)" ]; then
echo "--> outdated."
git pull
./install.sh
else
echo "--> nothing to do."
fi
cd - &> /dev/null
}
check=$(check_for_updates)
if [[ $check -gt 0 ]]; then
echo "Dotfiles might be out of date."
update
fi

View File

@@ -1,65 +0,0 @@
#!/bin/bash
PROFILE_BASE_DIR=$HOME/.dotfiles/profiles
# Link files of a single profile
link_profile() {
profile=$1
profile_dir=${PROFILE_BASE_DIR}/$profile
if [ ! -d $profile_dir ]; then
echo "$profile does not exist"
exit 1
else
echo "Linking files from profile $profile"
fi
cd $profile_dir
OIFS="$IFS"
IFS=$'\n'
# Find all files to link
for file in `find . -type f | cut -c 3- | grep -v "^$"`; do
dir=$(dirname "${file}")
src=`pwd`/$file
dst_dir=$HOME/$dir
dst=$HOME/$file
# create folder if not exist
if [ ! -d "$dst_dir" ]; then
echo "Creating destination direcory $dst_dir"
mkdir -p $dst_dir
fi
# link file
echo "Linking $src to $dst"
if [ -f "${dst}" ] || [ -L "${dst}" ]; then
difference="$(diff -y $src $dst)"
if [ "$?" -ne 0 ]; then
echo "$difference"
echo "$(basename $dst) already exists (and differs). Override? [y/N]"
read response
if [ "$response" == 'y' ] || [ "$response" == 'Y' ] \
|| [ "$response" == 'yes' ] || [ "$response" == 'Yes' ]; then
ln -sf $src $dst
else
echo "Skipping $file"
fi
else
echo "Skipping $file (no diff)"
fi
else
ln -s $src $dst
fi
done
}
# link profiles
if [ "$1" == "link" ]; then
shift
while [ "$1" != "" ]; do
link_profile $1
shift
done
fi

View File

@@ -1,66 +0,0 @@
# fzf
if [ ! -d "$HOME/.fzf" ]; then
git clone --depth 1 https://github.com/junegunn/fzf.git $HOME/.fzf
if [ ! -f "$HOME/.fzf/bin" ]; then
$HOME/.fzf/install --completion --key-bindings --update-rc
fi
fi
# diff-so-fancy
if [ ! -f "$HOME/.local/bin/diff-so-fancy" ]; then
if [ ! -d "$HOME/.local/lib/diff-so-fancy" ]; then
git clone --depth 1 https://github.com/so-fancy/diff-so-fancy.git $HOME/.local/lib/diff-so-fancy
fi
ln -s $HOME/.local/lib/diff-so-fancy/diff-so-fancy $HOME/.local/bin/diff-so-fancy
fi
# vimplug
if [ ! -d "$HOME/.vim/autoload" ]; then
echo "setup vim plug"
curl -fLo $HOME/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
fi
# install rust
if [ ! -d "$HOME/.cargo" ]; then
echo "setup cargo"
curl https://sh.rustup.rs -sSf | sh -s -- --no-modify-path -y --profile minimal -q
fi
# install some rust packages
for package in ripgrep bat; do
echo "setup $package"
$HOME/.cargo/bin/cargo install -q $package
done
# linking dotfiles
$HOME/.dotfiles/dotfiles.sh link base
if ! type zsh > /dev/null; then
echo "Cannnot change default shell to zsh: not installed"
else
# Make ZSH the default shell environment
if [ $(cat /etc/passwd | grep $USER | awk -F ':' '{print substr($7, length($7)-3)}') != "/zsh" ]; then
echo "Changing shell to zsh"
chsh -s $(which zsh)
fi
# Antidote Installation
if [ ! -d "$HOME/.antidote" ]; then
echo "Installing antidote"
# make sure git is installed
if ! type git > /dev/null; then
echo "Git not installed. Cannot install antidote"
else
git clone --depth=1 https://github.com/mattmc3/antidote.git $HOME/.antidote
fi
else
echo "antidote already exists."
fi
fi

View File

@@ -1,33 +0,0 @@
#/bin/bash
#-- Script to automate https://help.github.com/articles/why-is-git-always-asking-for-my-password
REPO_URL=`git remote -v | grep -m1 '^origin' | sed -Ene's#.*(https?://[^[:space:]]*).*#\1#p'`
if [ -z "$REPO_URL" ]; then
echo "-- ERROR: Could not identify Repo url."
echo " It is possible this repo is already using SSH instead of HTTPS."
exit
fi
USER=`echo $REPO_URL | sed -Ene's#https?://github.com/([^/]*)/(.*)[\.git]?#\1#p'`
if [ -z "$USER" ]; then
echo "-- ERROR: Could not identify User."
exit
fi
REPO=`echo $REPO_URL | sed -Ene's#https?://github.com/([^/]*)/(.*)[\.git]?#\2#p'`
if [ -z "$REPO" ]; then
echo "-- ERROR: Could not identify Repo."
exit
fi
NEW_URL="git@github.com:$USER/$REPO.git"
echo "Changing repo url from "
echo " '$REPO_URL'"
echo " to "
echo " '$NEW_URL'"
echo ""
CHANGE_CMD="git remote set-url origin $NEW_URL"
`$CHANGE_CMD`
echo "Success"

View File

@@ -1,258 +0,0 @@
# This file has been auto-generated by i3-config-wizard(1).
# It will not be overwritten, so edit it as you like.
#
# Should you change your keyboard layout somewhen, delete
# this file and re-run i3-config-wizard(1).
#
# i3 config file (v4)
#
# Please see http://i3wm.org/docs/userguide.html for a complete reference!
# exec xrandr --auto --output DP-4 --right-of HDMI-0 --primary --dpi 150
exec --no-startup-id ~/.config/i3/xrandr.sh
set $mod Mod4
# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below. ISO 10646 = Unicode
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
# The font above is very space-efficient, that is, it looks good, sharp and
# clear in small sizes. However, if you need a lot of unicode glyphs or
# right-to-left text rendering, you should instead use pango for rendering and
# chose a FreeType font, such as:
font pango:Source Code Pro for Powerline, FontAwesome Regular, Icons 12.5
new_window 1pixel
# Use Mouse+$mod to drag floating windows to their wanted position
floating_modifier $mod
# start a terminal
bindsym $mod+Return exec i3-sensible-terminal
# kill focused window
bindsym $mod+Shift+q kill
# start dmenu (a program launcher)
#bindsym $mod+d exec dmenu_run
# rofi
bindsym $mod+d exec "rofi -show combi"
# There also is the (new) i3-dmenu-desktop which only displays applications
# shipping a .desktop file. It is a wrapper around dmenu, so you need that
# installed.
# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop
# change focus
bindsym $mod+j focus left
bindsym $mod+k focus down
bindsym $mod+l focus up
bindsym $mod+semicolon focus right
# alternatively, you can use the cursor keys:
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
# move focused window
bindsym $mod+Shift+j move left
bindsym $mod+Shift+k move down
bindsym $mod+Shift+l move up
bindsym $mod+Shift+colon move right
# alternatively, you can use the cursor keys:
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right
# move workspace left/right
bindsym $mod+Shift+greater move workspace to output right
bindsym $mod+Shift+less move workspace to output left
# split in horizontal orientation
bindsym $mod+h split h
# split in vertical orientation
bindsym $mod+v split v
# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen
# change container layout (stacked, tabbed, toggle split)
#bindsym $mod+s layout stacking
#bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
# toggle tiling / floating
bindsym $mod+Shift+space floating toggle
# change focus between tiling / floating windows
bindsym $mod+space focus mode_toggle
# focus the parent container
bindsym $mod+a focus parent
# focus the child container
#bindsym $mod+d focus child
set $workspace1 1
set $workspace2 2
set $workspace3 3
set $workspace4 4
set $workspace5 5
set $workspace6 6
set $workspace7 7
#
set $workspace8 8
#
set $workspace9 9
#
# switch to workspace
bindsym $mod+1 workspace $workspace1
bindsym $mod+2 workspace $workspace2
bindsym $mod+3 workspace $workspace3
bindsym $mod+4 workspace $workspace4
bindsym $mod+5 workspace $workspace5
bindsym $mod+6 workspace $workspace6
bindsym $mod+7 workspace $workspace7
bindsym $mod+8 workspace $workspace8
bindsym $mod+9 workspace $workspace9
bindsym $mod+0 workspace $workspace10
# move focused container to workspace
bindsym $mod+Shift+1 move container to workspace $workspace1
bindsym $mod+Shift+2 move container to workspace $workspace2
bindsym $mod+Shift+3 move container to workspace $workspace3
bindsym $mod+Shift+4 move container to workspace $workspace4
bindsym $mod+Shift+5 move container to workspace $workspace5
bindsym $mod+Shift+6 move container to workspace $workspace6
bindsym $mod+Shift+7 move container to workspace $workspace7
bindsym $mod+Shift+8 move container to workspace $workspace8
bindsym $mod+Shift+9 move container to workspace $workspace9
bindsym $mod+Shift+0 move container to workspace $workspace10
# Make the currently focused window a scratchpad
bindsym $mod+Shift+minus move scratchpad
# Show the first scratchpad window
bindsym $mod+minus scratchpad show
# reload the configuration file
bindsym $mod+Shift+c reload
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindsym $mod+Shift+r restart
# exit i3 (logs you out of your X session)
bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
# resize window (you can also use the mouse for that)
mode "resize" {
# These bindings trigger as soon as you enter the resize mode
# Pressing left will shrink the windows width.
# Pressing right will grow the windows width.
# Pressing up will shrink the windows height.
# Pressing down will grow the windows height.
bindsym j resize shrink width 10 px or 10 ppt
bindsym k resize grow height 10 px or 10 ppt
bindsym l resize shrink height 10 px or 10 ppt
bindsym semicolon resize grow width 10 px or 10 ppt
# same bindings, but for the arrow keys
bindsym Left resize shrink width 10 px or 10 ppt
bindsym Down resize grow height 10 px or 10 ppt
bindsym Up resize shrink height 10 px or 10 ppt
bindsym Right resize grow width 10 px or 10 ppt
# back to normal: Enter or Escape
bindsym Return mode "default"
bindsym Escape mode "default"
}
bindsym $mod+r mode "resize"
# Start i3bar to display a workspace bar (plus the system information i3status
# finds out, if available)
#bar {
#position top
# status_command 2> /tmp/i3blocks.err i3blocks -c ~/.config/i3/i3blocks.conf | tee /tmp/i3blocks.out
#}
# hide window border
new_window 1pixel
exec_always --no-startup-id ~/.config/polybar/polybar.sh
# "special" workspaces
# workspace7 => zotero
# worksapce8 => chat
# workspace9 => emailing
# workspace0 => music
workspace $workspace7 output eDP-1
assign [class="Zotero"] → $workspace7
assign [class="Mendeley"] → $workspace7
workspace $workspace8 output eDP-1
assign [class="Skype" title="Skype"] → $workspace8
assign [class="Mattermost" instance="mattermost"] → $workspace8
assign [class="Rambox" instance="rambox"] → $workspace8
workspace $workspace9 output eDP-1
assign [class="thunderbird" window_role="3pane"] → $workspace9
workspace $workspace10 output eDP-1
assign [class="Spotify"] → $workspace10
for_window [window_role="pop-up"] floating enable
for_window [class="Chromium" window_role="pop-up"] floating disable
for_window [class="Tk"] floating enable
for_window [title="PyMOL Viewer"] floating enable
for_window [class="Toplevel"] floating enable
for_window [title="Figure*" instance="matplotlib"] floating enable
for_window [window_role="conversation" class="Pidgin"] floating enable
for_window [class="Com.github.alainm23.planner"] floating enable
# use tiling mode only for main/chat Skype window and floating of all dialogs
# Skype main window title looks like this - "alexey.diyan - Skype™"
for_window [instance="skype" title="^.*?(?<!Skype™)$"] floating enable
for_window [instance="skype" title="Skype|Skype™|Call with|File Transfers"] floating disable
# Pulse Audio controls
bindsym --release XF86AudioLowerVolume exec --no-startup-id amixer sset Master 5%- #decrease sound volume
bindsym --release XF86AudioRaiseVolume exec --no-startup-id amixer sset Master 5%+ #increase sound volume
bindsym --release XF86AudioMute exec --no-startup-id amixer sset Master toggle # mute sound
# Sreen brightness controls
bindsym XF86MonBrightnessUp exec xbacklight -inc 20 # increase screen brightness
bindsym XF86MonBrightnessDown exec xbacklight -dec 20 # decrease screen brightness
# Touchpad controls
bindsym XF86TouchpadToggle exec /some/path/toggletouchpad.sh # toggle touchpad
# Media player controls
bindsym XF86AudioPlay exec playerctl play-pause
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous
bindsym XF86HomePage exec "i3lock -i ~/lockscreens/`ls ~/lockscreens | shuf -n 1` -t -f"
# change ouput
bindsym $mod+Shift+s exec --no-startup-id ~/.config/i3/scripts/change_monitor.sh
# reload workspace layouts
#exec --no-startup-id "i3-msg 'workspace 9; append_layout /home/bauer/.i3/workspace-9.json'"
#exec feh --bg-fill /home/bauer/artistic/artistici2.png
#exec --no-startup-id xautolock -time 5 -locker 'i3lock -i ~/.lockscreen/`ls /home/bauer/lockscreens | shuf -n 1` -t -f'
#exec --no-startup-id thunderbird
#exec --no-startup-id skype
#exec --no-startup-id mattermost-desktop
#exec --no-startup-id nextcloud
#exec --no-startup-id nm-applet
#exec --no-startup-id xfsettingsd --sm-client-disable &
#exec --no-startup-id /usr/bin/blueman-applet

View File

@@ -1,20 +0,0 @@
#!/bin/bash
EXTERNAL_OUTPUT="HDMI2"
INTERNAL_OUTPUT="eDP1"
# if we don't have a file, start at zero
if [ ! -f "/tmp/monitor_mode.dat" ] ; then
monitor_mode="CLONES"
# otherwise read the value from the file
else
monitor_mode=`cat /tmp/monitor_mode.dat`
fi
if [ $monitor_mode = "CLONES" ]; then
monitor_mode="EXTERNAL"
$HOME/.screenlayout/external.sh
elif [ $monitor_mode = "EXTERNAL" ]; then
monitor_mode="CLONES"
$HOME/.screenlayout/clone.sh
fi
echo "${monitor_mode}" > /tmp/monitor_mode.dat

View File

@@ -1,60 +0,0 @@
#!/usr/bin/perl
#
# Copyright 2014 Pierre Mavro <deimos@deimos.fr>
# Copyright 2014 Vivien Didelot <vivien@didelot.org>
# Copyright 2014 Andreas Guldstrand <andreas.guldstrand@gmail.com>
#
# Licensed under the terms of the GNU GPL v3, or any later version.
use strict;
use warnings;
use utf8;
use Getopt::Long;
# default values
my $t_warn = 50;
my $t_crit = 80;
my $cpu_usage = -1;
my $decimals = 0;
sub help {
print "Usage: cpu_usage [-w <warning>] [-c <critical>] [-d <decimals>]\n";
print "-w <percent>: warning threshold to become yellow\n";
print "-c <percent>: critical threshold to become red\n";
print "-d <decimals>: Use <decimals> decimals for percentage (default is $decimals) \n";
exit 0;
}
GetOptions("help|h" => \&help,
"w=i" => \$t_warn,
"c=i" => \$t_crit,
"d=i" => \$decimals,
);
# Get CPU usage
$ENV{LC_ALL}="en_US"; # if mpstat is not run under en_US locale, things may break, so make sure it is
open (MPSTAT, 'mpstat 1 1 |') or die;
while (<MPSTAT>) {
if (/^.*\s+(\d+\.\d+)\s+$/) {
$cpu_usage = 100 - $1; # 100% - %idle
last;
}
}
close(MPSTAT);
$cpu_usage eq -1 and die 'Can\'t find CPU information';
# Print short_text, full_text
printf "%.${decimals}f%%\n", $cpu_usage;
printf "%.${decimals}f%%\n", $cpu_usage;
# Print color, if needed
if ($cpu_usage >= $t_crit) {
print "#fb4934\n";
exit 33;
} elsif ($cpu_usage >= $t_warn) {
print "#fabd2f\n";
}
exit 0;

View File

@@ -1,4 +0,0 @@
#!/bin/bash
eval $($(dirname $0)/sp eval)
echo ${SPOTIFY_ARTIST} - ${SPOTIFY_TITLE}

View File

@@ -1,42 +0,0 @@
#!/bin/sh
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
DIR="/scratch"
ALERT_LOW="${1:-10}" # color will turn red under this value (default: 10%)
df -h -P "$DIR" | awk -v alert_low=$ALERT_LOW '
/\/.*/ {
# full text
print $4" ("$5")"
# short text
print $4
use=$5
# no need to continue parsing
exit 0
}
END {
gsub(/%$/,"",use)
if (100 - use < alert_low) {
# color
print "#FF0000"
}
}
'

View File

@@ -1,12 +0,0 @@
#!/bin/bash
while [ "$select" != "NO" -a "$select" != "YES" ]; do
select=$(echo -e 'NO\nYES' | dmenu -nb '#2f343f'
-nf '#f3f4f5'
-sb '#9575cd'
-sf '#f3f4f5'
-fn '-*-*-medium-r-normal-*-*-*-*-*-*-100-*-*' -
i -p "Are you sure you want to logout?")
[ -z "$select" ] && exit 0
done
[ "$select" = "NO" ] && exit 0
i3-msg exit

View File

@@ -1,21 +0,0 @@
#!/bin/bash
t_warn=50
t_crit=70
GPU=$(nvidia-smi -q | grep Gpu | awk '{print $3}')
if [ $GPU -gt $t_crit ]
then
printf " %d%%" "$GPU"
printf "\n %d%%" "$GPU"
printf "\n#fb4934\n"
elif [ $GPU -gt $t_warn ]
then
printf " %d%%" "$GPU"
printf "\n %d%%" "$GPU"
printf "\n#fabd2f\n"
else
printf " %d%%" "$GPU"
printf "\n %d%%" "$GPU"
fi

View File

@@ -1 +0,0 @@
xkb-switch

View File

@@ -1,35 +0,0 @@
#!/bin/sh
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
load="$(cut -d ' ' -f1 /proc/loadavg)"
cpus="$(nproc)"
# full text
echo "$load"
# short text
echo "$load"
# color if load is too high
awk -v cpus=$cpus -v cpuload=$load '
BEGIN {
if (cpus <= cpuload) {
print "#FF0000";
exit 33;
}
}
'

View File

@@ -1,67 +0,0 @@
#!/bin/sh
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
TYPE="${BLOCK_INSTANCE:-mem}"
awk -v type=$TYPE '
/^MemTotal:/ {
mem_total=$2
}
/^MemFree:/ {
mem_free=$2
}
/^Buffers:/ {
mem_free+=$2
}
/^Cached:/ {
mem_free+=$2
}
/^SwapTotal:/ {
swap_total=$2
}
/^SwapFree:/ {
swap_free=$2
}
END {
if (type == "swap") {
free=swap_free/1024/102
used=(swap_total-swap_free)/1024/1024
total=swap_total/1024/1024
} else {
free=mem_free/1024/1024
used=(mem_total-mem_free)/1024/1024
total=mem_total/1024/1024
}
pct=used/total*100
# full text
printf("%.1fG / %.1fG ( %.f%% )\n", used, total, pct)
# short text
printf("%.f%%\n", pct)
# color
if (pct > 90) {
print("#E53935\n")
} else if (pct > 80) {
print("#FFAE00\n")
} else if (pct > 70) {
print("#FFF600\n")
}
}
' /proc/meminfo

View File

@@ -1,151 +0,0 @@
#!/usr/bin/perl
# Made by Pierre Mavro/Deimosfr <deimos@deimos.fr>
# Minor contribution by Thor K. H. <thor@roht.no>
# Licensed under the terms of the GNU GPL v3, or any later version.
# Version: 0.3
# Usage:
# 1. The configuration name of OpenVPN should be familiar for you (home,work...)
# 2. The device name in your configuration file should be fully named (tun0,tap1...not only tun or tap)
# 3. When you launch one or multiple OpenVPN connexion, be sure the PID file is written in the correct folder (ex: --writepid /run/openvpn/home.pid)
use strict;
use warnings;
use utf8;
use Getopt::Long;
my $openvpn_enabled='/dev/shm/openvpn_i3blocks_enabled';
my $openvpn_disabled='/dev/shm/openvpn_i3blocks_disabled';
# Print output
sub print_output {
my $ref_pid_files = shift;
my @pid_files = @$ref_pid_files;
my $change=0;
# Total pid files
my $total_pid = @pid_files;
if ($total_pid == 0) {
print "down\n"x2;
# Delete OpenVPN i3blocks temp files
if (-f $openvpn_enabled) {
unlink $openvpn_enabled or die "Can't delete $openvpn_enabled\n";
# Colorize if VPN has just went down
print '#FF0000\n';
}
unless (-f $openvpn_disabled) {
open(my $shm, '>', $openvpn_disabled) or die "Can't write $openvpn_disabled\n";
}
exit(0);
}
# Check if interface device is present
my $vpn_found=0;
my $pid;
my $cmd_line;
my @config_name;
my @config_path;
my $interface;
my $current_config_path;
my $current_config_name;
foreach (@pid_files) {
# Get current PID
$pid=0;
open(PID, '<', $_);
while(<PID>) {
chomp $_;
$pid = $_;
}
close(PID);
# Check if PID has been found
if ($pid ==0) {
print "Can't get PID $_: $!\n";
}
# Check if PID is still alive
$cmd_line='/proc/'.$pid.'/cmdline';
if (-f $cmd_line) {
# Get config name
open(CMD_LINE, '<', $cmd_line);
while(<CMD_LINE>) {
chomp $_;
if ($_ =~ /--config\s*(.*\.conf)/) {
# Get interface from config file
$current_config_path = $1;
# Remove unwanted escape chars
$current_config_path =~ s/\x{00}//g;
$interface = 'null';
# Get configuration name
if ($current_config_path =~ /(\w+).conf/) {
$current_config_name=$1;
} else {
$current_config_name='unknow';
}
# Get OpenVPN interface device name
open(CONFIG, '<', $current_config_path) or die "Can't read config file '$current_config_path': $!\n";
while(<CONFIG>) {
chomp $_;
if ($_ =~ /dev\s+(\w+)/) {
$interface=$1;
last;
}
}
close(CONFIG);
# check if interface exist
unless ($interface eq 'null') {
if (-d "/sys/class/net/$interface") {
push @config_name, $current_config_name;
$vpn_found=1;
# Write enabled file
unless (-f $openvpn_enabled) {
open(my $shm, '>', $openvpn_enabled) or die "Can't write $openvpn_enabled\n";
$change=1;
}
}
}
}
}
close(CMD_LINE);
}
}
# Check if PID found
my $names;
my $short_status;
if ($vpn_found == 1) {
$names = join('/', @config_name);
$short_status='up';
} else {
$short_status='down';
$names = $short_status;
}
print "$names\n";
print "$short_status\n";
# Print color if there were changes
print "#00FF00\n" if ($change == 1);
exit(0);
}
sub check_opts {
# Vars
my @pid_file=glob '/run/openvpn/*.pid';
# Set options
GetOptions( "help|h" => \&help,
"p=s" => \@pid_file);
print_output(\@pid_file);
}
sub help {
print "Usage: openvpn [-d pid folder files]\n";
print "-d : pid folder files (default /run/openvpn/*.pid)\n";
print "Note: devices in configuration file should be named with their number (ex: tun0, tap1)\n";
exit(1);
}
&check_opts;

View File

@@ -1,186 +0,0 @@
#!/usr/bin/env bash
#
# Use rofi/zenity to change system runstate thanks to systemd.
#
# Note: this currently relies on associative array support in the shell.
#
# Inspired from i3pystatus wiki:
# https://github.com/enkore/i3pystatus/wiki/Shutdown-Menu
#
# Copyright 2015 Benjamin Chrétien <chretien at lirmm dot fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#######################################################################
# BEGIN CONFIG #
#######################################################################
# Use a custom lock script
#LOCKSCRIPT="i3lock-extra -m pixelize"
# Colors: FG (foreground), BG (background), HL (highlighted)
FG_COLOR="#bbbbbb"
BG_COLOR="#111111"
HLFG_COLOR="#111111"
HLBG_COLOR="#bbbbbb"
BORDER_COLOR="#222222"
# Options not related to colors
ROFI_TEXT="Menu:"
ROFI_OPTIONS="-width -11 -location 3 -hide-scrollbar -bw 2"
# Zenity options
ZENITY_TITLE="Menu"
ZENITY_TEXT="Action:"
ZENITY_OPTIONS="--column= --hide-header"
#######################################################################
# END CONFIG #
#######################################################################
# Whether to ask for user's confirmation
enable_confirmation=false
# Preferred launcher if both are available
preferred_launcher="rofi"
usage="$(basename "$0") [-h] [-c] [-p name] -- display a menu for shutdown, reboot, lock etc.
where:
-h show this help text
-c ask for user confirmation
-p preferred launcher (rofi or zenity)
This script depends on:
- systemd,
- i3,
- rofi or zenity."
# Check whether the user-defined launcher is valid
launcher_list=(rofi zenity)
function check_launcher() {
if [[ ! "${launcher_list[@]}" =~ (^|[[:space:]])"$1"($|[[:space:]]) ]]; then
echo "Supported launchers: ${launcher_list[*]}"
exit 1
else
# Get array with unique elements and preferred launcher first
# Note: uniq expects a sorted list, so we cannot use it
i=1
launcher_list=($(for l in "$1" "${launcher_list[@]}"; do printf "%i %s\n" "$i" "$l"; let i+=1; done \
| sort -uk2 | sort -nk1 | cut -d' ' -f2- | tr '\n' ' '))
fi
}
# Parse CLI arguments
while getopts "hcp:" option; do
case "${option}" in
h) echo "${usage}"
exit 0
;;
c) enable_confirmation=true
;;
p) preferred_launcher="${OPTARG}"
check_launcher "${preferred_launcher}"
;;
*) exit 1
;;
esac
done
# Check whether a command exists
function command_exists() {
command -v "$1" &> /dev/null 2>&1
}
# systemctl required
if ! command_exists systemctl ; then
exit 1
fi
# menu defined as an associative array
typeset -A menu
# Menu with keys/commands
menu=(
[Shutdown]="systemctl poweroff"
[Reboot]="systemctl reboot"
[Hibernate]="systemctl hibernate"
[Suspend]="systemctl suspend"
[Halt]="systemctl halt"
[Lock]="${LOCKSCRIPT:-i3lock --color=${BG_COLOR#"#"}}"
[Logout]="i3-msg exit"
[Cancel]=""
)
menu_nrows=${#menu[@]}
# Menu entries that may trigger a confirmation message
menu_confirm="Shutdown Reboot Hibernate Suspend Halt Logout"
launcher_exe=""
launcher_options=""
rofi_colors=""
function prepare_launcher() {
if [[ "$1" == "rofi" ]]; then
rofi_colors="-bc ${BORDER_COLOR} -bg ${BG_COLOR} -fg ${FG_COLOR} \
-hlfg ${HLFG_COLOR} -hlbg ${HLBG_COLOR}"
launcher_exe="rofi"
launcher_options="-dmenu -i -lines ${menu_nrows} -p ${ROFI_TEXT} \
${rofi_colors} ${ROFI_OPTIONS}"
elif [[ "$1" == "zenity" ]]; then
launcher_exe="zenity"
launcher_options="--list --title=${ZENITY_TITLE} --text=${ZENITY_TEXT} \
${ZENITY_OPTIONS}"
fi
}
for l in "${launcher_list[@]}"; do
if command_exists "${l}" ; then
prepare_launcher "${l}"
break
fi
done
# No launcher available
if [[ -z "${launcher_exe}" ]]; then
exit 1
fi
launcher="${launcher_exe} ${launcher_options}"
selection="$(printf '%s\n' "${!menu[@]}" | sort | ${launcher})"
function ask_confirmation() {
if [ "${launcher_exe}" == "rofi" ]; then
confirmed=$(echo -e "Yes\nNo" | rofi -dmenu -i -lines 2 -p "${selection}?" \
${rofi_colors} ${ROFI_OPTIONS})
[ "${confirmed}" == "Yes" ] && confirmed=0
elif [ "${launcher_exe}" == "zenity" ]; then
zenity --question --text "Are you sure you want to ${selection,,}?"
confirmed=$?
fi
if [ "${confirmed}" == 0 ]; then
i3-msg -q "exec ${menu[${selection}]}"
fi
}
if [[ $? -eq 0 && ! -z ${selection} ]]; then
if [[ "${enable_confirmation}" = true && \
${menu_confirm} =~ (^|[[:space:]])"${selection}"($|[[:space:]]) ]]; then
ask_confirmation
else
i3-msg -q "exec ${menu[${selection}]}"
fi
fi

View File

@@ -1,22 +0,0 @@
/string *"xesam:artist/{
while (1) {
getline line
if (line ~ /string "/) {
sub(/.*string "/, "artist:", line)
sub(/".*$/, "", line)
print line
break
}
}
}
/string *"xesam:title/{
while(1) {
getline line
if (line ~ /string "/) {
sub(/.*string "/, "title:", line)
sub(/".*$/, "", line)
print line
break
}
}
}

View File

@@ -1,12 +0,0 @@
#!/usr/bin/python
import dbus
try:
bus = dbus.SessionBus()
spotify = bus.get_object("org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2")
spotify_iface = dbus.Interface(spotify, 'org.freedesktop.DBus.Properties')
props = spotify_iface.Get('org.mpris.MediaPlayer2.Player', 'Metadata')
print(str(props['xesam:artist'][0]) + " - " + str(props['xesam:title']))
exit
except dbus.exceptions.DBusException:
exit

View File

@@ -1,40 +0,0 @@
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No command?"
exit
fi
if [ "$(pidof spotify)" = "" ]
then
echo "Spotify is not running"
exit
fi
case $1 in
"play")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause
;;
"next")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next
;;
"prev")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous
;;
"getTitle")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'|egrep -A 1 "title"|egrep -v "title"|cut -b 44-|cut -d '"' -f 1|egrep -v ^$
;;
"getArtist")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'|egrep -A 2 "artist"|egrep -v "artist"|egrep -v "array"|cut -b 27-|cut -d '"' -f 1|egrep -v ^$
;;
"getAlbum")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'|egrep -A 2 "album"|egrep -v "album"|egrep -v "array"|cut -b 44-|cut -d '"' -f 1|egrep -v ^$
;;
"getStatus")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'PlaybackStatus'|grep 'string "[^"]*"'|sed 's/.*"\(.*\)"[^"]*$/\1/'
;;
*)
echo "Unknown command: " $1
;;
esac

View File

@@ -1,40 +0,0 @@
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No command?"
exit
fi
if [ "$(pidof spotify)" = "" ]
then
echo "Spotify is not running"
exit
fi
case $1 in
"play")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause
;;
"next")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next
;;
"prev")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous
;;
"getTitle")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'|egrep -A 1 "title"|egrep -v "title"|cut -b 44-|cut -d '"' -f 1|egrep -v ^$
;;
"getArtist")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'|egrep -A 2 "artist"|egrep -v "artist"|egrep -v "array"|cut -b 27-|cut -d '"' -f 1|egrep -v ^$
;;
"getAlbum")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'|egrep -A 2 "album"|egrep -v "album"|egrep -v "array"|cut -b 44-|cut -d '"' -f 1|egrep -v ^$
;;
"getStatus")
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'PlaybackStatus'|grep 'string "[^"]*"'|sed 's/.*"\(.*\)"[^"]*$/\1/'
;;
*)
echo "Unknown command: " $1
;;
esac

View File

@@ -1,41 +0,0 @@
#!/bin/sh
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
DIR="/"
ALERT_LOW="${1:-10}" # color will turn red under this value (default: 10%)
df -h -P "$DIR" | awk -v alert_low=$ALERT_LOW '
/\/.*/ {
# full text
print $4" ("$5")"
# short text
print $4
use=$5
# no need to continue parsing
exit 0
}
END {
gsub(/%$/,"",use)
if (100 - use < alert_low) {
# color
print "#FF0000"
}
}
'

View File

@@ -1,4 +0,0 @@
#!/bin/bash
tmux list-sessions | wc -l

View File

@@ -1,46 +0,0 @@
#!/usr/bin/env perl
## The sink we are interested in should be given as the
## 1st argument to the script.
my $sink=$ARGV[0] || die("Need a sink number as the first argument\n");
## If the script has been run with a second argument,
## that argument will be the volume threshold we are checking
my $volume_limit=$ARGV[1]||undef;
## Run the pactl command and save the output in
## ther filehandle $fh
open(my $fh, '-|', 'pactl list sinks');
## Set the record separator to consecutive newlines (same as -000)
## this means we read the info for each sink as a single "line".
$/="\n\n";
## Go through the pactl output
while (<$fh>) {
## If this is the sink we are interested in
if (/#$sink/) {
## Extract the current colume of this sink
/Volume:.*?(\d+)%/;
my $volume=$1;
## If the script has been run with a second argument,
## check whether the volume is above or below that
if ($volume_limit) {
## If the volume os greater than or equal to the
## value passed, print "y"
if ($volume >= $volume_limit) {
print "y\n";
exit 0;
}
else {
print "n\n";
exit 1;
}
}
## Else, if the script has been run with just one argument,
## print the current volume.
else {
print "$volume%\n";
}
}#
}

View File

@@ -1,162 +0,0 @@
#!/bin/bash
# Displays the default device, volume, and mute status for i3blocks
AUDIO_HIGH_SYMBOL=' '
AUDIO_MED_THRESH=50
AUDIO_MED_SYMBOL=' '
AUDIO_LOW_THRESH=0
AUDIO_LOW_SYMBOL=' '
AUDIO_MUTED_SYMBOL=' '
AUDIO_INTERVAL=5
DEFAULT_COLOR="#ffffff"
MUTED_COLOR="#a0a0a0"
LONG_FORMAT=0
SHORT_FORMAT=2
USE_PERCENT=1
USE_ALSA_NAME=0
USE_DESCRIPTION=0
SUBSCRIBE=0
while getopts F:Sf:padH:M:L:X:T:t:C:c:i:h opt; do
case "$opt" in
S) SUBSCRIBE=1 ;;
F) LONG_FORMAT="$OPTARG" ;;
f) SHORT_FORMAT="$OPTARG" ;;
p) USE_PERCENT=0 ;;
a) USE_ALSA_NAME=1 ;;
d) USE_DESCRIPTION=1 ;;
H) AUDIO_HIGH_SYMBOL="$OPTARG" ;;
M) AUDIO_MED_SYMBOL="$OPTARG" ;;
L) AUDIO_LOW_SYMBOL="$OPTARG" ;;
X) AUDIO_MUTED_SYMBOL="$OPTARG" ;;
T) AUDIO_MED_THRESH="$OPTARG" ;;
t) AUDIO_LOW_THRESH="$OPTARG" ;;
C) DEFAULT_COLOR="$OPTARG" ;;
c) MUTED_COLOR="$OPTARG" ;;
i) AUDIO_INTERVAL="$OPTARG" ;;
h) printf \
"Usage: volume-pulseaudio [-S] [-F format] [-f format] [-p] [-a|-d] [-H symb] [-M symb]
[-L symb] [-X symb] [-T thresh] [-t thresh] [-C color] [-c color] [-i inter] [-h]
Options:
-F, -f\tOutput format (-F long format, -f short format) to use, amonst:
\t0\t symb vol [index:name]\t (default long)
\t1\t symb vol [name]
\t2\t symb vol [index]\t (default short)
\t3\t symb vol
-S\tSubscribe to volume events (requires persistent block, always uses long format)
-p\tOmit the percent sign (%%) in volume
-a\tUse ALSA name if possible
-d\tUse device description instead of name if possible
-H\tSymbol to use when audio level is high. Default: '$AUDIO_HIGH_SYMBOL'
-M\tSymbol to use when audio level is medium. Default: '$AUDIO_MED_SYMBOL'
-L\tSymbol to use when audio level is low. Default: '$AUDIO_LOW_SYMBOL'
-X\tSymbol to use when audio is muted. Default: '$AUDIO_MUTED_SYMBOL'
-T\tThreshold for medium audio level. Default: $AUDIO_MED_THRESH
-t\tThreshold for low audio level. Default: $AUDIO_LOW_THRESH
-C\tColor for non-muted audio. Default: $DEFAULT_COLOR
-c\tColor for muted audio. Default: $MUTED_COLOR
-i\tInterval size of volume increase/decrease. Default: $AUDIO_INTERVAL
-h\tShow this help text
" && exit 0;;
esac
done
function move_sinks_to_new_default {
DEFAULT_SINK=$1
pacmd list-sink-inputs | grep index: | grep -o '[0-9]\+' | while read SINK
do
pacmd move-sink-input $SINK $DEFAULT_SINK
done
}
function set_default_playback_device_next {
inc=${1:-1}
num_devices=$(pacmd list-sinks | grep -c index:)
sink_arr=($(pacmd list-sinks | grep index: | grep -o '[0-9]\+'))
default_sink_index=$(( $(pacmd list-sinks | grep index: | grep -no '*' | grep -o '^[0-9]\+') - 1 ))
default_sink_index=$(( ($default_sink_index + $num_devices + $inc) % $num_devices ))
default_sink=${sink_arr[$default_sink_index]}
pacmd set-default-sink $default_sink
move_sinks_to_new_default $default_sink
}
case "$BLOCK_BUTTON" in
1) set_default_playback_device_next ;;
2) amixer -q -D pulse sset Master toggle ;;
3) set_default_playback_device_next -1 ;;
4) amixer -q -D pulse sset Master $AUDIO_INTERVAL%+ ;;
5) amixer -q -D pulse sset Master $AUDIO_INTERVAL%- ;;
esac
function print_format {
PERCENT="%"
[[ $USE_PERCENT == 0 ]] && PERCENT=""
case "$1" in
1) echo "$SYMBOL$VOL$PERCENT [$NAME]" ;;
2) echo "$SYMBOL$VOL$PERCENT [$INDEX]";;
3) echo "$SYMBOL$VOL$PERCENT" ;;
*) echo "$SYMBOL$VOL$PERCENT [$INDEX:$NAME]" ;;
esac
}
function print_block {
for name in INDEX NAME VOL MUTED; do
read $name
done < <(pacmd list-sinks | grep "index:\|name:\|volume: front\|muted:" | grep -A3 '*')
INDEX=$(echo "$INDEX" | grep -o '[0-9]\+')
VOL=$(echo "$VOL" | grep -o "[0-9]*%" | head -1 )
VOL="${VOL%?}"
NAME=$(echo "$NAME" | sed \
's/.*<.*\.\(.*\)>.*/\1/; t;'\
's/.*<\(.*\)>.*/\1/; t;'\
's/.*/unknown/')
if [[ $USE_ALSA_NAME == 1 ]] ; then
ALSA_NAME=$(pacmd list-sinks |\
awk '/^\s*\*/{f=1}/^\s*index:/{f=0}f' |\
grep "alsa.name\|alsa.mixer_name" |\
head -n1 |\
sed 's/.*= "\(.*\)".*/\1/')
NAME=${ALSA_NAME:-$NAME}
elif [[ $USE_DESCRIPTION == 1 ]] ; then
DESCRIPTION=$(pacmd list-sinks |\
awk '/^\s*\*/{f=1}/^\s*index:/{f=0}f' |\
grep "device.description" |\
head -n1 |\
sed 's/.*= "\(.*\)".*/\1/')
NAME=${DESCRIPTION:-$NAME}
fi
if [[ $MUTED =~ "no" ]] ; then
SYMBOL=$AUDIO_HIGH_SYMBOL
[[ $VOL -le $AUDIO_MED_THRESH ]] && SYMBOL=$AUDIO_MED_SYMBOL
[[ $VOL -le $AUDIO_LOW_THRESH ]] && SYMBOL=$AUDIO_LOW_SYMBOL
COLOR=$DEFAULT_COLOR
else
SYMBOL=$AUDIO_MUTED_SYMBOL
COLOR=$MUTED_COLOR
fi
if [[ $SUBSCRIBE == 1 ]] ; then
print_format "$LONG_FORMAT"
else
print_format "$LONG_FORMAT"
print_format "$SHORT_FORMAT"
echo "$COLOR"
fi
}
print_block
if [[ $SUBSCRIBE == 1 ]] ; then
while read -r EVENT; do
print_block
done < <(pactl subscribe | stdbuf -oL grep change)
fi

View File

@@ -1,71 +0,0 @@
#!/bin/bash
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
# Copyright (C) 2014 Alexander Keller <github@nycroth.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#------------------------------------------------------------------------
# The second parameter overrides the mixer selection
# For PulseAudio users, use "pulse"
# For Jack/Jack2 users, use "jackplug"
# For ALSA users, you may use "default" for your primary card
# or you may use hw:# where # is the number of the card desired
MIXER="default"
[ -n "$(lsmod | grep pulse)" ] && MIXER="pulse"
[ -n "$(lsmod | grep jack)" ] && MIXER="jackplug"
MIXER="${2:-$MIXER}"
# The instance option sets the control to report and configure
# This defaults to the first control of your selected mixer
# For a list of the available, use `amixer -D $Your_Mixer scontrols`
SCONTROL="${BLOCK_INSTANCE:-$(amixer -D $MIXER scontrols |
sed -n "s/Simple mixer control '\([A-Za-z ]*\)',0/\1/p" |
head -n1
)}"
# The first parameter sets the step to change the volume by (and units to display)
# This may be in in % or dB (eg. 5% or 3dB)
STEP="${1:-5%}"
#------------------------------------------------------------------------
capability() { # Return "Capture" if the device is a capture device
amixer -D $MIXER get $SCONTROL |
sed -n "s/ Capabilities:.*cvolume.*/Capture/p"
}
volume() {
amixer -D $MIXER get $SCONTROL $(capability)
}
format() {
perl_filter='if (/.*\[(\d+%)\] (\[(-?\d+.\d+dB)\] )?\[(on|off)\]/)'
perl_filter+='{CORE::say $4 eq "off" ? "0%" : "'
# If dB was selected, print that instead
perl_filter+=$([[ $STEP = *dB ]] && echo '$3' || echo '$1')
perl_filter+='"; exit}'
perl -ne "$perl_filter"
}
#------------------------------------------------------------------------
case $BLOCK_BUTTON in
3) amixer -q -D $MIXER sset $SCONTROL $(capability) toggle ;; # right click, mute/unmute
4) amixer -q -D $MIXER sset $SCONTROL $(capability) ${STEP}+ unmute ;; # scroll up, increase
5) amixer -q -D $MIXER sset $SCONTROL $(capability) ${STEP}- unmute ;; # scroll down, decrease
esac
volume | format

View File

@@ -1,19 +0,0 @@
[bar/base]
width=900 ;100%
height=35
radius=6.0
fixed-center=false
background=${colors.background}
foreground=${colors.foreground}
line-size=3
line-color=#f00
border-size=0
border-color=#00000000
padding-left=0
padding-right=2
module-margin-left=1
module-margin-right=3
font-0 = "Noto Sans:size=14:style=Regular;1"
font-1 = unifont:fontformat=truetype:size=14:antialias=false;0
font-2 = FontAwesome:size=14;0

View File

@@ -1,11 +0,0 @@
[colors]
background=#222
background-alt=#444
foreground=#dfdfdf
foreground-alt=#555
primary=#ffb52a
secondary=#e60053
alert=#bd2c40
green=#689d6a
yellow=#fabc2f
red=#cc241d

View File

@@ -1,416 +0,0 @@
[module/xwindow]
type=internal/xwindow
label="> %title:0:75:...%"
[module/xkeyboard]
type=internal/xkeyboard
blacklist-0=num lock
format-prefix=" "
format-prefix-foreground=${colors.foreground-alt}
format-prefix-underline=${colors.secondary}
label-layout=%layout%
label-layout-underline=${colors.secondary}
label-indicator-padding=2
label-indicator-margin=1
label-indicator-background=${colors.secondary}
label-indicator-underline=${colors.secondary}
[module/filesystem]
type=internal/fs
interval=25
mount-0=/
mount-1=/data
mount-2=/backup
label-mounted=%{F#0a81f5}%mountpoint%%{F-}: %percentage_used%%
label-unmounted=%mountpoint% not mounted
label-unmounted-foreground=${colors.foreground-alt}
[module/bspwm]
type=internal/bspwm
label-focused=%index%
label-focused-background=${colors.background-alt}
label-focused-underline=${colors.primary}
label-focused-padding=2
label-occupied=%index%
label-occupied-padding=2
label-urgent=%index%!
label-urgent-background=${colors.alert}
label-urgent-padding=2
label-empty=%index%
label-empty-foreground=${colors.foreground-alt}
label-empty-padding=2
[module/i3]
type=internal/i3
format=<label-state> <label-mode>
index-sort=true
wrapping-scroll=false
strip-wsnumbers=true
pin-workspaces=true
label-mode-padding=2
label-mode-foreground=#000
label-mode-background=${colors.primary}
label-focused=%icon%
label-focused-background=${colors.green}
label-focused-underline=${colors.green}
label-focused-padding=${module/bspwm.label-focused-padding}
label-unfocused=%icon%
label-unfocused-padding=${module/bspwm.label-occupied-padding}
label-urgent=%icon%
label-urgent-background=${colors.red}
label-urgent-underline=${colors.red}
label-urgent-padding=${module/bspwm.label-urgent-padding}
label-visible=%icon%
label-visible-background=${self.label-focused-background}
label-visible-underline=${self.label-focused-underline}
label-visible-padding=${self.label-focused-padding}
ws-icon-0=1;1
ws-icon-1=2;2
ws-icon-2=3;3
ws-icon-3=4;4
ws-icon-4=5;5
ws-icon-5=6;6
ws-icon-6=7;7 
ws-icon-7=8;8 
ws-icon-8=9;9 
ws-icon-9=10;0 
[module/mpd]
type=internal/mpd
format-online=<label-song> <icon-prev> <icon-stop> <toggle> <icon-next>
icon-prev=
icon-stop=
icon-play=
icon-pause=
icon-next=
label-song-maxlen=25
label-song-ellipsis=true
[module/xbacklight]
type=internal/xbacklight
format=<label> <bar>
label=BL
bar-width=10
bar-indicator=|
bar-indicator-foreground=#ff
bar-indicator-font=2
bar-fill=─
bar-fill-font=2
bar-fill-foreground=#9f78e1
bar-empty=─
bar-empty-font=2
bar-empty-foreground=${colors.foreground-alt}
[module/backlight-acpi]
inherit=module/xbacklight
type=internal/backlight
card=intel_backlight
[module/cpu]
type=internal/cpu
interval=0.5
format=<label> <ramp-coreload>
label=CPU
ramp-font=2
ramp-coreload-0=▁
ramp-coreload-font=3
ramp-coreload-0-foreground=${colors.green}
ramp-coreload-1=▂
ramp-coreload-1-font=2
ramp-coreload-1-foreground=${colors.green}
ramp-coreload-2=▃
ramp-coreload-2-font=2
ramp-coreload-2-foreground=${colors.green}
ramp-coreload-3=▄
ramp-coreload-3-font=2
ramp-coreload-3-foreground=${colors.green}
ramp-coreload-4=▅
ramp-coreload-4-font=2
ramp-coreload-4-foreground=${colors.yellow}
ramp-coreload-5=▆
ramp-coreload-5-font=2
ramp-coreload-5-foreground=${colors.yellow}
ramp-coreload-6=▇
ramp-coreload-6-font=2
ramp-coreload-6-foreground=${colors.red}
ramp-coreload-7=█
ramp-coreload-7-font=2
ramp-coreload-7-foreground=${colors.red}
[module/memory]
type=internal/memory
format=<label> <bar-used>
label=MEM
bar-used-indicator=
bar-used-width=20
bar-used-foreground-0=${colors.green}
bar-used-foreground-1=${colors.yellow}
bar-used-foreground-2=${colors.red}
bar-used-fill=▐
bar-used-empty=▐
bar-used-empty-foreground=#444444
[module/wlan]
type=internal/network
interface=
interval=3.0
format-connected=<ramp-signal> <label-connected>
format-connected-underline=#9f78e1
label-connected=%essid%
format-disconnected=
;format-disconnected=<label-disconnected>
;format-disconnected-underline=${self.format-connected-underline}
;label-disconnected=%ifname% disconnected
;label-disconnected-foreground=${colors.foreground-alt}
ramp-signal-0=
ramp-signal-1=
ramp-signal-2=
ramp-signal-3=
ramp-signal-4=
ramp-signal-foreground=${colors.foreground-alt}
[module/eth]
type=internal/network
interface=
interval=3.0
format-connected-underline=#55aa55
format-connected-prefix=" "
format-connected-prefix-foreground=${colors.foreground-alt}
label-connected=%local_ip%
format-disconnected=
;format-disconnected=<label-disconnected>
;format-disconnected-underline=${self.format-connected-underline}
;label-disconnected=%ifname% disconnected
;label-disconnected-foreground=${colors.foreground-alt}
[module/date]
type=internal/date
interval=1
date=%a %d %b %Y%%{F-}
date-alt=%a %d %b %Y%%{F-}
time=%H:%M
time-alt=%H:%M:%S
format-prefix-foreground=${colors.foreground-alt}
label=%time% %date%
format=<label>
[module/pulseaudio]
type=internal/pulseaudio
format-volume=<label-volume> <bar-volume>
label-volume=
label-volume-foreground=${root.foreground}
format-muted-foreground=${colors.foreground-alt}
label-muted=sound muted
bar-volume-width=20
bar-volume-foreground-0=#55aa55
bar-volume-foreground-1=#55aa55
bar-volume-foreground-2=#55aa55
bar-volume-foreground-3=#55aa55
bar-volume-foreground-4=#55aa55
bar-volume-foreground-5=#f5a70a
bar-volume-foreground-6=#ff5555
bar-volume-gradient=false
bar-volume-indicator=▐
bar-volume-indicator-font=2
bar-volume-fill=─
bar-volume-fill-font=2
bar-volume-empty=─
bar-volume-empty-font=2
bar-volume-empty-foreground=${colors.foreground-alt}
[module/volume]
type=internal/alsa
format-volume=<label-volume> <bar-volume>
label-volume=
label-volume-foreground=${root.foreground}
format-muted-foreground=${colors.foreground-alt}
label-muted=sound muted
bar-volume-width=20
bar-volume-foreground-0=#55aa55
bar-volume-foreground-1=#55aa55
bar-volume-foreground-2=#55aa55
bar-volume-foreground-3=#55aa55
bar-volume-foreground-4=#55aa55
bar-volume-foreground-5=#f5a70a
bar-volume-foreground-6=#ff5555
bar-volume-gradient=false
bar-volume-indicator=▐
bar-volume-indicator-font=2
bar-volume-fill=─
bar-volume-fill-font=2
bar-volume-empty=─
bar-volume-empty-font=2
bar-volume-empty-foreground=${colors.foreground-alt}
[module/temperature]
type=internal/temperature
thermal-zone=0
warn-temperature=60
format=<ramp> <label>
format-underline=#f50a4d
format-warn=<ramp> <label-warn>
format-warn-underline=${self.format-underline}
label=%temperature%
label-warn=%temperature%
label-warn-foreground=${colors.secondary}
ramp-0=
ramp-1=
ramp-2=
ramp-foreground=${colors.foreground-alt}
[module/powermenu]
type=custom/menu
format-spacing=1
label-open=
label-open-foreground=${colors.secondary}
label-close= cancel
label-close-foreground=${colors.secondary}
label-separator=|
label-separator-foreground=${colors.foreground-alt}
menu-0-0=reboot
menu-0-0-exec=menu-open-1
menu-0-1=power off
menu-0-1-exec=menu-open-2
menu-1-0=cancel
menu-1-0-exec=menu-open-0
menu-1-1=reboot
menu-1-1-exec=sudo reboot
menu-2-0=power off
menu-2-0-exec=sudo poweroff
menu-2-1=cancel
menu-2-1-exec=menu-open-0
[module/gpu]
type=custom/script
exec=/bin/bash ~/.config/polybar/gpu.sh
interval=1
tail=false
format=GPU <label>
[module/spotify]
type=custom/script
exec=python3 ~/.config/polybar/spotify.py "{artist} - {title}"
interval=1
tail=false
format= <label>
; vim:ft=dosini
[module/battery1]
type=internal/battery
full-at=95
battery=BAT0
adapter=ADP1
time-format=%Hh:%Mm
label-charging=%time% full
format-charging=<label-charging>
label-full=Fully charged
format_full=<label-full>
label-discharging=%percentage%% %time% left
format-discharging=<ramp-capacity> <label-discharging>
ramp-capacity-0=
ramp-capacity-0-foreground=${colors.red}
ramp-capacity-1=
ramp-capacity-1-foreground=${colors.yellow}
ramp-capacity-2=
ramp-capacity-2-foreground=${colors.green}
ramp-capacity-3=
ramp-capacity-3-foreground=${colors.green}
ramp-capacity-4=
ramp-capacity-4-foreground=${colors.green}
animation-discharging-0=
[module/previous]
type=custom/script
interval=86400
format="%{T3}<label>"
format-padding=1
exec=echo ""
exec-if="pgrep spotify"
line-size=1
click-left="dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous"
[module/playpause]
type=custom/script
interval=86400
format="%{T3}<label>"
format-padding=1
exec=echo "/"
exec-if="pgrep spotify"
line-size=1
click-left="dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause"
[module/next]
type=custom/script
interval=86400
format="%{T3}<label>"
format-padding=1
exec=echo ""
exec-if="pgrep spotify"
line-size=1
click-left="dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next"
[module/unread_mail]
type = custom/script
exec = "/home/bauer/conda/bin/python3 /home/bauer/.config/polybar/UnseenMail/UnseenMail.py"
interval = 100
format = <label>
click-left = thunderbird &;
[module/notifyd]
type = custom/ipc
initial = 1
format-foreground = ${colors.yellow}
hook-0 = echo "%{xfconf-query -c xfce4-notifyd -p /do-not-disturb -s true}%{A}" &
hook-1 = echo "%{xfconf-query -c xfce4-notifyd -p /do-not-disturb -s false}%{A}" &

View File

@@ -1,7 +0,0 @@
wm-restack=i3
scroll-up=i3wm-wsnext
scroll-down=i3wm-wsprev
[global/wm]
margin-top=5
margin-bottom=5

View File

@@ -1,21 +0,0 @@
#!/bin/bash
t_warn=50
t_crit=70
GPU=$(nvidia-smi -q | grep Gpu | awk '{print $3}')
if [ $GPU -gt $t_crit ]
then
printf " %d%%" "$GPU"
printf "\n %d%%" "$GPU"
printf "\n#fb4934\n"
elif [ $GPU -gt $t_warn ]
then
printf " %d%%" "$GPU"
printf "\n %d%%" "$GPU"
printf "\n#fabd2f\n"
else
printf " %d%%" "$GPU"
printf "\n %d%%" "$GPU"
fi

View File

@@ -1,29 +0,0 @@
#!/usr/bin/python2
import dbus
from sys import argv
if len(argv) > 1:
fmt = argv[1]
else:
fmt = None
def format_output(artist, title, fmt=None):
if fmt is None:
fmt = "{artist} - {title}"
return fmt.format(artist=artist, title=title)
try:
bus = dbus.SessionBus()
spotify = bus.get_object("org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2")
spotify_iface = dbus.Interface(spotify, 'org.freedesktop.DBus.Properties')
props = spotify_iface.Get('org.mpris.MediaPlayer2.Player', 'Metadata')
try:
out = format_output((props['xesam:artist'][0]), str(props['xesam:title']), fmt)
except IndexError:
out = ''
print(out)
exit
except dbus.exceptions.DBusException:
exit

View File

@@ -1,3 +0,0 @@
#!/usr/bin/env sh
/usr/bin/env python3 ~/scripts/spotify/py_spotify_listener.py

View File

@@ -1,125 +0,0 @@
#!/usr/bin/env python3
# Unwrap function: (C)2011-2015 Dennis Kaarsemaker
# License: GPL3+
"""Receiver related functionality."""
import dbus.service
import dbus.glib
from gi.repository import GObject
import dbus
class Test(dbus.service.Object):
"""Reciever test class."""
loop = None
def __init__(self, bus_name, object_path, loop):
"""Initialize the DBUS service object."""
dbus.service.Object.__init__(self, bus_name, object_path)
self.loop = loop
@dbus.service.method('tld.domain.sub.TestInterface')
def foo(self):
"""Return a string."""
return 'Foo'
# Stop the main loop
@dbus.service.method('tld.domain.sub.TestInterface')
def stop(self):
"""Stop the receiver."""
self.loop.quit()
return 'Quit loop'
# Pass an exception through dbus
@dbus.service.method('tld.domain.sub.TestInterface')
def fail(self):
"""Trigger an exception."""
raise Exception('FAIL!')
def catchall_handler(*args, **kwargs):
"""Catch all handler.
Catch and print information about all singals.
"""
print('---- Caught signal ----')
print('%s:%s\n' % (kwargs['dbus_interface'], kwargs['member']))
print("\n")
def quit_handler():
"""Signal handler for quitting the receiver."""
print('Quitting....')
loop.quit()
def event_handler(*args, **kwargs):
"""event handler for the receiver."""
"""arg[1] contains metadata"""
"""arg[1][1] contains PlaybackStatus"""
data = unwrap(args)
if data[1]['PlaybackStatus'] == "Playing":
print("Music is playing")
""" Send IPC hook 2 to the bottom bar pid for module playpause """
with open("/tmp/ipc-bottom", "w") as text_file:
print("hook:module/playpause2", file=text_file)
if data[1]['PlaybackStatus'] == "Paused":
print("Music is paused.")
""" Send IPC hook 3 to the bottom bar pid for module playpause """
with open("/tmp/ipc-bottom", "w") as text_file:
print("hook:module/playpause3", file=text_file)
""" Send IPC hook 2 to the bottom bar pid for module spotify """
with open("/tmp/ipc-bottom", "w") as text_file:
print("hook:module/spotify2", file=text_file)
def unwrap(val):
if isinstance(val, dbus.ByteArray):
return "".join([str(x) for x in val])
if isinstance(val, (dbus.Array, list, tuple)):
return [unwrap(x) for x in val]
if isinstance(val, (dbus.Dictionary, dict)):
return dict([(unwrap(x), unwrap(y)) for x, y in val.items()])
if isinstance(val, (dbus.Signature, dbus.String)):
return str(val)
if isinstance(val, dbus.Boolean):
return bool(val)
if isinstance(val, (dbus.Int16, dbus.UInt16, dbus.Int32, dbus.UInt32, dbus.Int64, dbus.UInt64)):
return int(val)
if isinstance(val, dbus.Byte):
return bytes([int(val)])
return val
loop = GObject.MainLoop()
"""
First we get the bus to attach to. This may be either the session bus, of the
system bus. For system bus root permission is required.
We claim a bus name on the chosen bus. The name should be in form of a
domain name.
"""
bus = dbus.SessionBus()
# bus = dbus.SystemBus()
bus_name = dbus.service.BusName('sub.domain.tld', bus=bus)
"""
We initialize our service object with our name and object path. Object
path should be in form of a reverse domain dame, delimited by / instead of .
and the Class name as last part.
The object path we set here is of importance for our invoker, since it will to
call it exactly as defined here.
"""
obj = Test(bus_name, '/tld/domain/sub/Test', loop)
"""
Attach signal handler.
Signal handlers may be attached in different ways, either by interface keyword
or DBUS interface and a signal name or member keyword.
You can easily gather all information by running the DBUS monitor.
"""
bus.add_signal_receiver(quit_handler,
dbus_interface='tld.domain.sub.event',
signal_name='quit_signal')
bus.add_signal_receiver(event_handler,
dbus_interface='org.freedesktop.DBus.Properties',
member_keyword='PropertiesChanged')
loop.run()

View File

@@ -1,67 +0,0 @@
#!/usr/bin/env python3
import sys
import dbus
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
'-t',
'--trunclen',
type=int,
metavar='trunclen'
)
parser.add_argument(
'-f',
'--format',
type=str,
metavar='custom format',
dest='custom_format'
)
args = parser.parse_args()
# Default parameters
output = '{artist}: {song}'
trunclen = 25
# parameters can be overwritten by args
if args.trunclen is not None:
trunclen = args.trunclen
if args.custom_format is not None:
output = args.custom_format
try:
session_bus = dbus.SessionBus()
spotify_bus = session_bus.get_object(
'org.mpris.MediaPlayer2.spotify',
'/org/mpris/MediaPlayer2'
)
spotify_properties = dbus.Interface(
spotify_bus,
'org.freedesktop.DBus.Properties'
)
metadata = spotify_properties.Get('org.mpris.MediaPlayer2.Player', 'Metadata')
artist = metadata['xesam:artist'][0]
song = metadata['xesam:title']
if len(song) > trunclen:
song = song[0:trunclen]
song += '...'
if ('(' in song) and (')' not in song):
song += ')'
# Python3 uses UTF-8 by default.
if sys.version_info.major == 3:
print(output.format(artist=artist, song=song))
else:
print(output.format(artist=artist, song=song).encode('UTF-8'))
except Exception as e:
if isinstance(e, dbus.exceptions.DBusException):
print('')
else:
print(e)

View File

@@ -1,7 +0,0 @@
configuration {
modi: "window,drun,ssh,combi";
theme: "slate";
font: "hack 10";
show-icons: true;
combi-modi: "window,drun,ssh";
}

View File

@@ -1,43 +0,0 @@
* {
background-color: #222;
border-color: #2e343f;
text-color: #8ca0aa;
spacing: 3;
}
inputbar {
border: 0 0 1px 0;
children: [prompt,entry];
}
prompt {
padding: 16px;
border: 0 1px 0 0;
}
textbox {
background-color: #2e343f;
border: 0 0 1px 0;
border-color: #282C33;
padding: 8px 16px;
}
entry {
padding: 16px;
}
listview {
cycle: false;
margin: 0 0 -1px 0;
scrollbar: false;
}
element {
border: 0 0 1px 0;
padding: 16px;
}
element selected {
background-color: #689d6a;
text-color: #222;
}

View File

@@ -1 +0,0 @@
/home/bauer/dotfiles/.pymol

View File

@@ -1,8 +0,0 @@
INCREMENT PYMOL_MAIN SCHROD 999 01-may-2019 uncounted HOSTID=ANY \
ISSUED=01-Sep-2018 NOTICE="PyMOL for educational use only" \
START=01-Oct-2018 TS_OK SIGN="12F2 36C7 3B45 39DF 18BE 27F4 \
3043 09ED F843 D2B0 442F 4433 0630 2AF5 F31B 07D5 2E50 A361 \
156E BE21 288B A8F9 F975 1C1A 92E5 441F 9521 F8EF 140B 1997" \
SIGN2="0E48 A34C FD12 8A53 0CA8 EABC 2671 1CA5 A621 EBB8 C6B6 \
AC3C BB33 EA41 97FC 1445 B6EC 20BF 1EE1 7B08 68F8 9DB9 187A \
6F06 9124 4BAD BF40 86C1 9E29 F44E"

View File

@@ -1,362 +0,0 @@
'''
Calculate and display the dimensions of a protein.
This is a first version, please use at your own risk!
REQUIREMENTS
numpy (http://numpy.scipy.org) that should be built into the newers versions of Pymol
(c) Pablo Guardado Calvo
Based on "inertia_tensor.py" (c) 2010 by Mateusz Maciejewski
License: MIT
'''
from __future__ import print_function
__author__ = 'Pablo Guardado Calvo'
__version__ = '0.1'
__email__ = 'pablo.guardado (at) gmail.com'
__date__ = '13/08/2015'
###########################################################################################################################################################
# USAGE
#
# The idea behing this script is to calculate an aproximate minimal bounding box to extract the cell dimensions of a protein. To calculate the minimal bounding
# is not trivial and usually the Axis Aligned Bounding Box (AABB) does not show up the real dimensions of the protein. This script calculates the inertia tensor
# of the object, extract the eigenvalues and use them to rotate the molecule (using as rotation matrix the transpose of the eigenvalues matrix). The result is that
# the molecule is oriented with the inertia axis aligned with the cartesian axis. A new Bounding Box is calculated that is called Inertia Axis Aligned Bounding Box
#(IABB), whose volume is always lower than AABB volume, and in many cases will correspond with the lowest volume. Of course, maybe it exists another Bounding Box
# with a lower volume (the minimal Bounding Box).
#
# As always with these type of things, you have to use at your own risk. I did not try all the possible combinations, but if you find a bug, do
# not hesitate to contact me (pablo.guardado (at) gmail.com) or try to modify the code for yourself to correct it.
#
# To load the script just type:
#
# run path-to-the-script/Draw_Protein_Dimensions.py
#
# or if you want something more permanent add the previous line to your .pymolrc file
#
# The script works just typing:
#
# draw_Protein_Dimensions selection
#
# This will draw the cell dimensions of your selection based on a IABB. It also generates the IABB box and the inertia axis, you just need to do "show cgo" to display them.
#
# You could also try:
#
# draw_BB selection
#
# This will draw the AABB and IABB boxes with their cell dimensions and show in the command line their volumes, you can compare both of them.
############################################################################################################################################################
from pymol import cmd, cgo
from pymol.cgo import *
import numpy
from random import randint
def matriz_inercia(selection):
'''
DESCRIPTION
The method calculates the mass center, the inertia tensor and the eigenvalues and eigenvectors
for a given selection. Mostly taken from inertia_tensor.py
'''
model = cmd.get_model(selection)
totmass = 0.0
x,y,z = 0,0,0
for a in model.atom:
m = a.get_mass()
x += a.coord[0]*m
y += a.coord[1]*m
z += a.coord[2]*m
totmass += m
global cM
cM = numpy.array([x/totmass, y/totmass, z/totmass])
I = []
for index in range(9):
I.append(0)
for a in model.atom:
temp_x, temp_y, temp_z = a.coord[0], a.coord[1], a.coord[2]
temp_x -= x
temp_y -= y
temp_z -= z
I[0] += a.get_mass() * (temp_y**2 + temp_z**2)
I[1] -= a.get_mass() * temp_x * temp_y
I[2] -= a.get_mass() * temp_x * temp_z
I[3] -= a.get_mass() * temp_x * temp_y
I[4] += a.get_mass() * (temp_x**2 + temp_z**2)
I[5] -= a.get_mass() * temp_y * temp_z
I[6] -= a.get_mass() * temp_x * temp_z
I[7] -= a.get_mass() * temp_y * temp_z
I[8] += a.get_mass() * (temp_x**2 + temp_y**2)
global tensor
tensor = numpy.array([(I[0:3]), (I[3:6]), (I[6:9])])
global autoval, autovect, ord_autoval, ord_autovect
autoval, autovect = numpy.linalg.eig(tensor)
auto_ord = numpy.argsort(autoval)
ord_autoval = autoval[auto_ord]
ord_autovect_complete = autovect[:, auto_ord].T
ord_autovect = numpy.around(ord_autovect_complete, 3)
return ord_autoval
def draw_inertia_axis(selection):
'''
DESCRIPTION
This method draw the inertia axis calculated with the method matriz_inercia.
'''
matriz_inercia(selection)
axis1 = ord_autovect[0]
x1, y1, z1 = cM[0], cM[1], cM[2]
x2, y2, z2 = cM[0]+50*axis1[0], cM[1]+50*axis1[1], cM[2]+50*axis1[2]
eje1 = [cgo.CYLINDER, x1, y1, z1, x2, y2, z2, 0.6, 1, 0, 0, 1, 0, 0, 0.0]
cmd.load_cgo(eje1, 'Inertia_Axis1')
axis2 = ord_autovect[1]
x3, y3, z3 = cM[0]+40*axis2[0], cM[1]+40*axis2[1], cM[2]+40*axis2[2]
eje1 = [cgo.CYLINDER, x1, y1, z1, x3, y3, z3, 0.6, 1, 0.5, 0, 1, 0.5, 0, 0.0]
cmd.load_cgo(eje1, 'Inertia_Axis2')
axis4 = ord_autovect[2]
x4, y4, z4 = cM[0]+30*axis4[0], cM[1]+30*axis4[1], cM[2]+30*axis4[2]
eje1 = [cgo.CYLINDER, x1, y1, z1, x4, y4, z4, 0.6, 1, 1, 0, 1, 1, 0, 0.0]
cmd.load_cgo(eje1, 'Inertia_Axis3')
def translacion_cM(selection):
'''
DESCRIPTION
Translate the center of mass of the molecule to the origin.
'''
model = cmd.get_model(selection)
totmass = 0.0
x,y,z = 0,0,0
for a in model.atom:
m = a.get_mass()
x += a.coord[0]*m
y += a.coord[1]*m
z += a.coord[2]*m
totmass += m
cM = numpy.array([x/totmass, y/totmass, z/totmass])
trans_array = ([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -cM[0], -cM[1], -cM[2], 1])
model_trans = cmd.transform_selection(selection, trans_array)
def rotacion_orig(selection):
'''
DESCRIPTION
Find the proper rotation matrix, i.e. the transpose of the matrix formed by the eigenvectors of the inertia tensor
'''
translacion_cM(selection)
matriz_inercia(selection)
global transf, transf_array, ord_autovect_array, transf_array_print
ord_autovect_array = numpy.array([[ord_autovect[0][0], ord_autovect[0][1], ord_autovect[0][2]],
[ord_autovect[1][0], ord_autovect[1][1], ord_autovect[1][2]],
[ord_autovect[2][0], ord_autovect[2][1], ord_autovect[2][2]]])
if numpy.linalg.det(ord_autovect_array) == -1:
ord_autovect_array = numpy.array([[ord_autovect[2][0], ord_autovect[2][1], ord_autovect[2][2]],
[ord_autovect[1][0], ord_autovect[1][1], ord_autovect[1][2]],
[ord_autovect[0][0], ord_autovect[0][1], ord_autovect[0][2]]])
transf = numpy.transpose(ord_autovect_array)
transf_array = numpy.array([transf[0][0], transf[0][1], transf[0][2], 0,
transf[1][0], transf[1][1], transf[1][2], 0,
transf[2][0], transf[2][1], transf[2][2], 0,
0, 0, 0, 1])
def transformar(selection):
'''
DESCRIPTION
Rotate the molecule and draw the inertia axis.
'''
rotacion_orig(selection)
model_rot = cmd.transform_selection(selection, transf_array, homogenous=0, transpose=1);
draw_inertia_axis(selection)
def draw_AABB(selection):
"""
DESCRIPTION
For a given selection, draw the Axes Aligned bounding box around it without padding. Code taken and modified from DrawBoundingBox.py.
"""
AA_original = selection + "_original"
model_orig = cmd.create(AA_original, selection)
([min_X, min_Y, min_Z],[max_X, max_Y, max_Z]) = cmd.get_extent(AA_original)
print("The Axis Aligned Bounding Box (AABB) dimensions are (%.2f, %.2f, %.2f)" % (max_X-min_X, max_Y-min_Y, max_Z-min_Z))
print("The Axis Aligned Bounding Box (AABB) volume is %.2f A3" % ((max_X-min_X)*(max_Y-min_Y)*(max_Z-min_Z)))
min_X = min_X
min_Y = min_Y
min_Z = min_Z
max_X = max_X
max_Y = max_Y
max_Z = max_Z
boundingBox = [
LINEWIDTH, float(2),
BEGIN, LINES,
COLOR, float(1), float(1), float(0),
VERTEX, min_X, min_Y, min_Z,
VERTEX, min_X, min_Y, max_Z,
VERTEX, min_X, max_Y, min_Z,
VERTEX, min_X, max_Y, max_Z,
VERTEX, max_X, min_Y, min_Z,
VERTEX, max_X, min_Y, max_Z,
VERTEX, max_X, max_Y, min_Z,
VERTEX, max_X, max_Y, max_Z,
VERTEX, min_X, min_Y, min_Z,
VERTEX, max_X, min_Y, min_Z,
VERTEX, min_X, max_Y, min_Z,
VERTEX, max_X, max_Y, min_Z,
VERTEX, min_X, max_Y, max_Z,
VERTEX, max_X, max_Y, max_Z,
VERTEX, min_X, min_Y, max_Z,
VERTEX, max_X, min_Y, max_Z,
VERTEX, min_X, min_Y, min_Z,
VERTEX, min_X, max_Y, min_Z,
VERTEX, max_X, min_Y, min_Z,
VERTEX, max_X, max_Y, min_Z,
VERTEX, min_X, min_Y, max_Z,
VERTEX, min_X, max_Y, max_Z,
VERTEX, max_X, min_Y, max_Z,
VERTEX, max_X, max_Y, max_Z,
END
]
p0 = '_0' + str(randint(0, 100))
p1 = '_1' + str(randint(0, 100))
p2 = '_2' + str(randint(0, 100))
p3 = '_3' + str(randint(0, 100))
cmd.pseudoatom (pos=[min_X, min_Y, min_Z], object=p0)
cmd.pseudoatom (pos=[min_X, min_Y, max_Z], object=p1)
cmd.pseudoatom (pos=[min_X, max_Y, min_Z], object=p2)
cmd.pseudoatom (pos=[max_X, min_Y, min_Z], object=p3)
cmd.distance(None, p0, p3)
cmd.distance(None, p0, p2)
cmd.distance(None, p0, p1)
cmd.hide("nonbonded")
boxName = "box_AABB_" + str(randint(0, 100))
cmd.load_cgo(boundingBox,boxName)
return boxName
def draw_IABB(selection):
"""
DESCRIPTION
For a given selection, draw the Inertia Axes Aligned bounding box around it without padding. Code taken and modified from DrawBoundingBox.py.
"""
transformar(selection)
([minX, minY, minZ],[maxX, maxY, maxZ]) = cmd.get_extent(selection)
print("The Inertia Axis Aligned Bounding Box (IABB) dimensions are (%.2f, %.2f, %.2f)" % (maxX-minX, maxY-minY, maxZ-minZ))
print("The Inertia Axis Aligned Bounding Box (IABB) volume is %.2f A3" % ((maxX-minX)*(maxY-minY)*(maxZ-minZ)))
minX = minX
minY = minY
minZ = minZ
maxX = maxX
maxY = maxY
maxZ = maxZ
boundingBox = [
LINEWIDTH, float(2),
BEGIN, LINES,
COLOR, float(1), float(0), float(0),
VERTEX, minX, minY, minZ,
VERTEX, minX, minY, maxZ,
VERTEX, minX, maxY, minZ,
VERTEX, minX, maxY, maxZ,
VERTEX, maxX, minY, minZ,
VERTEX, maxX, minY, maxZ,
VERTEX, maxX, maxY, minZ,
VERTEX, maxX, maxY, maxZ,
VERTEX, minX, minY, minZ,
VERTEX, maxX, minY, minZ,
VERTEX, minX, maxY, minZ,
VERTEX, maxX, maxY, minZ,
VERTEX, minX, maxY, maxZ,
VERTEX, maxX, maxY, maxZ,
VERTEX, minX, minY, maxZ,
VERTEX, maxX, minY, maxZ,
VERTEX, minX, minY, minZ,
VERTEX, minX, maxY, minZ,
VERTEX, maxX, minY, minZ,
VERTEX, maxX, maxY, minZ,
VERTEX, minX, minY, maxZ,
VERTEX, minX, maxY, maxZ,
VERTEX, maxX, minY, maxZ,
VERTEX, maxX, maxY, maxZ,
END
]
p4 = '_4' + str(randint(0, 100))
p5 = '_5' + str(randint(0, 100))
p6 = '_6' + str(randint(0, 100))
p7 = '_7' + str(randint(0, 100))
cmd.pseudoatom (pos=[minX, minY, minZ], object=p4)
cmd.pseudoatom (pos=[minX, minY, maxZ], object=p5)
cmd.pseudoatom (pos=[minX, maxY, minZ], object=p6)
cmd.pseudoatom (pos=[maxX, minY, minZ], object=p7)
cmd.distance(None, p4, p7)
cmd.distance(None, p4, p6)
cmd.distance(None, p4, p5)
cmd.hide("nonbonded")
boxName = "box_IABB_" + str(randint(0, 100))
cmd.load_cgo(boundingBox,boxName)
return boxName
def draw_BB(selection):
draw_AABB(selection)
draw_IABB(selection)
def draw_Protein_Dimensions(selection):
draw_IABB(selection)
cmd.hide("cgo")
cmd.extend ("draw_Protein_Dimensions", draw_Protein_Dimensions)
cmd.extend ("draw_BB", draw_BB)

View File

@@ -1,316 +0,0 @@
'''
(c) 2010 Thomas Holder
'''
from pymol import cmd, stored, CmdException
from chempy import cpv
import math
if cmd.get_version()[1] < 1.2:
def get_unused_name(name):
import random
return name + '%04d' % random.randint(0, 1000)
STATE = 1
else:
from pymol.cmd import get_unused_name
STATE = -1
def _vec_sum(vec_list):
# this is the same as
# return numpy.array(vec_list).sum(0).tolist()
vec = cpv.get_null()
for x in vec_list:
vec = cpv.add(vec, x)
return vec
def _mean_and_std(x):
# this is the same as
# return (numpy.mean(x), numpy.std(x, ddof=1))
N = len(x)
if N < 2:
return (x[0], 0.0)
mu = sum(x) / float(N)
var = sum([(i - mu) ** 2 for i in x]) / float(N - 1)
return (mu, var ** 0.5)
def _common_orientation(selection, vec, visualize=1, quiet=0):
'''
Common part of different helix orientation functions. Does calculate
the center of mass and does the visual feedback.
'''
stored.x = []
cmd.iterate_state(STATE, '(%s) and name CA' % (selection),
'stored.x.append([x,y,z])')
if len(stored.x) < 2:
print('warning: count(CA) < 2')
raise CmdException
center = cpv.scale(_vec_sum(stored.x), 1. / len(stored.x))
if visualize:
scale = cpv.distance(stored.x[0], stored.x[-1])
visualize_orientation(vec, center, scale, True)
cmd.zoom(selection, buffer=2)
if not quiet:
print('Center: (%.2f, %.2f, %.2f) Direction: (%.2f, %.2f, %.2f)' % tuple(center + vec))
return center, vec
def visualize_orientation(direction, center=[0, 0, 0], scale=1.0, symmetric=False, color='green', color2='red'):
'''
Draw an arrow. Helper function for "helix_orientation" etc.
'''
from pymol import cgo
color_list = cmd.get_color_tuple(color)
color2_list = cmd.get_color_tuple(color2)
if symmetric:
scale *= 0.5
end = cpv.add(center, cpv.scale(direction, scale))
radius = 0.3
obj = [cgo.SAUSAGE]
obj.extend(center)
obj.extend(end)
obj.extend([
radius,
0.8, 0.8, 0.8,
])
obj.extend(color_list)
if symmetric:
start = cpv.sub(center, cpv.scale(direction, scale))
obj.append(cgo.SAUSAGE)
obj.extend(center)
obj.extend(start)
obj.extend([
radius,
0.8, 0.8, 0.8,
])
obj.extend(color2_list)
coneend = cpv.add(end, cpv.scale(direction, 4.0 * radius))
if cmd.get_version()[1] >= 1.2:
obj.append(cgo.CONE)
obj.extend(end)
obj.extend(coneend)
obj.extend([
radius * 1.75,
0.0,
])
obj.extend(color_list * 2)
obj.extend([
1.0, 1.0, # Caps
])
cmd.load_cgo(obj, get_unused_name('oriVec'), zoom=0)
def cafit_orientation(selection, visualize=1, quiet=0):
'''
DESCRIPTION
Get the center and direction of a peptide by least squares
linear fit on CA atoms.
USAGE
cafit_orientation selection [, visualize]
NOTES
Requires python module "numpy".
SEE ALSO
helix_orientation
'''
visualize, quiet = int(visualize), int(quiet)
import numpy
stored.x = list()
cmd.iterate_state(STATE, '(%s) and name CA' % (selection),
'stored.x.append([x,y,z])')
x = numpy.array(stored.x)
U, s, Vh = numpy.linalg.svd(x - x.mean(0))
vec = cpv.normalize(Vh[0])
if cpv.dot_product(vec, x[-1] - x[0]) < 0:
vec = cpv.negate(vec)
return _common_orientation(selection, vec, visualize, quiet)
def loop_orientation(selection, visualize=1, quiet=0):
'''
DESCRIPTION
Get the center and approximate direction of a peptide. Works for any
secondary structure.
Averages direction of N(i)->C(i) pseudo bonds.
USAGE
loop_orientation selection [, visualize]
SEE ALSO
helix_orientation
'''
visualize, quiet = int(visualize), int(quiet)
stored.x = dict()
cmd.iterate_state(STATE, '(%s) and name N+C' % (selection),
'stored.x.setdefault(chain + resi, dict())[name] = x,y,z')
vec = cpv.get_null()
count = 0
for x in stored.x.values():
if 'C' in x and 'N' in x:
vec = cpv.add(vec, cpv.sub(x['C'], x['N']))
count += 1
if count == 0:
print('warning: count == 0')
raise CmdException
vec = cpv.normalize(vec)
return _common_orientation(selection, vec, visualize, quiet)
def helix_orientation(selection, visualize=1, sigma_cutoff=1.5, quiet=0):
'''
DESCRIPTION
Get the center and direction of a helix as vectors. Will only work
for helices and gives slightly different results than loop_orientation.
Averages direction of C(i)->O(i) bonds.
USAGE
helix_orientation selection [, visualize [, sigma_cutoff]]
ARGUMENTS
selection = string: atom selection of helix
visualize = 0 or 1: show fitted vector as arrow {default: 1}
sigma_cutoff = float: drop outliers outside
(standard_deviation * sigma_cutoff) {default: 1.5}
SEE ALSO
angle_between_helices, helix_orientation_hbond, loop_orientation, cafit_orientation
'''
visualize, quiet, sigma_cutoff = int(visualize), int(quiet), float(sigma_cutoff)
stored.x = dict()
cmd.iterate_state(STATE, '(%s) and name C+O' % (selection),
'stored.x.setdefault(chain + resi, dict())[name] = x,y,z')
vec_list = []
count = 0
for x in stored.x.values():
if 'C' in x and 'O' in x:
vec_list.append(cpv.sub(x['O'], x['C']))
count += 1
if count == 0:
print('warning: count == 0')
raise CmdException
vec = _vec_sum(vec_list)
if count > 2 and sigma_cutoff > 0:
angle_list = [cpv.get_angle(vec, x) for x in vec_list]
angle_mu, angle_sigma = _mean_and_std(angle_list)
vec_list = [vec_list[i] for i in range(len(vec_list))
if abs(angle_list[i] - angle_mu) < angle_sigma * sigma_cutoff]
if not quiet:
print('Dropping %d outlier(s)' % (len(angle_list) - len(vec_list)))
vec = _vec_sum(vec_list)
vec = cpv.normalize(vec)
return _common_orientation(selection, vec, visualize, quiet)
def helix_orientation_hbond(selection, visualize=1, cutoff=3.5, quiet=0):
'''
DESCRIPTION
Get the center and direction of a helix as vectors. Will only work
for alpha helices and gives slightly different results than
helix_orientation. Averages direction of O(i)->N(i+4) hydrogen bonds.
USAGE
helix_orientation selection [, visualize [, cutoff]]
ARGUMENTS
cutoff = float: maximal hydrogen bond distance {default: 3.5}
SEE ALSO
helix_orientation
'''
visualize, quiet, cutoff = int(visualize), int(quiet), float(cutoff)
stored.x = dict()
cmd.iterate_state(STATE, '(%s) and name N+O' % (selection),
'stored.x.setdefault(resv, dict())[name] = x,y,z')
vec_list = []
for resi in stored.x:
resi_other = resi + 4
if 'O' in stored.x[resi] and resi_other in stored.x:
if 'N' in stored.x[resi_other]:
vec = cpv.sub(stored.x[resi_other]['N'], stored.x[resi]['O'])
if cpv.length(vec) < cutoff:
vec_list.append(vec)
if len(vec_list) == 0:
print('warning: count == 0')
raise CmdException
vec = _vec_sum(vec_list)
vec = cpv.normalize(vec)
return _common_orientation(selection, vec, visualize, quiet)
def angle_between_helices(selection1, selection2, method='helix_orientation', visualize=1, quiet=0):
'''
DESCRIPTION
Calculates the angle between two helices
USAGE
angle_between_helices selection1, selection2 [, method [, visualize]]
ARGUMENTS
selection1 = string: atom selection of first helix
selection2 = string: atom selection of second helix
method = string: function to calculate orientation {default: helix_orientation}
or int: 0: helix_orientation, 1: helix_orientation_hbond,
2: loop_orientation, 3: cafit_orientation
visualize = 0 or 1: show fitted vector as arrow {default: 1}
SEE ALSO
helix_orientation, helix_orientation_hbond, loop_orientation, cafit_orientation
'''
visualize, quiet = int(visualize), int(quiet)
methods = {
'0': helix_orientation,
'1': helix_orientation_hbond,
'2': loop_orientation,
'3': cafit_orientation,
}
methods.update([(x.__name__, x) for x in list(methods.values())])
try:
orientation = methods[str(method)]
except KeyError:
print('no such method: ' + str(method))
raise CmdException
if not quiet:
print('Using method: ' + orientation.__name__)
cen1, dir1 = orientation(selection1, visualize, quiet=1)
cen2, dir2 = orientation(selection2, visualize, quiet=1)
angle = cpv.get_angle(dir1, dir2)
angle_deg = math.degrees(angle)
if not quiet:
print('Angle: %.2f deg' % (angle_deg))
if visualize:
cmd.zoom('(%s) or (%s)' % (selection1, selection2), buffer=2)
return angle_deg
cmd.extend('helix_orientation', helix_orientation)
cmd.extend('helix_orientation_hbond', helix_orientation_hbond)
cmd.extend('loop_orientation', loop_orientation)
cmd.extend('cafit_orientation', cafit_orientation)
cmd.extend('angle_between_helices', angle_between_helices)

File diff suppressed because it is too large Load Diff

View File

@@ -1,68 +0,0 @@
from pymol import cmd
from chempy import cpv
class PutCenterCallback(object):
prev_v = None
def __init__(self, name, corner=0):
self.name = name
self.corner = corner
self.cb_name = cmd.get_unused_name('_cb')
def load(self):
cmd.load_callback(self, self.cb_name)
def __call__(self):
if self.name not in cmd.get_names('objects'):
import threading
threading.Thread(None, cmd.delete, args=(self.cb_name,)).start()
return
v = cmd.get_view()
if v == self.prev_v:
return
self.prev_v = v
t = v[12:15]
if self.corner:
vp = cmd.get_viewport()
R_mc = [v[0:3], v[3:6], v[6:9]]
off_c = [0.15 * v[11] * vp[0] / vp[1], 0.15 * v[11], 0.0]
if self.corner in [2,3]:
off_c[0] *= -1
if self.corner in [3,4]:
off_c[1] *= -1
off_m = cpv.transform(R_mc, off_c)
t = cpv.add(t, off_m)
z = -v[11] / 30.0
m = [z, 0, 0, 0, 0, z, 0, 0, 0, 0, z, 0, t[0] / z, t[1] / z, t[2] / z, 1]
cmd.set_object_ttt(self.name, m)
def axes(name='axes'):
'''
DESCRIPTION
Puts coordinate axes to the lower left corner of the viewport.
'''
from pymol import cgo
cmd.set('auto_zoom', 0)
w = 0.06 # cylinder width
l = 0.75 # cylinder length
h = 0.25 # cone hight
d = w * 1.618 # cone base diameter
obj = [cgo.CYLINDER, 0.0, 0.0, 0.0, l, 0.0, 0.0, w, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
cgo.CYLINDER, 0.0, 0.0, 0.0, 0.0, l, 0.0, w, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
cgo.CYLINDER, 0.0, 0.0, 0.0, 0.0, 0.0, l, w, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
cgo.CONE, l, 0.0, 0.0, h+l, 0.0, 0.0, d, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
cgo.CONE, 0.0, l, 0.0, 0.0, h+l, 0.0, d, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
cgo.CONE, 0.0, 0.0, l, 0.0, 0.0, h+l, d, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0]
PutCenterCallback(name, 1).load()
cmd.load_cgo(obj, name)
cmd.extend('axes', axes)

View File

@@ -1,86 +0,0 @@
'''
See more here: http://www.pymolwiki.org/index.php/center_of_mass
DESCRIPTION
Places a pseudoatom at the center of mass
Author: Sean Law
Michigan State University
slaw (at) msu . edu
SEE ALSO
pseudoatom, get_com
'''
from __future__ import print_function
from pymol import cmd
def com(selection, state=None, mass=None, object=None, quiet=1, **kwargs):
quiet = int(quiet)
if (object == None):
try:
object = cmd.get_legal_name(selection)
object = cmd.get_unused_name(object + "_COM", 0)
except AttributeError:
object = 'COM'
cmd.delete(object)
if (state != None):
x, y, z = get_com(selection, mass=mass, quiet=quiet)
if not quiet:
print("%f %f %f" % (x, y, z))
cmd.pseudoatom(object, pos=[x, y, z], **kwargs)
cmd.show("spheres", object)
else:
for i in range(cmd.count_states()):
x, y, z = get_com(selection, mass=mass, state=i + 1, quiet=quiet)
if not quiet:
print("State %d:%f %f %f" % (i + 1, x, y, z))
cmd.pseudoatom(object, pos=[x, y, z], state=i + 1, **kwargs)
cmd.show("spheres", 'last ' + object)
cmd.extend("com", com)
def get_com(selection, state=1, mass=None, quiet=1):
"""
DESCRIPTION
Calculates the center of mass
Author: Sean Law
Michigan State University
slaw (at) msu . edu
"""
quiet = int(quiet)
totmass = 0.0
if mass != None and not quiet:
print("Calculating mass-weighted COM")
state = int(state)
model = cmd.get_model(selection, state)
x, y, z = 0, 0, 0
for a in model.atom:
if (mass != None):
m = a.get_mass()
x += a.coord[0] * m
y += a.coord[1] * m
z += a.coord[2] * m
totmass += m
else:
x += a.coord[0]
y += a.coord[1]
z += a.coord[2]
if (mass != None):
return x / totmass, y / totmass, z / totmass
else:
return x / len(model.atom), y / len(model.atom), z / len(model.atom)
cmd.extend("get_com", get_com)
# vi:expandtab:sw=3

View File

@@ -1,66 +0,0 @@
'''
See more here: http://www.pymolwiki.org/index.php/centroid
DESCRIPTION
get the centroid (geometric center) of a selection or move selection to the origin.
ARGUMENTS
selection = string: a valid PyMOL selection {default: all}
center = 0 or 1: if center=1 center the selection {default: 0}
returns: centroid: [ x, y, z ]
SEE ALSO
get_extent, get_position, http://pymolwiki.org/index.php/Center_Of_Mass
# @AUTHOR: Jason Vertrees
# Copyright (c) 2008, Jason Vertrees
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
# conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
# * disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
# * disclaimer in the documentation and/or other materials provided with the distribution.
# * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived
# * from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# DATE : 2008-09-26
# REV : 1
'''
from __future__ import print_function
from pymol import cmd
from pymol import stored
from chempy import cpv
def centroid(selection='all', center=0, quiet=1):
model = cmd.get_model(selection)
nAtom = len(model.atom)
centroid = cpv.get_null()
for a in model.atom:
centroid = cpv.add(centroid, a.coord)
centroid = cpv.scale(centroid, 1. / nAtom)
if not int(quiet):
print(' centroid: [%8.3f,%8.3f,%8.3f]' % tuple(centroid))
if int(center):
cmd.alter_state(1, selection, "(x,y,z)=sub((x,y,z), centroid)",
space={'centroid': centroid, 'sub': cpv.sub})
return centroid
cmd.extend("centroid", centroid)

View File

@@ -1,128 +0,0 @@
# color_h
# -------
# PyMOL command to color protein molecules according to the Eisenberg hydrophobicity scale
#
# Source: http://us.expasy.org/tools/pscale/Hphob.Eisenberg.html
# Amino acid scale: Normalized consensus hydrophobicity scale
# Author(s): Eisenberg D., Schwarz E., Komarony M., Wall R.
# Reference: J. Mol. Biol. 179:125-142 (1984)
#
# Amino acid scale values:
#
# Ala: 0.620
# Arg: -2.530
# Asn: -0.780
# Asp: -0.900
# Cys: 0.290
# Gln: -0.850
# Glu: -0.740
# Gly: 0.480
# His: -0.400
# Ile: 1.380
# Leu: 1.060
# Lys: -1.500
# Met: 0.640
# Phe: 1.190
# Pro: 0.120
# Ser: -0.180
# Thr: -0.050
# Trp: 0.810
# Tyr: 0.260
# Val: 1.080
#
# Usage:
# color_h (selection)
#
from pymol import cmd
def color_h(selection='all'):
s = str(selection)
print s
cmd.set_color('color_ile',[0.996,0.062,0.062])
cmd.set_color('color_phe',[0.996,0.109,0.109])
cmd.set_color('color_val',[0.992,0.156,0.156])
cmd.set_color('color_leu',[0.992,0.207,0.207])
cmd.set_color('color_trp',[0.992,0.254,0.254])
cmd.set_color('color_met',[0.988,0.301,0.301])
cmd.set_color('color_ala',[0.988,0.348,0.348])
cmd.set_color('color_gly',[0.984,0.394,0.394])
cmd.set_color('color_cys',[0.984,0.445,0.445])
cmd.set_color('color_tyr',[0.984,0.492,0.492])
cmd.set_color('color_pro',[0.980,0.539,0.539])
cmd.set_color('color_thr',[0.980,0.586,0.586])
cmd.set_color('color_ser',[0.980,0.637,0.637])
cmd.set_color('color_his',[0.977,0.684,0.684])
cmd.set_color('color_glu',[0.977,0.730,0.730])
cmd.set_color('color_asn',[0.973,0.777,0.777])
cmd.set_color('color_gln',[0.973,0.824,0.824])
cmd.set_color('color_asp',[0.973,0.875,0.875])
cmd.set_color('color_lys',[0.899,0.922,0.922])
cmd.set_color('color_arg',[0.899,0.969,0.969])
cmd.color("color_ile","("+s+" and resn ile)")
cmd.color("color_phe","("+s+" and resn phe)")
cmd.color("color_val","("+s+" and resn val)")
cmd.color("color_leu","("+s+" and resn leu)")
cmd.color("color_trp","("+s+" and resn trp)")
cmd.color("color_met","("+s+" and resn met)")
cmd.color("color_ala","("+s+" and resn ala)")
cmd.color("color_gly","("+s+" and resn gly)")
cmd.color("color_cys","("+s+" and resn cys)")
cmd.color("color_tyr","("+s+" and resn tyr)")
cmd.color("color_pro","("+s+" and resn pro)")
cmd.color("color_thr","("+s+" and resn thr)")
cmd.color("color_ser","("+s+" and resn ser)")
cmd.color("color_his","("+s+" and resn his)")
cmd.color("color_glu","("+s+" and resn glu)")
cmd.color("color_asn","("+s+" and resn asn)")
cmd.color("color_gln","("+s+" and resn gln)")
cmd.color("color_asp","("+s+" and resn asp)")
cmd.color("color_lys","("+s+" and resn lys)")
cmd.color("color_arg","("+s+" and resn arg)")
cmd.extend('color_h',color_h)
def color_h2(selection='all'):
s = str(selection)
print s
cmd.set_color("color_ile2",[0.938,1,0.938])
cmd.set_color("color_phe2",[0.891,1,0.891])
cmd.set_color("color_val2",[0.844,1,0.844])
cmd.set_color("color_leu2",[0.793,1,0.793])
cmd.set_color("color_trp2",[0.746,1,0.746])
cmd.set_color("color_met2",[0.699,1,0.699])
cmd.set_color("color_ala2",[0.652,1,0.652])
cmd.set_color("color_gly2",[0.606,1,0.606])
cmd.set_color("color_cys2",[0.555,1,0.555])
cmd.set_color("color_tyr2",[0.508,1,0.508])
cmd.set_color("color_pro2",[0.461,1,0.461])
cmd.set_color("color_thr2",[0.414,1,0.414])
cmd.set_color("color_ser2",[0.363,1,0.363])
cmd.set_color("color_his2",[0.316,1,0.316])
cmd.set_color("color_glu2",[0.27,1,0.27])
cmd.set_color("color_asn2",[0.223,1,0.223])
cmd.set_color("color_gln2",[0.176,1,0.176])
cmd.set_color("color_asp2",[0.125,1,0.125])
cmd.set_color("color_lys2",[0.078,1,0.078])
cmd.set_color("color_arg2",[0.031,1,0.031])
cmd.color("color_ile2","("+s+" and resn ile)")
cmd.color("color_phe2","("+s+" and resn phe)")
cmd.color("color_val2","("+s+" and resn val)")
cmd.color("color_leu2","("+s+" and resn leu)")
cmd.color("color_trp2","("+s+" and resn trp)")
cmd.color("color_met2","("+s+" and resn met)")
cmd.color("color_ala2","("+s+" and resn ala)")
cmd.color("color_gly2","("+s+" and resn gly)")
cmd.color("color_cys2","("+s+" and resn cys)")
cmd.color("color_tyr2","("+s+" and resn tyr)")
cmd.color("color_pro2","("+s+" and resn pro)")
cmd.color("color_thr2","("+s+" and resn thr)")
cmd.color("color_ser2","("+s+" and resn ser)")
cmd.color("color_his2","("+s+" and resn his)")
cmd.color("color_glu2","("+s+" and resn glu)")
cmd.color("color_asn2","("+s+" and resn asn)")
cmd.color("color_gln2","("+s+" and resn gln)")
cmd.color("color_asp2","("+s+" and resn asp)")
cmd.color("color_lys2","("+s+" and resn lys)")
cmd.color("color_arg2","("+s+" and resn arg)")
cmd.extend('color_h2',color_h2)

View File

@@ -1,981 +0,0 @@
""" 2011_04_11: Hongbo Zhu
PyMOL plugin for running DSSP and display SS using different colors.
The DSSP codes for secondary structure are:
H - Alpha helix (4-12)
G - 3-10 helix
I - pi helix
E - Strand
B - Isolated beta-bridge residue
T - Turn
S - Bend
- - None
2011_04_24: add stride
STRIDE code (taken from stride.doc) is nearly the same as DSSP
H Alpha helix
G 3-10 helix
I PI-helix
E Extended conformation
B or b Isolated bridge
T Turn
C Coil (none of the above)
"""
# Copyright Notice
# ================
#
# The PyMOL Plugin source code in this file is copyrighted, but you can
# freely use and copy it as long as you don't change or remove any of
# the copyright notices.
#
# ----------------------------------------------------------------------
# This PyMOL Plugin is Copyright (C) 2011 by
# Hongbo Zhu <hongbo.zhu.cn at googlemail dot com>
#
# All Rights Reserved
#
# Permission to use, copy, modify, distribute, and distribute modified
# versions of this software and its documentation for any purpose and
# without fee is hereby granted, provided that the above copyright
# notice appear in all copies and that both the copyright notice and
# this permission notice appear in supporting documentation, and that
# the name(s) of the author(s) not be used in advertising or publicity
# pertaining to distribution of the software without specific, written
# prior permission.
#
# THE AUTHOR(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
# NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# ----------------------------------------------------------------------
# python lib
import os
import sys
import platform
if sys.version_info >= (2,4):
import subprocess # subprocess is introduced in python 2.4
import math
import random
import tempfile
import tkSimpleDialog
import tkMessageBox
import tkFileDialog
import tkColorChooser
import Tkinter
# pymol lib
try:
from pymol import cmd
from pymol.cgo import *
except ImportError:
print 'Warning: pymol library cmd not found.'
sys.exit(1)
# external lib
try:
import Pmw
except ImportError:
print 'Warning: failed to import Pmw. Exit ...'
sys.exit(1)
VERBOSE = True
#################
## here we go
#################
def __init__(self):
""" DSSP and Stride plugin for PyMol
"""
self.menuBar.addmenuitem('Plugin', 'command',
'DSSP & Stride', label = 'DSSP & Stride',
command = lambda s=self : DSSPPlugin(s))
#################
## GUI related
#################
class DSSPPlugin:
def __init__(self, app):
self.parent = app.root
self.dialog = Pmw.Dialog(self.parent,
buttons = ('Run DSSP',
'Run Stride',
'Update Color',
'Update ss',
'Exit'),
title = 'DSSP and Stride Plugin for PyMOL',
command = self.execute)
Pmw.setbusycursorattributes(self.dialog.component('hull'))
# parameters used by DSSP
self.pymol_sel = Tkinter.StringVar()
self.dssp_bin = Tkinter.StringVar()
self.stride_bin = Tkinter.StringVar()
self.dssp_rlt_dict = {}
self.stride_rlt_dict = {}
self.ss_asgn_prog = None # which program is used to assign ss
self.sel_obj_list = [] # there may be more than one seletion or object
# defined by self.pymol_sel
# treat each selection and object separately
if 'DSSP_BIN' not in os.environ and 'PYMOL_GIT_MOD' in os.environ:
if sys.platform.startswith('linux') and platform.machine() == 'x86_32':
initialdir_dssp = os.path.join(os.environ['PYMOL_GIT_MOD'],"DSSP","i86Linux2","dssp-2")
os.environ['DSSP_BIN'] = initialdir_dssp
elif sys.platform.startswith('linux') and platform.machine() == 'x86_64':
initialdir_dssp = os.path.join(os.environ['PYMOL_GIT_MOD'],"DSSP","ia64Linux2","dssp-2")
os.environ['DSSP_BIN'] = initialdir_dssp
elif sys.platform.startswith('win'):
initialdir_dssp = os.path.join(os.environ['PYMOL_GIT_MOD'],"DSSP","win32","dssp.exe")
os.environ['DSSP_BIN'] = initialdir_dssp
else:
pass
if 'DSSP_BIN' in os.environ:
if VERBOSE: print 'Found DSSP_BIN in environmental variables', os.environ['DSSP_BIN']
self.dssp_bin.set(os.environ['DSSP_BIN'])
else:
if VERBOSE: print 'DSSP_BIN not found in environmental variables.'
self.dssp_bin.set('')
if 'STRIDE_BIN' not in os.environ and 'PYMOL_GIT_MOD' in os.environ:
if sys.platform.startswith('linux') and platform.machine() == 'x86_32':
initialdir_stride = os.path.join(os.environ['PYMOL_GIT_MOD'],"Stride","i86Linux2","stride")
os.environ['STRIDE_BIN'] = initialdir_stride
elif sys.platform.startswith('linux') and platform.machine() == 'x86_64':
initialdir_stride = os.path.join(os.environ['PYMOL_GIT_MOD'],"Stride","ia64Linux2","stride")
os.environ['STRIDE_BIN'] = initialdir_stride
elif sys.platform.startswith('win'):
initialdir_stride = os.path.join(os.environ['PYMOL_GIT_MOD'],"Stride","win32","stride.exe")
os.environ['STRIDE_BIN'] = initialdir_stride
else:
pass
if 'STRIDE_BIN' in os.environ:
if VERBOSE: print 'Found STRIDE_BIN in environmental variables', os.environ['STRIDE_BIN']
self.stride_bin.set(os.environ['STRIDE_BIN'])
else:
if VERBOSE: print 'STRIDE_BIN not found in environmental variables.'
self.stride_bin.set('')
# DSSP visualization color
# - H Alpha helix (4-12)
# - G 3-10 helix
# - I pi helix
#
# - E Extended strand
# - B Isolated beta-bridge residue
#
# - T Turn
# - S Bend
# - - None
# STRIDE does not have S and None, but it has two more
# codes: 'b' same as 'B' and 'C' for coil
self.DSSP_SSE_list = ['H','G','I', 'E','B','T','S','-'] # for the record of the order
self.STRIDE_SSE_list = ['H','G','I', 'E','B','b','T','C'] # for the record of the order
self.SSE_map = {'H':'H',
'G':'H',
'I':'H',
'E':'S',
'B':'S',
'T':'L',
'S':'L',
'-':'L',
'b':'S',
'C':'L'
}
self.SSE_name = {
'H' : 'Alpha helix',
'G' : '3-10 helix',
'I' : 'Pi helix',
'E' : 'Extended strand',
'B' : 'Isolated beta-bridge',
'T' : 'Turn',
'S' : 'Bend',
'-' : 'None',
'b' : 'Isolated beta-bridge',
'C' : 'Coil'
}
self.SSE_col_RGB = {
'H':(255, 0, 0),
'G':(255, 0,128),
'I':(255,170,170),
'E':(255,255, 0),
'B':(153,119, 85),
'T':( 0,255,255),
'S':(153,255,119),
'-':(179,179,179),
'b':(153,119, 85), # same as 'B'
'C':( 0, 0,255)
}
self.SSE_col = {}
for sse in self.SSE_col_RGB.keys():
self.SSE_col[sse] = '#%s%s%s' % (hex(self.SSE_col_RGB[sse][0])[2:].zfill(2),
hex(self.SSE_col_RGB[sse][1])[2:].zfill(2),
hex(self.SSE_col_RGB[sse][2])[2:].zfill(2))
self.SSE_res_dict = {}
self.SSE_sel_dict = {}
w = Tkinter.Label(self.dialog.interior(),
# text = '\nDSSP Plugin for PyMOL\nHongbo Zhu, 2011.\n\nColor proteins according to the secondary structure determined by DSSP.',
text = '\nDSSP and Stride Plugin for PyMOL\nby Hongbo Zhu, 2011\n',
background = 'black', foreground = 'green'
)
w.pack(expand = 1, fill = 'both', padx = 10, pady = 5)
# make a few tabs within the dialog
self.notebook = Pmw.NoteBook(self.dialog.interior())
self.notebook.pack(fill = 'both', expand=1, padx=10, pady=10)
######################
# Tab : Structure Tab
######################
page = self.notebook.add('Structure')
self.notebook.tab('Structure').focus_set()
group_struc = Tkinter.LabelFrame(page, text = 'Structure')
group_struc.pack(fill='both', expand=True, padx=10, pady=5)
pymol_sel_ent = Pmw.EntryField(group_struc,
label_text='PyMOL selection/object:',
labelpos='wn',
entry_textvariable=self.pymol_sel
)
dssp_bin_ent = Pmw.EntryField(group_struc,
label_text='DSSP binary:', labelpos='wn',
entry_textvariable=self.dssp_bin,
entry_width=20)
dssp_bin_but = Tkinter.Button(group_struc, text = 'Browse...',
command = self.getDSSPBin)
stride_bin_ent = Pmw.EntryField(group_struc,
label_text='Stride binary:', labelpos='wn',
entry_textvariable=self.stride_bin,
entry_width=20)
stride_bin_but = Tkinter.Button(group_struc, text = 'Browse...',
command = self.getStrideBin)
# arrange widgets using grid
pymol_sel_ent.grid(sticky='we', row=0, column=0,
columnspan=2, padx=5, pady=5)
dssp_bin_ent.grid(sticky='we', row=1, column=0, padx=5, pady=1)
dssp_bin_but.grid(sticky='we', row=1, column=1, padx=5, pady=1)
stride_bin_ent.grid(sticky='we', row=2, column=0, padx=5, pady=1)
stride_bin_but.grid(sticky='we', row=2, column=1, padx=5, pady=1)
group_struc.columnconfigure(0, weight=9)
group_struc.columnconfigure(1, weight=1)
######################
# Tab : Color Tab
######################
# H = alpha helix
# G = 3-helix (3/10 helix)
# I = 5 helix (pi helix)
# E = extended strand, participates in beta ladder
# B = residue in isolated beta-bridge
# T = hydrogen bonded turn
# S = bend
#
# H Alpha helix (4-12)
# G 3-10 helix
# I pi helix
# E Strand
# B Isolated beta-bridge residue
# T Turn
# S Bend
# - None
page = self.notebook.add('Color')
group_sse_color = Tkinter.LabelFrame(page, text = 'Secondary Structure Element Color')
group_sse_color.grid(sticky='eswn', row=0, column=0, padx=10, pady=5)
# colors for DSSP surface
H_col_lab = Tkinter.Label(group_sse_color, text='Alpha helix (H):')
self.H_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['H'],
activebackground=self.SSE_col['H'],
command = self.custermizeHColor)
G_col_lab = Tkinter.Label(group_sse_color, text='3-10 helix (G):')
self.G_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['G'],
activebackground=self.SSE_col['G'],
command = self.custermizeGColor)
I_col_lab = Tkinter.Label(group_sse_color, text='PI helix (I):')
self.I_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['I'],
activebackground=self.SSE_col['G'],
command = self.custermizeIColor)
E_col_lab = Tkinter.Label(group_sse_color, text='Extended strand (E):')
self.E_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['E'],
activebackground=self.SSE_col['E'],
command = self.custermizeEColor)
B_col_lab = Tkinter.Label(group_sse_color, text='Isolated beta-bridge (B):')
self.B_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['B'],
activebackground=self.SSE_col['B'],
command = self.custermizeBColor)
T_col_lab = Tkinter.Label(group_sse_color, text='Turn (T):')
self.T_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['T'],
activebackground=self.SSE_col['T'],
command = self.custermizeTColor)
S_col_lab = Tkinter.Label(group_sse_color, text='Bend (DSSP S):')
self.S_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['S'],
activebackground=self.SSE_col['S'],
command = self.custermizeSColor)
N_col_lab = Tkinter.Label(group_sse_color, text='None (DSSP NA):')
self.N_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['-'],
activebackground=self.SSE_col['-'],
command = self.custermizeNColor)
b_col_lab = Tkinter.Label(group_sse_color, text='Isolated beta-bridge (Stride b):')
self.b_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['b'],
activebackground=self.SSE_col['b'],
command = self.custermizebColor)
C_col_lab = Tkinter.Label(group_sse_color, text='Coil (Stride C):')
self.C_col_but = Tkinter.Button(group_sse_color,
bg=self.SSE_col['C'],
activebackground=self.SSE_col['C'],
command = self.custermizeCColor)
H_col_lab.grid(sticky='e', row=0, column=0, padx=5, pady=3)
self.H_col_but.grid(sticky='we', row=0, column=1, padx=5, pady=3)
G_col_lab.grid(sticky='e', row=1, column=0, padx=5, pady=3)
self.G_col_but.grid(sticky='we', row=1, column=1, padx=5, pady=3)
I_col_lab.grid(sticky='e', row=2, column=0, padx=5, pady=3)
self.I_col_but.grid(sticky='we', row=2, column=1, padx=5, pady=3)
E_col_lab.grid(sticky='e', row=0, column=2, padx=5, pady=3)
self.E_col_but.grid(sticky='we', row=0, column=3, padx=5, pady=3)
B_col_lab.grid(sticky='e', row=1, column=2, padx=5, pady=3)
self.B_col_but.grid(sticky='we', row=1, column=3, padx=5, pady=3)
T_col_lab.grid(sticky='e', row=0, column=4, padx=5, pady=3)
self.T_col_but.grid(sticky='we', row=0, column=5, padx=5, pady=3)
S_col_lab.grid(sticky='e', row=1, column=4, padx=5, pady=3)
self.S_col_but.grid(sticky='we', row=1, column=5, padx=5, pady=3)
N_col_lab.grid(sticky='e', row=2, column=4, padx=5, pady=3)
self.N_col_but.grid(sticky='we', row=2, column=5, padx=5, pady=3)
b_col_lab.grid(sticky='e', row=2, column=2, padx=5, pady=3)
self.b_col_but.grid(sticky='we', row=2, column=3, padx=5, pady=3)
C_col_lab.grid(sticky='e', row=3, column=4, padx=5, pady=3)
self.C_col_but.grid(sticky='we', row=3, column=5, padx=5, pady=3)
######################
# Tab : About Tab
######################
page = self.notebook.add('About')
group_about = Tkinter.LabelFrame(page, text = 'About DSSP and Stride Plugin for PyMOL')
group_about.grid(sticky='we', row=0,column=0,padx=5,pady=3)
about_plugin = """ Assign and color secondary structures using DSSP or Stride.
by Hongbo Zhu <hongbo.zhu.cn .at. googlemail.com>
Please cite this plugin if you use it in a publication.
Hongbo Zhu. DSSP and Stride plugin for PyMOL, 2011, BIOTEC, TU Dresden.
"""
label_about = Tkinter.Label(group_about,text=about_plugin)
label_about.grid(sticky='we', row=0, column=0, padx=5, pady=10)
self.notebook.setnaturalsize()
return
def getDSSPBin(self):
dssp_bin_fname = tkFileDialog.askopenfilename(
title='DSSP Binary', initialdir='',
filetypes=[('all','*')], parent=self.parent)
if dssp_bin_fname: # if nonempty
self.dssp_bin.set(dssp_bin_fname)
return
def getStrideBin(self):
stride_bin_fname = tkFileDialog.askopenfilename(
title='Stride Binary', initialdir='',
filetypes=[('all','*')], parent=self.parent)
if stride_bin_fname: # if nonempty
self.stride_bin.set(stride_bin_fname)
return
def runDSSPOneObj(self, one_obj_sel):
""" Run DSSP on only one object.
@param one_obj_sel: the selection/object involving only one object
@param type: string
"""
SSE_res = {
'H':{}, 'G':{}, 'I':{},
'E':{}, 'B':{},
'T':{}, 'S':{}, '-':{}
}
SSE_sel = {
'H':None, 'G':None, 'I':None,
'E':None, 'B':None,
'T':None, 'S':None, '-':None
}
pdb_fn = None
pdb_os_fh, pdb_fn = tempfile.mkstemp(suffix='.pdb') # file os handle, file name
os.close(pdb_os_fh)
# DSSP 2.0.4 ignores all residues after 1st TER in the same chain
v = cmd.get(name='pdb_use_ter_records')
if v: cmd.set(name='pdb_use_ter_records', value=0) # do not insert TER into the pdb
cmd.save(filename=pdb_fn, selection=one_obj_sel)
if v: cmd.set(name='pdb_use_ter_records', value=v) # restore old value
if VERBOSE:
print 'Selection %s saved to %s.' % (one_obj_sel, pdb_fn)
if pdb_fn is None:
print 'WARNING: DSSP has no pdb file to work on!'
return None
print 'Running DSSP for %s ...' % (one_obj_sel,)
dssp_sse_dict = {}
if sys.version_info >= (2,4):
dssp_proc = subprocess.Popen([self.dssp_bin.get(), pdb_fn],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
dssp_stdout, dssp_stderr = dssp_proc.communicate()
else: # use os.system + tempfile
dssp_tmpout_os_fh, dssp_tmpout_fn = tempfile.mkstemp(suffix='.dssp')
os.close(dssp_tmpout_os_fh)
dssp_cmd = '%s %s > %s' % (self.dssp_bin.get(), pdb_fn, dssp_tmpout_fn)
os.system(dssp_cmd)
fh = open(dssp_tmpout_fn)
dssp_stdout = ''.join(fh.readlines())
fh.close()
sse_started = False
for line in dssp_stdout.splitlines():
if line.startswith(' # RESIDUE'):
sse_started = True
continue
elif line.startswith(' !!!'):
sse_started = False
continue
elif sse_started:
if len(line) < 10 or line[9] == ' ': continue
ch,resname = line[11],line[13]
residen,sscode = line[5:11].strip(),line[16] # residen = resnum+icode, col 10 is for icode
if sscode == ' ': sscode = '-'
k = (ch,resname,residen)
dssp_sse_dict[k] = sscode
self.dssp_rlt_dict[one_obj_sel] = dssp_sse_dict
print 'Got SSE for %d residues.' % (len(self.dssp_rlt_dict[one_obj_sel]),)
# group residues according to their SSE, and chain name
for k in self.dssp_rlt_dict[one_obj_sel].keys():
#res = '/%s//%s/%d%s/' % (sel,k[0],k[1][1], k[1][2].strip()) # sel name, chain ID, res serial num, icode
sse = self.dssp_rlt_dict[one_obj_sel][k]
chn = k[0]
res = k[2]
if VERBOSE: print '(%s) and \"%s\"/%s/ sse=%s' % (str(one_obj_sel),
chn.strip(), res, sse)
SSE_res[sse].setdefault(chn,[]).append(res)
self.SSE_res_dict[one_obj_sel] = SSE_res
for sse in self.DSSP_SSE_list:
sse_sel_name = self.selectSSE(one_obj_sel, sse)
SSE_sel[sse] = sse_sel_name
self.SSE_sel_dict[one_obj_sel] = SSE_sel
print '\nNumber of residues with SSE element:'
for sse in self.DSSP_SSE_list:
num = sum([len(SSE_res[sse][chn]) for chn in SSE_res[sse]])
print '%20s (%s) : %5d' % (self.SSE_name[sse], sse, num)
print
# clean up pdb_fn and dssp_tmpout_fn created by tempfile.mkstemp()
if os.path.isfile(pdb_fn):
os.remove(pdb_fn)
if sys.version_info < (2,4) and os.path.isfile(dssp_tmpout_fn):
os.remove(dssp_tmpout_fn)
return
def runDSSP(self):
"""
@return: whether DSSP has been executed successfully
@rtype: boolean
"""
# delete old results
self.sel_obj_list = []
self.dssp_rlt_dict = {}
self.SSE_res_dict = {}
self.SSE_sel_dict = {}
pdb_fn = None
sel_name= None
sel = self.pymol_sel.get()
if len(sel) > 0: # if any pymol selection/object is specified
# save the pymol selection/object in the tmp dir
all_sel_names = cmd.get_names('all') # get names of all selections
if sel in all_sel_names:
if cmd.count_atoms(sel) == 0:
err_msg = 'ERROR: The selection %s is empty.' % (sel,)
print 'ERROR: %s' % (err_msg,)
tkMessageBox.showinfo(title='ERROR', message=err_msg)
return False
else:
sel_name = sel
# no selection/object with the input name is found
# we assume either a single-word selector or
# some other selection-expression is used
# NOTE: if more than one selection is selected, they should be
# saved separately and SSE should be calculated for each
# of the selections.
else:
print 'The selection/object you specified is not found.'
print 'Your input will be interpreted as a selection-expression.'
# check whether the selection is empty
tmpsel = self.randomSeleName(prefix='your_sele_')
cmd.select(tmpsel,sel)
if cmd.count_atoms(tmpsel) == 0:
cmd.delete(tmpsel)
err_msg = 'ERROR: The selection %s is empty.' % (sel,)
print 'ERROR: %s' % (err_msg,)
tkMessageBox.showinfo(title='ERROR', message=err_msg)
return False
else:
sel_name = tmpsel
else: # what structure do you want DSSP to work on?
err_msg = 'No PyMOL selection/object specified!'
print 'ERROR: %s' % (err_msg,)
tkMessageBox.showinfo(title='ERROR', message=err_msg)
return False
# each object in the selection is treated as an independent struc
objlist = cmd.get_object_list(sel_name)
self.ss_asgn_prog = 'DSSP'
print 'Starting %s ...' % (self.ss_asgn_prog, )
for objname in objlist:
self.sel_obj_list.append('%s and %s' % (sel_name, objname))
self.runDSSPOneObj(self.sel_obj_list[-1])
## cmd.delete(tmpsel)
return True
def runStrideOneObj(self, one_obj_sel):
""" Run Stride on only one object.
@param one_obj_sel: the selection/object involving only one object
@param type: string
"""
SSE_res = {
'H':{}, 'G':{}, 'I':{},
'E':{}, 'B':{}, 'b':{},
'T':{}, 'C':{}
}
SSE_sel = {
'H':None, 'G':None, 'I':None,
'E':None, 'B':None, 'b':None,
'T':None, 'C':None
}
pdb_fn = None
pdb_os_fh, pdb_fn = tempfile.mkstemp(suffix='.pdb') # file os handle, file name
os.close(pdb_os_fh)
cmd.save(filename=pdb_fn, selection=one_obj_sel)
if VERBOSE:
print 'Selection %s saved to %s.' % (one_obj_sel, pdb_fn)
if pdb_fn is None:
print 'WARNING: Stride has no pdb file to work on!'
return None
print 'Running Stride for %s ...' % (one_obj_sel,)
stride_sse_dict = {}
if sys.version_info >= (2,4):
stride_proc = subprocess.Popen([self.stride_bin.get(), pdb_fn],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
stride_stdout, stride_stderr = stride_proc.communicate()
else: # use os.system + tempfile
stride_tmpout_os_fh, stride_tmpout_fn = tempfile.mkstemp(suffix='.stride')
os.close(stride_tmpout_os_fh)
stride_cmd = '%s %s > %s' % (self.stride_bin.get(), pdb_fn, stride_tmpout_fn)
os.system(stride_cmd)
fh = open(stride_tmpout_fn)
stride_stdout = ''.join(fh.readlines())
fh.close()
for line in stride_stdout.splitlines():
if line.startswith('ASG'):
resname,ch=line[5:8], line[9]
# according to stride doc, col 12-15 are used for residue number
# actually, resnum+icode is used in 12-15.
# In addition, if residue number is 4-digit or longer,
# the field 12-16 or more are used.
if line[15] == ' ': # col 16 is not occupied
residen, sscode = line[11:15].strip(),line[24] # residen = resnum+icode
else:
shift = line[15:].find(' ') # find where residen stops
residen, sscode = line[11:15+shift].strip(),line[24+shift]
k = (ch,resname,residen)
stride_sse_dict[k] = sscode
self.stride_rlt_dict[one_obj_sel] = stride_sse_dict
print 'Got SSE for %d residues.' % (len(self.stride_rlt_dict[one_obj_sel]),)
# group residues according to their SSE, and chain name
for k in self.stride_rlt_dict[one_obj_sel].keys():
sse=self.stride_rlt_dict[one_obj_sel][k]
chn = k[0] # this can be a space!
res = k[2]
if VERBOSE: print '(%s) and \"%s\"/%s/ sse=%s' % (str(one_obj_sel),
chn.strip(), res, sse)
SSE_res[sse].setdefault(chn,[]).append(res)
self.SSE_res_dict[one_obj_sel] = SSE_res
for sse in self.STRIDE_SSE_list:
sse_sel_name = self.selectSSE(one_obj_sel, sse)
SSE_sel[sse] = sse_sel_name
self.SSE_sel_dict[one_obj_sel] = SSE_sel
print '\nNumber of residues with SSE element:'
for sse in self.STRIDE_SSE_list:
num = sum([len(SSE_res[sse][chn]) for chn in SSE_res[sse]])
print '%20s (%s) : %5d' % (self.SSE_name[sse], sse, num)
print
# clean up pdb_fn and dssp_tmpout_fn created by tempfile.mkstemp()
if os.path.isfile(pdb_fn):
os.remove(pdb_fn)
if sys.version_info < (2,4) and os.path.isfile(stride_tmpout_fn):
os.remove(stride_tmpout_fn)
return True
def runStride(self):
"""
"""
# delete old results
self.sel_obj_list = []
self.stride_rlt_dict = {}
self.SSE_res_dict = {}
self.SSE_sel_dict = {}
pdb_fn = None
sel_name= None
sel = self.pymol_sel.get()
if len(sel) > 0: # if any pymol selection/object is specified
all_sel_names = cmd.get_names('all') # get names of all selections
if sel in all_sel_names:
if cmd.count_atoms(sel) == 0:
err_msg = 'ERROR: The selection %s is empty.' % (sel,)
print 'ERROR: %s' % (err_msg,)
tkMessageBox.showinfo(title='ERROR', message=err_msg)
return False
else:
sel_name = sel
# no selection/object with the input name is found
# we assume either a single-word selector or
# some other selection-expression is uesd
else:
print 'The selection/object you specified is not found.'
print 'Your input will be interpreted as a selection-expression.'
tmpsel = self.randomSeleName(prefix='your_sele_')
cmd.select(tmpsel,sel)
if cmd.count_atoms(tmpsel) == 0:
cmd.delete(tmpsel)
err_msg = 'ERROR: The selection %s is empty.' % (sel,)
print 'ERROR: %s' % (err_msg,)
tkMessageBox.showinfo(title='ERROR', message=err_msg)
return False
else:
sel_name = tmpsel
else: # what structure do you want Stride to work on?
err_msg = 'No PyMOL selection/object specified!'
print 'ERROR: %s' % (err_msg,)
tkMessageBox.showinfo(title='ERROR', message=err_msg)
return False
# each object in the selection is treated as an independent struc
objlist = cmd.get_object_list(sel_name)
self.ss_asgn_prog = 'Stride'
print 'Starting %s ...' % (self.ss_asgn_prog, )
for objname in objlist:
self.sel_obj_list.append('%s and %s' % (sel_name, objname))
self.runStrideOneObj(self.sel_obj_list[-1])
return True
def randomSeleName(self, prefix='sele',suffix=''):
""" generate a random selection name.
"""
sel_list = cmd.get_names('all')
sel_dict = dict(zip(sel_list, range(len(sel_list))))
sel_name = '%s%d%s' % (prefix, random.randint(1000,9999), suffix)
while(sel_name in sel_dict):
sel_name = '%s%d%s' % (prefix, random.randint(1000,9999), suffix)
return sel_name
def selectSSE(self, sel, sse):
""" generate selector for selecting all residues having the given sse.
return the selection name.
"""
#sel = self.pymol_sel.get()
sel_list_chn = []
if VERBOSE: print '\nSelecting SSE %s ... \n' % (sse)
for chn in self.SSE_res_dict[sel][sse]: # color one chain at a time
if chn == ' ': chn_str = '-'
else: chn_str = chn
if VERBOSE: print 'Selecting SSE %s on chain %s ... \n' % (sse, chn)
limit=150 # color every 150 residues
sel_name_chn = self.randomSeleName(prefix='%s_%s_%s_' % ('_'.join(sel.split()),chn_str,sse))
if len(self.SSE_res_dict[sel][sse][chn]) < limit:
#sel_expr = '/%s//%s/%s/' % (sel,chn.strip(), '+'.join(self.SSE_res[sse][chn]))
# always quote chain name in case it is empty (otherwise sel misinterpreted)
sel_expr = '(%s) and \"%s\"/%s/' % (sel,chn.strip(), '+'.join(self.SSE_res_dict[sel][sse][chn]))
cmd.select(sel_name_chn, sel_expr)
if VERBOSE: print 'select %s, %s' % (sel_name_chn, sel_expr)
sel_list_chn.append(sel_name_chn)
else:
rn = len(self.SSE_res_dict[sel][sse][chn])
print 'total number of res with %s = %d' % (sse,rn)
sz = int(math.ceil(rn/float(limit)))
sel_list_seg = []
for i in xrange(sz):
s,e = i*limit, min((i+1)*limit, rn)
print s,e
#sel_expr = '/%s//%s/%s/' % (sel,chn.strip(), '+'.join(self.SSE_res[sse][chn][s:e]))
# always quote chain name in case it is empty (otherwise sel misinterpreted)
sel_expr = '(%s) and \"%s\"/%s/' % (sel, chn.strip(),
'+'.join(self.SSE_res_dict[sel][sse][chn][s:e]))
sel_name_seg = self.randomSeleName(prefix='%s_%s_%s_tmp_' % ('_'.join(sel.split()),chn_str,sse))
cmd.select(sel_name_seg, sel_expr)
if VERBOSE: print 'select %s, %s' % (sel_name_seg, sel_expr)
sel_list_seg.append(sel_name_seg)
sel_expr = ' or '.join(sel_list_seg)
cmd.select(sel_name_chn, sel_expr)
if VERBOSE: print 'select %s, %s' % (sel_name_chn, sel_expr)
[cmd.delete(asel) for asel in sel_list_seg]
sel_list_chn.append(sel_name_chn)
if len(sel_list_chn) > 0:
sel_name = self.randomSeleName(prefix='%s_%s_%s_' % ('_'.join(sel.split()), sse, self.ss_asgn_prog))
sel_expr = ' or '.join(sel_list_chn)
cmd.select(sel_name,sel_expr)
[cmd.delete(asel) for asel in sel_list_chn]
else:
print 'INFO: No residues are assigned to SSE \'%s\'.' % (sse,)
sel_name = None
return sel_name
def updateColor(self):
if self.ss_asgn_prog is None:
err_msg = 'Run DSSP or Stride to assign secondary structures first!'
print 'ERROR: %s' % (err_msg,)
tkMessageBox.showinfo(title='ERROR', message=err_msg)
else:
print 'Update color for %s' % (self.pymol_sel.get()),
print 'using secondary structure assignment by %s' % (self.ss_asgn_prog,)
if self.ss_asgn_prog == 'DSSP': SSE_list = self.DSSP_SSE_list
elif self.ss_asgn_prog == 'Stride': SSE_list = self.STRIDE_SSE_list
for sse in SSE_list: # give color names
cmd.set_color('%s_color'%(sse,), self.SSE_col_RGB[sse])
for sse in SSE_list: # color each SSE
for sel_obj in self.sel_obj_list:
if self.SSE_sel_dict[sel_obj][sse] is not None:
cmd.color('%s_color'%(sse,), self.SSE_sel_dict[sel_obj][sse])
print 'color',self.SSE_sel_dict[sel_obj][sse],',',self.SSE_col_RGB[sse]
else:
print 'No residues with SSE \'%s\' to color.' % (sse,)
return
def updateSS(self):
if self.ss_asgn_prog is None:
err_msg = 'Run DSSP or Stride to assign secondary structures first!'
print 'ERROR: %s' % (err_msg,)
tkMessageBox.showinfo(title='ERROR', message=err_msg)
else:
print 'Update secondary structures for %s' % (self.pymol_sel.get()),
print 'using secondary structure assignment by %s' % (self.ss_asgn_prog,)
print 'SSE mapping: (H,G,I) ==> H; (E,B,b) ==> S; (T,S,-,C) ==> L'
if self.ss_asgn_prog == 'DSSP': SSE_list = self.DSSP_SSE_list
elif self.ss_asgn_prog == 'Stride': SSE_list = self.STRIDE_SSE_list
for sse in SSE_list:
for sel_obj in self.sel_obj_list:
if self.SSE_sel_dict[sel_obj][sse] is not None:
cmd.alter(self.SSE_sel_dict[sel_obj][sse], 'ss=\'%s\''% (self.SSE_map[sse],))
print 'alter %s, ss=%s' % (self.SSE_sel_dict[sel_obj][sse], self.SSE_map[sse])
else:
print 'No residue with SSE %s to update ss.' % (sse,)
# show cartoon for the input selection, and rebuild
cmd.show('cartoon',self.pymol_sel.get())
cmd.rebuild(self.pymol_sel.get())
return
def custermizeHColor(self):
self.custermizeSSEColor('H')
def custermizeGColor(self):
self.custermizeSSEColor('G')
def custermizeIColor(self):
self.custermizeSSEColor('I')
def custermizeEColor(self):
self.custermizeSSEColor('E')
def custermizeBColor(self):
self.custermizeSSEColor('B')
def custermizeTColor(self):
self.custermizeSSEColor('T')
def custermizeSColor(self):
self.custermizeSSEColor('S')
def custermizeNColor(self):
self.custermizeSSEColor('-')
def custermizebColor(self):
self.custermizeSSEColor('b')
def custermizeCColor(self):
self.custermizeSSEColor('C')
def custermizeSSEColor(self,sse):
SSE_col_but = {
'H':self.H_col_but,
'G':self.G_col_but,
'I':self.I_col_but,
'E':self.E_col_but,
'B':self.B_col_but,
'T':self.T_col_but,
'S':self.S_col_but,
'-':self.N_col_but,
'b':self.b_col_but,
'C':self.C_col_but,
}
try:
color_tuple, color = tkColorChooser.askcolor(color=self.SSE_col[sse])
if color_tuple is not None and color is not None:
self.SSE_col_RGB[sse] = color_tuple
self.SSE_col[sse] = color
SSE_col_but[sse]['bg']=self.SSE_col[sse]
SSE_col_but[sse]['activebackground']=self.SSE_col[sse]
SSE_col_but[sse].update()
except Tkinter._tkinter.TclError:
print 'Old color (%s) will be used.' % (self.mesh_col)
def execute(self, butcmd):
""" Run the cmd represented by the botton clicked by user.
"""
if butcmd == 'OK':
print 'is everything OK?'
elif butcmd == 'Run DSSP':
rtn = self.runDSSP()
if rtn and VERBOSE: print 'Done with DSSP!'
elif butcmd == 'Run Stride':
rtn = self.runStride()
if rtn and VERBOSE: print 'Done with Stride!'
elif butcmd == 'Update Color':
self.updateColor()
elif butcmd == 'Update ss':
self.updateSS()
elif butcmd == 'Exit':
print 'Exiting DSSP and Stride Plugin ...'
if __name__ == '__main__':
self.parent.destroy()
else:
self.dialog.withdraw()
print 'Done.'
else:
print 'Exiting DSSP and Stride Plugin because of unknown button click ...'
self.dialog.withdraw()
print 'Done.'
def quit(self):
self.dialog.destroy()
#############################################
#
#
# Create demo in root window for testing.
#
#
##############################################
if __name__ == '__main__':
class App:
def my_show(self,*args,**kwargs):
pass
app = App()
app.root = Tkinter.Tk()
Pmw.initialise(app.root)
app.root.title('It seems to work!')
widget = DSSPPlugin(app)
app.root.mainloop()

View File

@@ -1,887 +0,0 @@
'''
Described at PyMOL wiki:
http://www.pymolwiki.org/index.php/propka
#-------------------------------------------------------------------------------
# Name: propka for pymol
# Purpose: To fetch and display the pka values for protein of intetest
#
# Author: Troels E. Linnet
#
# Created: 14/08/2011
# Copyright: (c) Troels E. Linnet 2011
# Contact: tlinnet snabela gmail dot com
# Licence: Free for all
#
#
#-------------------------------------------------------------------------------
The PROPKA method is developed by the
Jensen Research Group
Department of Chemistry
University of Copenhagen
Please cite these references in publications:
Hui Li, Andrew D. Robertson, and Jan H. Jensen
"Very Fast Empirical Prediction and Interpretation of Protein pKa Values"
Proteins, 2005, 61, 704-721.
Delphine C. Bas, David M. Rogers, and Jan H. Jensen
"Very Fast Prediction and Rationalization of pKa Values for Protein-Ligand Complexes"
Proteins, 2008, 73, 765-783.
Mats H.M. Olsson, Chresten R. Soendergard, Michal Rostkowski, and Jan H. Jensen
"PROPKA3: Consistent Treatment of Internal and Surface Residues in Empirical pKa predictions"
Journal of Chemical Theory and Computation, 2011 7 (2), 525-537
Chresten R. Soendergaard, Mats H.M. Olsson, Michaz Rostkowski, and Jan H. Jensen
"Improved Treatment of Ligands and Coupling Effects in Empirical Calculation and Rationalization of pKa Values"
Journal of Chemical Theory and Computation, 2011 in press
"""
#-------------------------------------------------------------------------------
# The script needs mechanize to run.
# On windows, it is not easy to make additional modules available for pymol. So put in into your working folder.
#1)The easy manual way:
#a)Go to: http://wwwsearch.sourceforge.net/mechanize/download.html
#b)Download mechanize-0.2.5.zip. http://pypi.python.org/packages/source/m/mechanize/mechanize-0.2.5.zip
#c)Extract to .\mechanize-0.2.5 then move the in-side folder "mechanize" to your folder with propka.py. The rest of .\mechanize-0.2.5 you don't need.
#You can also see other places where you could put the "mechanize" folder. Write this in pymol to see the paths where pymol is searching for "mechanize"
# import sys; print(sys.path)
#-------------------------------------------------------------------------------
"""
Example for pymol script to start the functions. For example: trypropka.pml
Execute with pymol or start pymol and: File->Run->trypropka.pml
##############################################################################################################################################################################################################################
### Point to your directory with your pdb file and where to save the results
#cd /homes/linnet/Documents/Speciale/5NT-project/Mutant-construct/predict_reactivity/propka
cd C:/Users/tlinnet/Documents/My Dropbox/Speciale/5NT-project/Mutant-construct/predict_reactivity/propka
### The fastest method is just to write propka. Then the last pymol molecule is assumed and send to server. verbose=yes makes the script gossip mode.
import propka
fetch 4ins, async=0
propka
#fetch 1hp1, async=0
#propka logtime=_, resi=5-10.20-30, resn=CYS.ATP.TRP, verbose=yes
### Fetch 4ins from web. async make sure, we dont execute script before molecule is loaded. The resi and resn prints the interesting results right to command line.
#fetch 4ins, async=0
#propka chain=*, resi=5-10.20-30, resn=ASP.CYS, logtime=_
### If there is no web connection, one can process a local .pka file. Either from a previous run or from a downloaded propka webpage result.
### Then run and point to .pka file with: pkafile=./Results_propka/pkafile.pka Remember the dot "." in the start, to make it start in the current directory.
#load 4ins.pdb
#propka pkafile=./Results_propka/4ins_.pka, resi=18.25-30, resn=cys,
### Some more examples. This molecule has 550 residues, so takes a longer time. We select to run the last molecule, by writing: molecule=1hp1
#fetch 4ins, async=0
#fetch 1hp1, async=0
#propka molecule=1hp1, chain=A, resi=300-308.513, resn=CYS.ATP.TRP, logtime=_, verbose=no, showresult=no
#propka molecule=1hp1, pkafile=./Results_propka/1hp1_.pka, verbose=yes
### One can also just make a lookup for a protein. Use function: getpropka
### Note. This does only print the result to the pymol command line
#getpropka source=ID, PDBID=4ake, logtime=_, showresult=yes
#getpropka source=ID, PDBID=4ins, logtime=_, server_wait=10.0, verbose=yes, showresult=no
############################################Input parameters: propka############################################
############# The order of input and changable things:
############# propka(molecule="NIL",chain="*",resi="0",resn="NIL",method="upload",logtime=time.strftime("%m%d",time.localtime()),server_wait=3.0,version="v3.1",verbose="no",showresult="no",pkafile="NIL")
# method : method=upload is default. This sends .pdb file and request result from propka server.
## method=file will only process a manual .pka file, and write a pymol command file. No use of mechanize.
## If one points to an local .pka file, then method is auto-changed to method=file. This is handsome in off-line environment, ex. teaching or seminar.
# pkafile: Write the path to .pka file. Ex: pkafile=./Results_propka/4ins_.pka
# molecule : name of the molecule. Ending of file is assumed to be .pdb
# chain : which chains are saved to file, before molecule file is send to server. Separate with "." Ex: chain=A.b
# resi : Select by residue number, which residues should be printed to screen and saved to the log file: /Results_propka/_Results.log.
## Separate with "." or make ranges with "-". Ex: resi=35.40-50
# resn : Select by residue name, which residues should be printed to screen and saved to the log file: /Results_propka/_Results.log.
## Separate with "." Ex: resn=cys.tyr
# logtime : Each execution give a set of files with the job id=logtime. If logtime is not provided, the current time is used.
## Normal it usefull to set it empty. Ex: logtime=_
# verbose : Verbose is switch, to turn on messages for the mechanize section. This is handsome to see how mechanize works, and for error searching.
# showresult : Switch, to turn on all results in pymol command window. Ex: showresult=yes
# server_wait=10.0 is default. This defines how long time between asking the server for a result. Set no lower than 3 seconds.
# version=v3.1 is default. This is what version of propka which would be used.
## Possible: 'v3.1','v3.0','v2.0'. If a newer version is available than the current v3.1, a error message is raised to make user update the script.
############################################Input parameters: getpropka############################################
############# The order of input and changable things:
############# getpropka(PDB="NIL",chain="*",resi="0",resn="NIL",source="upload",PDBID="",logtime=time.strftime("%Y%m%d%H%M%S",time.localtime()),server_wait=3.0,version="v3.1",verbose="no",showresult="no")
# PDB: points the path to a .pdb file. This is auto-set from propka function.
# source : source=upload is default and is set at the propka webpage.
# source=ID, PDBID=4ake , one can print to the command line, the pka value for any official pdb ID. No files are displayed in pymol.
# PDBID: is used as the 4 number/letter pdb code, when invoking source=ID.
##############################################################################################################################################################################################################################
'''
from __future__ import print_function
try:
from pymol import cmd
runningpymol = 'yes'
except:
runningpymol = 'no'
pass
import time
import platform
import os
import sys
def propka(molecule="NIL", chain="*", resi="0", resn="NIL", method="upload", logtime=time.strftime("%m%d", time.localtime()), server_wait=3.0, version="v3.1", verbose="no", showresult="no", pkafile="NIL", makebonds="yes"):
Script_Version = "20110823"
# First we have to be sure, we give reasonable arguments
if pkafile != "NIL":
method = 'file'
assert method in ['upload', 'file'], "'method' has to be either: method=upload or method=file"
# If molecule="all", then try to get the last molecule
##assert molecule not in ['NIL'], "You always have to provide molecule name. Example: molecule=4ins"
if molecule == "NIL":
assert len(cmd.get_names()) != 0, "Did you forget to load a molecule? There are no objects in pymol."
molecule = cmd.get_names()[-1]
# To print out to screen for selected residues. Can be separated with "." or make ranges with "-". Example: resi="4-8.10"
if resi != "0":
resi_range = ResiRange(resi)
else:
resi_range = []
# Also works for residue names. They are all converted to bigger letters. Example: resn="cys.Tyr"
if resn != "NIL":
resn_range = ResnRange(resn)
else:
resn_range = resn
# Make chain range, and upper case.
chain = ChainRange(chain)
# Make result directory. We also the absolut path to the new directory.
Newdir = createdirs()
if method == "upload":
# We try to load mechanize. If this fail, one can always get the .pka file manual and the run: method=file
try:
from modules import mechanize
importedmechanize = 'yes'
except ImportError:
print("Import error. Is a module missing?")
print(sys.exc_info())
print("Look if missing module is in your python path\n%s" % sys.path)
importedmechanize = 'no'
import modules.mechanize as mechanize
# The name for the new molecule
newmolecule = "%s%s" % (molecule, logtime)
# Create the new molecule from original loaded and for the specified chains. Save it, and disable the old molecule.
cmd.create("%s" % newmolecule, "%s and chain %s" % (molecule, chain))
cmd.save("%s%s.pdb" % (Newdir, newmolecule), "%s" % newmolecule)
cmd.disable("%s" % molecule)
if molecule == "all":
cmd.enable("%s" % molecule)
cmd.show("cartoon", "%s" % molecule)
# Let the new molecule be shown in cartoon.
cmd.hide("everything", "%s" % newmolecule)
cmd.show("cartoon", "%s" % newmolecule)
# Make the absolut path to the newly created .pdb file.
PDB = "%s%s.pdb" % (Newdir, newmolecule)
source = "upload"
PDBID = ""
# Request server, and get the absolut path to the result file.
pkafile = getpropka(PDB, chain, resi, resn, source, PDBID, logtime, server_wait, version, verbose, showresult)
# Open the result file and put in into a handy list.
list_results, ligands_results = importpropkaresult(pkafile)
if method == "file":
assert pkafile not in ['NIL'], "You have to provide path to file. Example: pkafile=./Results_propka/4ins_2011.pka"
assert ".pka" in pkafile, 'The propka result file should end with ".pka" \nExample: pkafile=./Results_propka/4ins_2011.pka \npkafile=%s' % (pkafile)
# The name for the molecule we pass to the writing script of pymol commands
newmolecule = "%s" % molecule
cmd.hide("everything", "%s" % newmolecule)
cmd.show("cartoon", "%s" % newmolecule)
# We open the result file we have got in the manual way and put in into a handy list.
list_results, ligands_results = importpropkaresult(pkafile)
# Then we print the interesting residues to the screen.
printpropkaresult(list_results, resi, resi_range, resn, resn_range, showresult, ligands_results)
# Now create the pymol command file. This should label the protein. We get back the absolut path to the file, so we can execute it.
result_pka_pymol_name = writepymolcmd(newmolecule, pkafile, verbose, makebonds)
# Now run our command file. But only if we are running pymol.
if runningpymol == 'yes':
cmd.do("run %s" % result_pka_pymol_name)
##if runningpymol=='yes': cmd.do("@%s"%result_pka_pymol_name)
return(list_results)
if runningpymol != 'no':
cmd.extend("propka", propka)
def getpropka(PDB="NIL", chain="*", resi="0", resn="NIL", source="upload", PDBID="", logtime=time.strftime("%Y%m%d%H%M%S", time.localtime()), server_wait=3.0, version="v3.1", verbose="no", showresult="no"):
try:
import modules.mechanize as mechanize
importedmechanize = 'yes'
except ImportError:
print("Import error. Is a module missing?")
print(sys.exc_info())
print("Look if missing module is in your python path \n %s" % sys.path)
importedmechanize = 'no'
propka_v_201108 = 3.1
url = "http://propka.ki.ku.dk/"
assert version in ['v2.0', 'v3.0', 'v3.1'], "'version' has to be either: 'v2.0', 'v3.0', 'v3.1'"
assert source in ['ID', 'upload', 'addr', 'input_file'], "'source' has to be either: 'ID', 'upload', 'addr', 'input_file'"
if source == "upload":
assert PDB not in ['NIL'], "You always have to provide PDB path. Example: PDB=.\Results_propka\4ins2011.pdb"
if source == "ID":
assert len(PDBID) == 4, "PDBID has to be 4 characters"
# To print out to screen for selected residues. Can be separated with "." or make ranges with "-". Example: resi="4-8.10"
if resi != "0":
resi_range = ResiRange(resi)
else:
resi_range = []
# Also works for residue names. They are all converted to bigger letters. Example: resn="cys.Tyr"
if resn != "NIL":
resn_range = ResnRange(resn)
else:
resn_range = resn
# Start the browser
br = mechanize.Browser()
# We pass to the server, that we are not a browser, but this python script. Can be used for statistics at the propka server.
br.addheaders = [('User-agent', 'pythonMechanizeClient')]
# To turn on debugging messages
# br.set_debug_http(True)
# To open the start page.
page_start = br.open(url)
read_start = page_start.read()
if verbose == 'yes':
print(br.title())
print(br.geturl())
# To get available forms
page_forms = [f.name for f in br.forms()]
if verbose == 'yes':
print(page_forms)
# Select first form
br.select_form(name=page_forms[0])
# Print the current selected form, so we see that we values we start with.
if verbose == 'yes':
print(br.form)
# Print the parameters of the 'version' RadioControl button and current value
if verbose == 'yes':
print(br.find_control(name='version'), br.find_control(name='version').value)
# This is to check, that the current script is "up-to-date".
propka_v_present = float(br.find_control(name='version').value[0].replace('v', ''))
if propka_v_present > propka_v_201108:
raise UserWarning('\nNew version of propka exist.\nCheck/Update your script.\nPresent:v%s > Script:v%s' % (propka_v_present, propka_v_201108))
# Change the parameters of the 'version' radio button and then reprint the new value. Input has to be in a list [input].
br.form['version'] = [version]
if verbose == 'yes':
print(br.find_control(name='version').value)
# Print the parameters of the 'source' RadioControl button and current value
if verbose == 'yes':
print(br.find_control(name='source'), br.find_control(name='source').value)
# Change the parameters of the 'source' radio button and then reprint the new value. Input has to be in a list [input].
br.form['source'] = [source]
if verbose == 'yes':
print(br.find_control(name='source').value)
# This step was the must strange and took a long time. For finding the information and the double negative way.
# One have to enable the pdb button. Read more here: http://wwwsearch.sourceforge.net/old/ClientForm/ ("# All Controls may be disabled.....)
PDBID_control = br.find_control("PDBID")
PDB_control = br.find_control("PDB")
if verbose == 'yes':
print(PDBID_control.disabled, PDB_control.disabled)
if source == "ID":
PDBID_control.disabled = False
PDB_control.disabled = True
if source == "upload":
PDBID_control.disabled = True
PDB_control.disabled = False
if verbose == 'yes':
print(PDBID_control.disabled, PDB_control.disabled)
# We create the result dir, and take with us the 'path' to the result dir.
Newdir = createdirs()
# Open all the files, and assign them.
if source == "upload":
filename = PDB
if source == "ID":
filename = PDBID
files = openfiles(Newdir, filename, logtime, source)
result_pka_file = files[0]
result_input_pka_file = files[1]
result_log = files[2]
filepath = files[3]
result_pka_pkafile = files[4]
result_pka_file_stripped = files[5]
result_pka_file_bonds = files[6]
# Print the parameters of the 'PDBID' TextControl button and current value
if source == "ID" and verbose == 'yes':
print(br.find_control(name='PDBID'))
print(br.find_control(name='PDBID').value)
# Change the parameters of the 'PDBID' TextControl and then reprint the new value. Input has just to be a string.
if source == "ID":
br.form["PDBID"] = PDBID
if source == "ID" and verbose == 'yes':
print(br.find_control(name='PDBID').value)
# Print the parameters of the 'PDB' TextControl button and current value
if source == "upload" and verbose == 'yes':
print(br.find_control(name='PDB'))
print(br.find_control(name='PDB').value)
# Change the parameters of the 'PDB' FileControl and then reprint the new value. Input has just to be a string.
if source == "upload":
PDBfilename = PDB
PDBfilenamepath = PDB
if source == "upload":
br.form.add_file(open(PDBfilename), 'text/plain', PDBfilenamepath, name='PDB')
if source == "upload" and verbose == 'yes':
print(br.find_control(name='PDB'))
print(br.find_control(name='PDB').value)
# Now reprint the current selected form, so we see that we have the right values.
if verbose == 'yes':
print(br.form)
# Make "how" we would like the next request. We would like to "Click the submit button", but we have not opened the request yet.
req = br.click(type="submit", nr=0)
# Have to pass by a mechanize exception. Thats the reason for the why True
# The error was due to: br.open(req)
# mechanize._response.httperror_seek_wrapper: HTTP Error refresh: The HTTP server returned a redirect error that would lead to an infinite loop.
# The last 30x error message was:
# OK
# I haven't been able to find the refresh problem or extend the time. So we make a pass on the raised exception.
try:
print("Now sending request to server")
br.open(req)
# If there is raised an exception, we jump through to the result page after some sleep.
except mechanize.HTTPError:
# We can extract the jobid from the current browser url.
jobid = br.geturl()[32:-5]
# We notice how the script at the server presents the final result page.
url_result = url + "pka/" + jobid + ".html"
# Now we continue to try to find the result page, until we have succes. If page doesn't exist, we wait a little.
while True:
print("Result still not there. Waiting %s seconds more" % server_wait)
time.sleep(float(server_wait))
# To pass the "break" after the exception, we make a hack, wait and then go to the result page, which is the jobid.
try:
page_result = br.open(url_result)
read_result = page_result.read()
# If we don't receive a error in getting the result page, we break out of the while loop.
break
# If the page doesn't exist yet. We go back in the while loop.
except mechanize.HTTPError:
# Wait another round
pass
# If we get a timeout, we also wait.
except mechanize.URLError:
# Wait another round
pass
htmlresult = "The detailed result is now available at: %s" % br.geturl()
print(htmlresult)
read_result = br.response().read()
# Now save the available links from the current page. But only links that satisfy the expression.
links_result = []
for l in br.links(url_regex='http://propka.ki.ku.dk/pka'):
links_result.append(l)
# We also extract the information for neighbour bons. This is given in the url links.
bonds = []
for l in br.links(url_regex='http://propka.ki.ku.dk/view/new_view.cgi'):
l_split = str(l).split()
lresn = l_split[2]
lresi = l_split[3]
lchain = l_split[4]
lurl = l_split[1]
lurl_split = lurl.split("&")
lresn2 = lurl_split[1]
lchain2 = lurl_split[2]
lpka = lurl_split[3]
ldesolvation = lurl_split[4]
lneighbours = lurl_split[5:]
for i in range(len(lneighbours)):
bonds.append([lresn, lresi, lchain, lresn2, lchain2, lpka, ldesolvation, lneighbours[i]])
# Now follow the link to the .propka_input resultpage
if len(links_result) > 1:
br.follow_link(links_result[1])
# Now get the page text for the current link
if len(links_result) > 1:
read_result1 = br.response().read()
# Save the result
if len(links_result) > 1:
result_input_pka_file.write(read_result1)
# Now follow the link to the .pka resultpage
if len(links_result) > 1:
br.back()
result_input_pka_file.close()
# Now follow first link. "Should be" available for all versions of propka.
br.follow_link(links_result[0])
# Now get the page for the current link
read_result0 = br.response().read()
# Save the result and close file.
result_pka_file.write(read_result0)
result_pka_file.close()
# Now get the result in a list, which is sorted
list_results, ligands_results = importpropkaresult(result_pka_pkafile)
# Print to log file
result_log.write("# executed: %s \n# logtime: %s \n# source=%s \n# PDB=%s \n# chain=%s \n# PDBID=%s \n# server_wait=%s version=%s verbose=%s showresult=%s \n# resi=%s resn=%s\n# %s \n" % (time.strftime("%Y%m%d%H%M%S", time.localtime()), logtime, source, PDB, chain, PDBID, server_wait, version, verbose, showresult, resi, resn, htmlresult))
# Print to screen
printpropkaresult(list_results, resi, resi_range, resn, resn_range, showresult, ligands_results)
# Now write to log and the stripped file
for l in list_results:
if resi != "0" and int(l[1]) in resi_range:
result_log.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n')
if resn != "NIL" and l[0] in resn_range and int(l[1]) not in resi_range:
result_log.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n')
result_pka_file_stripped.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n')
for l in ligands_results:
if resn != "NIL" and l[0] in resn_range:
result_log.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n')
result_pka_file_stripped.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n')
result_pka_file_stripped.close()
result_log.close()
# Now handle the bonds. We have to delete dublicates first.
bonds.sort()
last = bonds[-1]
for i in range(len(bonds) - 2, -1, -1):
if last == bonds[i]:
del bonds[i]
else:
last = bonds[i]
# Now make a selection for known residue
bonds_selected = []
bonds_ligands = []
for l in bonds:
if l[0][6:] in ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR', 'C-', 'N+']:
bonds_selected.append(l)
else:
bonds_ligands.append(l)
# And now sort it.
bonds_selected.sort(key=lambda residue: int(residue[1]))
# Now write it to file
bonddic = {'=': ' ', ':': ' ', ',': ' ', "'": " "}
for l in bonds_selected:
nb = replace_all(l[7], bonddic)
result_pka_file_bonds.write("%3s %3s %s %7s %7s %9s %17s %s" % (l[0][6:], l[1], l[2][:1], l[3][8:], l[4], l[5], l[6], nb) + '\n')
for l in bonds_ligands:
nb = replace_all(l[7], bonddic)
result_pka_file_bonds.write("%3s %3s %s %7s %7s %9s %17s %s" % (l[0][6:], l[1], l[2][:1], l[3][8:], l[4], l[5], l[6], nb) + '\n')
result_pka_file_bonds.close()
return(result_pka_pkafile)
if runningpymol != 'no':
cmd.extend("getpropka", getpropka)
def openpymolfiles(pkafile):
result_pka_pymol_name = pkafile.replace(".pka", ".pml")
result_pka_pymol = open(result_pka_pymol_name, "w")
return(result_pka_pymol, result_pka_pymol_name)
def printpropkaresult(list_results, resi, resi_range, resn, resn_range, showresult, ligands_results):
for l in list_results:
if resi != "0" and int(l[1]) in resi_range:
if showresult != 'yes':
print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]))
if resn != "NIL" and l[0] in resn_range and int(l[1]) not in resi_range:
if showresult != 'yes':
print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]))
if showresult == 'yes':
print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]))
for l in ligands_results:
if resn != "NIL" and l[0] in resn_range:
if showresult != 'yes':
print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]))
if showresult == 'yes':
print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]))
def importpropkaresult(result_pka_pkafile):
result_pka_file = open(result_pka_pkafile, "r")
list_results = []
ligands_results = []
##bonding_partners = []
for l in result_pka_file:
if not l.strip():
continue
else:
# To search for the right lines
if l.strip().split()[0] in ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR', 'C-', 'N+'] and len(l.strip().split()) > 20:
list_results.append([l.strip().split()[0], l.strip().split()[1], l.strip().split()[2], l.strip().split()[3], l.strip().split()[4], l.strip().split()[6], l.strip().split()[7], l.strip().split()[8], l.strip().split()[9]])
# bonding_partners.append(l.strip().split()[11]);bonding_partners.append(l.strip().split()[15]);bonding_partners.append(l.strip().split()[19])
if l.strip().split()[0] not in ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR', 'C-', 'N+'] and len(l.strip().split()) > 20:
ligands_results.append([l.strip().split()[0], l.strip().split()[1], l.strip().split()[2], l.strip().split()[3], l.strip().split()[4], l.strip().split()[6], l.strip().split()[7], l.strip().split()[8], l.strip().split()[9]])
# bonding_partners.append(l.strip().split()[11]);bonding_partners.append(l.strip().split()[15]);bonding_partners.append(l.strip().split()[19])
# Sort the result after the residue number and then chain.
list_results.sort(key=lambda residue: int(residue[1]))
list_results.sort(key=lambda chain: chain[2])
# bonding_partners=uniqifi(bonding_partners)
##bonding_partners[:] = [x for x in bonding_partners if x != "XXX"]
result_pka_file.close()
return(list_results, ligands_results)
def importpropkabonds(result_pka_pkafile):
bonds = []
result_pka_file_bonds = open(result_pka_pkafile[:-4] + ".bonds", "r")
for l in result_pka_file_bonds:
bonds.append(l.split())
result_pka_file_bonds.close()
return(bonds)
def createdirs():
if platform.system() == 'Windows':
Newdir = os.getcwd() + "\Results_propka\\"
if platform.system() == 'Linux':
Newdir = os.getcwd() + "/Results_propka/"
if not os.path.exists(Newdir):
os.makedirs(Newdir)
return(Newdir)
def openfiles(Newdir, filename, logtime, source):
if source == "upload":
result_pka_pkafile = filename.replace(".pdb", ".pka")
result_pka_input_pkafile = filename.replace(".pdb", ".propka_input")
result_log_name = "%s_Results.log" % (Newdir)
result_pka_file_stripped_name = filename.replace(".pdb", ".stripped")
result_pka_file_bonds_name = filename.replace(".pdb", ".bonds")
if source == "ID":
result_pka_pkafile = "%s%s%s.pka" % (Newdir, filename, logtime)
result_pka_input_pkafile = "%s%s%s.propka_input" % (Newdir, filename, logtime)
result_log_name = "%s_Results.log" % (Newdir)
result_pka_file_stripped_name = "%s%s%s.stripped" % (Newdir, filename, logtime)
result_pka_file_bonds_name = "%s%s%s.bonds" % (Newdir, filename, logtime)
if platform.system() == 'Windows':
filepath = "\\"
if platform.system() == 'Linux':
filepath = "/"
# Open the files
result_pka_file = open(result_pka_pkafile, "w")
result_input_pka_file = open(result_pka_input_pkafile, "w")
result_log = open(result_log_name, "a")
result_pka_file_stripped = open(result_pka_file_stripped_name, "w")
result_pka_file_bonds = open(result_pka_file_bonds_name, "w")
return(result_pka_file, result_input_pka_file, result_log, filepath, result_pka_pkafile, result_pka_file_stripped, result_pka_file_bonds)
def ResiRange(resi):
resi = resi.split('.')
resiList = []
for i in resi:
if '-' in i:
tmp = i.split('-')
resiList.extend(list(range(int(tmp[0]), int(tmp[-1]) + 1)))
if '-' not in i:
resiList.append(int(i))
return(resiList)
def ResnRange(resn):
resn_split = resn.split('.')
resn_range = [resnr.upper() for resnr in resn_split]
return(resn_range)
def ChainRange(chain):
chainstring = chain.replace(".", "+").upper()
return(chainstring)
def writepymolcmd(newmolecule, pkafile, verbose, makebonds):
list_results, ligands_results = importpropkaresult(pkafile)
# Now find the available bonding partners that pymol knows of
bonding_partners = []
bonding_partners_str = cmd.get_pdbstr("%s and resn * and not resn ASP+GLU+ARG+LYS+HIS+CYS+TYR+GLN+ASN+SER+THR+GLY+PHE+LEU+ALA+ILE+TRP+MET+PRO+VAL+HOH" % (newmolecule))
for i in range(len(bonding_partners_str.splitlines()) - 1):
bonding_partners_split = bonding_partners_str.splitlines()[i].split()
if bonding_partners_split[0] == "HETATM" or bonding_partners_split[0] == "ATOM":
bonding_partners_single = bonding_partners_split[3]
bonding_partners.append(bonding_partners_single)
bonding_partners = uniqifi(bonding_partners)
if verbose == 'yes':
print("And other possible bonding partners is: %s" % bonding_partners)
# Read in the bond file, if it exists
writebonds = "no"
if os.path.isfile(pkafile[:-4] + ".bonds") and makebonds == "yes":
bonds = importpropkabonds(pkafile)
writebonds = "yes"
# Open the pymol command file for writing
files_pka_pymol = openpymolfiles(pkafile)
result_pka_pymol = files_pka_pymol[0]
result_pka_pymol_name = files_pka_pymol[1]
# Make some dictionary for propka->pymol name conversion
dictio = {'ASP': 'CG', 'GLU': 'CD', 'ARG': 'CZ', 'LYS': 'NZ', 'HIS': 'CG', 'CYS': 'SG', 'TYR': 'OH', 'C-': 'C', 'N+': 'N', 'NTR': 'N', 'CTR': 'C', 'GLN': 'CD', 'ASN': 'CG', 'SER': 'OG', 'THR': 'OG1', 'GLY': 'CA', 'PHE': 'CZ', 'LEU': 'CG', 'ALA': 'CB', 'ILE': 'CD1', 'TRP': 'NE1', 'MET': 'SD', 'PRO': 'CG', 'VAL': 'CB'}
dictio2 = {'ASP': 'D', 'GLU': 'E', 'ARG': 'R', 'LYS': 'K', 'HIS': 'H', 'CYS': 'C', 'TYR': 'Y', 'C-': 'C-', 'N+': 'N+'}
# This list is from: http://en.wikipedia.org/wiki/Protein_pKa_calculations
pkaaminoacid = ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR']
pkadictio = {'ASP': 3.9, 'GLU': 4.3, 'ARG': 12.0, 'LYS': 10.5, 'HIS': 6.0, 'CYS': 8.3, 'TYR': 10.1}
# Now start write to the file.
# Try to make silent
# result_pka_pymol.write("cmd.feedback('disable','all','actions')\n")
# result_pka_pymol.write("cmd.feedback('disable','all','results')\n")
# Change the GUI width, to make the long names possible.
result_pka_pymol.write("cmd.set('internal_gui_width','360')\n")
# Set fonts
result_pka_pymol.write("cmd.set('label_font_id','12')\n")
result_pka_pymol.write("cmd.set('label_size','-0.5')\n")
result_pka_pymol.write("cmd.set('label_color','grey')\n")
# No auto zoom the new objects
result_pka_pymol.write("cmd.set('auto_zoom','off')\n")
# The name for the molecules are defined here
pkamolecule = "%spKa" % (newmolecule)
pkalabelmolecule = "%sLab" % (newmolecule)
# Create the groups now, so they come in order. They will be empty
result_pka_pymol.write("cmd.group('%sResi','Res*')\n" % (newmolecule))
result_pka_pymol.write("cmd.group('%sLigands','Lig*')\n" % (newmolecule))
if writebonds == "yes":
result_pka_pymol.write("cmd.group('%sBonds','%sBond*')\n" % (newmolecule, newmolecule))
# Create new empty pymol pka molecules. For pka atoms and its label. This is a "bucket" we where we will put in the atoms together.
result_pka_pymol.write("cmd.create('%s','None')\n" % (pkamolecule))
result_pka_pymol.write("cmd.create('%s','None')\n" % (pkalabelmolecule))
# Now make the pka atoms and alter, color and such
for l in list_results:
name = dictio[l[0]]
resn = dictio2[l[0]]
resi = l[1]
chain = l[2]
pka = l[3]
buried = l[4]
if "*" in pka:
pka = pka.replace("*", "")
comment = "*Coupled residue"
else:
comment = ""
if l[0] in pkaaminoacid:
pkadiff = (float(pka) - pkadictio[l[0]])
pkadiff = "(%s)" % pkadiff
if pka == "99.99":
pkadiff = ""
else:
pkadiff = ""
# Make the selection for which atom to copy
newselection = ("/%s//%s/%s/%s" % (newmolecule, chain, resi, name))
protselect = ("%sRes_%s%s%s" % (newmolecule, chain, resn, resi))
result_pka_pymol.write("cmd.select('%s','byres %s')\n" % (protselect, newselection))
result_pka_pymol.write("cmd.show('sticks','byres %s')\n" % (protselect))
# The temporary name
tempname = ("%s%s%s%s" % (pkamolecule, chain, resi, name))
tempnamelabel = ("%s%s%s%s" % (pkalabelmolecule, chain, resi, name))
tempselect = ("/%s//%s/%s" % (tempname, chain, resi))
tempselectlabel = ("/%s//%s/%s" % (tempnamelabel, chain, resi))
# Copy the atom, call it by the residue name
result_pka_pymol.write("cmd.create('%s','%s',quiet=1)\n" % (tempname, newselection))
# Alter the name and the b value of the newly created atom
result_pka_pymol.write("cmd.alter('%s','b=%s')\n" % (tempselect, pka))
result_pka_pymol.write("cmd.alter('%s','vdw=0.5')\n" % (tempselect))
result_pka_pymol.write("cmd.alter('%s','name=%s%s%s')\n" % (tempselect, '"', pka, '"'))
# Now create a fake label atom, and translate it
result_pka_pymol.write("cmd.create('%s','%s',quiet=1)\n" % (tempnamelabel, tempname))
movelabelxyz = (1.5, 0, 0)
result_pka_pymol.write("cmd.translate('[%s,%s,%s]','%s',camera=0)\n" % (movelabelxyz[0], movelabelxyz[1], movelabelxyz[2], tempnamelabel))
# Labelling alternate positions are not allowed, so we delete that attribute for the label atoms.
result_pka_pymol.write("cmd.alter('%s','alt=%s%s')\n" % (tempselectlabel, '"', '"'))
result_pka_pymol.write("cmd.label('%s','text_type=%spka=%s%s Bu:%s%s%s%s')\n" % (tempselectlabel, '"', pka, pkadiff, buried, '%', comment, '"'))
# Now put the atoms into a bucket of atoms
result_pka_pymol.write("cmd.create('%s','%s or (%s)',quiet=1)\n" % (pkamolecule, pkamolecule, tempselect))
result_pka_pymol.write("cmd.create('%s','%s or (%s)',quiet=1)\n" % (pkalabelmolecule, pkalabelmolecule, tempselectlabel))
# Remove the temporary atoms
result_pka_pymol.write("cmd.remove('%s')\n" % (tempname))
result_pka_pymol.write("cmd.remove('%s')\n" % (tempnamelabel))
# Delete the temporary molecule/selection
result_pka_pymol.write("cmd.delete('%s')\n" % (tempname))
result_pka_pymol.write("cmd.delete('%s')\n" % (tempnamelabel))
# Group the resi together
result_pka_pymol.write("cmd.group('%sResi','%sRes*')\n" % (newmolecule, newmolecule))
for l in ligands_results:
resn = l[0]
atom = l[1]
chain = l[2]
pka = l[3]
buried = l[4]
if verbose == 'yes':
print("Ligand. resn:%s atom:%s chain:%s pka:%s buried:%s" % (resn, atom, chain, pka, buried))
if Check_bonding_partners(bonding_partners, resn)[0]:
if "*" in pka:
pka = pka.replace("*", "")
comment = "*Coupled residue"
else:
comment = ""
# Make the selection for which atom to copy
ligselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, chain, resn, atom))
ligselect = ("%sLig_%s%s%s" % (newmolecule, chain, resn, atom))
result_pka_pymol.write("cmd.select('%s','%s')\n" % (ligselect, ligselection))
result_pka_pymol.write("cmd.show('sticks','byres %s')\n" % (ligselect))
result_pka_pymol.write("cmd.util.cbap('byres %s')\n" % (ligselect))
# The temporary name
tempname = ("%s%s%s%s" % (pkamolecule, chain, resn, atom))
tempnamelabel = ("%s%s%s%s" % (pkalabelmolecule, chain, resn, atom))
tempselect = ("/%s and chain %s and resn %s" % (tempname, chain, resn))
tempselectlabel = ("/%s and chain %s and resn %s" % (tempnamelabel, chain, resn))
# Copy the atom, call it by the residue name
result_pka_pymol.write("cmd.create('%s','%s',quiet=1)\n" % (tempname, ligselection))
# Alter the name and the b value of the newly created atom
result_pka_pymol.write("cmd.alter('%s','b=%s')\n" % (tempselect, pka))
result_pka_pymol.write("cmd.alter('%s','vdw=0.5')\n" % (tempselect))
result_pka_pymol.write("cmd.alter('%s','name=%s%s%s')\n" % (tempselect, '"', pka, '"'))
# Now create a fake label atom, and translate it
result_pka_pymol.write("cmd.create('%s','%s',quiet=1)\n" % (tempnamelabel, tempname))
movelabelxyz = (1.5, 0, 0)
result_pka_pymol.write("cmd.translate('[%s,%s,%s]','%s',camera=0)\n" % (movelabelxyz[0], movelabelxyz[1], movelabelxyz[2], tempnamelabel))
# Labelling alternate positions are not allowed, so we delete that attribute for the label atoms.
result_pka_pymol.write("cmd.alter('%s','alt=%s%s')\n" % (tempselectlabel, '"', '"'))
result_pka_pymol.write("cmd.label('%s','text_type=%spka=%s Bu:%s%s%s%s')\n" % (tempselectlabel, '"', pka, buried, '%', comment, '"'))
# Now put the atoms into a bucket of atoms
result_pka_pymol.write("cmd.create('%s','%s or (%s)',quiet=1)\n" % (pkamolecule, pkamolecule, tempselect))
result_pka_pymol.write("cmd.create('%s','%s or (%s)',quiet=1)\n" % (pkalabelmolecule, pkalabelmolecule, tempselectlabel))
# Remove the temporary atoms
result_pka_pymol.write("cmd.remove('%s')\n" % (tempname))
result_pka_pymol.write("cmd.remove('%s')\n" % (tempnamelabel))
# Delete the temporary molecule/selection
result_pka_pymol.write("cmd.delete('%s')\n" % (tempname))
result_pka_pymol.write("cmd.delete('%s')\n" % (tempnamelabel))
# Group the resi together
result_pka_pymol.write("cmd.group('%sLigands','%sLig*')\n" % (newmolecule, newmolecule))
# Finish the pka atoms, and show spheres
result_pka_pymol.write("cmd.show('spheres','%s')\n" % (pkamolecule))
result_pka_pymol.write("cmd.spectrum('b','red_white_blue',selection='%s',minimum='0',maximum='14')\n" % (pkamolecule))
result_pka_pymol.write("cmd.alter('%s and name 99.9','vdw=0.8')\n" % (pkamolecule))
result_pka_pymol.write("cmd.show('spheres','%s and name 99.9')\n" % (pkamolecule))
result_pka_pymol.write("cmd.color('sulfur','%s and name 99.9')\n" % (pkamolecule))
# Now we make the bonds
if writebonds == "yes":
Bondgroups = []
naturalaminoacids = ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR', 'NTR', 'N+', 'CTR', 'C-', 'GLN', 'ASN', 'SER', 'THR', 'GLY', 'PHE', 'LEU', 'ALA', 'ILE', 'TRP', 'MET', 'PRO', 'VAL']
for l in bonds:
if l[0] in naturalaminoacids:
name = dictio[l[0]]
resi = l[1]
chain = l[2]
desolvation = l[6][12:]
pkachange = l[11]
NBresi = l[8][3:]
NBchain = l[9]
NBbond = l[-1][:2]
if l[8][:3] in naturalaminoacids:
NBname, cutoff = BondTypeName(dictio[l[8][:3]], NBbond)
fromselection = ("/%s//%s/%s/%s" % (newmolecule, chain, resi, name))
toselection = ("/%s//%s/%s/%s" % (newmolecule, NBchain, NBresi, NBname))
if l[8][:3] == 'NTR':
extind = cmd.identify("chain %s and name N" % (NBchain))[0]
toselection = ("/%s and id %s and name N" % (newmolecule, extind))
NBresi = "N+"
if l[8][:3] == 'CTR':
extind = cmd.identify("chain %s and name C" % (NBchain))[-1]
toselection = ("/%s and id %s and name C" % (newmolecule, extind))
NBresi = "C-"
distname = ("%s_%s%s%s%s_%s_%s" % (newmolecule, chain, resi, NBchain, NBresi, NBbond, pkachange))
result_pka_pymol.write("cmd.distance('%s','%s','%s'%s)\n" % (distname, fromselection, toselection, cutoff))
result_pka_pymol.write("cmd.color('%s','%s')\n" % (SetDashColor(NBbond), distname))
# result_pka_pymol.write("cmd.disable('%s')\n"%(distname))
Bondgroups.append("%s%s" % (chain, resi))
if l[8][:3] not in naturalaminoacids and Check_bonding_partners(bonding_partners, l[8])[0]:
cutoff = ""
NBresn = Check_bonding_partners(bonding_partners, l[8])[1]
NBname = l[8][len(NBresn):] + "*"
fromselection = ("/%s//%s/%s/%s" % (newmolecule, chain, resi, name))
toselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, NBchain, NBresn, NBname))
if verbose == 'yes':
print("Res->Ligand: (%s) -> (%s)" % (fromselection, toselection))
result_pka_pymol.write("cmd.show('sticks','%s')\n" % (toselection))
distname = ("%s_%s%s%s_%s_%s" % (newmolecule, chain, resi, NBresn, NBbond, pkachange))
result_pka_pymol.write("cmd.distance('%s','%s','%s'%s)\n" % (distname, fromselection, toselection, cutoff))
result_pka_pymol.write("cmd.color('%s','%s')\n" % (SetDashColor(NBbond), distname))
# result_pka_pymol.write("cmd.disable('%s')\n"%(distname))
Bondgroups.append("%s%s" % (chain, resi))
if l[0] in bonding_partners:
resn = l[0]
atom = l[1]
chain = l[2]
desolvation = l[6][12:]
pkachange = l[11]
NBresi = l[8][3:]
NBchain = l[9]
NBbond = l[-1][:2]
if not Check_bonding_partners(bonding_partners, l[8])[0]:
NBname, cutoff = BondTypeName(dictio[l[8][:3]], NBbond)
fromselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, chain, resn, atom))
toselection = ("/%s//%s/%s/%s" % (newmolecule, NBchain, NBresi, NBname))
if l[8][:3] == 'NTR':
extind = cmd.identify("chain %s and name N" % (NBchain))[0]
toselection = ("/%s and id %s and name N" % (newmolecule, extind))
NBresi = "N+"
if l[8][:3] == 'CTR':
extind = cmd.identify("chain %s and name C" % (NBchain))[-1]
toselection = ("/%s and id %s and name C" % (newmolecule, extind))
NBresi = "C-"
distname = ("%s_%s%s%s%s%s_%s_%s" % (newmolecule, chain, resn, atom, NBchain, NBresi, NBbond, pkachange))
result_pka_pymol.write("cmd.distance('%s','%s','%s'%s)\n" % (distname, fromselection, toselection, cutoff))
result_pka_pymol.write("cmd.color('%s','%s')\n" % (SetDashColor(NBbond), distname))
Bondgroups.append("%s%s%s" % (chain, resn, atom))
# result_pka_pymol.write("cmd.disable('%s')\n"%(distname))
if Check_bonding_partners(bonding_partners, l[8])[0]:
cutoff = ""
NBresn = Check_bonding_partners(bonding_partners, l[8])[1]
NBname = l[8][len(NBresn):] + "*"
fromselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, chain, resn, atom))
toselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, NBchain, NBresn, NBname))
if verbose == 'yes':
print("Ligand->Ligand: (%s) -> (%s)" % (fromselection, toselection))
result_pka_pymol.write("cmd.show('sticks','%s')\n" % (toselection))
distname = ("%s_%s%s%s%s_%s_%s" % (newmolecule, chain, resn, atom, NBresn, NBbond, pkachange))
result_pka_pymol.write("cmd.distance('%s','%s','%s'%s)\n" % (distname, fromselection, toselection, cutoff))
result_pka_pymol.write("cmd.color('%s','%s')\n" % (SetDashColor(NBbond), distname))
# result_pka_pymol.write("cmd.disable('%s')\n"%(distname))
Bondgroups.append("%s%s%s" % (chain, resn, atom))
Bondgroups = uniqifi(Bondgroups)
for l in Bondgroups:
result_pka_pymol.write("cmd.group('%sBonds_%s','%s_%s*')\n" % (newmolecule, l, newmolecule, l))
result_pka_pymol.write("cmd.disable('%sBonds_%s')\n" % (newmolecule, l))
result_pka_pymol.write("cmd.group('%sBonds','%sBonds_*')\n" % (newmolecule, newmolecule))
result_pka_pymol.write("cmd.set('auto_zoom','on')\n")
# result_pka_pymol.write("cmd.feedback('enable','all','actions')\n")
# result_pka_pymol.write("cmd.feedback('enable','all','results')\n")
result_pka_pymol.close()
return(result_pka_pymol_name)
def replace_all(text, dic):
for i, j in dic.items():
text = text.replace(i, j)
return(text)
def uniqifi(seq, idfun=None):
# Order preserving
if idfun is None:
def idfun(x):
return x
seen = {}
result = []
for item in seq:
marker = idfun(item)
if marker in seen:
continue
seen[marker] = 1
result.append(item)
return(result)
def BondTypeName(NBname, NBbond):
if NBbond == "SH":
cutoff = ""
return(NBname, cutoff)
if NBbond == "BH":
cutoff = ""
return("N", cutoff)
else:
cutoff = ""
return(NBname, cutoff)
def Check_bonding_partners(bonding_partners, NBname):
answer = False
for l in bonding_partners:
if l in NBname:
answer = True
NBname = l
break
else:
answer = False
return(answer, NBname)
def SetDashColor(NBbond):
if NBbond == "SH":
color = "brightorange"
if NBbond == "BH":
color = "lightorange"
if NBbond == "CC":
color = "red"
return(color)

View File

@@ -1,58 +0,0 @@
#!/usr/bin/env python
import tkFileDialog
import tkSimpleDialog
from pymol import cmd
import math
from distutils.util import strtobool
def __init__(self):
self.menuBar.addmenuitem('Plugin', 'command', 'Contact map', label='Show contact map', command=lambda s=self: load_map(s))
def load_map(app):
contacts_file = tkFileDialog.askopenfile(initialdir=".", title="Load contact map")
if contacts_file is None:
return
show_contact_map(file=contacts_file)
def show_contact_map(selection="all", file=None, as_bonds=1, quiet=0):
""" Visualize contact map
"""
as_bonds = bool(as_bonds)
quiet = bool(quiet)
contacts = read_contacts(file)
for contact in contacts:
name = "contact{}-{}".format(contact[0], contact[1])
seleA = "id %s and %s" % (contact[0], selection)
seleB = "id %s and %s" % (contact[1], selection)
# skip non-exsistant
if cmd.select("seleA", seleA) == "0" or cmd.select("seleB", seleB) == "0":
print("%s to %s not found!" % (seleA, seleB))
if not quiet:
print("New bond: residue %s to %s" % (contact[0], contact[1]))
if as_bonds:
cmd.bond(seleA, seleB)
else:
cmd.distance(name, seleA, seleB)
cmd.delete('seleA')
cmd.delete('seleB')
def read_contacts(contacts_file, separator=' '):
contacts = []
if not isinstance(contacts_file, file):
contacts_file = open(contacts_file, 'r')
for line in contacts_file.readlines():
split = line.split(",")
resA = int(split[0])
resB = int(split[1])
contacts.append([resA, resB])
contacts_file.close()
return contacts
cmd.extend("contact_map", show_contact_map)

View File

@@ -1,92 +0,0 @@
'''
http://pymolwiki.org/index.php/spectrum_states
(c) 2011 Takanori Nakane and Thomas Holder
License: BSD-2-Clause
'''
from __future__ import print_function
from pymol import cmd, CmdException
def spectrum_states(selection='all', representations='cartoon ribbon',
color_list='blue cyan green yellow orange red',
first=1, last=0, quiet=1):
'''
DESCRIPTION
Color each state in a multi-state object different.
USAGE
spectrum_states [ selection [, representations [, color_list [, first [, last ]]]]]
ARGUMENTS
selection = string: object names (works with complete objects only)
{default: all}
representations = string: space separated list of representations
{default: cartoon ribbon}
color_list = string: space separated list of colors {default: blue cyan
green yellow orange red}
SEE ALSO
spectrum, spectrumany
'''
from math import floor, ceil
first, last, quiet = int(first), int(last), int(quiet)
colors = color_list.split()
if len(colors) < 2:
print(' Error: please provide at least 2 colors')
raise CmdException
colvec = [cmd.get_color_tuple(i) for i in colors]
# filter for valid <repr>_color settings
settings = []
for r in representations.split():
if r[-1] == 's':
r = r[:-1]
s = r + '_color'
if s in cmd.setting.name_list:
settings.append(s)
elif not quiet:
print(' Warning: no such setting:', s)
# object names only
selection = ' '.join(cmd.get_object_list('(' + selection + ')'))
if cmd.count_atoms(selection) == 0:
print(' Error: empty selection')
raise CmdException
if last < 1:
last = cmd.count_states(selection)
val_range = int(last - first + 1)
if val_range < 2:
print(' Error: no spectrum possible, need more than 1 state')
raise CmdException
for i in range(val_range):
p = float(i) / (val_range - 1) * (len(colvec) - 1)
p0, p1 = int(floor(p)), int(ceil(p))
ii = (p - p0)
col_list = [colvec[p1][j] * ii + colvec[p0][j] * (1.0 - ii) for j in range(3)]
col_name = '0x%02x%02x%02x' % (col_list[0] * 255, col_list[1] * 255, col_list[2] * 255)
for s in settings:
cmd.set(s, col_name, selection, state=i + first)
cmd.extend('spectrum_states', spectrum_states)
# tab-completion of arguments
cmd.auto_arg[0]['spectrum_states'] = cmd.auto_arg[0]['disable']
cmd.auto_arg[1]['spectrum_states'] = [cmd.auto_arg[0]['show'][0], 'representation', ' ']
cmd.auto_arg[2]['spectrum_states'] = [cmd.auto_arg[0]['color'][0], 'color', ' ']
# vi:expandtab:smarttab

View File

@@ -1,87 +0,0 @@
#!/usr/bin/env python
import tkFileDialog
import tkSimpleDialog
from pymol import cmd
import math
DEFAULT_CUTOFF = 10
DEFAULT_FLOOR = 0.6
DEFAULT_MAX_CONTACTS = -1
def __init__(self):
self.menuBar.addmenuitem('Plugin', 'command', 'MSA Scores', label='MSA Scores', command=lambda s=self: load_scores_dialog(s))
def load_scores_dialog(app):
scores_file = tkFileDialog.askopenfile(initialdir=".", title="Load scores")
if scores_file is None:
return
cutoff = tkSimpleDialog.askinteger("Cutoff", "Backbone cutoff", initialvalue=DEFAULT_CUTOFF, minvalue=1)
if cutoff is None:
return
floor = tkSimpleDialog.askfloat("Minimal Score", "Minimal Score", initialvalue=DEFAULT_FLOOR)
if floor is None:
return
max_contacts = tkSimpleDialog.askfloat("Limit contacts", "Maximal contacts to show", initialvalue=DEFAULT_MAX_CONTACTS)
if max_contacts is None:
return
show_scores(scores=scores_file, cutoff=cutoff, floor=floor, max_contacts=max_contacts)
def show_scores(selection='all', scores="scores.csv", floor=DEFAULT_FLOOR, cutoff=DEFAULT_CUTOFF, max_contacts=None):
""" Visualize score csv
selection: Selection for visualization
floor: minimal score for visualization
cutoff: minimal distance between amino acids
scores: scores file for visualization
"""
cutoff = int(cutoff)
floor = float(floor)
scores = read_scores(scores)
max_contacts = int(max_contacts)
if max_contacts is None or max_contacts == -1:
max_contacts = len(scores)
# filter for cutoff
scores = list(filter(lambda x: x[1] - x[0] >= cutoff, scores))
# filter for score floor
scores = list(filter(lambda x: x[2] >= floor, scores))
# show distances
counter = 0
for score in scores:
if counter > max_contacts:
print("max contacts reached! (%s contacts not shown)" % (len(scores)-int(max_contacts)))
break
print("new msa contact between %s and %s" % (score[0], score[1]))
name = "msa{}-{}_{:.3f}".format(score[0], score[1], score[2])
seleA = "resid %s and n. CA and %s" % (score[0], selection)
seleB = "resid %s and n. CA and %s" % (score[1], selection)
if cmd.select("seleA", seleA) == "0" or cmd.select("seleB", seleB) == "0":
continue
cmd.distance(name, seleA, seleB)
counter += 1
cmd.delete('seleA')
cmd.delete('seleB')
def read_scores(scores_file):
scores = []
if not isinstance(scores_file, file):
scores_file = open(scores_file, 'r')
for line in scores_file.readlines():
split = line.split(",")
resA = int(split[0])
resB = int(split[1])
score = float(split[2])
dist = abs(resB - resA)
scores.append([resA, resB, score, dist])
scores_file.close()
return scores
def remove_scores():
cmd.delete("msa*")
cmd.extend("remove_scores", remove_scores)
cmd.extend("show_scores", show_scores)

View File

@@ -1,76 +0,0 @@
# general environment
bg_color white
#space cmyk
set fetch_path, /tmp
log_open /tmp/pymol_log.pml
set retain_order
load ~/.pymol/chimera_colors.pml
# interface
set overlay, 1
# performance
set async_builds, on
set max_threads, 8
set cache_mode
set defer_builds_mode, 3
set hash_max, 500
# raytrace
set depth_cue, 0
set ray_opaque_background, false
set orthoscopic, 0
#set ray_shadow, false
set spec_reflect, 0.25
set antialias, 1
set surface_quality, 1
set ray_trace_mode, 0
# hide nonbonded and nbsphreres
set nonbonded_transparency, 1
set nb_spheres_size, 0
# stick settings
set valence, 0
# cartoon
set cartoon_gap_cutoff, 1
set cartoon_side_chain_helper, 1
set cartoon_discrete_colors, on
#set cartoon_highlight_color, gray
set cartoon_oval_length, 0.8
# spheres
set sphere_scale, 0.5
# custom colors
set_color sodium, [1.0, 0.87, 0.37]
set_color potassium, [0.0, 0.5, 1.0]
# bigger dashes
set dash_gap, .35
set dash_length, .3
# shortcuts
set_key F1, toggle sticks, solvent
set_key F2, toggle sticks, (r. POPC or r. POP) and not hydrogen
set_key F3, toggle spheres, inorganic and (n. NA or n. K)
set_key F4, toggle spheres, n. CL
set_key F9, set depth_cue
set_key F10, set depth_cue, off
set_key F11, ray 800,800
set_key F12, ray 1600,1600
alias clean, hide everything, hydrogen or n. 1M* or n. 2M* or n. MC*
alias sf_as_sticks_HCN4, show sticks, residue 478-484 and (not hydrogen or (hydrogen and neighbor (elem O+N+S))) and not (n. 1M* or n. 2M* or n. MC*); hide cartoon, resi 479-483;
alias sf_as_sticks_HCN4_sele, show sticks, sele and residue 478-484 and (not hydrogen or (hydrogen and neighbor (elem O+N+S))) and not (n. 1M* or n. 2M* or n. MC*); hide cartoon, resi 479-483;
alias sideview_HCN4, hide sticks; hide everything, polymer and chain B+D; select polymer and chain A+C; sf_as_sticks_HCN4_sele; deselect;
alias sf_as_sticks_HCN1, show sticks, residue 357-362 and (not hydrogen or (hydrogen and neighbor (elem O+N+S))) and not (n. 1M* or n. 2M* or n. MC*); hide cartoon, resi 358-361
alias ionwatch, hide everything; show cartoon; show spheres, n. NA or n. K; sf_as_sticks_HCN4; hide everything, ID 1-1899; hide everything, ID 3799-5695
alias dockfix, as sticks, bonded and not polymer

View File

@@ -0,0 +1,15 @@
#!/bin/bash
set -e
echo "Installing packages"
sudo apt update -qq
for package in git neovim git ripgrep; do
if dpkg -s "$package" >/dev/null 2>&1; then
echo $package is already installed.
else
echo Installing $package
sudo apt install -y $package
fi
done

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
if ! type zsh > /dev/null; then
echo "Cannnot change default shell to zsh: not installed"
else
# Make ZSH the default shell environment
if [ $(cat /etc/passwd | grep $USER | awk -F ':' '{print substr($7, length($7)-3)}') != "/zsh" ]; then
echo "Changing shell to zsh."
chsh -s $(which zsh)
else
echo "Shell is already zsh."
fi
# Antidote Installation
if [ ! -d "$HOME/.antidote" ]; then
echo "Installing Antidote"
# make sure git is installed
if ! type git > /dev/null; then
echo "Git not installed. Cannot install antidote"
else
git clone --depth=1 https://github.com/mattmc3/antidote.git $HOME/.antidote
fi
else
echo "Antidote already exists."
fi
fi

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env sh
if [ ! -d "$HOME/.fzf" ]; then
echo "Installing fzf into ~/.fzf"
git clone --depth 1 https://github.com/junegunn/fzf.git $HOME/.fzf
if [ ! -f "$HOME/.fzf/bin" ]; then
$HOME/.fzf/install --completion --key-bindings --update-rc
fi
fi

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
if [ ! -f "$HOME/.local/bin/diff-so-fancy" ]; then
echo "Installing diff-so-fance into .local/bin"
if [ ! -d "$HOME/.local/lib/diff-so-fancy" ]; then
git clone --depth 1 https://github.com/so-fancy/diff-so-fancy.git $HOME/.local/lib/diff-so-fancy
fi
ln -s $HOME/.local/lib/diff-so-fancy/diff-so-fancy $HOME/.local/bin/diff-so-fancy
fi

View File

@@ -0,0 +1,7 @@
#!/usr/bin/env sh
if [ ! -d "$HOME/.vim/autoload" ]; then
echo "setup vim plug"
curl -fLo $HOME/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
fi