#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2004-07-28 14:22 PDT by <conrad@cicero.cgl.ucsf.edu>.
# Source directory was `/home/conrad'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#   2891 -rw-rw-r-- ksdssp/README
#   2228 -rw-rw-r-- ksdssp/Atom.h
#   2349 -rw-rw-r-- ksdssp/ListArray.h
#   4836 -rw-rw-r-- ksdssp/List.h
#   1187 -rw-rw-r-- ksdssp/Makefile
#  20075 -rw-rw-r-- ksdssp/Model.cc
#   3370 -rw-rw-r-- ksdssp/Model.h
#   6130 -rw-rw-r-- ksdssp/Residue.cc
#   3268 -rw-rw-r-- ksdssp/Residue.h
#   2369 -rw-rw-r-- ksdssp/SquareArray.h
#   3207 -rw-rw-r-- ksdssp/Structure.h
#   4458 -rw-rw-r-- ksdssp/Structure.cc
#   4473 -rw-rw-r-- ksdssp/ksdssp.1
#   5855 -rw-rw-r-- ksdssp/ksdssp.cc
#   2228 -rwxrwxr-x ksdssp/ksdssp.csh.sed
#   1783 -rw-rw-r-- ksdssp/ksdssp.h
#   3861 -rw-rw-r-- ksdssp/misc.cc
#   2317 -rw-rw-r-- ksdssp/misc.h
#   4403 -rw-rw-r-- ksdssp/ksdssp.html
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
  shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
  shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
  shar_touch='touch -am $3$4$5$6$2 "$8"'
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
#
if mkdir _sh13329; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= ksdssp/README ==============
if test ! -d 'ksdssp'; then
  $echo 'x -' 'creating directory' 'ksdssp'
  mkdir 'ksdssp'
fi
if test -f 'ksdssp/README' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/README' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/README' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/README' &&
This is an implementation of
X
X	Dictionary of Protein Secondary Structure: Pattern Recognition
X	of Hydrogen-Bonded and Geometrical Features.
X	Wolfgang Kabsch and Christian Sander
X	Biopolymers, Vol. 22, 2577-2637 (1983)
X
or better known as "dssp".  This program is being distributed in
source form under the following license:
X
X
* Copyright (c) 2002 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*   1. Redistributions of source code must retain the above copyright
*      notice, this list of conditions, and the following disclaimer.
*   2. 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.
*   3. Redistributions must acknowledge that this software was
*      originally developed by the UCSF Computer Graphics Laboratory
*      under support by the NIH National Center for Research Resources,
*      grant P41-RR01081.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "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 REGENTS 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.
X
X
To compile this program, you will also need the Protein Data Bank
record I/O library, available via the UCSF Computer Graphics Laboratory
software web page (http://www.cgl.ucsf.edu/Overview/software.html).
BE SURE TO GET THE C++ VERSION OF THE LIBRARY.
X
Once you have the pdb++ library compiled, you can compile ksdssp by
editing the Makefile in this directory and fixing the definitions for
the following:
X
X	CXX		C++ compiler
X	LINKER		Linker that works with C++ code
X	OPT		Options to pass to the compiler
X	PDBINCDIR	Name of directory containing the pdb++ header file
X	LFLAGS		Options to pass to the linker
X	PDBLIBDIR	Name of directory containing the pdb++ library/archive
X
After fixing Makefile, you should be able to type "make" and create the
executable file "ksdssp".  Documentation for using the program may be
found in "ksdssp.1" in Unix manual page format, or "ksdssp.html" in
HyperText Mark-up Language.
X
Please send problem reports and comments to midas-bugs@cgl.ucsf.edu.
SHAR_EOF
  (set 20 04 07 28 14 05 16 'ksdssp/README'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/README' ||
  $echo 'restore of' 'ksdssp/README' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/README:' 'MD5 check failed'
6d11d57df8b9a784c91cbf2fe72996ba  ksdssp/README
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/README'`"
    test 2891 -eq "$shar_count" ||
    $echo 'ksdssp/README:' 'original size' '2891,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/Atom.h ==============
if test -f 'ksdssp/Atom.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/Atom.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/Atom.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/Atom.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef atom_h
#define atom_h
X
#include <stdio.h>
#include <string>
X
class Atom {
X	std::string	name_;
X	float		coord_[3];
public:
X			Atom(const std::string &name, double coord[3]);
X			Atom(const std::string &name, float coord[3]);
X	const std::string	&name(void) const { return name_; }
X	const float	*coord(void) const { return coord_; }
};
X
inline
Atom::Atom(const std::string &name, double coord[3])
X	: name_(name)
{
X	for (int i = 0; i < 3; i++)
X		coord_[i] = coord[i];
}
X
inline
Atom::Atom(const std::string &name, float coord[3])
X	: name_(name)
{
X	for (int i = 0; i < 3; i++)
X		coord_[i] = coord[i];
}
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 05 16 'ksdssp/Atom.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/Atom.h' ||
  $echo 'restore of' 'ksdssp/Atom.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/Atom.h:' 'MD5 check failed'
8055474ed0c44fb51920d9a8b70a02be  ksdssp/Atom.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/Atom.h'`"
    test 2228 -eq "$shar_count" ||
    $echo 'ksdssp/Atom.h:' 'original size' '2228,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/ListArray.h ==============
if test -f 'ksdssp/ListArray.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/ListArray.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/ListArray.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/ListArray.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef listarray_h
#define listarray_h
X
#include "List.h"
X
template <class T>
class ListArray {
X	int		size_;
X	T		**array_;
public:
X			ListArray(const List<T> &list);
X			~ListArray(void);
X	T		*operator()(int n) const;
X	int		count(void) const;
};
X
template <class T>
ListArray<T>::ListArray(const List<T> &list)
{
X	size_ = list.count();
X	array_ = new T *[size_];
X	int i = 0;
X	for (Pix p = list.first(); p != 0; list.next(p))
X		array_[i++] = list(p);
}
X
template <class T>
ListArray<T>::~ListArray(void)
{
X	delete[] array_;
}
X
template <class T>
T *
ListArray<T>::operator()(int n) const
{
X	if (n < 0 || n >= size_)
X		return NULL;
X	return array_[n];
}
X
template <class T>
int
ListArray<T>::count(void) const
{
X	return size_;
}
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 05 16 'ksdssp/ListArray.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/ListArray.h' ||
  $echo 'restore of' 'ksdssp/ListArray.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/ListArray.h:' 'MD5 check failed'
62a47ca21a2cb53630135645f2f3badf  ksdssp/ListArray.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/ListArray.h'`"
    test 2349 -eq "$shar_count" ||
    $echo 'ksdssp/ListArray.h:' 'original size' '2349,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/List.h ==============
if test -f 'ksdssp/List.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/List.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/List.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/List.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef LIST_INCLUDE
#define	LIST_INCLUDE
X
#include <stddef.h>
X
typedef void	*Pix;
X
template <class T>
class ListItem	{
X	ListItem<T>	*_next;
X	T		*_value;
public:
X			ListItem(T *value)
X				{
X					_next = NULL;
X					_value = value;
X				}
X	void		append(ListItem<T> *element)
X				{
X					ListItem<T> *n;
X					for (n = this; n->_next != NULL;
X					n = n->_next)
X						continue;
X					n->_next = element;
X				}
X	ListItem<T>	*next(void) const
X				{
X					return _next;
X				}
X	void		setNext(ListItem<T> *n)
X				{
X					_next = n;
X				}
X	T		*value(void) const
X				{
X					return _value;
X				}
};
X
template <class T>
class List	{
X	ListItem<T>	*_head;
public:
X			List(void);
X			List(List *orig);
X			~List(void);
X	int		add(T *element);
X	int		append(T *element);
X	int		remove(T *element);
X	void		clear(void);
X	T		*head(void);
X	T		*pop(void);
X	T		*find(const void *data, int (*match)(const T *t,
X						const void *mdata)) const;
X
X	int		count(void) const;
X	Pix		first(void) const;
X	void		next(Pix &p) const;
X	T		*operator()(Pix p) const;
};
X
//
// Implementation of List
//
X
template <class T>
List<T>::List(void)
{
X	_head = NULL;
}
X
template <class T>
List<T>::List(List *orig)
{
X	// This constructor is mainly used in functions that return
X	// a list.  The function can create a local list, then
X	//	return List(&local_list);
X	// which should prevent a deep copy (that we don't currently provide)
X	_head = orig->_head;
X	orig->_head = NULL;
}
X
template <class T>
List<T>::~List(void)
{
X	clear();
}
X
template <class T>
int
List<T>::add(T *element)
{
X	ListItem<T> *item = new ListItem<T>(element);
X	item->append(_head);
X	_head = item;
X	return 0;
}
X
template <class T>
int
List<T>::append(T *element)
{
X	ListItem<T> *item = new ListItem<T>(element);
X	if (_head == NULL)
X		_head = item;
X	else
X		_head->append(item);
X	return 0;
}
X
template <class T>
int
List<T>::remove(T *element)
{
X	ListItem<T> *p = NULL;
X	ListItem<T> *t;
X	for (t = _head; t != NULL; p = t, t = t->next())
X		if (t->value() == element)
X			break;
X	if (t == NULL)
X		return -1;
X	if (p == NULL)
X		_head = t->next();
X	else
X		p->setNext(t->next());
X	delete t;
X	return 0;
}
X
template <class T>
void
List<T>::clear(void)
{
X
X	while (_head != NULL) {
X		ListItem<T> *n = _head->next();
X		delete _head;
X		_head = n;
X	}
}
X
template <class T>
T *
List<T>::head(void)
{
X	if (_head == NULL)
X		return NULL;
X	return _head->value();
}
X
template <class T>
T *
List<T>::pop(void)
{
X	if (_head == NULL)
X		return NULL;
X	T *v = _head->value();
X	ListItem<T> *n = _head->next();
X	delete _head;
X	_head = n;
X	return v;
}
X
template <class T>
T *
List<T>::find(const void *data, int (*match)(const T *t, const void *mdata))
X		const
{
X	for (Pix p = first(); p != 0; next(p)) {
X		T *element = (*this)(p);
X		if ((*match)(element, data))
X			return element;
X	}
X	return NULL;
}
X
template <class T>
int
List<T>::count(void) const
{
X	int count = 0;
X	for (ListItem<T> *item = _head; item != NULL; item = item->next())
X		count++;
X	return count;
}
X
template <class T>
Pix	
List<T>::first(void) const
{
X	return _head;
}
X
template <class T>
void
List<T>::next(Pix &p) const
{
X	p = ((ListItem<T> *) p)->next();
}
X
template <class T>
T *
List<T>::operator()(Pix p) const
{
X	return ((ListItem<T> *) p)->value();
}
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 05 16 'ksdssp/List.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/List.h' ||
  $echo 'restore of' 'ksdssp/List.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/List.h:' 'MD5 check failed'
1591e76dffe73dfb1637af40125570a0  ksdssp/List.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/List.h'`"
    test 4836 -eq "$shar_count" ||
    $echo 'ksdssp/List.h:' 'original size' '4836,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/Makefile ==============
if test -f 'ksdssp/Makefile' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/Makefile' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/Makefile' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/Makefile' &&
SHELL		= /bin/sh
X
CXX		= g++
LINKER		= g++
X
OPT		= -O
PDBINCDIR	= ../libpdb++
CFLAGS		= $(OPT) -I$(PDBINCDIR)
X
LFLAGS		=
PDBLIBDIR	= ../libpdb++
LIBRARIES	= -L$(PDBLIBDIR) -lpdb++ -lm
X
#
# MODIFY ITEMS BELOW AT YOUR OWN RISK
#
X
X.SUFFIXES:	.cc
X.cc.o:
X	$(CXX) $(CFLAGS) -c $< -o $@
X
PROG	= ksdssp
X
HDRS	= Atom.h ListArray.h Residue.h Structure.h misc.h \
X	  List.h Model.h SquareArray.h ksdssp.h
SRCS	= ksdssp.cc Model.cc Residue.cc Structure.cc misc.cc
OBJS	= ksdssp.o Model.o Residue.o Structure.o misc.o
X
$(PROG):	$(OBJS)
X	$(LINKER) $(LFLAGS) $(OBJS) $(LIBRARIES) -o $@
X
ksdssp.csh: ksdssp.csh.sed
X	sed s\|BINDIR\|${BINDIR}\| < ${.CURDIR}/ksdssp.csh.sed > ${.TARGET}
X	chmod +x ${.TARGET}
X
clean:
X	-rm -f $(OBJS)
X	-rm -rf ii_files cxx_repository
X
distclean:	clean
X	-rm -f $(PROG)
X
ksdssp.o:	ksdssp.cc ksdssp.h Model.h Residue.h Atom.h List.h \
X		ListArray.h SquareArray.h Structure.h \
X		${PDBINCDIR}/pdb++.h
X
Model.o:	Model.cc ksdssp.h Model.h Residue.h Atom.h List.h \
X		ListArray.h SquareArray.h Structure.h misc.h \
X		${PDBINCDIR}/pdb++.h
X
Residue.o:	Residue.cc ksdssp.h Residue.h Atom.h List.h misc.h
X
Structure.o:	Structure.cc Structure.h List.h
X
misc.o:		misc.cc ksdssp.h misc.h 
SHAR_EOF
  (set 20 04 07 28 14 13 54 'ksdssp/Makefile'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/Makefile' ||
  $echo 'restore of' 'ksdssp/Makefile' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/Makefile:' 'MD5 check failed'
d3c565a7307cbb931c5e17f2f26e1737  ksdssp/Makefile
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/Makefile'`"
    test 1187 -eq "$shar_count" ||
    $echo 'ksdssp/Makefile:' 'original size' '1187,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/Model.cc ==============
if test -f 'ksdssp/Model.cc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/Model.cc' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/Model.cc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/Model.cc' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#include <ctype.h>
#include <string.h>
#include "ksdssp.h"
#include "Model.h"
#include "misc.h"
X
#ifndef DONT_INSTANIATE
template class List<Residue>;
template class ListArray<Residue>;
template class SquareArray<char>;
template class List<Helix>;
template class List<Ladder>;
template class List<Sheet>;
#endif
X
static int	curModelNumber = -1;
static int	minStrandLength = 3;
static int	minHelixLength = 3;
static int	checkBulges = 1;
X
inline int
min(int i1, int i2)
{
X	return i1 < i2 ? i1 : i2;
}
X
inline int
max(int i1, int i2)
{
X	return i1 > i2 ? i1 : i2;
}
X
//
// Constructor for Model (read residues/atoms from PDB file)
//
Model::Model(FILE *input)
X	: error_(), rList_(), helixList_(), ladderList_(), sheetList_(),
X	  fileRecord_(PDB::USER_FILE)
{
X	Residue *r = NULL;
X	anyMore_ = 0;
X	char buf[256];
X	modelNumber_ = curModelNumber;
X	while (fgets(buf, sizeof buf, input) != NULL) {
X		PDB pdb(buf);
X		switch (pdb.type()) {
X		  case PDB::ATOM: {
X			PDB::Atom &a = pdb.atom;
X			if (a.residue.chainId == '\0')
X				a.residue.chainId = ' ';
X			if (a.residue.insertCode == '\0')
X				a.residue.insertCode = ' ';
X			if (r == NULL || !r->sameAs(a.residue)) {
X				r = new Residue(a.residue);
X				rList_.append(r);
X			}
X			r->addAtom(new Atom(a.name, a.xyz));
X			break;
X		  }
X		  case PDB::TER:
X			if (r != NULL)
X				r->setFlag(R_TER);
X			anyMore_ = 1;
X			goto done;
X		  case PDB::USER_FILE:
X			fileRecord_ = pdb;
X			curModelNumber = pdb.userFile.model;
X			modelNumber_ = curModelNumber;
X			break;
X		  case PDB::END:
X			curModelNumber = -1;
X			anyMore_ = 1;
X			goto done;
X		}
X	}
done:
X	if (rList_.count() > 0) {
X		rArray_ = new ListArray<Residue>(rList_);
X		hBond_ = new SquareArray<char>(rArray_->count());
X	}
}
X
//
// Destructor for Model (get rid of residue list)
//
Model::~Model(void)
{
X	Pix p;
X	for (p = rList_.first(); p != 0; rList_.next(p))
X		delete rList_(p);
X	for (p = helixList_.first(); p != 0; helixList_.next(p))
X		delete helixList_(p);
X	for (p = ladderList_.first(); p != 0; ladderList_.next(p))
X		delete ladderList_(p);
X	for (p = sheetList_.first(); p != 0; sheetList_.next(p))
X		delete sheetList_(p);
X	if (rList_.count() > 0) {
X		delete rArray_;
X		delete hBond_;
X	}
}
X
//
// Define secondary structure using K&S definition
//
void
Model::defineSecondaryStructure(void)
{
X	addImideHydrogens();
X	findHBonds();
X
X	findTurns(3);
X	markHelices(3);
X	findTurns(4);
X	markHelices(4);
X	findHelices();
X
X	findBridges();
X	findSheets();
}
X
//
// Print list of residues to given file
//
void
Model::printResidues(FILE *output) const
{
X	int sn = 1;
X	for (Pix p = rList_.first(); p != 0; rList_.next(p))
X		sn = rList_(p)->printAtoms(output, sn);
}
X
//
// Print summary of residues
//
void
Model::printSummary(FILE *output) const
{
X	(void) fputs("Helix Summary\n", output);
X	Pix p;
X	for (p = helixList_.first(); p != 0; helixList_.next(p)) {
X		Helix *h = helixList_(p);
X		const PDB::Residue &from = residue(h->from())->residue();
X		const PDB::Residue &to = residue(h->to())->residue();
X		(void) fprintf(output, "%2d: %4d%c[%c] -> %4d%c[%c]\n",
X			h->type(),
X			from.seqNum, from.chainId, from.insertCode,
X			to.seqNum, to.chainId, to.insertCode);
X	}
X	(void) fputs("\n", output);
X
X	(void) fputs("Ladder Summary\n", output);
X	for (p = ladderList_.first(); p != 0; ladderList_.next(p)) {
X		Ladder *l = ladderList_(p);
X		const PDB::Residue &f0 = residue(l->start(0))->residue();
X		const PDB::Residue &t0 = residue(l->end(0))->residue();
X		const PDB::Residue &f1 = residue(l->start(1))->residue();
X		const PDB::Residue &t1 = residue(l->end(1))->residue();
X		(void) fprintf(output, "%c %4d%c[%c] -> %4d%c[%c] "
X			"%-12s %4d%c[%c] -> %4d%c[%c]\n",
X			l->name(),
X			f0.seqNum, f0.chainId, f0.insertCode,
X			t0.seqNum, t0.chainId, t0.insertCode,
X			l->type() == B_PARA ? "parallel" : "antiparallel",
X			f1.seqNum, f1.chainId, f1.insertCode,
X			t1.seqNum, t1.chainId, t1.insertCode);
X	}
X	(void) fputs("\n", output);
X
X	(void) fputs("Sheet Summary\n", output);
X	for (p = sheetList_.first(); p != 0; sheetList_.next(p)) {
X		Sheet *s = sheetList_(p);
X		(void) fprintf(output, "Sheet %c:\n", s->name());
X		Ladder *fl = s->firstLadder();
X		Ladder *pl = NULL;
X		Ladder *spl = NULL;
X		for (Ladder *l = fl; l != NULL && !(l == fl && pl != NULL);
X		spl = l, l = l->otherNeighbor(pl), pl = spl) {
X			char n0 = l->neighbor(0) == NULL ? '-' :
X					l->neighbor(0)->name();
X			char n1 = l->neighbor(1) == NULL ? '-' :
X					l->neighbor(1)->name();
X			(void) fprintf(output, "\tLadder %c: %c %c\n",
X						l->name(), n0, n1);
X		}
X	}
X	(void) fputs("\n", output);
X
X	(void) fputs("Residue Summary\n", output);
X	for (p = rList_.first(); p != 0; rList_.next(p))
X		rList_(p)->printSummary(output);
}
X
//
// Print pdb HELIX records
// id is a zero-based counter of the number of HELIX records printed
//
int
Model::printHelix(FILE *output, int id) const
{
X	PDB pdb(PDB::HELIX);
X
X	PDB::Helix &helix = pdb.helix;
X	helix.comment[0] = '\0';
X	for (Pix p = helixList_.first(); p != 0; helixList_.next(p)) {
X		id++;
X		Helix *h = helixList_(p);
X		helix.serialNum = id;
X		(void) sprintf(helix.id, "%d", id);
X		helix.residues[0] = residue(h->from())->residue();
X		helix.residues[1] = residue(h->to())->residue();
X		helix.type = h->type();
X		(void) fprintf(output, "%-71.71s%5d\n", pdb.chars(),
X				h->to() - h->from() + 1);
X	}
X	return id;
}
X
//
// Print pdb SHEET records
// sid is a zero-based counter of the number of HELIX records printed
//
char
Model::printSheet(FILE *output, int sid) const
{
X	//
X	// Printing the sheet records is a bit tricky because
X	// we need to derive the strands from the ladders.
X	// We do so by first creating an ordered array of the
X	// ladders.  We then define the first strand (method
X	// depends on whether the sheet is cyclic or not), and
X	// then iterate through.  We also have to do some post-
X	// processing if the sheet is cyclic
X	//
X	PDB pdb(PDB::SHEET);
X	PDB::Sheet &sheet = pdb.sheet;
X	for (Pix p = sheetList_.first(); p != 0; sheetList_.next(p)) {
X		Sheet *s = sheetList_(p);
X		Ladder *fl = s->firstLadder();
X		Ladder *pl = NULL;
X		Ladder *spl = NULL;
X		int ladderCount = s->ladderList().count();
X		Ladder **lList = new Ladder *[ladderCount];
X		int i = 0;
X		for (Ladder *l = fl; l != NULL && !(l == fl && pl != NULL);
X		spl = l, l = l->otherNeighbor(pl), pl = spl)
X			lList[i++] = l;
X		if (i != ladderCount) {
X			(void) fprintf(stderr,
X				"Inconsistent ladder count for sheet %c "
X				"(%d should be %d)\n",
X				s->name(), i, ladderCount);
X			ladderCount = i;
X		}
X		int cyclic = fl->neighborCount() > 1;
X		int overlap[2];
X
X		PDB firstStrand(PDB::SHEET);
X		PDB::Sheet &firstSheet = firstStrand.sheet;
X		char sheetId[4];
X		int idLen = 0;
X		int idCount = sid++;
X		sheetId[idLen++] = 'A' + (idCount % 26);
X		idCount = idCount / 26;
X		while (idLen < 3 && idCount > 0) {
X			sheetId[idLen++] = 'A' + (idCount % 26) - 1;
X			idCount = idCount / 26;
X		}
X		char *idPtr = firstSheet.id;
X		while (--idLen >= 0)
X			*idPtr++ = sheetId[idLen];
X		*idPtr++ = '\0';
X		firstSheet.count = ladderCount;
X		firstSheet.strandNum = 1;
X		firstSheet.sense = 0;
X		if (cyclic) {
X			pl = lList[ladderCount - 1];
X			(void) fl->overlaps(pl, overlap);
X			int start = min(fl->start(overlap[0]),
X					pl->start(overlap[1]));
X			int end = max(fl->end(overlap[0]),
X					pl->end(overlap[1]));
X			firstSheet.residues[0] = residue(start)->residue();
X			firstSheet.residues[1] = residue(end)->residue();
X			(void) fprintf(output, "%s\n", firstStrand.chars());
X			registerLadder(pl, &firstSheet, overlap[1]);
X		}
X		else {
X			firstSheet.count++;
X			if (ladderCount == 1)
X				// If there is only one ladder, then we print
X				// strand 0 first, then strand 1
X				overlap[0] = 0;
X			else {
X				// If there are more than one ladder, then
X				// we find the overlapping strand with the
X				// next ladder and use the other one
X				(void) fl->overlaps(lList[1], overlap);
X				overlap[0] = 1 - overlap[0];
X			}
X			firstSheet.residues[0] =
X				residue(fl->start(overlap[0]))->residue();
X			firstSheet.residues[1] =
X				residue(fl->end(overlap[0]))->residue();
X			(void) fprintf(output, "%s\n", firstStrand.chars());
X		}
X
X		sheet = firstSheet;
X		for (i = 1; i < ladderCount; i++) {
X			Ladder *l = lList[i];
X			pl = lList[i - 1];
X			(void) l->overlaps(pl, overlap);
X			sheet.strandNum++;
X			int start = min(l->start(overlap[0]),
X					pl->start(overlap[1]));
X			int end = max(l->end(overlap[0]),
X					pl->end(overlap[1]));
X			sheet.residues[0] = residue(start)->residue();
X			sheet.residues[1] = residue(end)->residue();
X			registerLadder(pl, &sheet, 1 - overlap[1]);
X			(void) fprintf(output, "%s\n", pdb.chars());
X		}
X
X		if (cyclic)
X			(void) fprintf(output, "%s\n", firstStrand.chars());
X		else {
X			sheet.strandNum++;
X			int n = 1 - overlap[0];
X			Ladder *&last = lList[ladderCount - 1];
X			sheet.residues[0] = residue(last->start(n))->residue();
X			sheet.residues[1] = residue(last->end(n))->residue();
X			registerLadder(last, &sheet, overlap[0]);
X			(void) fprintf(output, "%s\n", pdb.chars());
X		}
X		delete [] lList;
X	}
X	return sid;
}
X
//
// Set minimum number of residues in a helix
//
void
Model::setMinHelixLength(int n)
{
X	minHelixLength = n;
}
X
//
// Set minimum number of residues in a strand
//
void
Model::setMinStrandLength(int n)
{
X	minStrandLength = n;
}
X
//
// Set whether we should try to merge ladders in beta-bulges
//
void
Model::ignoreBulges(void)
{
X	checkBulges = 0;
}
X
//
// Add the imide hydrogens to all residue
//
void
Model::addImideHydrogens(void)
{
X	Pix p = rList_.first();
X	Residue *prev = rList_(p);
X	for (rList_.next(p); p != 0; rList_.next(p)) {
X		Residue *r = rList_(p);
X		(void) r->addImideHydrogen(prev);
X		if (r->flag(R_TER))
X			prev = NULL;
X		else
X			prev = r;
X	}
}
X
//
// Find hydrogen bonds
//
void
Model::findHBonds(void)
{
X	int max = rArray_->count();
X	for (int i = 0; i < max; i++)
X		for (int j = i + 2; j < max; j++) {
X			(*hBond_)(i, j) = residue(i)->hBondedTo(residue(j));
X			(*hBond_)(j, i) = residue(j)->hBondedTo(residue(i));
X		}
}
X
//
// Find the n-turns (n = 3,4)
//
void
Model::findTurns(int n)
{
X	int donor = n == 3 ? R_3DONOR : R_4DONOR;
X	int acceptor = n == 3 ? R_3ACCEPTOR : R_4ACCEPTOR;
X	int gap = n == 3 ? R_3GAP : R_4GAP;
X	int max = rArray_->count() - n;
X	for (int i = 0; i < max; i++)
X		if (hBonded(i, i + n)) {
X			residue(i)->setFlag(acceptor);
X			for (int j = 1; j < n; j++)
X				residue(i + j)->setFlag(gap);
X			residue(i + n)->setFlag(donor);
X		}
}
X
//
// Mark helices based on n-turn information
//
void
Model::markHelices(int n)
{
X	int donor = n == 3 ? R_3DONOR : R_4DONOR;
X	int acceptor = n == 3 ? R_3ACCEPTOR : R_4ACCEPTOR;
X	int gap = n == 3 ? R_3GAP : R_4GAP;
X	int helix = n == 3 ? R_3HELIX : R_4HELIX;
X	int max = rArray_->count() - n;
X	for (int i = 1; i < max; i++)
X		if (residue(i - 1)->flag(acceptor)
X		&&  residue(i)->flag(acceptor))
X			for (int j = 0; j < n; j++)
X				residue(i + j)->setFlag(helix);
}
X
//
// Construct helices based on marker information
//
void
Model::findHelices(void)
{
X	int max = rArray_->count();
X	int first = -1;
X	for (int i = 0; i < max; i++)
X		if (residue(i)->flag(R_3HELIX | R_4HELIX)) {
X			if (first < 0)
X				first = i;
X		}
X		else if (first >= 0) {
X			if (i - first >= minHelixLength) {
X				Helix *h = new Helix(first, i - 1);
X				helixList_.append(h);
X				h->setType(helixClass(h));
X			}
X			first = -1;
X		}
}
X
//
// Find bridges
//
void
Model::findBridges(void)
{
X	int max = rArray_->count();
X
X	// First we construct a matrix and mark the bridges
X	SquareArray<char> bridge(max);
X	bridge.zero();
X	int i;
X	for (i = 1; i < max; i++) {
X		for (int j = i + 1; j < max; j++) {
X			if ((hBonded(i - 1, j) && hBonded(j, i + 1))
X			||  (hBonded(j - 1, i) && hBonded(i, j + 1))) {
X				bridge(i, j) = 'P';
X				residue(i)->setFlag(R_PBRIDGE);
X				residue(j)->setFlag(R_PBRIDGE);
X			}
X			else if ((hBonded(i, j) && hBonded(j, i))
X			|| (hBonded(i - 1, j + 1) && hBonded(j - 1, i + 1))) {
X				bridge(i, j) = 'A';
X				residue(i)->setFlag(R_ABRIDGE);
X				residue(j)->setFlag(R_ABRIDGE);
X			}
X		}
X	}
X
X	// Now we loop through and find the ladders
X	int k;
X	for (i = 0; i < max; i++) {
X		for (int j = i + 1; j < max; j++) {
X			switch (bridge(i, j)) {
X			  case 'P':
X				for (k = 0; bridge(i + k, j + k) == 'P'; k++) 
X					bridge(i + k, j + k) = 'p';
X				k--;
X				ladderList_.append(new Ladder(B_PARA,
X								i, i + k,
X								j, j + k));
X				break;
X			  case 'A':
X				for (k = 0; bridge(i + k, j - k) == 'A'; k++) 
X					bridge(i + k, j - k) = 'a';
X				k--;
X				ladderList_.append(new Ladder(B_ANTI,
X								i, i + k,
X								j - k , j));
X				break;
X			}
X		}
X	}
X
X	// Now we merge ladders of beta-bulges
X	if (checkBulges)
X		while (findBetaBulge())
X			continue;
X
X	// Finally we get rid of any ladder that is too short
X	// (on either strand)
X	int pruned;
X	do {
X		pruned = 0;
X		for (Pix p = ladderList_.first(); p != 0; ladderList_.next(p)) {
X			Ladder *l = ladderList_(p);
X			if (l->end(0) - l->start(0) + 1 < minStrandLength
X			||  l->end(1) - l->start(1) + 1 < minStrandLength) {
X				ladderList_.remove(l);
X				pruned = 1;
X				break;
X			}
X		}
X	} while (pruned);
}
X
//
// Find beta-bulges and merge the ladders
//
int
Model::findBetaBulge(void)
{
X	for (Pix p1 = ladderList_.first(); p1 != 0; ladderList_.next(p1)) {
X		Ladder *l1 = ladderList_(p1);
X		if (l1->isBulge())
X			continue;
X		Pix p2 = p1;
X		for (ladderList_.next(p2); p2 != 0; ladderList_.next(p2)) {
X			Ladder *l2 = ladderList_(p2);
X			if (l2->isBulge())
X				continue;
X			Ladder *l = Ladder::mergeBulge(l1, l2);
X			if (l != NULL) {
X				ladderList_.remove(l1);
X				ladderList_.remove(l2);
X				ladderList_.append(l);
X				return 1;
X			}
X		}
X	}
X	return 0;
}
X
//
// Find beta-sheet based on ladder information
//
void
Model::findSheets(void)
{
X	char sName = 'A';
X	for (Pix p = ladderList_.first(); p != 0; ladderList_.next(p)) {
X		Ladder *l = ladderList_(p);
X		if (l->sheet() != NULL)
X			continue;
X		Sheet *s = new Sheet(sName);
X		sheetList_.append(s);
X		if (sName == 'Z')
X			sName = 'A';
X		else
X			sName++;
X		markLadder(l, s);
X	}
}
X
//
// Mark this ladder (and all overlapped ladders, including closure)
// as part of given sheet
//
void
Model::markLadder(Ladder *ladder, Sheet *sheet)
{
X	sheet->addLadder(ladder);
X	ladder->setSheet(sheet);
X	for (Pix p = ladderList_.first(); p != 0; ladderList_.next(p)) {
X		Ladder *l = ladderList_(p);
X		if (l->sheet() != NULL)
X			continue;
X		int overlap[2];
X		if (!l->overlaps(ladder, overlap))
X			continue;
X		if (l->neighbor(overlap[0]) != NULL) {
X			reportOverlap(l, overlap[0],
X					ladder, l->neighbor(overlap[0]));
X			continue;
X		}
X		if (ladder->neighbor(overlap[1]) != NULL) {
X			reportOverlap(ladder, overlap[1],
X					l, ladder->neighbor(overlap[1]));
X			continue;
X		}
X		l->setNeighbor(overlap[0], ladder);
X		ladder->setNeighbor(overlap[1], l);
X		markLadder(l, sheet);
X	}
}
X
//
// Report a ladder as overlapping on the same side with two other ladders
//
void
Model::reportOverlap(const Ladder *l, int side,
X			const Ladder *o1, const Ladder *o2) const
{
X	const PDB::Residue &first = residue(l->start(side))->residue();
X	const PDB::Residue &last = residue(l->end(side))->residue();
X	const PDB::Residue &ofirst = residue(l->start(1 - side))->residue();
X	const PDB::Residue &olast = residue(l->end(1 - side))->residue();
X	(void) fprintf(stderr,
X		"Strand %d%c[%c]-%d%c[%c] (%d%c[%c]-%d%c[%c]) "
X		"is paired with multiple ladders\n",
X		first.seqNum, first.chainId, first.insertCode,
X		last.seqNum, last.chainId, last.insertCode,
X		ofirst.seqNum, ofirst.chainId, ofirst.insertCode,
X		olast.seqNum, olast.chainId, olast.insertCode);
X
X	const PDB::Residue &s10 = residue(o1->start(0))->residue();
X	const PDB::Residue &e10 = residue(o1->end(0))->residue();
X	const PDB::Residue &s11 = residue(o1->start(1))->residue();
X	const PDB::Residue &e11 = residue(o1->end(1))->residue();
X	(void) fprintf(stderr,
X		"\t1 - Ladder %d%c[%c]-%d%c[%c], %d%c[%c]-%d%c[%c]\n",
X		s10.seqNum, s10.chainId, s10.insertCode,
X		e10.seqNum, e10.chainId, e10.insertCode,
X		s11.seqNum, s11.chainId, s11.insertCode,
X		e11.seqNum, e11.chainId, e11.insertCode);
X
X	const PDB::Residue &s20 = residue(o2->start(0))->residue();
X	const PDB::Residue &e20 = residue(o2->end(0))->residue();
X	const PDB::Residue &s21 = residue(o2->start(1))->residue();
X	const PDB::Residue &e21 = residue(o2->end(1))->residue();
X	(void) fprintf(stderr,
X		"\t2 - Ladder %d%c[%c]-%d%c[%c], %d%c[%c]-%d%c[%c]\n",
X		s20.seqNum, s20.chainId, s20.insertCode,
X		e20.seqNum, e20.chainId, e20.insertCode,
X		s21.seqNum, s21.chainId, s21.insertCode,
X		e21.seqNum, e21.chainId, e21.insertCode);
}
X
//
// Generate registration information for given ladder
//
void
Model::registerLadder(const Ladder *l, PDB::Sheet *sheet, int prev) const
{
X	int cur = 1 - prev;
X	if (l->type() == B_PARA) {
X		//
X		// We know that hBond(l->start(prev), l->start(cur))
X		//
X		sheet->sense = 1;
X		Residue *r = residue(l->start(prev));
X		if (r->hBondedTo(residue(l->start(cur) + 1))) {
X			(void) strcpy(sheet->atoms[1].name, " O");
X			sheet->atoms[1].residue = r->residue();
X			r = residue(l->start(cur) + 1);
X			(void) strcpy(sheet->atoms[0].name, " N");
X			sheet->atoms[0].residue = r->residue();
X		}
X		else {
X			r = residue(l->start(prev) + 1);
X			(void) strcpy(sheet->atoms[1].name, " O");
X			sheet->atoms[1].residue = r->residue();
X			r = residue(l->start(cur));
X			(void) strcpy(sheet->atoms[0].name, " N");
X			sheet->atoms[0].residue = r->residue();
X		}
X	}
X	else {
X		//
X		// We know that hBond(l->start(prev), l->end(cur))
X		//
X		sheet->sense = -1;
X		Residue *r = residue(l->start(prev));
X		if (r->hBondedTo(residue(l->end(cur)))) {
X			(void) strcpy(sheet->atoms[1].name, " O");
X			sheet->atoms[1].residue = r->residue();
X			r = residue(l->end(cur));
X			(void) strcpy(sheet->atoms[0].name, " N");
X			sheet->atoms[0].residue = r->residue();
X		}
X		else {
X			r = residue(l->start(prev) + 1);
X			(void) strcpy(sheet->atoms[1].name, " O");
X			sheet->atoms[1].residue = r->residue();
X			r = residue(l->end(cur) - 1);
X			(void) strcpy(sheet->atoms[0].name, " N");
X			sheet->atoms[0].residue = r->residue();
X		}
X	}
}
X
//
// Determine the PDB class of the helix
//
int
Model::helixClass(const Helix *h) const
{
X	Atom *ca[4];
X	int from = h->from();
X	Residue *r = residue(from);
X	for (int i = 0; i < 4; i++) {
X		ca[i] = residue(from + i)->atom(" CA");
X		if (ca[i] == NULL)
X			return 0;
X	}
X	float angle = dihedral(ca[0]->coord(), ca[1]->coord(),
X				ca[2]->coord(), ca[3]->coord());
X	if (angle > 0) {
X		if (r->flag(R_4HELIX))
X			return 1;
X		else if (r->flag(R_3HELIX))
X			return 5;
X	}
X	else {
X		if (r->flag(R_4HELIX))
X			return 6;
X	}
X	return 0;
}
SHAR_EOF
  (set 20 04 07 28 14 05 16 'ksdssp/Model.cc'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/Model.cc' ||
  $echo 'restore of' 'ksdssp/Model.cc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/Model.cc:' 'MD5 check failed'
c788ec69b1b0027fff9662405150cd6d  ksdssp/Model.cc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/Model.cc'`"
    test 20075 -eq "$shar_count" ||
    $echo 'ksdssp/Model.cc:' 'original size' '20075,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/Model.h ==============
if test -f 'ksdssp/Model.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/Model.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/Model.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/Model.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef model_h
#define model_h
X
#include <stdio.h>
#include <string>
#include "Residue.h"
#include "List.h"
#include "ListArray.h"
#include "SquareArray.h"
#include "Structure.h"
X
class Model {
X	int			anyMore_;
X	std::string		error_;
X	List<Residue>		rList_;
X	ListArray<Residue>	*rArray_;
X	SquareArray<char>	*hBond_;
X	List<Helix>		helixList_;
X	List<Ladder>		ladderList_;
X	List<Sheet>		sheetList_;
X	int			modelNumber_;
X	PDB			fileRecord_;
public:
X			Model(FILE *input);
X			~Model(void);
X	int		okay(void) const { return error_ == ""; }
X	int		anyMore(void) const { return anyMore_; }
X	int		anyAtoms(void) const { return rList_.count() > 0; }
X	const char	*error(void) const { return error_.c_str(); }
X	int		modelNumber(void) const { return modelNumber_; }
X	const PDB	&fileRecord(void) const { return fileRecord_; }
X	void		defineSecondaryStructure(void);
X	void		printResidues(FILE *output) const;
X	void		printSummary(FILE *output) const;
X	int		printHelix(FILE *output, int id) const;
X	char		printSheet(FILE *output, int id) const;
public:
X	static void	setMinStrandLength(int n);
X	static void	setMinHelixLength(int n);
X	static void	ignoreBulges(void);
private:
X	int		hBonded(int i, int j) { return (*hBond_)(i, j); }
X	Residue		*residue(int n) const { return (*rArray_)(n); }
X	void		addImideHydrogens(void);
X	void		findHBonds(void);
X	void		findTurns(int n);
X	void		markHelices(int n);
X	void		findHelices(void);
X	void		findBridges(void);
X	int		findBetaBulge(void);
X	void		findSheets(void);
X	void		markLadder(Ladder *ladder, Sheet *sheet);
X	void		reportOverlap(const Ladder *l, int s, const Ladder *o1,
X					const Ladder *o2) const;
X	void		registerLadder(const Ladder *l, PDB::Sheet *sheet,
X					int prev) const;
X	int		helixClass(const Helix *h) const;
};
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/Model.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/Model.h' ||
  $echo 'restore of' 'ksdssp/Model.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/Model.h:' 'MD5 check failed'
40ff94f44daa23eeca6681b3a4232b4a  ksdssp/Model.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/Model.h'`"
    test 3370 -eq "$shar_count" ||
    $echo 'ksdssp/Model.h:' 'original size' '3370,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/Residue.cc ==============
if test -f 'ksdssp/Residue.cc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/Residue.cc' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/Residue.cc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/Residue.cc' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#include <math.h>
#include <string.h>
#include "ksdssp.h"
#include "Residue.h"
#include "misc.h"
X
#ifndef DONT_INSTANIATE
template class List<Atom>;
#endif
X
static float	hBondCutoff = -0.5;
X
//
// Check if two PDB residues are the same
//
int
Residue::sameAs(const PDB::Residue &r) const
{
X	if (r.seqNum != residue_.seqNum)
X		return 0;
X	if (r.chainId != residue_.chainId)
X		return 0;
X	if (r.insertCode != residue_.insertCode)
X		return 0;
X	if (strncmp(r.name, residue_.name, sizeof (PDB::RName)) != 0)
X		return 0;
X	return 1;
}
X
//
// Add the imide hydrogen if it is missing
//
int
Residue::addImideHydrogen(const Residue *prev)
{
X	if (prev == NULL || atom(" H") != NULL)
X		return 0;		// Already there
X	Atom *n = atom(" N");
X	if (n == NULL) {
X		if (verbose)
X			(void) fprintf(stderr,
X				"N missing in residue %d%c[%c]\n",
X				residue_.seqNum, residue_.chainId,
X				residue_.insertCode);
X		return -1;
X	}
X	Atom *ca = atom(" CA");
X	if (ca == NULL) {
X		if (verbose)
X			(void) fprintf(stderr,
X				"CA missing in residue %d%c[%c]\n",
X				residue_.seqNum, residue_.chainId,
X				residue_.insertCode);
X		return -1;
X	}
X	Atom *c = prev->atom(" C");
X	if (c == NULL) {
X		if (verbose)
X			(void) fprintf(stderr,
X				"C missing in residue %d%c[%c]\n",
X				prev->residue().seqNum,
X				prev->residue().chainId,
X				prev->residue().insertCode);
X		return -1;
X	}
X	Atom *o = prev->atom(" O");
X	if (o == NULL) {
X		if (verbose)
X			(void) fprintf(stderr,
X				"O missing in residue %d%c[%c]\n",
X				prev->residue().seqNum,
X				prev->residue().chainId,
X				prev->residue().insertCode);
X		return -1;
X	}
X
X	const float *nCoord = n->coord();
X	const float *caCoord = ca->coord();
X	const float *cCoord = c->coord();
X	const float *oCoord = o->coord();
X	float v1[3], v2[3], v3[3];
X	int i;
X	for (i = 0; i < 3; i++) {
X		v1[i] = caCoord[i] - nCoord[i];
X		v2[i] = cCoord[i] - nCoord[i];
X		v3[i] = oCoord[i] - cCoord[i];
X	}
X	normalize(v1);
X	normalize(v2);
X	normalize(v3);
X	float p1[3], hDir[3];
X	bisect(p1, v1, v2);
X	bisect(hDir, p1, v3);
X
X	const float nhLength = 1.01;
X	float hCoord[3];
X	for (i = 0; i < 3; i++)
X		hCoord[i] = nCoord[i] - nhLength * hDir[i];
X
X	addAtom(new Atom(" H", hCoord));
X	return 0;
}
X
//
// Check if other residue is hydrogen bonded to this one
//
int
Residue::hBondedTo(const Residue *other) const
{
X	const float q1 = 0.42;
X	const float q2 = 0.20;
X	const float f = 332;
X
X	Atom *c = atom(" C");
X	Atom *o = atom(" O");
X	if (c == NULL || o == NULL)
X		return 0;
X	Atom *n = other->atom(" N");
X	Atom *h = other->atom(" H");
X	if (n == NULL || h == NULL)
X		return 0;
X	float rCN = distSquared(c->coord(), n->coord());
X	if (rCN > 49.0)		// Optimize a little bit
X		return 0;
X	rCN = sqrtf(rCN);
X	float rON = distance(o->coord(), n->coord());
X	float rCH = distance(c->coord(), h->coord());
X	float rOH = distance(o->coord(), h->coord());
X
X	float E = q1 * q2 * (1 / rON + 1 / rCH - 1 / rOH - 1 / rCN) * f;
X	return E < hBondCutoff;
}
X
//
// Print atom list to output stream
//
int
Residue::printAtoms(FILE *output, int sn) const
{
X	for (Pix p = aList_.first(); p != 0; aList_.next(p)) {
X		Atom *a = aList_(p);
X		const float *c = a->coord();
X		PDB pdb(PDB::ATOM);
X		PDB::Atom &atom = pdb.atom;
X		atom.serialNum = sn++;
X		(void) strncpy(atom.name, a->name().c_str(),
X				sizeof (PDB::AName));
X		atom.residue = residue_;
X		for (int i = 0; i < 3; i++)
X			atom.xyz[i] = c[i];
X		(void) fprintf(output, "%s\n", pdb.chars());
X	}
X	return sn;
}
X
//
// Print summary of residue state
//
void
Residue::printSummary(FILE *output) const
{
X	char summary = ' ';
X	if (flag(R_3HELIX))
X		summary = 'G';
X	else if (flag(R_4HELIX))
X		summary = 'H';
X	else if (flag(R_PBRIDGE | R_ABRIDGE))
X		summary = 'E';
X
X	char turn3 = ' ';
X	if (flag(R_3DONOR) && flag(R_3ACCEPTOR))
X		turn3 = 'X';
X	else if (flag(R_3ACCEPTOR))
X		turn3 = '>';
X	else if (flag(R_3DONOR))
X		turn3 = '<';
X	else if (flag(R_3GAP))
X		turn3 = '3';
X
X	char turn4 = ' ';
X	if (flag(R_4DONOR) && flag(R_4ACCEPTOR))
X		turn4 = 'X';
X	else if (flag(R_4ACCEPTOR))
X		turn4 = '>';
X	else if (flag(R_4DONOR))
X		turn4 = '<';
X	else if (flag(R_4GAP))
X		turn4 = '4';
X
X	char bridge = ' ';
X	if (flag(R_PBRIDGE) && flag(R_ABRIDGE))
X		bridge = '+';
X	else if (flag(R_PBRIDGE))
X		bridge = 'p';
X	else if (flag(R_ABRIDGE))
X		bridge = 'A';
X
X	(void) fprintf(output, "%4.4s %4d%c[%c] -> %c %c %c %c\n",
X		residue_.name, residue_.seqNum,
X		residue_.chainId, residue_.insertCode,
X		summary, turn3, turn4, bridge);
}
X
//
// Set the energy cutoff for hydrogen bondedness
//
void
Residue::setHBondCutoff(float cutoff)
{
X	hBondCutoff = cutoff;
}
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/Residue.cc'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/Residue.cc' ||
  $echo 'restore of' 'ksdssp/Residue.cc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/Residue.cc:' 'MD5 check failed'
0ff386110a8630d3617497222ec00842  ksdssp/Residue.cc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/Residue.cc'`"
    test 6130 -eq "$shar_count" ||
    $echo 'ksdssp/Residue.cc:' 'original size' '6130,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/Residue.h ==============
if test -f 'ksdssp/Residue.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/Residue.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/Residue.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/Residue.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef residue_h
#define residue_h
X
#ifdef NEED_BOOL
#define	bool	int
#define	false	0
#define	true	1
#endif
X
#include <stdio.h>
#include <pdb++.h>
#include "Atom.h"
#include "List.h"
X
#define	R_3DONOR	0x0001
#define	R_3ACCEPTOR	0x0002
#define	R_3GAP		0x0004
#define	R_3HELIX	0x0008
#define	R_4DONOR	0x0010
#define	R_4ACCEPTOR	0x0020
#define	R_4GAP		0x0040
#define	R_4HELIX	0x0080
#define	R_PBRIDGE	0x0100
#define	R_ABRIDGE	0x0200
#define	R_TER		0x8000
X
class Residue;
X
class Residue {
X	PDB::Residue	residue_;
X	List<Atom>	aList_;
X	int		flags_;
public:
X			Residue(const PDB::Residue &r);
X			~Residue(void);
X	const PDB::Residue &
X			residue(void) const { return residue_; }
X	void		addAtom(Atom *a);
X	int		addImideHydrogen(const Residue *prev);
X	Atom		*atom(const std::string &name) const;
X	int		sameAs(const PDB::Residue &r) const;
X	int		hBondedTo(const Residue *other) const;
X	int		printAtoms(FILE *output, int sn) const;
X	void		printSummary(FILE *output) const;
X	int		flag(int f) const;
X	void		setFlag(int f);
public:
X	static void	setHBondCutoff(float cutoff);
};
X
inline
Residue::Residue(const PDB::Residue &r)
X	: aList_()
{
X	residue_ = r;
X	flags_ = 0;
}
X
inline
Residue::~Residue(void)
{
X	for (Pix p = aList_.first(); p != 0; aList_.next(p))
X		delete aList_(p);
}
X
inline void
Residue::addAtom(Atom *a)
{
X	aList_.append(a);
}
X
inline Atom *
Residue::atom(const std::string &name) const
{
X	for (Pix p = aList_.first(); p != 0; aList_.next(p)) {
X		Atom *a = aList_(p);
X		if (a->name() == name)
X			return a;
X	}
X	return NULL;
}
X
inline int
Residue::flag(int f) const
{
X	return flags_ & f;
}
X
inline void
Residue::setFlag(int f)
{
X	flags_ |= f;
}
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/Residue.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/Residue.h' ||
  $echo 'restore of' 'ksdssp/Residue.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/Residue.h:' 'MD5 check failed'
c9a2a28ff7fde1cd349ae01cfe51fefa  ksdssp/Residue.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/Residue.h'`"
    test 3268 -eq "$shar_count" ||
    $echo 'ksdssp/Residue.h:' 'original size' '3268,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/SquareArray.h ==============
if test -f 'ksdssp/SquareArray.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/SquareArray.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/SquareArray.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/SquareArray.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef squarearray_h
#define squarearray_h
X
#include <string.h>
X
template <class T>
class SquareArray
{
X	int		dim_;
X	T		*array_;
public:
X			SquareArray(int size);
X			~SquareArray(void);
X	void		zero(void);
X	int		dimension(void) const;
X	T		&operator()(int row, int col);
};
X
template <class T>
SquareArray<T>::SquareArray(int size)
{
X	dim_ = size;
X	array_ = new T[dim_ * dim_];
}
X
template <class T>
SquareArray<T>::~SquareArray(void)
{
X	delete[] array_;
}
X
template <class T>
int
SquareArray<T>::dimension(void) const
{
X	return dim_;
}
X
template <class T>
void
SquareArray<T>::zero(void)
{
X	memset(array_, 0, dim_ * dim_ * sizeof (T));
}
X
template <class T>
T &
SquareArray<T>::operator()(int row, int col)
{
X	return array_[row * dim_ + col];
}
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/SquareArray.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/SquareArray.h' ||
  $echo 'restore of' 'ksdssp/SquareArray.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/SquareArray.h:' 'MD5 check failed'
9311ee2fae6983c7691407d96ec5ab70  ksdssp/SquareArray.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/SquareArray.h'`"
    test 2369 -eq "$shar_count" ||
    $echo 'ksdssp/SquareArray.h:' 'original size' '2369,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/Structure.h ==============
if test -f 'ksdssp/Structure.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/Structure.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/Structure.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/Structure.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef structure_h
#define structure_h
X
#include "List.h"
X
#define	B_PARA	1
#define	B_ANTI	2
X
class Sheet;
X
class Helix {
X	int	from_, to_;
X	int	type_;		// For pdb HELIX record
public:
X		Helix(int from, int to)
X			{ from_ = from; to_ = to; type_ = 0; }
X	int	type(void) const { return type_; }
X	int	from(void) const { return from_; }
X	int	to(void) const { return to_; }
X	void	setType(int t) { type_ = t; }
};
X
class Ladder {
X	char	name_;
X	int	type_;
X	int	start_[2], end_[2];
X	Ladder	*neighbor_[2];
X	Sheet	*sheet_;
X	int	isBulge_;
public:
X		Ladder(int type, int s1, int e1, int s2, int e2);
X	int	type(void) const { return type_; }
X	int	start(int n) const { return start_[n]; }
X	int	end(int n) const { return end_[n]; }
X	char	name(void) const { return name_; }
X	void	setName(char n);
X	Sheet	*sheet(void) const { return sheet_; }
X	void	setSheet(Sheet *s) { sheet_ = s; }
X	Ladder	*neighbor(int n) const { return neighbor_[n]; }
X	void	setNeighbor(int n, Ladder *l) { neighbor_[n] = l; }
X	int	isBulge(void) const { return isBulge_; }
X	void	setBulge(void) { isBulge_ = 1; }
X	int	overlaps(const Ladder *l, int overlap[2]) const;
X	Ladder	*otherNeighbor(Ladder *l) const;
X	int	neighborCount(void) const;
public:
X	static Ladder
X		*mergeBulge(const Ladder *l1, const Ladder *l2);
};
X
class Sheet {
X	char		name_;
X	List<Ladder>	ladderList_;
public:
X		Sheet(char name) : ladderList_() { name_ = name; }
X	char	name(void) const { return name_; }
X	void	addLadder(Ladder *l) { ladderList_.append(l); }
X	const List<Ladder> &
X		ladderList(void) const { return ladderList_; }
X	Ladder	*firstLadder(void);
};
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/Structure.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/Structure.h' ||
  $echo 'restore of' 'ksdssp/Structure.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/Structure.h:' 'MD5 check failed'
cfc96d888601621a72db53c07bb69cba  ksdssp/Structure.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/Structure.h'`"
    test 3207 -eq "$shar_count" ||
    $echo 'ksdssp/Structure.h:' 'original size' '3207,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/Structure.cc ==============
if test -f 'ksdssp/Structure.cc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/Structure.cc' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/Structure.cc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/Structure.cc' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#include <stdio.h>
#include <ctype.h>
#include "Structure.h"
X
//
// Constructor for Ladder
//
Ladder::Ladder(int type, int s1, int e1, int s2, int e2)
{
X	name_ = '?';
X	type_ = type;
X	neighbor_[0] = NULL;
X	neighbor_[1] = NULL;
X	sheet_ = NULL;
X	isBulge_ = 0;
X	if (s1 < e1) {
X		start_[0] = s1;
X		end_[0] = e1;
X	}
X	else {
X		start_[0] = e1;
X		end_[0] = s1;
X	}
X	if (s2 < e2) {
X		start_[1] = s2;
X		end_[1] = e2;
X	}
X	else {
X		start_[1] = e2;
X		end_[1] = s2;
X	}
}
X
//
// Set the name of this ladder
//
void
Ladder::setName(char n)
{
X	if (type() == B_PARA)
X		name_ = isupper(n) ? tolower(n) : n;
X	else
X		name_ = islower(n) ? toupper(n) : n;
}
X
//
// Check if two ladders overlap (share a residue)
//
int
Ladder::overlaps(const Ladder *l, int overlap[2]) const
{
X	for (int i = 0; i < 2; i++) {
X		int s1 = start(i);
X		int e1 = end(i);
X		for (int j = 0; j < 2; j++) {
X			int s2 = l->start(j);
X			int e2 = l->end(j);
X			if (e1 >= s2 && e2 >= s1) {
X				overlap[0] = i;
X				overlap[1] = j;
X				return 1;
X			}
X		}
X	}
X	return 0;
}
X
//
// Return neighbor which is not the given neighbor
//
Ladder *
Ladder::otherNeighbor(Ladder *l) const
{
X	if (neighbor_[0] == l)
X		return neighbor_[1];
X	return neighbor_[0];
}
X
//
// Check number of neighbors
//
int
Ladder::neighborCount(void) const
{
X	int count = 0;
X	if (neighbor_[0] != NULL)
X		count++;
X	if (neighbor_[1] != NULL)
X		count++;
X	return count;
}
X
//
// Check whether two ladders should merge to form a beta bulge
// We take advantage of some properties of how the ladders were generated:
//	start/end(0) < start/end(1)
//
// Beta-bulge as defined by K&S:
//	"a bulge-linked ladder consists of two (perfect)
//	ladders or bridges of the same type connected by
//	at most one extra residue on one strand and at most
//	four residues on the other strand."
//
Ladder *
Ladder::mergeBulge(const Ladder *l1, const Ladder *l2)
{
X	if (l1->type() != l2->type())
X		return NULL;
X	// Make sure that l1 precedes l2
X	if (l1->start(0) > l2->start(0)) {
X		const Ladder *tmp = l1;
X		l1 = l2;
X		l2 = tmp;
X	}
X
X	int d0 = l2->start(0) - l1->end(0);
X	if (d0 < 0 || d0 > 4)
X		return NULL;
X	int d1;
X	if (l1->type() == B_PARA)
X		d1 = l2->start(1) - l1->end(1);
X	else
X		d1 = l1->start(1) - l2->end(1);
X	if (d1 < 0 || d1 > 4)
X		return NULL;
X	if (d0 > 1 && d1 > 1)
X		return NULL;
X
X	int s0 = l1->start(0);
X	int e0 = l2->end(0);
X	int s1, e1;
X	if (l1->type() == B_PARA) {
X		s1 = l1->start(1);
X		e1 = l2->end(1);
X	}
X	else {
X		s1 = l2->start(1);
X		e1 = l1->end(1);
X	}
X	Ladder *l = new Ladder(l1->type(), s0, e0, s1, e1);
X	l->setBulge();
X	return l;
}
X
//
// Find a ladder on one end of the sheet (or a random one
// if its a barrel)
//
Ladder *
Sheet::firstLadder(void)
{
X	for (Pix p = ladderList_.first(); p != 0; ladderList_.next(p)) {
X		Ladder *l = ladderList_(p);
X		if (l->neighborCount() == 1)
X			return l;
X	}
X	return ladderList_.head();
}
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/Structure.cc'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/Structure.cc' ||
  $echo 'restore of' 'ksdssp/Structure.cc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/Structure.cc:' 'MD5 check failed'
da223a026977d619fb94b5f347e48aa0  ksdssp/Structure.cc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/Structure.cc'`"
    test 4458 -eq "$shar_count" ||
    $echo 'ksdssp/Structure.cc:' 'original size' '4458,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/ksdssp.1 ==============
if test -f 'ksdssp/ksdssp.1' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/ksdssp.1' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/ksdssp.1' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/ksdssp.1' &&
X.\"
X.\"Copyright (c) 2002 The Regents of the University of California.
X.\"All rights reserved.
X.\"
X.\"Redistribution and use in source and binary forms, with or without
X.\"modification, are permitted provided that the following conditions
X.\"are met:
X.\"  1. Redistributions of source code must retain the above copyright
X.\"     notice, this list of conditions, and the following disclaimer.
X.\"  2. Redistributions in binary form must reproduce the above
X.\"     copyright notice, this list of conditions, and the following
X.\"     disclaimer in the documentation and/or other materials provided
X.\"     with the distribution.
X.\"  3. Redistributions must acknowledge that this software was
X.\"     originally developed by the UCSF Computer Graphics Laboratory
X.\"     under support by the NIH National Center for Research Resources,
X.\"     grant P41-RR01081.
X.\"
X.\"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X.\"EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X.\"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X.\"PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X.\"FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X.\"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X.\"OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X.\"BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X.\"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X.\"OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X.\"EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X.\"
X.ds *k \fIksdssp\fP
X.ds *K \fIKsdssp\fP
X.ds *H \fB\s-1HELIX\s0\fP
X.ds *S \fB\s-1SHEET\s0\fP
X.ds *A \fB\s-1ATOM\s0\fP
X.TH KSDSSP 1 "" "\fBAPPENDIX 6\fP" "\fBUCSF MidasPlus\fP"
X.UC 4
X.iX 09 start
X.iX 26 start
X.iX ax start
X.iX al start
X.SH NAME
ksdssp \- generate \*(*H and \*(*S records from protein coordinates
X.SH SYNOPSIS
X.B ksdssp [
X.B \-c
\fIcutoff\fP ] [
X.B \-h
\fIlength\fP ] [
X.B \-s
\fIlength\fP ] [
X.B \-S
\fIfile\fP ]
[ \fIPDB_file\fP [ \fIoutput_file\fR ] ]
X.SH DESCRIPTION
X.PP
\*(*K
is an implementation of the Kabsch and Sander algorithm for defining
secondary structure of proteins.
\*(*K
reads a Protein Data Bank format file containing coordinates of
the backbone atoms (N, CA, C, O, and optionally H) of a protein
and generates \*(*H and \*(*S records.
If an amide hydrogen is missing, it is placed 1.01 angstroms 
from N along the bisector of
(1) the vector opposite the bisector of C-N-CA, and
(2) the vector opposite the C-O vector from the previous amino acid.
X.SH "COMMAND ARGUMENTS"
X.TP
\fB\-c\fP \fIenergy_cutoff\fP
The default energy cutoff for defining hydrogen bonds as recommended by
Kabsch and Sander is \-0.5 kcal/mol (``A good H-bond has about \-3 kcal/mol
binding energy'').  This option allows the user to change the cutoff.
X.TP
\fB\-h\fP \fIminimum_helix_length\fP
Normally, \*(*H records for helices of length three residues or greater are generated.
This option allows the user to change the minimum helix length.
X.TP
\fB\-s\fP \fIminimum_strand_length\fP
Normally, \*(*S records for strands of length three residues or greater are generated.
This option allows the user to change the minimum strand length.
Reducing the minimum strand length to 1 is not recommended, as there
are bridges in many structures that confuse the
algorithm for defining sheets.
X.TP
\fB\-S\fP \fIsummary_file\fP
Normally, \*(*k silently discards all the hydrogen-bonding information
after generating the \*(*H and \*(*S records.  This option makes \*(*k
print the information to a file.  The notation is similar to that used
by Kabsch and Sander, but is in a vertical instead of horizontal format.
X.TP
\fIPDB_file\fP
The input Protein Data Bank (\c
X.SM PDB\c
) file may contain any legal
X.SM PDB
records.
Only \*(*A records will be used.  All others are silently discarded.
If no
X.I PDB_file
argument is given, the data is read from standard input.
X.TP
\fIoutput_file\fP
The output of \*(*k is a set of
X.SM PDB
\*(*H and \*(*S records.
If no
X.I output_file
argument is given, the records are written to standard output.
X.SH "SEE ALSO"
Wolfgang Kabsch and Christian Sander,
``Dictionary of Protein Secondary Structure:
Pattern Recognition of Hydrogen-Bonded and
Geometrical Features,''
X.IR Biopolymers ,
X.BR 22 ,
2577-2637 (1983).
X.SH "AUTHORS"
Conrad Huang
X.br
UCSF Computer Graphics Laboratory
X.iX 09 stop
X.iX 26 stop
X.iX ax stop
X.iX al stop
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/ksdssp.1'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/ksdssp.1' ||
  $echo 'restore of' 'ksdssp/ksdssp.1' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/ksdssp.1:' 'MD5 check failed'
4bdf3f196171388c08a4c706089afbb8  ksdssp/ksdssp.1
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/ksdssp.1'`"
    test 4473 -eq "$shar_count" ||
    $echo 'ksdssp/ksdssp.1:' 'original size' '4473,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/ksdssp.cc ==============
if test -f 'ksdssp/ksdssp.cc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/ksdssp.cc' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/ksdssp.cc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/ksdssp.cc' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifdef NEED_BOOL
#define	bool	int
#define	false	0
#define	true	1
#endif
X
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <pdb++.h>
#include "ksdssp.h"
#include "Model.h"
X
#ifndef DONT_INSTANIATE
template class List<Model>;
#endif
X
#if defined(NeXT) || defined(mips)
extern "C" char *strerror(int);
#endif
X
int verbose = 0;
X
//
// This is an implementation of
//
//	Dictionary of Protein Secondary Structure:
//	Pattern Recognition of Hydrogen-Bonded and
//	Geometrical Features
//	Wolfgang Kabsch and Christian Sander
//	Biopolymers, Vol. 22, 2577-2637 (1983)
//
int
main(int argc, char **argv)
{
X	// Parse command line options
X	int o;
X	char *summaryFile = NULL;
X	while ((o = getopt(argc, argv, "c:h:s:vBS:")) != EOF)
X		switch (o) {
X		  case 'c':
X			Residue::setHBondCutoff(atof(optarg));
X			break;
X		  case 'h':
X			Model::setMinHelixLength(atoi(optarg));
X			break;
X		  case 's':
X			Model::setMinStrandLength(atoi(optarg));
X			break;
X		  case 'v':
X			verbose++;
X			break;
X		  case 'B':
X			Model::ignoreBulges();
X			break;
X		  case 'S':
X			summaryFile = optarg;
X			break;
X		}
X
X	// Check input PDB file
X	FILE *input = NULL;
X	FILE *output = NULL;
X	const char *inputFile = NULL;
X	const char *outputFile = NULL;
X	switch (argc - optind) {
X	  case 0:
X		input = stdin;
X		inputFile = "standard input";
X		output = stdout;
X		outputFile = "standard output";
X		break;
X	  case 1:
X		inputFile = argv[optind];
X		if (strcmp(inputFile, "-") == 0) {
X			input = stdin;
X			inputFile = "standard input";
X		}
X		else {
X			input = fopen(inputFile, "r");
X			if (input == NULL) {
X				(void) fprintf(stderr, "%s: %s: %s\n",
X					argv[0], inputFile, strerror(errno));
X				return 1;
X			}
X		}
X		output = stdout;
X		outputFile = "standard output";
X		break;
X	  case 2:
X		inputFile = argv[optind];
X		if (strcmp(inputFile, "-") == 0) {
X			input = stdin;
X			inputFile = "standard input";
X		}
X		else {
X			input = fopen(inputFile, "r");
X			if (input == NULL) {
X				(void) fprintf(stderr, "%s: %s: %s\n",
X					argv[0], argv[optind],
X					strerror(errno));
X				return 1;
X			}
X		}
X		outputFile = argv[optind + 1];
X		if (strcmp(outputFile, "-") == 0) {
X			output = stdout;
X			outputFile = "standard output";
X		}
X		else {
X			output = fopen(outputFile, "w");
X			if (output == NULL) {
X				(void) fprintf(stderr, "%s: %s: %s\n",
X					argv[0], outputFile, strerror(errno));
X				return 1;
X			}
X		}
X		break;
X	  default:
X		(void) fprintf(stderr, "Usage: %s [-c config] [pdb_file]\n",
X			argv[0]);
X		return 1;
X	}
X
X	// Construct molecule from PDB file
X	List<Model> modelList;
X	for (;;) {
X		Model *m = new Model(input);
X		if (!m->okay()) {
X			(void) fprintf(stderr, "%s: %s: %s\n",
X				argv[0], inputFile, m->error());
X			return 1;
X		}
X		int anyMore = m->anyMore();
X		if (m->anyAtoms())
X			modelList.append(m);
X		else
X			delete m;
X		if (!anyMore)
X			break;
X	}
X	if (modelList.count() <= 0) {
X		(void) fprintf(stderr, "%s: %s: no atoms read\n",
X			argv[0], inputFile);
X		return 1;
X	}
X
X	// Compute secondary structure and print helix and sheet records
X	Pix p;
X	for (p = modelList.first(); p != 0; modelList.next(p))
X		modelList(p)->defineSecondaryStructure();
X	Pix hp = modelList.first();
X	Pix sp = hp;
X	int fileCount = 0;
X	while (hp != 0) {
X		if (fileCount++ > 0)
X			(void) fprintf(output, "%s\n", PDB(PDB::END).chars());
X		int helixId = 0;
X		int sheetId = 0;
X		Model *m = modelList(hp);
X		if (m->modelNumber() != -1)
X			fprintf(output, "%s\n", m->fileRecord().chars());
X		int modelNumber = m->modelNumber();
X		for (; hp != 0 && modelList(hp)->modelNumber() == modelNumber;
X		modelList.next(hp))
X			helixId = modelList(hp)->printHelix(output, helixId);
X		for (; sp != hp; modelList.next(sp))
X			sheetId = modelList(sp)->printSheet(output, sheetId);
X	}
X	if (fileCount > 1)
X		(void) fprintf(output, "%s\n", PDB(PDB::END).chars());
X
X	// Print chain summaries
X	FILE *summary = NULL;
X	if (summaryFile != NULL
X	&& (summary = fopen(summaryFile, "w")) == NULL) {
X		(void) fprintf(stderr, "%s: %s: %s\n",
X			argv[0], summaryFile, strerror(errno));
X		return 1;
X	}
X	if (summary != NULL) {
X		for (p = modelList.first(); p != 0; modelList.next(p))
X			modelList(p)->printSummary(summary);
X		(void) fclose(summary);
X	}
X
X	return 0;
}
SHAR_EOF
  (set 20 04 07 28 14 06 45 'ksdssp/ksdssp.cc'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/ksdssp.cc' ||
  $echo 'restore of' 'ksdssp/ksdssp.cc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/ksdssp.cc:' 'MD5 check failed'
6bd2bb080630fbf2b8037590c9acb6c9  ksdssp/ksdssp.cc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/ksdssp.cc'`"
    test 5855 -eq "$shar_count" ||
    $echo 'ksdssp/ksdssp.cc:' 'original size' '5855,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/ksdssp.csh.sed ==============
if test -f 'ksdssp/ksdssp.csh.sed' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/ksdssp.csh.sed' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/ksdssp.csh.sed' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/ksdssp.csh.sed' &&
#!/bin/csh -f
X
#
# Copyright (c) 2002 The Regents of the University of California.
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#   1. Redistributions of source code must retain the above copyright
#      notice, this list of conditions, and the following disclaimer.
#   2. 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.
#   3. Redistributions must acknowledge that this software was
#      originally developed by the UCSF Computer Graphics Laboratory
#      under support by the NIH National Center for Research Resources,
#      grant P41-RR01081.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "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 REGENTS 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.
#
X
set realksdssp = "BINDIR/ksdssp"
set tmpout = "/usr/tmp/ksdssp.$$"
X
set rawerrfile = "/usr/tmp/ksdssp.err1.$$"
set errfile = "/usr/tmp/ksdssp.err2.$$"
(eval $realksdssp $* > $tmpout) >& $rawerrfile
X
if (! -z $rawerrfile) then
X	echo "Running ksdssp produced the following errors:" > $errfile
X	echo >> $errfile
X	cat $rawerrfile >> $errfile
X	echo >> $errfile
X	echo "Secondary structure is NOT updated" >> $errfile
X	echo help $errfile
X	echo \!/bin/rm -f $errfile $rawerrfile $tmpout
X	exit 1
else
X	echo update original $tmpout
X	echo \!/bin/rm -f $errfile $rawerrfile $tmpout
X	echo echo Secondary structure is updated
X	exit 0
endif
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/ksdssp.csh.sed'; eval "$shar_touch") &&
  chmod 0775 'ksdssp/ksdssp.csh.sed' ||
  $echo 'restore of' 'ksdssp/ksdssp.csh.sed' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/ksdssp.csh.sed:' 'MD5 check failed'
6363123088272ecd89df3fe6c8be3f1f  ksdssp/ksdssp.csh.sed
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/ksdssp.csh.sed'`"
    test 2228 -eq "$shar_count" ||
    $echo 'ksdssp/ksdssp.csh.sed:' 'original size' '2228,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/ksdssp.h ==============
if test -f 'ksdssp/ksdssp.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/ksdssp.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/ksdssp.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/ksdssp.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef ksdssp_h
#define ksdssp_h
X
#ifdef NO_SQRTF
#define	sqrtf	sqrt
#else
#ifndef __GNUC__
extern "C" float sqrtf(float);
#endif
#endif
X
extern int	verbose;
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 13 18 'ksdssp/ksdssp.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/ksdssp.h' ||
  $echo 'restore of' 'ksdssp/ksdssp.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/ksdssp.h:' 'MD5 check failed'
9e85afe7b4e80049fdcd00cae92c050c  ksdssp/ksdssp.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/ksdssp.h'`"
    test 1783 -eq "$shar_count" ||
    $echo 'ksdssp/ksdssp.h:' 'original size' '1783,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/misc.cc ==============
if test -f 'ksdssp/misc.cc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/misc.cc' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/misc.cc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/misc.cc' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#include <math.h>
#include "ksdssp.h"
#include "misc.h"
X
//
// Compute distance squared between two points
//
float
distSquared(const float v1[3], const float v2[3])
{
X	float l = 0;
X	for (int i = 0; i < 3; i++) {
X		float d = v2[i] - v1[i];
X		l += d * d;
X	}
X	return l;
}
X
//
// Compute distance between two points
//
float
distance(const float v1[3], const float v2[3])
{
X	float l = 0;
X	for (int i = 0; i < 3; i++) {
X		float d = v2[i] - v1[i];
X		l += d * d;
X	}
X	return sqrtf(l);
}
X
//
// Compute distance between two points
//
float
magnitude(const float v[3])
{
X	float l = 0;
X	for (int i = 0; i < 3; i++)
X		l += v[i] * v[i];
X	return sqrtf(l);
}
X
//
// Normalize given vector
//
void
normalize(float r[3])
{
X	float l = magnitude(r);
X	for (int i = 0; i < 3; i++)
X		r[i] /= l;
}
X
//
// Bisect two unit vectors
//
void
bisect(float r[3], const float v1[3], const float v2[3])
{
X	for (int i = 0; i < 3; i++)
X		r[i] = (v1[i] + v2[i]) / 2;
X	normalize(r);
}
X
//
// Compute angle between two vectors
//
float
angle(const float v1[3], const float v2[3])
{
X	return acos(dotProduct(v1, v2) / magnitude(v1) / magnitude(v2));
}
X
//
// Compute angle defined by three points
//
float
angle(const float v1[3], const float v2[3], const float v3[3])
{
X	float d1[3], d2[3];
X	for (int i = 0; i < 3; i++) {
X		d1[i] = v1[i] - v2[i];
X		d2[i] = v3[i] - v2[i];
X	}
X	return angle(d1, d2);
}
X
//
// Compute the cross product of two vectors
//
void
crossProduct(float answer[3], const float v1[3], const float v2[3])
{
X	answer[0] = v1[1] * v2[2] - v2[1] * v1[2];
X	answer[1] = v1[2] * v2[0] - v2[2] * v1[0];
X	answer[2] = v1[0] * v2[1] - v2[0] * v1[1];
}
X
//
// Compute the dot product of two vectors
//
float
dotProduct(const float v1[3], const float v2[3])
{
X	float d = 0;
X	for (int i = 0; i < 3; i++)
X		d += v1[i] * v2[i];
X	return d;
}
X
//
// Compute the dihedral formed by four vectors
//
float
dihedral(const float v1[3], const float v2[3],
X		const float v3[3], const float v4[3])
{
X	float d12[3], d32[3];
X	float d23[3], d43[3];
X	for (int i = 0; i < 3; i++) {
X		d12[i] = v1[i] - v2[i];
X		d32[i] = v3[i] - v2[i];
X		d23[i] = v2[i] - v3[i];
X		d43[i] = v4[i] - v3[i];
X	}
X
X	float d1[3], d2[3];
X	crossProduct(d1, d12, d32);
X	crossProduct(d2, d23, d43);
X	return angle(d1, d2);
}
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/misc.cc'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/misc.cc' ||
  $echo 'restore of' 'ksdssp/misc.cc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/misc.cc:' 'MD5 check failed'
af6442d561680418b0f12d36b2f03e1b  ksdssp/misc.cc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/misc.cc'`"
    test 3861 -eq "$shar_count" ||
    $echo 'ksdssp/misc.cc:' 'original size' '3861,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/misc.h ==============
if test -f 'ksdssp/misc.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/misc.h' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/misc.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/misc.h' &&
/*
X * Copyright (c) 2002 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *   1. Redistributions of source code must retain the above copyright
X *      notice, this list of conditions, and the following disclaimer.
X *   2. Redistributions in binary form must reproduce the above
X *      copyright notice, this list of conditions, and the following
X *      disclaimer in the documentation and/or other materials provided
X *      with the distribution.
X *   3. Redistributions must acknowledge that this software was
X *      originally developed by the UCSF Computer Graphics Laboratory
X *      under support by the NIH National Center for Research Resources,
X *      grant P41-RR01081.
X *
X * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
X * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
X * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
X * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
X * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
X * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
X * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
X * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
X * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X */
X
#ifndef misc_h
#define	misc_h
X
extern float	distSquared(const float v1[3], const float v2[3]);
extern float	distance(const float v1[3], const float v2[3]);
extern float	magnitude(const float v[3]);
extern void	normalize(float r[3]);
extern void	bisect(float r[3], const float v1[3], const float v2[3]);
extern float	angle(const float v1[3], const float v2[3]);
extern float	angle(const float v1[3], const float v2[3],
X				const float v3[3]);
extern void	crossProduct(float answer[3], const float v1[3],
X				const float v2[3]);
extern float	dotProduct(const float v1[3], const float v2[3]);
extern float	dihedral(const float v1[3], const float v2[3],
X				const float v3[3], const float v4[3]);
X
#endif
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/misc.h'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/misc.h' ||
  $echo 'restore of' 'ksdssp/misc.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/misc.h:' 'MD5 check failed'
4cd2c3aba948e0b95fd45915d39a3f26  ksdssp/misc.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/misc.h'`"
    test 2317 -eq "$shar_count" ||
    $echo 'ksdssp/misc.h:' 'original size' '2317,' 'current size' "$shar_count!"
  fi
fi
# ============= ksdssp/ksdssp.html ==============
if test -f 'ksdssp/ksdssp.html' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ksdssp/ksdssp.html' '(file already exists)'
else
  $echo 'x -' extracting 'ksdssp/ksdssp.html' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ksdssp/ksdssp.html' &&
<html>
<!--
Copyright (c) 2002 The Regents of the University of California.
All rights reserved.
X *
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
X  1. Redistributions of source code must retain the above copyright
X     notice, this list of conditions, and the following disclaimer.
X  2. Redistributions in binary form must reproduce the above
X     copyright notice, this list of conditions, and the following
X     disclaimer in the documentation and/or other materials provided
X     with the distribution.
X  3. Redistributions must acknowledge that this software was
X     originally developed by the UCSF Computer Graphics Laboratory
X     under support by the NIH National Center for Research Resources,
X     grant P41-RR01081.
X *
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "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 REGENTS 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.
-->
<head>
<title>ksdssp documentation</title>
</head>
<body>
<h2>NAME</h2>
ksdssp - generate <b>HELIX</b> and <b>SHEET</b> records from protein coordinates
<h2>SYNOPSIS</h2>
<b>ksdssp</b>
[ <b>-c</b> <i>cutoff</i> ]
[ <b>-h</b> <i>length</i> ]
[ <b>-s</b> <i>length</i> ]
[ <b>-S</b> <i>file</i> ]
[ <i>PDB_file</i> [ <i>output_file</i> ] ]
<h2>DESCRIPTION</h2>
<i>Ksdssp</i>
is an implementation of the Kabsch and Sander algorithm for defining
secondary structure of proteins.
<i>Ksdssp</i>
reads a Protein Data Bank format file containing coordinates of
the backbone atoms (N, CA, C, O, and optionally H) of a protein
and generates <b>HELIX</b> and <b>SHEET</b> records.
If an amide hydrogen is missing, it is placed 1.01 angstroms 
from N along the bisector of
<ol>
<li>the vector opposite the bisector of C-N-CA, and
<li>the vector opposite the C-O vector from the previous amino acid.
</ol>
<h2>COMMAND ARGUMENTS</h2>
<dl>
<dt>
<b>-c</b> <i>energy_cutoff</i>
<dd>
The default energy cutoff for defining hydrogen bonds as recommended by
Kabsch and Sander is -0.5 kcal/mol ("A good H-bond has about -3 kcal/mol
binding energy").  This option allows the user to change the cutoff.
<dt>
<b>-h</b> <i>minimum_helix_length</i>
<dd>
Normally, <b>HELIX</b> records for helices of length
three residues or greater are generated.
This option allows the user to change the minimum helix length.
<dt>
<b>-s</b> <i>minimum_strand_length</i>
<dd>
Normally, <b>SHEET</b> records for strands of length
three residues or greater are generated.
This option allows the user to change the minimum strand length.
Reducing the minimum strand length to 1 is not recommended, as there
are bridges in many structures that confuse the
algorithm for defining sheets.
<dt>
<b>-S</b> <i>summary_file</i>
<dd>
Normally, <i>ksdssp</i> silently discards all
the hydrogen-bonding information
after generating the <b>HELIX</b> and <b>SHEET</b> records.
This option makes <i>ksdssp</i>
print the information to a file.  The notation is similar to that used
by Kabsch and Sander, but is in a vertical instead of horizontal format.
<dt>
<i>PDB_file</i>
<dd>
The input Protein Data Bank (PDB) file may contain any legal
PDB records.
Only <b>ATOM</b> records will be used.  All others are silently discarded.
If no
<i>PDB_file</i>
argument is given, the data is read from standard input.
<dt>
<i>output_file</i>
<dd>
The output of <i>ksdssp</i> is a set of PDB
<b>HELIX</b> and <b>SHEET</b> records.
If no
<i>output_file</i>
argument is given, the records are written to standard output.
</dl>
<h2>SEE ALSO</h2>
Wolfgang Kabsch and Christian Sander,
"Dictionary of Protein Secondary Structure:
Pattern Recognition of Hydrogen-Bonded and
Geometrical Features,"
<i>Biopolymers</i>,
<b>22</b>,
2577-2637 (1983).
<h2>AUTHORS</h2>
Conrad Huang
<br>
UCSF Computer Graphics Laboratory
</body>
</html>
SHAR_EOF
  (set 20 04 07 28 14 05 17 'ksdssp/ksdssp.html'; eval "$shar_touch") &&
  chmod 0664 'ksdssp/ksdssp.html' ||
  $echo 'restore of' 'ksdssp/ksdssp.html' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ksdssp/ksdssp.html:' 'MD5 check failed'
7101ad3e3560323937882648bc4d7460  ksdssp/ksdssp.html
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ksdssp/ksdssp.html'`"
    test 4403 -eq "$shar_count" ||
    $echo 'ksdssp/ksdssp.html:' 'original size' '4403,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh13329
exit 0
