#!/usr/bin/perl -w # make-chimera -mix foo.mix < super.pdb > chimera.pdb # # makes a chimeric conformation by mixing residues from two more models from stdin. # The mix file contains lines of the form # 2 1:13 13A 14:16 # 1 17:28 # 2 32:43 # 1 44 # # where the first non-blank on the line defines the model number and the # rest specifies a PDB number or range of PDB numbers. # Kevin Karplus 20 Sept 2004 use strict; use English; use File::Basename; use Getopt::Long; use Pod::Usage; # add a mapping from $key->$data, if it is not conflicting with # existing mapping sub add_key(\%$$) { my ($whichref, $key, $data) = @_; if (! defined($$whichref{$key})) { $$whichref{$key} = $data; return; } return if ($$whichref{$key} eq $data); die "Error: $key specified as both $$whichref{$key} and $data\n"; } # main { my $mix_file; GetOptions( "mix=s" => \$mix_file , "help|?" => sub {pod2usage("verbose"=>1);} , "man" => sub {pod2usage("verbose"=>2);} ) or pod2usage("verbose" => 0); pod2usage("verbose" => 0) if (!defined($mix_file)); my %which_model; # hash mapping pdbid # (including insertion code if not blank) to # model to use open(MIX, "<$mix_file") || die("Couldn't read mix_file $mix_file\n"); while () { my ($model, @ranges) = split; next if ($model =~ /^#/); # skip comments foreach my $range (@ranges) { if ($range =~ /(\d+):(\d+)/) { foreach my $id ($1 .. $2) { add_key(%which_model, $id, $model); } } else { add_key(%which_model, $range, $model); } } } close MIX; my @residue_order; # order of residues, taken from first model my %atoms; # atom lines for a residue my $model=1; my $copy_residue_order=1; my $residue_count=0; # how many residues read from first model my $old_id=""; while() { if (/^MODEL/) { $model = substr($_, 10, 4); $copy_residue_order = ! defined($residue_order[0]); next; } next if ! /^ATOM /; # only read atom records # get the residue id my $id = substr($_, 22, 5); $id =~ tr/ //d; if ($copy_residue_order && ($id ne $old_id)) { $residue_order[$residue_count++] = $id; $old_id=$id; } # print STDERR "DEBUG: which_model{$id} = $which_model{$id}\n"; if (defined($which_model{$id})? ($model == $which_model{$id}) : $copy_residue_order) { $atoms{$id} .= $_; } } foreach my $id (@residue_order) { print $atoms{$id}; } } __END__ =pod =head1 NAME make-chimera =head1 SYNOPSIS make-chimera -mix foo.mix < super.pdb > chimera.pdb makes a chimeric conformation by mixing ATOM records for residues from two or more models from stdin. The assumption is that the models in the input are different conformations of the same protein, and that they have been optimally superimposed. =head1 OPTIONS =over 4 =item B<-help> Print a brief help message and exits. =item B<-man> Prints the manual page and exits. =item B<-mix> filename Required parameter (no default). Specifies what model each residue is to be copied from. The mix file has any number of lines, each of which starts with a model number, followed by white-space separated PDB numbers or PDB-number ranges. The PDB numbers may contain an insertion code. A range consists of a pair of integer PDB numbers (no insertion codes), separated by a colon (no white space). The mix file may include comment lines starting with #, but does not currently support comments on the same lines as the pdb numbers or ranges. A chimeric conformation is made by copying the residues from the specified models. If no model is specified for a residue, then the first model (whatever it is numbered) is assumed. =back =head1 DESCRIPTION =cut