git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@641 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp 2007-06-21 22:53:58 +00:00
parent b78e208740
commit 988a4479e8
26 changed files with 6056 additions and 0 deletions

21
tools/pymol_asphere/README Executable file
View File

@ -0,0 +1,21 @@
asphere_vis: Tool for triangulating aspherical particles
to convert LAMMPS output to PyMol input
Building the tool:
cd src
make # may need to edit Makefile for your system
This will place the asphere_vis executable in the bin directory.
Documentation is in the doc directory. Note that the doc file says
the ellipsoid axes are specified by an "Ellipsoid" section in the data
file. In the current version of LAMPS, this is now a "Shapes"
section.
See instructions on how to run an example ellipsoid viz in the
examples dir.
Mike Brown, Sandia National Labs
wmbrown at sandia.gov
June 2007

View File

@ -0,0 +1,209 @@
.if !'\*(.T'ps' .if !'\*(.T'html' .tm warning: eqn should have been given a `-T\*(.T' option
.if '\*(.T'html' .if !'ps'ps' .tm warning: eqn should have been given a `-Tps' option
.if '\*(.T'html' .if !'ps'ps' .tm warning: (it is advisable to invoke groff via: groff -Thtml -e)
.lf 1 /usr/share/groff/1.18.1.1/tmac/eqnrc
.\" Startup file for eqn.
.EQ
.nr 0C \n(.C
.cp 0
.ds 10
.cp \n(0C
.lf 63
.EN
.lf 1 asphere_vis.manpage
.TH asphere_vis 1 "June 11, 2007" "asphere_vis (Graphics Utilities) 0.1" "Graphics Utilities"
.SH NAME
\fBasphere_vis\fR - Tools for LAMMPS ellipsoid trajectory visualization in PyMol.
.PD 2
.SH VERSION
.PD 1
Version 0.1
.PD 2
.SH SYNOPSIS
.PD 1
.TP
\fBasphere_vis\fR input_data_file input_dump_file output_py_file [\fB-b\fR] [\fB-c\fR \fIcolor_file\fR] [\fB-d\fR] [\fB-f\fR \fImax_frame\fR] [\fB-h\fR] [\fB-i\fR \fIstart_frame\fR \fIskip\fR \fIend_frame\fR] [\fB-n\fR \fInotice_level\fR] [\fB-r\fR \fIellip_res\fR] [\fB-s\fR]
.br
.PD 2
.SH DESCRIPTION
.PD 1
Tool for LAMMPS trajectory visualization in PyMol. The input is a LAMMPS 'data' file or a 'in' file with ellipsoid semi-axes specified using the ellipsoid command. The trajectory is input from a 'dump' file that must be generated using a custom style with the following arguments in order:
.PD 0
.PP
.PD 1
.PD 0
.TP
.PP
.PD 1
\fItag type x y z quatw quati quatj quatk\fR
.PD 0
.PP
.PD 1
.PD 2
.SH PARAMETERS
.PD 1
.TP
\fB-b\fR
When used with \fB-s\fR, the option will number the filenames based on the frame number. By default, they are numbered consequtively from zero.
.TP
\fB-c\fR \fIcolor_file\fR
.PD 0
.TP
.PP
.PD 1
Color the atom_types and set transparency based on the input file. The input file contains a space delimited set sequence of the color for an atom followed by the alpha. The color should be the string name and the alpha should be between 0 and 1.
.TP
\fB-d\fR
Use a LAMMPS input file rather than a data file for extracting atom type information. The input filename is specified as \fIinput_data_file\fR.
.TP
\fB-f\fR \fImax_frame\fR
.PD 0
.TP
.PP
.PD 1
Do not write more than \fImax_frame\fR frames to the output file.
.TP
\fB-h\fR
Print out the man page for help
.TP
\fB-i\fR \fIstart_frame\fR \fIskip\fR \fIend_frame\fR
.PD 0
.TP
.PP
.PD 1
Render the specified frame interval inclusive between \fIstart_frame\fR and \fIend_frame\fR. \fIskip\fR gives the number of frames to \fIskip\fR between each rendered frame. A value of 0 outputs every frame between \fIstart_frame\fR and \fIend_frame\fR. The first frame in the dump file is frame 0.
.TP
\fB-n\fR \fInotice_level\fR
.PD 0
.TP
.PP
.PD 1
Set the degree of program output. Use:
.PD 0
.PP
.PD 1
.PD 0
.PP
.PD 1
\fB-n\fR 0 No output
.PD 0
.PP
.PD 1
\fB-n\fR 10 Normal program output
.PD 0
.PP
.PD 1
\fB-n\fR 20 Parameters useful for reproducing the results
.PD 0
.PP
.PD 1
\fB-n\fR 30 All output
.TP
\fB-r\fR \fIellip_res\fR
.PD 0
.TP
.PP
.PD 1
Resolution of ellipsoids in trajectory. The number of triangles per ellipsoid is equal to 2*(\fIellip_res\fR^2). Default is 10.
.TP
\fB-s\fR
Output the results into separate .py files. The filename and extension for the output files is taken from \fIoutput_py_file\fR.
.PD 2
.SH AVAILABLE COLORS
.PD 1
.PD 0
.PP
.PD 1
black
.PD 0
.PP
.PD 1
blue
.PD 0
.PP
.PD 1
brown
.PD 0
.PP
.PD 1
cmyk_blue
.PD 0
.PP
.PD 1
cmyk_marine
.PD 0
.PP
.PD 1
deep
.PD 0
.PP
.PD 1
forest
.PD 0
.PP
.PD 1
green
.PD 0
.PP
.PD 1
grey
.PD 0
.PP
.PD 1
hotpink
.PD 0
.PP
.PD 1
magenta
.PD 0
.PP
.PD 1
marine
.PD 0
.PP
.PD 1
orange
.PD 0
.PP
.PD 1
purple
.PD 0
.PP
.PD 1
red
.PD 0
.PP
.PD 1
slate
.PD 0
.PP
.PD 1
teal
.PD 0
.PP
.PD 1
wheat
.PD 0
.PP
.PD 1
white
.PD 0
.PP
.PD 1
yellow
.PD 0
.PP
.PD 1
.PD 2
.SH KNOWN BUGS
.PD 1
Comments are not allowed at any point between a section header and the end of the contents for a section in either the data file or the input file.
.PD 2
.SH AUTHORS
.PD 1
W. Michael Brown

View File

@ -0,0 +1,196 @@
.TH asphere_vis 1 "June 11, 2007" "asphere_vis (Graphics Utilities) 0.1" "Graphics Utilities"
.SH NAME
\fBasphere_vis\fR - Tools for LAMMPS ellipsoid trajectory visualization in PyMol.
.PD 2
.SH VERSION
.PD 1
Version 0.1
.PD 2
.SH SYNOPSIS
.PD 1
.TP
\fBasphere_vis\fR input_data_file input_dump_file output_py_file [\fB-b\fR] [\fB-c\fR \fIcolor_file\fR] [\fB-d\fR] [\fB-f\fR \fImax_frame\fR] [\fB-h\fR] [\fB-i\fR \fIstart_frame\fR \fIskip\fR \fIend_frame\fR] [\fB-n\fR \fInotice_level\fR] [\fB-r\fR \fIellip_res\fR] [\fB-s\fR]
.br
.PD 2
.SH DESCRIPTION
.PD 1
Tool for LAMMPS trajectory visualization in PyMol. The input is a LAMMPS 'data' file or a 'in' file with ellipsoid semi-axes specified using the ellipsoid command. The trajectory is input from a 'dump' file that must be generated using a custom style with the following arguments in order:
.PD 0
.PP
.PD 1
.PD 0
.TP
.PP
.PD 1
\fItag type x y z quatw quati quatj quatk\fR
.PD 0
.PP
.PD 1
.PD 2
.SH PARAMETERS
.PD 1
.TP
\fB-b\fR
When used with \fB-s\fR, the option will number the filenames based on the frame number. By default, they are numbered consequtively from zero.
.TP
\fB-c\fR \fIcolor_file\fR
.PD 0
.TP
.PP
.PD 1
Color the atom_types and set transparency based on the input file. The input file contains a space delimited set sequence of the color for an atom followed by the alpha. The color should be the string name and the alpha should be between 0 and 1.
.TP
\fB-d\fR
Use a LAMMPS input file rather than a data file for extracting atom type information. The input filename is specified as \fIinput_data_file\fR.
.TP
\fB-f\fR \fImax_frame\fR
.PD 0
.TP
.PP
.PD 1
Do not write more than \fImax_frame\fR frames to the output file.
.TP
\fB-h\fR
Print out the man page for help
.TP
\fB-i\fR \fIstart_frame\fR \fIskip\fR \fIend_frame\fR
.PD 0
.TP
.PP
.PD 1
Render the specified frame interval inclusive between \fIstart_frame\fR and \fIend_frame\fR. \fIskip\fR gives the number of frames to \fIskip\fR between each rendered frame. A value of 0 outputs every frame between \fIstart_frame\fR and \fIend_frame\fR. The first frame in the dump file is frame 0.
.TP
\fB-n\fR \fInotice_level\fR
.PD 0
.TP
.PP
.PD 1
Set the degree of program output. Use:
.PD 0
.PP
.PD 1
.PD 0
.PP
.PD 1
\fB-n\fR 0 No output
.PD 0
.PP
.PD 1
\fB-n\fR 10 Normal program output
.PD 0
.PP
.PD 1
\fB-n\fR 20 Parameters useful for reproducing the results
.PD 0
.PP
.PD 1
\fB-n\fR 30 All output
.TP
\fB-r\fR \fIellip_res\fR
.PD 0
.TP
.PP
.PD 1
Resolution of ellipsoids in trajectory. The number of triangles per ellipsoid is equal to 2*(\fIellip_res\fR^2). Default is 10.
.TP
\fB-s\fR
Output the results into separate .py files. The filename and extension for the output files is taken from \fIoutput_py_file\fR.
.PD 2
.SH AVAILABLE COLORS
.PD 1
.PD 0
.PP
.PD 1
black
.PD 0
.PP
.PD 1
blue
.PD 0
.PP
.PD 1
brown
.PD 0
.PP
.PD 1
cmyk_blue
.PD 0
.PP
.PD 1
cmyk_marine
.PD 0
.PP
.PD 1
deep
.PD 0
.PP
.PD 1
forest
.PD 0
.PP
.PD 1
green
.PD 0
.PP
.PD 1
grey
.PD 0
.PP
.PD 1
hotpink
.PD 0
.PP
.PD 1
magenta
.PD 0
.PP
.PD 1
marine
.PD 0
.PP
.PD 1
orange
.PD 0
.PP
.PD 1
purple
.PD 0
.PP
.PD 1
red
.PD 0
.PP
.PD 1
slate
.PD 0
.PP
.PD 1
teal
.PD 0
.PP
.PD 1
wheat
.PD 0
.PP
.PD 1
white
.PD 0
.PP
.PD 1
yellow
.PD 0
.PP
.PD 1
.PD 2
.SH KNOWN BUGS
.PD 1
Comments are not allowed at any point between a section header and the end of the contents for a section in either the data file or the input file.
.PD 2
.SH AUTHORS
.PD 1
W. Michael Brown

Binary file not shown.

View File

@ -0,0 +1,16 @@
The asphere_vis tool needs an input script and a dump file
from a LAMMPS run.
In examples/ellipse, you can run LAMMPS with in.ellipse
to generate dump.ellipse
Copy in.ellipse and dump.ellipse to this dir.
Run the tool to create a PyMol input file called ellipse.py by typing:
../bin/asphere_vis in.ellipse dump.ellipse ellipse.py -c colors.ellipse -d
Launch PyMol on this input and you should see a nice viz of
4 ellipsoids in a box of LJ particles:
pymol ellipse.py

View File

@ -0,0 +1,3 @@
marine 0.3
red 1.0

200
tools/pymol_asphere/src/Makefile Executable file
View File

@ -0,0 +1,200 @@
#***************************************************************************
# Makefile
# -------------------
#
# _________________________________________________________________________
# Build for the Graphics Utilities
# _________________________________________________________________________
#
# begin : Thu June 9 2005
# copyright : (C) 2003 by W. Michael Brown
# email : wmbrown@sandia.gov
# ***************************************************************************/
#Compiler type
#COMPILER = intel
COMPILER = gnu
#COMPILER = mpi
#COMPILER = mingw
#Locations of outside objects relative to a source directory
HOBJ_DIR = ../obj
BIN_DIR = ../bin
ALL_DIR = .
ALL_LIB = $(HOBJ_DIR)/liball.a
GRPHICS_DIR = .
GRPHICS_LIB = $(HOBJ_DIR)/libgraphics.a
GRID_DIR = .
GRID_LIB = $(HOBJ_DIR)/libgrid.a
MOL_DIR = .
MOL_LIB = $(HOBJ_DIR)/libmol.a
MATH_DIR = .
MATH_LIB = $(HOBJ_DIR)/libmath.a
EVERY_LIB = $(MOL_LIB) $(GRID_LIB) $(GRPHICS_LIB) $(MATH_LIB) $(ALL_LIB)
MOLSIM_DIR = .
MOLSIM_LIB = $(HOBJ_DIR)/molsim.o $(HOBJ_DIR)/dynmif.o $(HOBJ_DIR)/dynmifq.o
# Include directories
INC = -I$(ALL_DIR) -I$(MOLSIM_DIR) -I$(MOL_DIR) -I$(MATH_DIR) -I$(GRID_DIR) -I$(GRPHICS_DIR)
ifeq ($(COMPILER),intel)
CPP = icpc # C++ Compiler
CC = icc # C compiler
AR = xiar #ar
DBUG = -g -DDEBUG -DNANCHECK #-Wall #-ansi
OPT = -O2 -xP -ipo -no-prec-div -static
endif
ifeq ($(COMPILER),gnu)
CPP = g++ # C++ Compiler
CC = gcc # C compiler
AR = ar
DBUG = -g -DDEBUG -DNANCHECK -Wall -pedantic #-ansi
OPT = #-O3
endif
ifeq ($(COMPILER),mpi)
CPP = mpic++ -DMUSE_MPI # C++ Compiler
CC = mpicc -DMUSE_MPI # C compiler
AR = ar
DBUG = -g -DDEBUG -DNANCHECK #-Wall #-pedantic #-ansi
OPT = #-xN -O3 #-ipo -no-prec-div -static #-O3
endif
ifeq ($(COMPILER),mingw)
CPP = /cygdrive/c/MINGW/bin/g++ # C++ Compiler
CC = /cygdrive/c/MINGW/bin/gcc # C compiler
AR = /cygdrive/c/MINGW/bin/ar
DBUG = #-g -DDEBUG -DNANCHECK -Wall -pedantic #-ansi
OPT = -O3 -static
endif
# Large file support?
LFSC = #-D_LARGEFILE_SOURCE `getconf LFS_CFLAGS`
LFSL = #`getconf LFS_LDFLAGS` `getconf LFS_LIBS`
# GNU Scientific Library?
GSLC = #-DUSEGSL -I/usr/local/include/
GSLL = #-lgsl -lgslcblas
# GA Library?
LIBGAC = #-DLIBGA -I/usr/local/include/
LIBGAL = #-lga -L/usr/local/lib/ -Wl,--allow-multiple-definition
# Movie frame support?
MOVIE = #-DMOVIE
# VTK ?
VTKH = #-DUSEVTK -I/usr/local/include/vtk-5.0
VTKL = #-lvtkWidgets -lvtkHybrid -lvtkVolumeRendering -lvtkRendering -lvtkIO -lvtkGenericFiltering -lvtkGraphics -lvtkImaging -l vtkFiltering -lvtkCommon -L/usr/X11R6/lib/ -lGL -lXt -lSM -lICE -lX11 -lXext -lpthread -ldl
CFLAGS = $(OPT) $(MOVIE) $(DBUG) $(INC) $(GSLC) $(LIBGAC) $(VTKH) -c
LFLAGS = $(OPT)
LLIBS = $(GSLL) $(LIBGAL) $(LFSL) $(VTKL)
# Distribution Directories
DIST_BIN = /home/wmbrown/distbin/
DIST_MAN = /home/wmbrown/cpp/manpages/man1/
DIST_DOC = /home/wmbrown/cpp/doc/
OBJ_DIR = $(HOBJ_DIR)
# Objects for this project
THIS_OBJ = $(OBJ_DIR)/asphere_vis.o $(GRPHICS_LIB) $(MATH_LIB) $(ALL_LIB)
EXECS = $(BIN_DIR)/asphere_vis
all: $(EXECS)
libraries:
cd $(ALL_DIR); make; cd $(MATH_DIR); make; cd $(GRID_DIR); make; \
cd $(GRPHICS_DIR); make;
ALL_OBJS = $(OBJ_DIR)/error.o $(OBJ_DIR)/commandline.o \
$(OBJ_DIR)/misc.o
$(OBJ_DIR)/error.o: error.h error.cpp
$(CPP) $(CFLAGS) -o $@ error.cpp
$(OBJ_DIR)/commandline.o: commandline.h commandline.cpp
$(CPP) $(CFLAGS) -o $@ commandline.cpp
$(OBJ_DIR)/misc.o: misc.h misc.cpp
$(CPP) $(CFLAGS) -o $@ misc.cpp
$(ALL_LIB): $(ALL_OBJS)
$(AR) -crusv $(ALL_LIB) $(ALL_OBJS)
GRPHICS_O = $(OBJ_DIR)/colors.o $(OBJ_DIR)/glsurface.o
$(OBJ_DIR)/colors.o: colors.h colors.cpp
$(CPP) $(CFLAGS) -o $@ colors.cpp
$(OBJ_DIR)/glsurface.o: glsurface.h glsurface.cpp
$(CPP) $(CFLAGS) -o $@ glsurface.cpp
$(GRPHICS_LIB): $(GRPHICS_O)
$(AR) -crusv $(GRPHICS_LIB) $(GRPHICS_O)
MATH_OBJS = $(OBJ_DIR)/cartesian.o $(OBJ_DIR)/miscm.o \
$(OBJ_DIR)/spherical.o
$(OBJ_DIR)/miscm.o: miscm.h miscm.cpp
$(CPP) $(CFLAGS) -o $@ miscm.cpp
$(OBJ_DIR)/cartesian.o: cartesian.h cartesian.cpp
$(CPP) $(CFLAGS) -o $@ cartesian.cpp
$(OBJ_DIR)/spherical.o: spherical.h spherical.cpp
$(CPP) $(CFLAGS) -o $@ spherical.cpp
$(MATH_LIB): $(MATH_OBJS)
$(AR) -crusv $(MATH_LIB) $(MATH_OBJS)
$(OBJ_DIR)/asphere_vis.o: asphere_vis.cpp
$(CPP) $(CFLAGS) -o $@ asphere_vis.cpp
$(BIN_DIR)/asphere_vis: $(THIS_OBJ)
$(CPP) $(LFLAGS) -o $@ $(THIS_OBJ) $(LLIBS)
#
# Documentation
#
manpages: all
/bin/tcsh make_manpages.sh
#
# Create a .tar distribution file
#
dist: all manpages
/bin/tcsh makedistribution.sh
#
# INSTALL to Mike's Directories
install: all manpages
/bin/cp $(EXECS) $(DIST_BIN); \
/bin/cp ./manpages/*.1 $(DIST_MAN); \
/bin/cp ./manpages/*.pdf $(DIST_DOC)
#
# Remove objects, cores, etc.
#
clean:
rm -rf $(EXECS) $(THIS_OBJ) $(ALL_OBJ) $(MATH_OBJ) $(GRPHICS_O)
cd $(OBJ_DIR); rm -f *.o
veryclean: clean
rm -rf *~ ./api ./manpages
cleanproject: clean
cd $(ALL_DIR); make clean; cd $(MATH_DIR); make clean; \
cd $(GRPHICS_DIR); make clean;

View File

@ -0,0 +1,438 @@
/***************************************************************************
asphere_vis.cpp
-------------------
Convert a Lammps ellipsoid trajectory to a Pymol CGO trajectory
__________________________________________________________________________
This file is part of the Graphics Utilities package for command-line
access to Graphics Library functions
__________________________________________________________________________
begin : Fri Jan 12 2007
copyright : (C) 2007 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#include "commandline.h"
#include "glsurface.h"
#include <limits>
// Describe the program parameters
void Describe(CommandLine &cl,ostream &out);
// Parse the command line parameters
void HandleArgs(CommandLine &cl, int argc, char *argv[], Error *error);
// Parse past an ITEM line in the lammps dump file
bool parse_to(const char *token,ifstream &in);
int main(int argc, char *argv[]) {
CommandLine cl;
Error error;
Colors colors;
FileIterator fi;
// Parse the command line
HandleArgs(cl,argc,argv,&error);
// ----------------- Set up file names
if (cl['s']) {
fi.set_file_header(a::namewoext(cl.argstring(' ',2))+".");
fi.set_file_extensions("."+a::extension(cl.argstring(' ',2)));
fi.set_lead_zeros(4);
}
// ----------------- Get the frame interval
unsigned start_frame=0;
unsigned skip=0;
unsigned end_frame=std::numeric_limits<unsigned>::max();
if (cl['i']) {
start_frame=cl.argint('i',0);
skip=cl.argint('i',1);
end_frame=cl.argint('i',2);
}
// ----------------- Get the atom type info from a data file
unsigned atom_types=0;
vector<cPt> shapes;
ifstream in;
if (!cl['d']) {
a::fileopen(in,cl.argstring(' ',0),error);
while (!in.eof()) {
char iline[500];
in.getline(iline,500);
vector<string> tokens;
a::get_tokens(iline,tokens);
if (tokens.size()>2)
if (tokens[1]=="atom" && tokens[2]=="types") {
atom_types=atoi(tokens[0].c_str());
break;
}
if (!in)
break;
}
if (atom_types==0)
error.generate_error(0,"asphere_vis",
"Could not find number of atom types in data file.");
// ----------------- Get the atom type shapes
if (parse_to("Shapes",in))
for (unsigned i=0; i<atom_types; i++) {
double tempd;
cPt shape;
in >> tempd >> shape;
shape.x *= 0.5;
shape.y *= 0.5;
shape.z *= 0.5;
if (in.eof() || !in)
break;
shapes.push_back(shape);
char iline[500];
in.getline(iline,500);
}
if (shapes.size()!=atom_types) {
error.buffer() << "Error reading shapes from Pair Coeffs section of "
<< "data file. Read " << shapes.size() << " valid shapes, "
<< "but expected " << atom_types;
error.addbuf(0,"asphere_vis");
}
a::fileclose(in,error);
} else {
// ----------------- Get the atom type info from a input file
a::fileopen(in,cl.argstring(' ',0),error);
while (!in.eof()) {
string token;
in >> token;
if (token=="create_box") {
in >> atom_types;
shapes.assign(atom_types,cPt(0.5,0.5,0.5));
} else if (token=="shape") {
unsigned type;
cPt shape;
in >> type >> shape;
shape.x *= 0.5;
shape.y *= 0.5;
shape.z *= 0.5;
if (type>atom_types) {
error.buffer() << "Error reading shapes from LAMMPS input file. "
<< "I thought there were " << atom_types
<< " atom types. But found an shape command for "
<< "atom type: " << type;
error.addbuf(0,"asphere_vis");
}
shapes[type-1]=shape;
} else {
char iline[500];
in.getline(iline,500);
}
if (!in && !in.eof())
error.generate_error(0,"asphere_vis",
"Error reading from LAMMPS input file");
}
a::fileclose(in,error);
}
if (atom_types==0)
error.generate_error(0,"asphere_vis","Found 0 atom types!");
// ----------------- Get the colors and alpha values for atom types
vector<colorPt> color_list;
vector<double> alpha_list;
if (cl['c']) {
a::fileopen(in,cl.argstring('c',0),error);
for (unsigned i=0; i<atom_types; i++) {
double alpha;
string color;
in >> color >> alpha;
if (in.eof() || !in)
error.generate_error(0,"asphere_vis",
"Improperly formatted color file.");
color_list.push_back(colors[color]);
alpha_list.push_back(alpha);
}
a::fileclose(in,error);
}
a::fileopen(in,cl.argstring(' ',1),error);
ofstream out;
if (!cl['s']) {
a::fileopen(out,cl.argstring(' ',2),error);
}
// ----------------- Get the atom count
unsigned atom_count;
if (parse_to("ITEM: NUMBER OF ATOMS",in))
in >> atom_count;
else
error.generate_error(0,"asphere_vis",
"Could not find ITEM: NUMBER OF ATOMS in input file.");
if (!in)
error.generate_error(0,"asphere_vis",
"Error reading ITEM: NUMBER OF ATOMS in input file.");
// ----------------- Get the triangles per ellipsoid
unsigned ellip_res=10;
if (cl['r'])
ellip_res=cl.argint('r',0);
if (ellip_res==0) {
error.addwarning(0,9,"asphere_vis","Cannot use -r 0. Setting to 10.");
ellip_res=10;
}
// ----------------- Get the bounding box
bool bound_found=false;
if (!cl['s']) {
if (parse_to("ITEM: BOX BOUNDS",in)) {
bound_found=true;
cPt bound[2];
in >> bound[0].x >> bound[1].x;
in >> bound[0].y >> bound[1].y;
in >> bound[0].z >> bound[1].z;
GLSurface gls;
Vertex v;
v.transparency=1;
v.valid_normal=false;
v.color=colors["white"];
for (unsigned i=0; i<2; i++)
for (unsigned j=0; j<2; j++)
for (unsigned k=0; k<2; k++) {
v.cpt=cPt(bound[i].x,bound[j].y,bound[k].z);
gls.addvertex(v);
}
gls.addline(0,1);
gls.addline(0,2);
gls.addline(0,4);
gls.addline(1,3);
gls.addline(1,5);
gls.addline(2,3);
gls.addline(2,6);
gls.addline(3,7);
gls.addline(4,5);
gls.addline(4,6);
gls.addline(5,7);
gls.addline(6,7);
gls.writelines(out,"gridb");
out << "cmd.set('cgo_dot_width',8)\n";
} else
error.addwarning(0,9,"asphere_vis",
"Could not find ITEM: BOX BOUNDS in input file. No box output.");
}
if (!in)
error.generate_error(0,"asphere_vis",
"Error reading ITEM: BOX BOUNDS.");
// ----------------- Generate the frames
unsigned frame=0;
unsigned max_frame=std::numeric_limits<unsigned>::max();
if (cl['f'])
max_frame=cl.argint('f',0);
colorPt color=colors["marine"];
double alpha=1.0;
Vertex v;
v.color=color;
v.transparency=1.0;
// ----------------- Get to the start frame
while (frame<start_frame)
if (!parse_to("ITEM: ATOMS",in))
error.generate_error(0,"asphere_vis",
"Could not find first frame in interval in dump file.");
else
frame++;
unsigned wrote=0;
while (true) {
if (frame>end_frame)
break;
if (!parse_to("ITEM: ATOMS",in))
break;
GLSurface gls;
for (unsigned i=0; i<atom_count; i++) {
unsigned id;
unsigned atom_type;
in >> id >> atom_type;
cPt atom_center;
in >> atom_center;
Quaternion q;
in >> q;
if (!in) {
error.addwarning(0,9,"asphere_vis","Error reading frame: "+
a::itoa(frame));
break;
}
cPt radius(shapes[atom_type-1]);
if (radius.x == radius.y && radius.y == radius.z) {
v.cpt=atom_center;
if (cl['c']) {
v.color=color_list[atom_type-1];
v.transparency=alpha_list[atom_type-1];
}
gls.addvertex(v);
gls.add_sphere(gls.size_vertices()-1,radius.x);
} else {
if (cl['c']) {
color=color_list[atom_type-1];
alpha=alpha_list[atom_type-1];
}
gls.add_ellipsoid(atom_center,radius,q,
color,alpha,ellip_res);
}
}
if (!in)
break;
if (cl['s']) {
if (cl['b'])
fi.set_file_num(frame);
a::fileopen(out,fi.nextfilename(),error);
}
gls.writetris(out,"ellipse");
if (gls.size_spheres()!=0)
gls.writespheres(out,"spheres");
if (cl['s'])
a::fileclose(out,error);
wrote++;
frame++;
if (frame==max_frame)
break;
for (unsigned i=0; i<skip; i++)
if (!parse_to("ITEM: ATOMS",in))
break;
else
frame++;
}
if (frame==0)
error.addwarning(0,9,"asphere_vis",
"Could not find any frams in input_file!");
if (cl['i'] && frame<end_frame) {
error.buffer() << "Only found " << frame << " frames in input file.";
error.addbuf(0,9,"asphere_vis");
}
if (bound_found)
out << "cmd.zoom(\"gridb\",animate=-1)\n";
cout << "Wrote " << wrote << " frames to output file.\n";
a::fileclose(out,error);
return 0;
}
void Describe(CommandLine &cl,ostream &out) {
string name=cl.program_name();
string progname=a::strcenter(name,70);
string gridversion=a::strcenter("Graphics Library Version 0.1",70);
out << endl << progname << endl << gridversion << endl
<< "______________________________________________________________________\n"
<< a::strcenter("W. Michael Brown",70) << endl
<< a::strcenter("1/12/2007",70) << endl
<< "______________________________________________________________________\n"
<< "Tool for LAMMPS aspherical trajectory visualization in pymol.\n\n"
<< cl.format_synopsis("","","") << endl << endl
<< "Use '" << name << " -h > " << name
<< ".1' to generate a man page for this\n"
<< "program and type 'man ./" << name << ".1' for help\n"
<< "______________________________________________________________________\n";
return;
}
void HandleArgs(CommandLine &cl, int argc, char *argv[], Error *error) {
// Arguments
cl.addmanditory(' ',3);
cl.addargname(' ',"input_data_file");
cl.addargname(' ',"input_dump_file");
cl.addargname(' ',"output_py_file");
cl.add('d',0);
cl.adddescription('d',"Use a LAMMPS input file rather than a data file for extracting atom type information. The input filename is specified as input_data_file.");
cl.add('f',1);
cl.addargname('f',"max_frame");
cl.adddescription('f',"Do not write more than max_frame frames to the output file.");
cl.add('r',1);
cl.addargname('r',"ellip_res");
cl.adddescription('r',"Resolution of ellipsoids in trajectory. The number of triangles per ellipsoid is equal to 2*(ellip_res^2). Default is 10.");
cl.add('c',1);
cl.addargname('c',"color_file");
cl.adddescription('c',"Color the atom_types and set transparency based on the input file. The input file contains a space delimited set sequence of the color for an atom followed by the alpha. The color should be the string name and the alpha should be between 0 and 1.");
cl.add('s',0);
cl.adddescription('s',"Output the results into separate .py files. The filename and extension for the output files is taken from output_py_file.");
cl.add('i',3);
cl.addargname('i',"start_frame");
cl.addargname('i',"skip");
cl.addargname('i',"end_frame");
cl.adddescription('i',"Render the specified frame interval inclusive between start_frame and end_frame. skip gives the number of frames to skip between each rendered frame. A value of 0 outputs every frame between start_frame and end_frame. The first frame in the dump file is frame 0.");
cl.add('b',0);
cl.adddescription('b',"When used with -s, the option will number the filenames based on the frame number. By default, they are numbered consequtively from zero.");
// Stuff for every executable
cl.addhelp('h',0);
cl.adddescription('h',"Print out the man page for help");
cl.add('n',1);
cl.addargname('n',"notice_level");
cl.adddescription('n',"Set the degree of program output. Use: \n\n\t-n 0\tNo output\n\t-n 10\tNormal program output\n\t-n 20\tParameters useful for reproducing the results\n\t-n 30\tAll output");
// Short Description
cl.addtoman_chapter("NAME","Tools for LAMMPS ellipsoid trajectory visualization in PyMol.");
// Version
cl.addtoman_chapter("VERSION","Version 0.1");
// Full Description
const string desc[5]={
"Tool for LAMMPS trajectory visualization in PyMol. The input is a LAMMPS ",
"'data' file or a 'in' file with ellipsoid semi-axes specified using the ",
"ellipsoid command. The trajectory is input from a 'dump' file that must ",
"be generated using a custom style with the following arguments in order:\n",
".TP\\fItag type x y z quatw quati quatj quatk\\fR\n"
};
cl.addtoman_chapter("DESCRIPTION",5,desc);
Colors colors;
cl.addtoman_chapter("AVAILABLE COLORS",colors.colorlist());
// bugs
const string bugs[3]={
"Comments are not allowed at any point between a section header and ",
"the end of the contents for a section in either the data file or ",
"the input file."
};
cl.addtoman_chapter("KNOWN BUGS",3,bugs);
// Authors
cl.addtoman_chapter("AUTHORS","W. Michael Brown");
// Parse the commandline
if (!cl.parse(argc,argv,error)) {
Describe(cl,cout);
error->generate_error(0,a::filenameonly(argv[0]),"Bad Command Line\n");
}
// Set the notice level
if (cl['n'])
error->note.set_notice_level(cl.argint('n',0));
// Generate a notice with the command line for records purposes
string cm=cl.program_name();
for (int j=1; j<argc; j++)
cm+=' '+string(argv[j]);
cm+="\n";
error->note.notice(19,"CommandLine",cm);
// Output the help
if (cl['h']) {
cl.write_man_page(cout,"0.1","Graphics Utilities");
exit(0);
}
}
// Parse past an ITEM line in the lammps dump file
bool parse_to(const char * token,ifstream &in) {
char iline[5000];
while (true) {
in.getline(iline,5000);
if (in.eof() || !in)
return false;
if (strcmp(token,iline)==0)
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,466 @@
/****************************************************************************
* cartesian.h
* Shared stuff for dealing with Cartesian coordinates
* Also contains quaternion structures and operations
*
* Cartesian point of doubles: cPt
* Cartesian point of intergers: iPt
* Vector of doubles: vectorPt
* Color of doubles: colorPt
* Quaternion: Quaternion
*
* Can be accessed as cPt.x, cPt[X], colorPt[GREEN], iPt[I], etc.
*
*
* W. Michael Brown
****************************************************************************/
/*! \file */
#ifndef CARTESIAN_H
#define CARTESIAN_H
#include "miscm.h"
#include "m_constants.h"
#include "spherical.h"
#include <assert.h>
#include <math.h>
#include <iostream>
#include <fstream>
using namespace std;
enum { X, ///<0
Y, ///<1
Z ///<2
};
enum { I, ///<0
J, ///<1
K, ///<2
W ///<3
};
enum { RED, ///<0
GREEN, ///<1
BLUE ///<2
};
// Other coordinates
template<class numtyp> class Ball;
// Template friend declarations
template<class numtyp> class TwoD;
template<class numtyp>
ostream & operator<< (ostream &out, const TwoD<numtyp> &t);
template<class numtyp>
istream & operator>> (istream &in, TwoD<numtyp> &t);
template<class numtyp> class ThreeD;
template<class numtyp>
ostream & operator<< (ostream &out, const ThreeD<numtyp> &t);
template<class numtyp>
istream & operator>> (istream &in, ThreeD<numtyp> &t);
template<class numtyp>
ThreeD<numtyp> operator+ (const numtyp, const ThreeD<numtyp> &two);
template<class numtyp>
ThreeD<numtyp> operator- (const numtyp, const ThreeD<numtyp> &two);
template<class numtyp>
ThreeD<numtyp> operator* (const numtyp, const ThreeD<numtyp> &two);
template<class numtyp>
ThreeD<numtyp> operator/ (const numtyp, const ThreeD<numtyp> &two);
/// Two dimensional vector
/** The elements can be accessed directly .x or .y
* or by using the operator [] ( [X], [Y] or [I], [J] )
*
* The following operators are currently overloaded:
* +,-,*
*
* operators *,/ returns a vector with each element multiplied
* times the corresponding element in the other vector (Matlab .* )
*
* the member function dot can be used to compute dot products
*
* Input and output are overloaded for element I/O of the form "x y"
* <<, >>
*
* \sa cartesian.h for typedefs and defines*/
template<class numtyp>
class TwoD {
public:
/// Empty construct. Not necessarily initialized to [0 0]
TwoD();
/// Assign both x and y the value
TwoD(numtyp x);
/// Assignment Constructor
TwoD(numtyp cx, numtyp cy);
/// Type conversion
TwoD(const TwoD<float> &two);
/// Ball projection (onto xy-plane)
TwoD(const Ball<float> &ball);
numtyp x; ///< First element
numtyp y; ///< Last element
numtyp &operator[](unsigned i);
friend ostream & operator<< <>(ostream &out, const TwoD<numtyp> &t);
friend istream & operator>> <>(istream &in, TwoD<numtyp> &t);
TwoD<numtyp> operator + (const TwoD<numtyp> &two) const;
void operator += (const TwoD<numtyp> &two);
TwoD<numtyp> operator + (const numtyp two) const;
TwoD<numtyp> operator - (const TwoD<numtyp> &two) const;
TwoD<numtyp> operator - (const numtyp two) const;
TwoD<numtyp> operator * (const numtyp two) const;
TwoD<numtyp> operator * (const TwoD<numtyp> &two) const;
void operator /= (const numtyp two);
bool operator != (const TwoD<numtyp> &two) const;
/// Dot Product
numtyp dot(const TwoD<numtyp> &two) const;
/// Distance between two points
numtyp dist(const TwoD<numtyp> &two) const;
/// Distance squared between two points
numtyp dist2(const TwoD<numtyp> &two) const;
/// Returns one of two normals to a line represented by vector
TwoD<numtyp> normal();
/// Move coordinates into array
void to_array(numtyp *array);
/// Set coordinates from array
void from_array(numtyp *array);
// -------------- Weird functions that help with coord templating
unsigned dimensionality();
/// Returns the index of *this (for unsigned) in a square 3D array
/** \param s_size s_size[0]=1Dsize **/
numtyp array_index(vector<unsigned> &s_size);
/// Increment a 2D index from min to max (same as nested for)
/** Returns false when increment is complete **/
bool increment_index(TwoD &minp,TwoD &maxp);
/// Return false if x or y is not within the inclusive range
bool check_bounds(numtyp min,numtyp max);
private:
};
///\var typedef TwoD<double> c2DPt
/// Two dimensional vector of doubles
typedef TwoD<double> c2DPt;
/// Three dimensional vector
/** The elements can be accessed directly .x or .y or .z
* or by using the operator [] ( [X], [Y], [Z] or [I], [J], [K] or
* [RED], [GREEN], [BLUE] )
*
* The following operators are currently overloaded:
* +,-,*,/,+=,-=,*=,/=,==,!=
*
* operators *,/,*=,/= returns a vector with each element multiplied
* times the corresponding element in the other vector (Matlab .* )
* or with each element multiplied by a scalar
*
* the member function dot can be used to compute dot products
*
* Input and output are overloaded for element I/O of the form "x y z"
* <<, >>
*
* \sa cartesian.h for typedefs and defines*/
template<class numtyp>
class ThreeD {
public:
/// Assignment Constructor
ThreeD(numtyp cx, numtyp cy, numtyp cz);
/// Assign all the value
ThreeD(numtyp in);
/// Type Conversion
ThreeD(const ThreeD<unsigned>&);
/// Type Conversion
ThreeD(const ThreeD<int>&);
/// Type Conversion
ThreeD(const ThreeD<float>&);
/// Type Conversion
ThreeD(const ThreeD<double>&);
/// TwoD with (z-coordinate set to zero)
ThreeD(const TwoD<float>&);
/// Spherical Conversion
ThreeD(const Ball<double>&);
/// Spherical Conversion
ThreeD(const Ball<float>&);
/// Empty construct (Not necessarily initialized to zero)
ThreeD();
numtyp x; ///< First Element
numtyp y; ///< Second Element
numtyp z; ///< Last Element
friend ostream & operator<< <>(ostream &out, const ThreeD<numtyp> &t);
friend istream & operator>> <>(istream &in, ThreeD<numtyp> &t);
friend ThreeD<numtyp> operator+ <>(const numtyp, const ThreeD<numtyp> &two);
friend ThreeD<numtyp> operator- <>(const numtyp, const ThreeD<numtyp> &two);
friend ThreeD<numtyp> operator* <>(const numtyp, const ThreeD<numtyp> &two);
friend ThreeD<numtyp> operator/ <>(const numtyp, const ThreeD<numtyp> &two);
numtyp &operator[](unsigned i);
numtyp operator[](unsigned i) const;
bool operator == (const ThreeD<numtyp> &two) const;
bool operator != (const ThreeD<numtyp> &two) const;
ThreeD<numtyp> operator + (const ThreeD<numtyp> &two) const;
ThreeD<numtyp> operator + (const numtyp &two) const;
ThreeD<numtyp> operator - (const ThreeD<numtyp> &two) const;
ThreeD<numtyp> operator - (const numtyp &two) const;
ThreeD<numtyp> operator * (const numtyp &two) const;
ThreeD<numtyp> operator * (const ThreeD<numtyp> &two) const;
ThreeD<numtyp> operator / (const numtyp &two) const;
ThreeD<numtyp> operator / (const ThreeD<numtyp> &two) const;
void operator = (const ThreeD &two);
void operator += (const numtyp &two);
void operator += (const ThreeD &two);
void operator -= (const numtyp &two);
void operator -= (const ThreeD &two);
void operator *= (const numtyp &two);
void operator /= (const numtyp &two);
/// Move coordinates into array
void to_array(numtyp *array);
/// Set coordinates from array
void from_array(numtyp *array);
/// Returns the dot product of *this and two
numtyp dot(const ThreeD<numtyp> &two) const;
/// Returns the cross product of \b *this and \b two
/** The input vectors do not need to be normalized, however, the output
* vector will not be */
ThreeD<numtyp> cross(const ThreeD<numtyp> &two) const;
/// Returns the angle between \b *this and \b two
numtyp angle(const ThreeD<numtyp> &two) const;
/// Returns an arbitrary vector that is perpendicular to the input
/** The output vector is not normalized */
ThreeD<numtyp> perpendicular();
/// Rotate a vector in xz-plane by t radians
ThreeD<numtyp> rotatey(double t) const;
/// Rotate a vector in xy-plane by t radians
ThreeD<numtyp> rotatez(double t) const;
/// Magnitude of vector
numtyp norm() const;
/// Squared norm of a vector
numtyp norm2() const;
/// Magnitude of vector
numtyp hypot() const;
/// Distance between two points
numtyp dist(const ThreeD<numtyp> &two);
/// Distance squared between two points
numtyp dist2(const ThreeD<numtyp> &two);
/// Converts \b *this to the unit vector
void normalize();
/// Return the unit vector of \b *this
ThreeD<numtyp> unit();
/// Returns the projection of the point or vector onto Z-plane
c2DPt projz();
/// Set this to be the max of one and two for each dimension
void max(ThreeD &one, ThreeD &two);
/// Set this to be the min of one and two for each dimension
void min(ThreeD &one, ThreeD &two);
// -------------- Weird functions that help with coord templating
/// Returns 3
unsigned dimensionality();
/// Returns the index of *this (for unsigned) in a square 3D array
/** \param s_size s_size[0]=1Dsize, and s_size[1]=1D size*1Dsize **/
numtyp array_index(vector<unsigned> &s_size);
/// Increment a 3D index from min to max (same as nested for)
/** \note This is currently only implemented for unsigned numbers
* Returns false when increment is complete **/
bool increment_index(ThreeD &minp,ThreeD &maxp);
/// Return false if x,y, or z is not within the inclusive range
bool check_bounds(numtyp min,numtyp max);
private:
};
///\var typedef ThreeD<int> iPt;
/// Three dimensional vector of integers
typedef ThreeD<int> iPt;
///\var typedef ThreeD<unsigned> uPt;
/// Three dimensional vector of unsigned
typedef ThreeD<unsigned> uPt;
///\var typedef ThreeD<double> cPt;
/// Three dimensional vector of doubles
typedef ThreeD<double> cPt;
///\var typedef ThreeD<double> vectorPt;
/// Three dimensional vector of doubles
typedef ThreeD<double> vectorPt;
///\var typedef ThreeD<double> colorPt;
/// Three dimensional vector of doubles
typedef ThreeD<double> colorPt;
///\def ORIGIN
/// Point at origin
#define ORIGIN cPt(0.0,0.0,0.0)
///\def XAXIS
/// Unit vector for x-axis
#define XAXIS vectorPt(1.0,0.0,0.0)
///\def YAXIS
/// Unit vector for y-axis
#define YAXIS vectorPt(0.0,1.0,0.0)
///\def ZAXIS
/// Unit vector for z-axis
#define ZAXIS vectorPt(0.0,0.0,1.0)
class RotMat;
/// Euler Rotation
class EulerRot {
public:
EulerRot();
EulerRot(double theta,double psi,double phi);
/// Rotate the rotation axis by a given rotation matrix
void rotate_axis(const RotMat &rotmat);
void operator= (const EulerRot &two);
friend ostream & operator<<(ostream &out, const EulerRot &rot);
double theta;
double psi;
double phi;
};
///\def EU_NOROTATE
/// EulerRot with no rotation
#define EU_NOROTATE EulerRot(0.0,0.0,0.0)
//---------------------------Quaternion Stuff -------------------------
/// Class for handling Quaternion vectors
/** The elements can be accessed directly .w .i .j or .k
* or by using the operator[] ( [W], [X], [Y], [Z] or [W], [I], [J], [K] )
*
* The following operators are currently overloaded:
* +=,*,*=,=,==
*
* Overloaded * concatenates two successive rotations \n
* \e It \e is \e not \e communative \n
* For \e join=q1*q2, \e join is equivalent to performing rotation \e q1
* \b followed by \e q2.
*
* Input and output are overloaded for element I/O of the form "w i j k"
* <<, >>
*
* \sa cartesian.h for typedefs and defines*/
class Quaternion {
public:
Quaternion();
~Quaternion();
double w; ///<Real Component
double i; ///<Imaginary Component
double j; ///<Imaginary Component
double k; ///<Imaginary Component
double &operator[](unsigned index);
/// Copy Constructor
Quaternion(const Quaternion &two);
/// Assignment constructor
Quaternion(double inw, double ini, double inj, double ink);
/// Axis-Angle Rotation (\b v must be a \b UNIT vector)
Quaternion(const vectorPt &v, double angle);
/// Rotation from vector 1 to vector 2 (v1 and v2 need not be normalized)
/** Angle is between \b v1 and \b v2 and axis is calculated as the cross
* product of \b v1 and \b v2 */
Quaternion(const vectorPt &v1, const vectorPt &v2);
/// Spherical rotation
Quaternion(double longitude, double latitude);
/// From Euler angles
Quaternion(const EulerRot &erot);
void operator += (const Quaternion &two);
Quaternion operator * (const Quaternion &two) const;
void operator*= (const Quaternion &two);
Quaternion operator * (const double two) const;
void operator*= (const double two);
void operator= (const Quaternion &two);
bool operator== (const Quaternion &two) const;
/// Returns the conjugate
Quaternion conj() const;
/// Returns the norm
double norm();
/// Form \b *this into the unit vector
void normalize();
/// Returns the unit vector of \b *this
Quaternion unit();
friend ostream & operator<<(ostream &out, const Quaternion &q);
friend istream & operator>>(istream &in, Quaternion &q);
};
/// Rotation matrix (about origin)
/** Rotation of ThreeD can be applied via overloaded * operator **/
class RotMat {
public:
/// Unspecified matrix!
RotMat();
/// Initialize with quaternion
RotMat(const Quaternion &q);
/// Set based on quaternion
void set(const Quaternion &q);
/// Assert that the rotation is proper
void proper();
cPt operator*(const cPt &in) const;
double x_x,x_y,x_z,y_x,y_y,y_z,z_x,z_y,z_z;
};
///\def NOROTATE
/// Quaternion with no rotation
#define NOROTATE Quaternion(1.0,0.0,0.0,0.0)
/// Global geometry functions
namespace c {
/// Returns point on a line closest to an outside point
/** The line is described by a directional vector and a point on the line
*\param v Vector describing the line direction
*\param v_point Point on the line
*\param point The Outside point */
cPt point_to_line(const vectorPt &v, const cPt &v_point,
const cPt &point);
/// Return the closest distance between two line segments input as end points
/**\param l1_1 End point of segment 1
*\param l1_2 End point of segment 1
*\param l2_1 End point of segment 2
*\param l2_2 End point of segment 2 */
double closest_approach(const cPt &l1_1, const cPt &l1_2,
const cPt &l2_1, const cPt &l2_2);
/// Calculates the points where two line segments are closest
/**\param l1_1 End point of segment 1
*\param l1_2 End point of segment 1
*\param l2_1 End point of segment 2
*\param l2_2 End point of segment 2
*\param close_l1 Calculated closest point on line segment 1
*\param close_l2 Calculated closest point on line segment 2 */
void closest_approach_points(const cPt &l1_1, const cPt &l1_2,
const cPt &l2_1, const cPt &l2_2,
cPt &close_l1, cPt &close_l2);
/// Returns true if two line segments intersect
bool intersect(const c2DPt &line1_start, const c2DPt &line1_end,
const c2DPt &line2_start, const c2DPt &line2_end);
/// Liang-Barsky Intersection between line segment and line
bool sline_intersect(const c2DPt &line1_start, const c2DPt &line1_end,
const c2DPt &line2normal, const c2DPt &line2_point);
/// Average position
cPt mean(vector<cPt> &vec);
}
#endif

View File

@ -0,0 +1,111 @@
/***************************************************************************
colors.cpp
W. Michael Brown
-------------------
begin : Wed Jun 11 2003
copyright : (C) 2003 by mbrown
email : wmbrown@sandia.gov
***************************************************************************/
#include "colors.h"
Colors::Colors() {
colors.insert(pair<string,colorPt>("white",colorPt(1,1,1)));
colors.insert(pair<string,colorPt>("red",colorPt(1,0,0)));
colors.insert(pair<string,colorPt>("green",colorPt(0,1,0)));
colors.insert(pair<string,colorPt>("blue",colorPt(0,0,1)));
colors.insert(pair<string,colorPt>("cmyk_blue",colorPt(0.074,0.168,0.614)));
colors.insert(pair<string,colorPt>("yellow",colorPt(1,1,0)));
colors.insert(pair<string,colorPt>("purple",colorPt(0.697,0.2,0.697)));
colors.insert(pair<string,colorPt>("hotpink",colorPt(1,0,0.5)));
colors.insert(pair<string,colorPt>("brown",colorPt(0.551,0.272,0.15)));
colors.insert(pair<string,colorPt>("orange",colorPt(1,0.5,0)));
colors.insert(pair<string,colorPt>("black",colorPt(0,0,0)));
colors.insert(pair<string,colorPt>("magenta",colorPt(1,0,1)));
colors.insert(pair<string,colorPt>("slate",colorPt(0.5,0.5,1)));
colors.insert(pair<string,colorPt>("marine",colorPt(0,0.5,1)));
colors.insert(pair<string,colorPt>("cmyk_marine",colorPt(0.273,0.469,0.758)));
colors.insert(pair<string,colorPt>("teal",colorPt(0.2,0,0.598)));
colors.insert(pair<string,colorPt>("forest",colorPt(0.098,0.5,0.098)));
colors.insert(pair<string,colorPt>("deep",colorPt(0.098,0.098,0.5)));
colors.insert(pair<string,colorPt>("grey",colorPt(0.5,0.5,0.5)));
colors.insert(pair<string,colorPt>("wheat",colorPt(0.988,0.819,0.646)));
}
Colors::~Colors(){
}
// Number of colors in the map
unsigned Colors::size() {
return colors.size();
}
// Return the color in the gradient between start and end according to
// value
colorPt Colors::gradient(double start, double end, double value,
const colorPt &startcolor, const colorPt &endcolor) {
double percent;
if (value<start)
return startcolor;
else if (value>end)
return endcolor;
if (start==end)
return startcolor;
percent=((value-start)/(end-start));
return ((endcolor-startcolor)*percent)+startcolor;
}
// Three color gradient
colorPt Colors::gradient(double start, double mid, double end, double value,
const colorPt &startcolor, const colorPt &midcolor,
const colorPt &endcolor) {
double percent;
if (value==mid)
return midcolor;
else if (value<start)
return startcolor;
else if (value>end)
return endcolor;
else if (value<mid) {
percent=((value-start)/(mid-start));
return ((midcolor-startcolor)*percent)+startcolor;
} else {
if (mid==end)
return midcolor;
percent=((value-mid)/(end-mid));
return ((endcolor-midcolor)*percent)+midcolor;
}
}
// Output the colors to standard out
void Colors::outputcolors() {
map<string, colorPt>::iterator m;
for (m=colors.begin(); m!=colors.end(); m++)
cout << " " << m->first << endl;
}
// Return a string with the list of available colors
string Colors::colorlist() {
string colorl;
map<string, colorPt>::iterator m;
for (m=colors.begin(); m!=colors.end(); m++)
colorl+="\n\t"+m->first;
colorl+="\n";
return colorl;
}
colorPt Colors::operator[](const string &name) {
map<string, colorPt>::iterator m;
m=colors.find(name);
if (m==colors.end())
return colorPt(1,1,1); // Return white if not found
else
return m->second;
}

View File

@ -0,0 +1,59 @@
/***************************************************************************
colors.h
W. Michael Brown
-------------------
Storage and manipulation of colors.
begin : Wed Jun 11 2003
copyright : (C) 2003 by mbrown
email : wmbrown@sandia.gov
***************************************************************************/
#ifndef COLORS_H
#define COLORS_H
#include "cartesian.h"
#include <map>
#include <string>
#include <iostream>
using namespace std;
/// Class for dealing with RGB color space
class Colors {
public:
Colors();
~Colors();
/// Return number of colors in the map
unsigned size();
/// Return the color in the gradient between start and end
/** \param start Starting value
* \param end Ending Value
* \param value Color in gradient determined for value
* relative to start and end
* \param startcolor Starting color for the gradient
* \param endcolor Ending color for the gradient */
colorPt gradient(double start, double end, double value,
const colorPt &startcolor, const colorPt &endcolor);
/// Three color gradient
/** \sa gradient() */
colorPt gradient(double start, double mid, double end, double value,
const colorPt &startcolor, const colorPt &midcolor,
const colorPt &endcolor);
/// Output the colors to standard out
void outputcolors();
/// Return a string with the list of available colors
string colorlist();
/// Return an RGB color based on name
colorPt operator[](const string &name);
private:
map<string, colorPt> colors;
};
#endif

View File

@ -0,0 +1,504 @@
/***************************************************************************
commandline.cpp
W. Michael Brown
-------------------
Command line parsing stuff..
* Add argument with ' ' for arguments that do not use - (i.e. filenames)
* Manditory for the ' ' requires only 1 argument regardless of the number
- use argsize;
begin : Sun Jun 11 2003
copyright : (C) 2003 by W. Michael Brown
email : mbrown@nirvana.unm.edu
***************************************************************************/
#include "commandline.h"
CommandLine::Parameter::Parameter() {
num_args=0;
manditory_args=0;
manditory=false;
dash=false;
set=false;
}
CommandLine::Parameter::~Parameter() {}
CommandLine::CommandLine() {
help_set=false;
progname="";
// Set up the default man chapters
manchapter_order[0]="NAME";
man_chapters["NAME"].clear();
manchapter_order[1]="VERSION";
man_chapters["VERSION"].clear();
manchapter_order[2]="SYNOPSIS";
man_chapters["SYNOPSIS"].clear();
manchapter_order[3]="DESCRIPTION";
man_chapters["DESCRIPTION"].clear();
manchapter_order[4]="PARAMETERS";
man_chapters["PARAMETERS"].clear();
man_numchapters=5;
}
CommandLine::~CommandLine() {
}
void CommandLine::addargname(char n, const string &an) {
parameters[n].argnames.push_back(an);
}
void CommandLine::adddescription(char n, const string &d) {
parameters[n].description.push_back(d);
}
// Returns the argument size for a parameter
unsigned CommandLine::argsize(char n) {
return parameters[n].args.size();
}
bool CommandLine::operator [](char n) {
return set(n);
}
string CommandLine::program_name() {
return progname;
}
string CommandLine::full_command_line() {
return full_line;
}
// ----------------- Add allowed arguments
void CommandLine::add(char n, unsigned num) {
check(n);
parameters[n].num_args=num;
parameters[n].manditory_args=num;
}
// Where num represents maximum number of arguments and man_num represents
// manditory number of arguments for a parameter
void CommandLine::add(char n, unsigned num, unsigned man_num) {
check(n);
parameters[n].num_args=num;
parameters[n].manditory_args=man_num;
}
void CommandLine::addmanditory(char n, unsigned num) {
check(n);
parameters[n].manditory_args=num;
parameters[n].num_args=num;
parameters[n].manditory=true;
}
// Where num represents maximum number of arguments and man_num represents
// manditory number of arguments for a parameter
void CommandLine::addmanditory(char n, unsigned num, unsigned man_num) {
check(n);
parameters[n].num_args=num;
parameters[n].manditory_args=man_num;
parameters[n].manditory=true;
}
// Allow parameter that takes signed numbers as input
void CommandLine::addsigned(char n, unsigned num) {
check(n);
parameters[n].num_args=num;
parameters[n].manditory_args=num;
parameters[n].dash=true; // Allow dashes in arguments
}
// Allow parameter that takes signed numbers as input
void CommandLine::addsigned(char n, unsigned num, unsigned man_num) {
check(n);
parameters[n].num_args=num;
parameters[n].manditory_args=man_num;
parameters[n].dash=true; // Allow dashes in arguments
}
void CommandLine::addhelp(char n, unsigned num) {
check(n);
parameters[n].num_args=num;
parameters[n].manditory_args=num;
help_set=true;
help_param=n;
}
// Add descriptions for man pages
void CommandLine::addargnames(char n, unsigned num, const string args[]) {
for (unsigned i=0; i<num; i++)
parameters[n].argnames.push_back(args[i]);
}
void CommandLine::adddescription(char n, unsigned num, const string d[]) {
for (unsigned i=0; i<num; i++)
parameters[n].description.push_back(d[i]);
}
void CommandLine::addtoman_chapter(const string &name, const string &body) {
if (man_chapters.find(name)==man_chapters.end()) {
manchapter_order[man_numchapters]=name;
man_numchapters++;
}
man_chapters[name].push_back(body);
}
void CommandLine::addtoman_chapter(const string &name, unsigned line_count,
const string body[]) {
if (man_chapters.find(name)==man_chapters.end()) {
manchapter_order[man_numchapters]=name;
man_numchapters++;
}
for (unsigned i=0; i<line_count; i++)
man_chapters[name].push_back(body[i]);
}
void CommandLine::check(char n) {
map<char,Parameter>::iterator m;
m=parameters.find(n);
if (m!=parameters.end()) {
cerr << "DEVELOPER ERROR: Parameter: " << n << " set twice!\n";
cerr << "commandline.h: Exiting...\n\n";
exit(1);
}
}
bool CommandLine::optargparams() {
map<char,Parameter>::iterator m;
for (m=parameters.begin(); m!=parameters.end(); m++)
if (m->second.manditory_args<m->second.num_args)
return true;
return false;
}
// Returns the number of arguments that are not parameters (' ' name)
unsigned CommandLine::argsize() {
return parameters[' '].args.size();
}
// Whether or not this parameter was set
bool CommandLine::set(char n) {
return parameters[n].set;
}
// Force a parameter to be unset
void CommandLine::unset(char n) {
parameters[n].set=false;
}
char* CommandLine::arg(char n, unsigned num) {
return parameters[n].args[num];
}
int CommandLine::argint(char n, unsigned num) {
return atoi(parameters[n].args[num]);
}
double CommandLine::argdouble(char n, unsigned num) {
return atof(parameters[n].args[num]);
}
string CommandLine::argstring(char n, unsigned num) {
string s;
s=parameters[n].args[num];
return s;
}
bool CommandLine::parse(int argc, char* argv[], Error *error) {
unsigned i;
map<char,Parameter>::iterator m;
char flag;
int parameter; // Set to the parameter that arguments are being parsed
progname=a::filenameonly(argv[0]);
full_line=string(argv[0]);
for (unsigned i=1; i<unsigned(argc); i++)
full_line+=' '+string(argv[i]);
int argnum=1;
while (argnum<argc) {
// Set an argument
if (argv[argnum][0]!='-') {
if (parameters[' '].args.size()==parameters[' '].num_args) {
error->addwarning(3,9,"CommandLine","Invalid Command Line Argument: "+
string(argv[argnum]));
return false;
}
parameters[' '].set=true;
parameters[' '].args.push_back(argv[argnum]);
argnum++;
continue;
}
// Set a parameter
flag=argv[argnum][1];
m=parameters.find(flag);
if (m==parameters.end()) {
error->addwarning(4,9,"CommandLine","Invalid Command Line Parameter: "+
string(argv[argnum]));
return false;
}
// Make sure all required arguments are set before parameters with
// optional arguments
if (m->second.manditory_args<m->second.num_args)
if (parameters[' '].args.size()<parameters[' '].num_args) {
error->buffer() << "Parameters with optional arguments must be "
<< "placed after manditory commandline arguments";
error->addbuf(5,9,"CommandLine");
return false;
}
parameter=argnum;
argnum++;
m->second.set=true;
// Get the parameter arguments
for (i=0; i<m->second.num_args; i++) {
// Make sure we are not at the end of the parameter list
if (argnum>=argc)
if (m->second.args.size()<m->second.manditory_args) {
error->buffer() << "Invalid Number of Arguments: -" << m->first
<< " requires " << m->second.num_args
<< " arguments!";
error->addbuf(5,9,"CommandLine");
return false;
} else
break;
// Assure the right number of arguments for signed numbers
if (argv[argnum][0]=='-' && m->second.dash==true)
if (!isdigit(argv[argnum][1]))
if (m->second.args.size()<m->second.manditory_args) {
error->buffer() << "Invalid Number of Arguments: -" << m->first
<< " requires " << m->second.num_args
<< " arguments!";
error->addbuf(5,9,"CommandLine");
return false;
} else
break;
// Assure the right number of arguments for other numbers
if (argv[argnum][0]=='-' && m->second.dash==false)
if (m->second.args.size()<m->second.manditory_args) {
error->buffer() << "Invalid Number of Arguments: -" << m->first
<< " requires " << m->second.num_args
<< " arguments!";
error->addbuf(5,9,"CommandLine");
return false;
} else
break;
m->second.args.push_back(argv[argnum]);
argnum++;
}
}
// If help was set, we do not need to check for manditory args
if (help_set)
if (parameters[help_param].set)
return true;
// Assure that the manditory arguments were set for commandline
if (parameters[' '].manditory)
if (parameters[' '].args.size()<parameters[' '].manditory_args) {
error->addwarning(6,9,"CommandLine","Missing Required Argument!");
return false;
}
// Assure that manditory arguments were set for parameters!
for (m=parameters.begin(); m!=parameters.end(); m++) {
if (m->second.manditory)
if (m->second.set==false) {
error->buffer() << "Missing Required Argument: \n\n";
if (m->first!=' ')
error->buffer() << "-" << m->first << " must be set!";
error->addbuf(7,9,"CommandLine");
return false;
}
}
return true;
}
void CommandLine::write_man_page(ostream & out, const string &version,
const string &header) {
unsigned i;
map<char,Parameter>::iterator m;
string bold="\\fB";
string italic="\\fI";
string regular="\\fR";
out << ".TH " << program_name() << " 1 \"" << a::date()
<< "\"" << " \"" << program_name() << " (" << header << ") "
<< version << "\" \"" << header << '\"' << endl;
// Go through the chapters
map<unsigned,string>::iterator mc;
for (mc=manchapter_order.begin(); mc!=manchapter_order.end(); mc++) {
// NAME Section
if (mc->second=="NAME") {
out << ".SH NAME\n" << bold << program_name() << regular;
if (man_chapters["NAME"].size()!=0) {
out << " - ";
for (i=0; i<man_chapters["NAME"].size(); i++)
out << man_chapters["NAME"][i];
}
out << endl;
continue;
} // end NAME
// SYNOPSIS section
if (mc->second=="SYNOPSIS" && man_chapters["SYNOPSIS"].empty()) {
out << ".PD 2\n.SH SYNOPSIS\n.PD 1\n.TP\n";
if (program_name().length()>6)
out << bold << program_name() << regular << " ";
else
out << ".B " << program_name() << endl;
out << format_synopsis(bold,italic,regular) << endl;
if (program_name().length()>6)
out << ".br\n";
if (parameters[' '].num_args!=0 && optargparams())
out << ".PD 2\n.PP\nParameters with optional arguments should be placed "
<< "after manditory commandline arguments.\n";
continue;
} // end SYNOPSIS
// PARAMETERS
if (mc->second=="PARAMETERS") {
if (!(parameters.size()==0 ||
(parameters.size()==1 && (parameters.begin())->first==' '))) {
out << ".PD 2\n.SH PARAMETERS\n.PD 1\n";
for (m=parameters.begin(); m!=parameters.end(); m++) {
if (m->first==' ')
continue;
out << ".TP\n";
out << format_parameter(m->first,bold,italic,regular) << endl;
if (format_parameter(m->first,"","","").length()>6)
out << ".PD 0\n.TP\n.PP\n.PD 1\n";
// Output the description
vector<string> fdesc=man_format(m->second.description,bold,
italic,regular);
for (i=0; i<fdesc.size(); i++)
out << fdesc[i];
out << endl;
} // end for m=
}
continue;
} // end PARAMETERS
writeman_chapter(out,mc->second,bold,italic,regular);
}
}
void CommandLine::writeman_chapter(ostream &out,const string &name,
const string &bold, const string &italic,
const string &regular) {
if (man_chapters[name].empty())
return;
out << ".PD 2\n.SH " << name << "\n.PD 1\n";
vector<string> formatted=man_format(man_chapters[name],bold,italic,regular);
for (unsigned i=0; i<formatted.size(); i++)
out << formatted[i];
out << endl;
}
string CommandLine::format_synopsis(const string &bold, const string &italic,
const string &regular) {
string s;
map<char,Parameter>::iterator m;
bool space=false;
s=format_parameter(' ',bold,italic,regular)+" ";
for (m=parameters.begin(); m!=parameters.end(); m++) {
if (m->first==' ')
continue;
if (space)
s+=' ';
space=true;
if (m->second.manditory==false)
s+='[';
s+=format_parameter(m->first,bold,italic,regular);
if (m->second.manditory==false)
s+="]";
} // end for
return s;
}
// Write a synopsis in plain text format fitted to a given column width
void CommandLine::write_text_synopsis(ostream &out, unsigned column_width) {
string s=format_synopsis("","","");
vector<string> lines;
a::format_fit(column_width-program_name().length()-1,s,lines);
out << program_name() << " ";
for (unsigned i=0; i<lines.size(); i++) {
out << lines[i] << endl;
for (unsigned j=0; j<(program_name().length()+1); j++)
out << " ";
}
out << endl;
}
string CommandLine::format_parameter(char param, const string &bold,
const string &italic,
const string &regular) {
Parameter &p=parameters[param];
string strp="";
if (param!=' ')
strp=bold+"-"+param+regular;
if (p.num_args!=0)
for (unsigned i=0; i<p.argnames.size(); i++) {
if (!(param==' ' && i==0)) // Ignore first space on command args
strp+=' ';
if (i>=p.manditory_args)
strp+='[';
if (param!=' ')
strp+=italic+p.argnames[i]+regular;
else
strp+=p.argnames[i];
if (i>=p.manditory_args)
strp+=']';
}
if (p.argnames.size()<p.num_args)
strp+=" [...]";
return strp;
}
vector<string> CommandLine::man_format(const vector<string> &input,
const string &bold, const string &italic,
const string &regular) {
vector<string> output;
map<char,Parameter>::iterator m;
for (unsigned i=0; i<input.size(); i++) {
string temp=input[i];
a::str_replace("\n","\n.PD 0\n.PP\n.PD 1\n",temp);
a::str_replace(".EN","\n.EN\n",temp);
a::str_replace(".EQ","\n.EQ\n",temp);
a::str_replace(".TP","\n.PD 0\n.TP\n.PP\n.PD 1\n",temp);
a::str_replace(program_name(),bold+program_name()+regular,temp);
for (m=parameters.begin(); m!=parameters.end(); m++) {
if (m->first!=' ') {
string source="-";
source+=m->first;
a::str_replace(source,bold+source+regular,temp);
}
for (unsigned j=0; j<m->second.argnames.size(); j++)
a::str_replace(m->second.argnames[j],
italic+m->second.argnames[j]+regular,temp);
}
output.push_back(temp);
}
return output;
}

View File

@ -0,0 +1,214 @@
/***************************************************************************
commandline.h
W. Michael Brown
-------------------
Command line parsing stuff..
begin : Sun Jun 11 2003
copyright : (C) 2003 by W. Michael Brown
email : mbrown@nirvana.unm.edu
***************************************************************************/
#ifndef COMMANDLINE_H
#define COMMANDLINE_H
#include "error.h"
#include "misc.h"
#include <map>
#include <vector>
#include <string>
#include <stdlib.h>
#include <iostream>
using namespace std;
/// Parsing of command-line parameters and automatic man page generation
/** Allows manditory and optional command line arguments to be specified along
* with parameters set using flags. For arguments that do not require flags,
* a space char is used to set the flag. To specify the command line:
*
* foo input_file output_file -t signed_number [-o]
*
* \verbatim CommandLine cl;
cl.addmanditory(' ',2);
cl.addargname(' ',"input_file"); cl.addargname(' ',"output_file");
cl.addsigned('t',1,1);
cl.addargname('t',"arg_name");
cl.adddescription('t',"Manditory parameter allowing signed_numbers");
cl.add('o',0);
\endverbatim
* To instead specify that the outputfile is an optional argument:
* \verbatim cl.addmanditory(' ',2,1) \endverbatim
*
* A help flag can also be set which does not require other command line
* arguments to be set
*
* When the commandline is parsed, it is asserted that all manditory arguments
* and flags are set, that each flag is set with the correct number of
* parameters, and that no unknown flags have been set.
*
* One can check whether or not optional flags have been set using set() or
* the [] operator:
* \verbatim cl.set('o') <--> cl['o'] \endverbatim
*
* Man pages can be generated automatically by adding chapters. The SYNOPSIS
* and description of commandline arguments and flags is generated
* automatically. Examples of chapters that are consistently used are
* NAME, VERSION, DESCRIPTION, PARAMETERS, USAGE, EXAMPLES, AUTHORS, BUGS,
* SEE ALSO.
*
* The following characters can be used for formatting in parameter
* descriptions and chapters:
* \verbatim
\t tab
\n forced newline
.TP new paragraph (margin indented)
\\fB all following text is bold
\\fI all following text is italic
\\fR all following text is regular
\endverbatim
*
* The arguments, flags and parameter_names are automatically formatted
* throughout the man page with bold and italic typeface.
**/
class CommandLine {
public:
CommandLine();
~CommandLine();
/// Add an optional argument which takes num parameters
/** \note Use ' ' for n to specify an argument with no flag
* \param n flag used to pass arguments (i.e. -f)
* \param num the number of arguments that must be specified after flag */
void add(char n, unsigned num);
/// Add a manditory argument which takes num parameters
/** \sa add() **/
void addmanditory(char n, unsigned num);
/// Add a flag which can take signed numbers as parameters
/** \sa add() **/
void addsigned(char n, unsigned num);
/// Add an optional flag with minimum and maximum number of args
/** \sa add() **/
void add(char n, unsigned num, unsigned man_num);
/// Add a manditory flag with minimum and maximum number of args
/** \sa add() **/
void addmanditory(char n, unsigned num, unsigned man_num);
/// Add a flag with minimum and maximum number of args that takes signed nums
/** \sa add() **/
void addsigned(char n, unsigned num, unsigned man_num);
/// Add a help argument (does not require other manditory arguments be set)
/** \sa add() **/
void addhelp(char n, unsigned num);
/// Specify the names for arguments in the synopsis (for man page)
/** The names can be added one by one in the order of the flag parameters **/
void addargname(char n, const string &an);
/// Specify the names for arguments in the synopsis (for man page)
void addargnames(char n, unsigned num, const string args[]);
/// Specify the description for an argument (for the man page SYNOPSIS)
/** See the class description for formating characters **/
void adddescription(char n, const string &d);
/// Specify the description for an argument (for the man page SYNOPSIS)
/** See the class description for formating characters **/
void adddescription(char n, unsigned num, const string d[]);
/// Add a man page chapter with title 'name'
void addtoman_chapter(const string &name,const string &body);
/// Add a man page chapter with title 'name'
void addtoman_chapter(const string &name,unsigned line_count,
const string body[]);
/// Returns the number of arguments that are not flags (char n=' ')
unsigned argsize();
/// Returns the number of parameters passed for a given flag
unsigned argsize(char n);
/// Returns true if the optional flag was set on the commandline
bool set(char n);
/// Returns true if the optional flag was set on the commandline
bool operator [](char n);
/// Force a parameter to be unset
void unset(char n);
/// Return flag parameter or argument as a cstring (0-based index)
char *arg(char n, unsigned num);
/// Return flag parameter or argument as a integer (0-based index)
int argint(char n, unsigned num);
/// Return flag parameter or argument as a double (0-based index)
double argdouble(char n, unsigned num);
/// Return flag parameter or argument as a string (0-based index)
string argstring(char n, unsigned num);
/// Parse the command line arguments
bool parse(int argc, char* argv[], Error *error);
/// Return the program name
string program_name();
/// Return a string with the entire commandline as entered
string full_command_line();
/// Write out a man_page
void write_man_page(ostream & out, const string &version,
const string &header);
/// Advanced writing of man page
void writeman_chapter(ostream &out, const string &name, const string &bold,
const string &italic, const string &regular);
/// Return a string with all of the options in a man page synopsis format
string format_synopsis(const string &bold, const string &italic,
const string &regular);
/// Write a synopsis in plain text format fitted to a given column width
void write_text_synopsis(ostream &out, unsigned column_width);
private:
string full_line;
void check(char n);
// Returns true if parameters have been set with optional arguments
bool optargparams();
class Parameter;
map<char,Parameter> parameters;
bool help_set; // True if there is a parameter for getting help
char help_param; // Parameter for help
// Stuff for man page
string progname; // The name for the program (argv[0])
unsigned man_numchapters; // Number of chapters in man page
map<string,vector<string> > man_chapters;
map<unsigned, string> manchapter_order;
// Format a parameter as a string with argument names
string format_parameter(char param, const string &bold, const string &italic,
const string &regular);
// Formats the strings in input for a man page by replacing newlines and
// adding bold and italic fonts to parameters and arguments respectively
vector<string> man_format(const vector<string> &input, const string &bold,
const string &italic, const string &regular);
};
// This class is for internal use within CommandLine
class CommandLine::Parameter {
public:
friend class CommandLine;
Parameter();
~Parameter();
private:
unsigned num_args; // Maximum number of arguments for the parameter
unsigned manditory_args; // Minimum number of arguments for the parameter
bool manditory; // This parameter MUST be set
bool dash; // Allow for signed numbers (dashes in args)
bool set; // This parameter has been set
vector<char *> args;
// Strings for man page description
vector<string> argnames; // Names for each argument to the parameter
vector<string> description; // Description for how to set this parameter
};
#endif

279
tools/pymol_asphere/src/error.cpp Executable file
View File

@ -0,0 +1,279 @@
/***************************************************************************
error.cpp
-------------------
Class for error handling
__________________________________________________________________________
begin : Thu Oct 9 2003
copyright : (C) 2003 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#include "error.h"
Notice::Notice() {
nullout=new ostream(NULL);
noteout=&cout;
notice_level=9;
}
Notice::~Notice() {
if (nullout!=NULL)
delete nullout;
}
// Returns a null stream if level is two high, else returns notice stream
ostream & Notice::operator[] (const unsigned level) {
if (level<=notice_level)
return *noteout;
else
return *nullout;
}
void Notice::setostream(ostream &out) {
noteout=&out;
}
void Notice::set_notice_level(unsigned l) {
notice_level=l;
}
unsigned Notice::get_notice_level() {
return notice_level;
}
void Notice::notice(unsigned level, const string calling_class,
const string note) {
if (level<notice_level)
*noteout << calling_class << "::" << note;
}
void Notice::notice(unsigned level,const string calling_class,
vector<string> &notes) {
if (level<=notice_level) {
*noteout << calling_class << "::";
for (unsigned i=0; i<notes.size(); i++)
*noteout << notes[i];
}
}
void Notice::notice(unsigned level, const string note) {
if (level<=notice_level)
*noteout << note;
}
void Notice::notice(unsigned level, vector<string> &notes) {
if (level<=notice_level)
for (unsigned i=0; i<notes.size(); i++)
*noteout << notes[i];
}
Error::Error() {
nullout=new ostream(NULL);
unhandled_warnings=0;
handled_warnings=0;
max_level=9;
min_level=2;
handleatend=true;
writetotalatend=true;
errout=&cerr;
logout=nullout;
column_width=70;
}
Error::~Error() {
if (handleatend && unhandled_warnings!=0)
writewarnings();
if (writetotalatend && total_warnings()!=0)
writetotals(0);
if (nullout!=NULL)
delete nullout;
}
// Set a log file for error AND notice output
void Error::set_logfile(ostream &out) {
logout=&out;
note.setostream(out);
}
// Total number of warnings
unsigned Error::total_warnings() {
return unhandled_warnings+handled_warnings;
}
// Returns the number of errors generated with ID
unsigned Error::operator[](unsigned id) {
warning_iter m;
m=warning_list.find(id);
if (m==warning_list.end())
return 0;
return m->second.size();
}
void Error::addwarning(unsigned ID, unsigned level, const string calling_class,
const string warning) {
if (level<min_level)
return;
if (level>max_level)
generate_error(ID,calling_class,warning);
vector<ErrCom> *e=&(warning_list[ID]);
e->push_back(ErrCom());
e->back().level=level;
e->back().calling_class=calling_class;
e->back().message=warning;
unhandled_warnings++;
}
void Error::generate_error(unsigned ID, const string calling_class,
const string error) {
ErrCom err;
err.level=max_level+1;
err.calling_class=calling_class;
err.message=error;
if (warnings()!=0)
writewarnings();
write_err(ID,err);
writetotals(1);
#ifdef MUSE_MPI
MPI_Abort ( MPI_COMM_WORLD, 1 );
#else
exit(1);
#endif
}
// Add an error/warning (Program termination if level >= max level
ostringstream & Error::buffer() {
return buffer_stream;
}
// Generate warning with message in buffer
void Error::addbuf(unsigned ID, unsigned level, const string calling_class) {
addwarning(ID,level,calling_class,buffer_stream.str());
buffer_stream.str("");
}
// Generate serious error with message in buffer
void Error::addbuf(unsigned ID, const string calling_class) {
generate_error(ID,calling_class,buffer_stream.str());
}
unsigned Error::warnings() {
return unhandled_warnings;
}
void Error::writeline() {
*errout << "+";
*logout << "+";
for (unsigned i=0; i<column_width-2; i++) {
*errout << "-";
*logout << "-";
}
*errout << "+\n";
*logout << "+\n";
}
void Error::write_err(unsigned ID, ErrCom &err) {
if (err.level<min_level)
return;
*errout << "\n";
*logout << "\n";
writeline();
(*errout).setf(ios::left);
(*errout).unsetf(ios::right);
// Output the IDs
unsigned width12=(unsigned)floor((double)(column_width-10)/3.0);
unsigned width3=column_width-10-width12-width12;
string et;
unsigned width1;
if (err.level>max_level) {
et="| Error: "; width1=width12-7;
} else {
et="| Warning: "; width1=width12-9;
}
*errout << et << setw(width1) << ID << " | Level: "
<< setw(width12-7) << err.level << " | " << setw(width3)
<< err.calling_class << " |\n";
*logout << et << setw(width1) << ID << " | Level: "
<< setw(width12-7) << err.level << " | " << setw(width3)
<< err.calling_class << " |\n";
writeline();
// Output the message
vector <string> messages;
a::format_fit(column_width-3,err.message,messages);
for (unsigned i=0; i<messages.size(); i++) {
*errout << "| " << setw(column_width-3) << messages[i] << "|\n";
*logout << "| " << setw(column_width-3) << messages[i] << "|\n";
}
writeline();
return;
}
void Error::writewarning(unsigned ID) {
for (unsigned i=0; i<warning_list[ID].size(); i++)
write_err(ID,warning_list[ID][i]);
handled_warnings+=warning_list[ID].size();
dismiss_all_warnings(ID);
return;
}
void Error::dismiss_warning(unsigned ID) {
warning_iter m;
m=warning_list.find(ID);
if (m==warning_list.end())
return;
unhandled_warnings--;
if (m->second.size()==1)
warning_list.erase(m);
else
m->second.erase(m->second.end()--);
}
void Error::dismiss_all_warnings(unsigned ID) {
warning_iter m;
m=warning_list.find(ID);
if (m==warning_list.end())
return;
unhandled_warnings-=m->second.size();
warning_list.erase(m);
}
void Error::writewarnings() {
while (warning_list.size()>0)
writewarning(warning_list.begin()->first);
return;
}
void Error::dismiss_warnings() {
while (warning_list.size()>0)
dismiss_warning(warning_list.begin()->first);
return;
}
// Write out the total warnings and errors
void Error::writetotals(unsigned errorcount) {
*errout << "\n";
*logout << "\n";
writeline();
(*errout).setf(ios::left);
(*errout).unsetf(ios::right);
unsigned width1=(unsigned)floor((double)(column_width-7)/2.0);
unsigned width2=column_width-7-width1;
string swarnings="Total Warnings: "+a::itoa(handled_warnings+
unhandled_warnings);
string serrors="Total Errors: "+a::itoa(errorcount);
*errout << "| " << setw(width1) << swarnings << " | " << setw(width2)
<< serrors << " |\n";
*logout << "| " << setw(width1) << swarnings << " | " << setw(width2)
<< serrors << " |\n";
writeline();
}

218
tools/pymol_asphere/src/error.h Executable file
View File

@ -0,0 +1,218 @@
/***************************************************************************
error.h
-------------------
Class for error handling
__________________________________________________________________________
begin : Thu Oct 9 2003
copyright : (C) 2003 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#ifndef ERRORCLASS
#define ERRORCLASS
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <math.h>
#ifdef MUSE_MPI
#include <mpi.h>
#endif
using namespace std;
// forward declarations
namespace a {
string itoa(unsigned int);
void format_fit(unsigned, const string &, vector<string> &);
}
/// Notice Class for Handling Object Output
/** A notice object stores an ostream for output and a notice_level.
* All output is sent along with a level. Any output whose level is
* greater than notice_level is sent to a null stream. The C++ output
* operator '<<' can be used with the Notice operator '[]' which passes
* the level:
* \verbatim notice_object[29] << "This notice has level 29" << endl;
* \endverbatim
*
* The guidelines for output notice levels are:
* - \e 0: Information that must be output
* - \e 1 - 9: Normal program output
* - \e 10-19: Parameters useful for storing how the program was run
* - \e 20-29: Extraneous information useful that may be useful to user
* - \e 30- : Debugging information */
class Notice {
public:
/// Standard output (cout) is the default notice output ostream
/** The default maximum notice level is 9 \e (notice_level=10) */
Notice();
~Notice();
/// Set the output stream for notice output
void setostream(ostream &out);
/// Returns a null stream if level is two high, else returns notice stream
ostream & operator[] (const unsigned level);
/// Set the degree of program output
void set_notice_level(unsigned l);
/// Get the degree of program output
unsigned get_notice_level();
/// Generate a notice with a specified calling class
void notice(unsigned level, const string calling_class, const string note);
/// Generate a notice with a specified calling class
void notice(unsigned level, const string calling_class,
vector<string> &notes);
/// Generate a notice
void notice(unsigned level, const string note);
/// Generate a notice
void notice(unsigned level, vector<string> &note);
private:
unsigned notice_level;
ostream *nullout; // Null stream for redirecting output to nowhere
ostream *noteout; // Output for notices
};
/// Error and Notice Handling
/** This class is intended to handle all output to the user. Output is
* divided into notices and warnings/errors. Output of any message is
* associated with a level. For notices, if level is greater than or equal to
* max_notice_level, no output is generated. For warnings, if level is less
* than min_warning_level, it is dismissed with no output. If the level is
* greater than max_warning_level, the program is terminated and all warnings
* and errors are output.
*
* \note By default, on destruction of an Error object, all unhandled
* warnings and errors are output
*
* A log file can be specified for each object. In this case, all notices
* are output to the log file only and errors are output to both stderr
* and the log file
*
* Errors can be generated with a string or using the internal message buffer:
\verbatim
Error error;
error.buffer() << "Incorrect file format for file: " << filename;
error.addbuf(512,19,"FooClass";
// --- OR
string message = "Incorrect file format for file: "+filename;
error.addwarning(512,19,"FooClass",message);
\endverbatim
*
* Newlines will be inserted into the error message automatically in order
* to format it for the string. Forced newlines can be specified with \n
*
* Programs can check whether or not errors have been generated using the []
* operator and can 'handle' them by outputing the message or dismissing
* them without any output
*
* Notices are generated using the public Notice class (see Notice())
*
* \b Error \b Levels:
* - \e 0 - 1: Errors expected to happen during normal execution
* - \e 2 - 9: Errors that a non-interactive program can handle and continue
* - \e 10-19: Errors that interactive program can handle (file not found,etc.)
* - \e 20- : Serious errors that should terminate execution
**/
class Error {
public:
/// Default constructor (use cerr for output and no log file)
/** Default max notice level is 9, min warning level is 2, and max warning
* level is 9 */
Error();
~Error();
/// Set a log file for error AND notice output
void set_logfile(ostream &out);
/// Returns the number of errors (if any) generated with id
unsigned operator[](unsigned id);
/// Add warning, terminate if level is greater than max level
/** Newlines will be inserted into the message automatically when the
* message is formatted for output. However, forced newlines can also
* be inserted. **/
void addwarning(unsigned ID, unsigned level, const string calling_class,
const string warning);
/// Add serious error (terminates execution)
void generate_error(unsigned ID, const string calling_class,
const string error);
/// Add an message to the error buffer. Warning generated with addbuf()
/** Newlines will be inserted into the message automatically when the
* message is formatted for output. However, forced newlines can also
* be inserted.
*
\verbatim
Error error;
error.buffer() << "Choice not supported: " << choice;
error.addbuf(512,9,"FooClass");
\endverbatim **/
ostringstream & buffer();
/// Generate warning with message in buffer
/** \sa buffer() **/
void addbuf(unsigned ID, unsigned level, const string calling_class);
/// Generate serious error with message in buffer
/** \sa buffer() **/
void addbuf(unsigned ID, const string calling_class);
/// Number of Unhandled Warnings
unsigned warnings();
/// Total number of warnings
unsigned total_warnings();
/// Handle all warnings with this ID by writing them to out
void writewarning(unsigned ID);
/// Handle LAST warning with this ID WITHOUT writing it
void dismiss_warning(unsigned ID);
/// Handle ALL warnings with this ID WITHOUT writing it
void dismiss_all_warnings(unsigned ID);
/// Handle all warnings by writing them out
void writewarnings();
/// Handle all warnings without writing
void dismiss_warnings();
/// Write out the total warnings (write errorcount errors)
void writetotals(unsigned errorcount);
/// For generating notices
/** \sa Notice **/
Notice note;
private:
struct ErrCom;
map<unsigned,vector<ErrCom> > warning_list;
typedef multimap<unsigned, vector<ErrCom> >::iterator warning_iter;
unsigned handled_warnings;
unsigned unhandled_warnings;
bool handleatend; // Write any unhandled errors on destruct
bool writetotalatend; // Write totals on destruct if not 0
unsigned min_level; // Don't output warnings less than min_level
unsigned max_level; // if a warning has a level>max_level error!
ostream *errout, *logout; // Output for errors and warnings!
ostream *nullout; // No output
ostringstream buffer_stream; // For creating messages for warnings
unsigned column_width;
void write_err(unsigned ID, ErrCom &err);
void writeline();
};
struct Error::ErrCom {
unsigned level;
string calling_class;
string message;
};
#endif

View File

@ -0,0 +1,592 @@
/***************************************************************************
glsurface.cpp
W. Michael Brown
-------------------
Store and manipulate surfaces as OpenGL primitives
begin : Sun Jun 8 2003
copyright : (C) 2003 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#include "glsurface.h"
GLSurface::GLSurface(){
}
GLSurface::~GLSurface(){
}
// Operations on GLline structure
bool operator < (const GLline &one, const GLline &two) {
unsigned minone, mintwo, maxone, maxtwo;
if (one.points[0]<one.points[1]) {
minone=one.points[0];
maxone=one.points[1];
} else {
minone=one.points[1];
maxone=one.points[0];
}
if (two.points[0]<two.points[1]) {
mintwo=two.points[0];
maxtwo=two.points[1];
} else {
mintwo=two.points[1];
maxtwo=two.points[0];
}
if (minone<mintwo)
return true;
else if (minone==mintwo)
if (maxone<maxtwo)
return true;
return false;
}
bool operator == (const GLline &one, const GLline &two) {
if (one.points[0]==two.points[0] && one.points[1]==two.points[1])
return true;
if (one.points[0]==two.points[1] && one.points[1]==two.points[0])
return true;
return false;
}
void GLSurface::clear() {
gllines.clear();
linestrips.clear();
triangles.clear();
vertices.clear();
xmesh.clear();
ymesh.clear();
zmesh.clear();
}
// Reserve vector space for specified number of vertices and triangles
void GLSurface::reserve(unsigned num_v, unsigned num_t) {
vertices.reserve(num_v); triangles.reserve(num_t);
}
// Add a triangle
void GLSurface::addtriangle(Triangle &t) {
triangles.push_back(t);
}
// Add a vertex
void GLSurface::addvertex(Vertex &v) {
vertices.push_back(v);
}
// Add many triangles (via swap)
void GLSurface::addtriangles(vector<Triangle> &t) {
triangles.swap(t);
}
// Add many lines (via swap)
void GLSurface::addlinestrips(vector<LineStrip> &l) {
linestrips.swap(l);
}
// Add a mesh (via swap)
void GLSurface::addxyzmesh(vector<GLline> &x,vector<GLline> &y,
vector<GLline> &z) {
xmesh.swap(x); ymesh.swap(y); zmesh.swap(z);
}
// Preconditions:
// Triangles all loaded with correct vertex ordering
// Vertices all loaded
// Vertices that need to be calculated are marked as invalid
// Postconditions:
// For any normals that are marked as invalid, calculate normals by
// averaging normals for each triangle
void GLSurface::calculatenormals() {
unsigned i;
// Set all invalid normals to zero
for (i=0; i<vertices.size(); i++)
if (vertices[i].valid_normal==false)
vertices[i].normal=vectorPt(0,0,0);
for (i=0; i<triangles.size(); i++) {
vectorPt vec1, vec2, normal;
unsigned id0, id1, id2;
id0=triangles[i].point[0];
id1=triangles[i].point[1];
id2=triangles[i].point[2];
vec1=vertices[id1].cpt-vertices[id0].cpt;
vec2=vertices[id2].cpt-vertices[id0].cpt;
normal[X]=vec1[Z]*vec2[Y]-vec1[Y]*vec2[Z];
normal[Y]=vec1[X]*vec2[Z]-vec1[Z]*vec2[X];
normal[Z]=vec1[Y]*vec2[X]-vec1[X]*vec2[Y];
// Only do vertex averaging if the normal has not been
// explicitly set
if (vertices[id0].valid_normal==false)
vertices[id0].normal+=normal;
if (vertices[id1].valid_normal==false)
vertices[id1].normal+=normal;
if (vertices[id2].valid_normal==false)
vertices[id2].normal+=normal;
}
// Mark all normals as valid
for (i=0; i<vertices.size(); i++)
if (vertices[i].valid_normal==false) {
vertices[i].valid_normal=true;
double no=vertices[i].normal.norm();
if (no==0)
vertices[i].normal=ORIGIN;
else
vertices[i].normal/=no*-1;
}
//error->note[31] << "Calculated normals: " << flush;
return;
}
// Normalize normals.
void GLSurface::normalize() {
unsigned i;
for (i=0; i<vertices.size(); i++) {
vertices[i].normal.normalize();
if (am::not_nan(vertices[i].normal.x)==false) {
cerr << "Bad normal!"; // cerr fix me
vertices[i].normal=vectorPt(0,0,0);
}
}
//error->note[31] << "Normalized normals: " << flush;
}
// Flip normals
void GLSurface::flipnormals() {
unsigned i;
for (i=0; i<vertices.size(); i++)
vertices[i].normal*=-1.0;
//error->note[31] << "Flipped normals: " << flush;
}
// Calculate the Area of the Surface
double GLSurface::surfacearea() {
double sa=0;
for (unsigned i=0; i<triangles.size(); i++)
sa+=triarea(triangles[i]);
return sa;
}
double GLSurface::triarea(Triangle &t) {
double a=vertices[t.point[0]].cpt.dist(vertices[t.point[1]].cpt);
double b=vertices[t.point[1]].cpt.dist(vertices[t.point[2]].cpt);
double c=vertices[t.point[0]].cpt.dist(vertices[t.point[2]].cpt);
double d=a+b+c;
return (sqrt(d*(d-a)*(d-b)*(d-c))/4);
}
// Color surfaces
void GLSurface::color(const colorPt &color) {
unsigned i;
for (i=0; i<vertices.size(); i++)
vertices[i].color=color;
}
void GLSurface::colorbygradient(const colorPt &start, const colorPt &end) {
colorPt step, current;
unsigned i;
step=(end-start)/double(vertices.size());
current=start;
for (i=0; i<vertices.size(); i++) {
vertices[i].color=current;
current+=step;
}
}
void GLSurface::colorbymarker(const colorPt &zero, const colorPt &nonzero) {
unsigned i;
for (i=0; i<vertices.size(); i++) {
if (vertices[i].marker==0)
vertices[i].color=zero;
else
vertices[i].color=nonzero;
}
return;
}
// Color a surface based on interpolation of values on a grid
// void GLSurface::colorbygrid(GridNUM<double> &grid,const colorPt &neg,
// const colorPt &mid, const colorPt &pos, double minv,
// double midv, double maxv) {
// Colors c;
// for (unsigned i=0; i<vertices.size(); i++)
// vertices[i].color=c.gradient(minv,midv,maxv,grid.interp(vertices[i].cpt),
// neg,mid,pos);
// }
void GLSurface::set_transparency(double alpha) {
for (unsigned i=0; i<vertices.size(); i++)
vertices[i].transparency=alpha;
}
// Write out triangles as BEGIN,TRIANGLES,END primitives
void GLSurface::writetris(ofstream &out, const string &objname) {
unsigned i,j,k;
int index;
writepymolheader(out);
out << "BEGIN, TRIANGLES," << endl;
for (i=0; i<triangles.size(); i++) {
// Output coords, colors, and normals of points
for (j=0; j<3; j++) {
index=triangles[i].point[j];
// if (vertices[index].transparency!=1)
out << "ALPHA," << vertices[index].transparency << ",";
out << "COLOR,";
for (k=X; k<=Z; k++)
out << vertices[index].color[k] << ",";
if (vertices[index].valid_normal) {
out << "NORMAL,";
for (k=RED; k<=BLUE; k++)
out << vertices[index].normal[k] << ",";
}
out << "VERTEX,";
for (k=X; k<=Z; k++)
out << vertices[index].cpt[k] << ",";
}
out << endl;
}
out << "END";
writepymoltail(out,objname);
}
// Write out triangles as TRIANGLE primitives
void GLSurface::writetris_surf(ofstream &out, const string &objname) {
unsigned i,j,k;
int index;
writepymolheader(out);
for (i=0; i<triangles.size(); i++) {
// if (vertices[triangles[i].point[0]].transparency!=1)
out << "ALPHA," << vertices[triangles[i].point[0]].transparency << ",";
out << "TRIANGLE,";
// Output coords of points
for (j=0; j<3; j++) {
index=triangles[i].point[j];
for (k=X; k<=Z; k++)
out << vertices[index].cpt[k] << ",";
}
// Output normals of points
for (j=0; j<3; j++) {
index=triangles[i].point[j];
for (k=X; k<=Z; k++)
out << vertices[index].normal[k] << ",";
}
// Output colors of points
for (j=0; j<3; j++) {
index=triangles[i].point[j];
for (k=RED; k<=BLUE; k++)
out << vertices[index].color[k] << ",";
}
out << endl;
}
writepymoltail(out,objname);
}
// Write out triangles as POINTS
void GLSurface::writetris_points(ofstream &out, const string &objname) {
unsigned i,k;
writepymolheader(out);
out << "BEGIN, POINTS," << endl;
for (i=0; i<vertices.size(); i++) {
// Output coords, colors, and normals of points
// if (vertices[i].transparency!=1)
out << "ALPHA," << vertices[i].transparency << ",";
out << "COLOR,";
for (k=X; k<=Z; k++)
out << vertices[i].color[k] << ",";
if (vertices[i].valid_normal) {
out << "NORMAL,";
for (k=RED; k<=BLUE; k++)
out << vertices[i].normal[k] << ",";
}
out << "VERTEX,";
for (k=X; k<=Z; k++)
out << vertices[i].cpt[k] << ",";
out << endl;
}
out << "END\n";
writepymoltail(out,objname);
}
// Write out triangles as POINTS
void GLSurface::write_vspheres(ofstream &out, const string &objname,
double radius) {
unsigned i,k;
writepymolheader(out);
for (i=0; i<vertices.size(); i++) {
// Output coords, colors, and normals of points
// if (vertices[i].transparency!=1)
out << "ALPHA," << vertices[i].transparency << ",";
out << "COLOR,";
for (k=X; k<=Z; k++)
out << vertices[i].color[k] << ",";
out << "SPHERE,";
for (k=X; k<=Z; k++)
out << vertices[i].cpt[k] << ",";
out << radius << ",\n";
}
writepymoltail(out,objname);
}
// Write out triangles as POINTS
void GLSurface::writespheres(ofstream &out, const string &objname) {
unsigned i,k;
writepymolheader(out);
for (i=0; i<spheres.size(); i++) {
// Output coords, colors, and normals of points
// if (vertices[i].transparency!=1)
out << "ALPHA," << vertices[spheres[i].i].transparency << ",";
out << "COLOR,";
for (k=X; k<=Z; k++)
out << vertices[spheres[i].i].color[k] << ",";
out << "SPHERE,";
for (k=X; k<=Z; k++)
out << vertices[spheres[i].i].cpt[k] << ",";
out << spheres[i].radius << ",\n";
}
writepymoltail(out,objname);
}
// Write out triangles as mesh
// OPTIMIZE TO REMOVE IDENTICAL LINES
void GLSurface::writetris_mesh(ofstream &out, const string &objname) {
unsigned i,j,k;
int index;
writepymolheader(out);
for (i=0; i<triangles.size(); i++) {
out << "BEGIN, LINE_LOOP," << endl;
// Output coords, colors, and normals of points
for (j=0; j<3; j++) {
index=triangles[i].point[j];
// if (vertices[index].transparency!=1)
out << "ALPHA," << vertices[index].transparency << ",";
out << "COLOR,";
for (k=X; k<=Z; k++)
out << vertices[index].color[k] << ",";
if (vertices[index].valid_normal) {
out << "NORMAL,";
for (k=RED; k<=BLUE; k++)
out << vertices[index].normal[k] << ",";
}
out << "VERTEX,";
for (k=X; k<=Z; k++)
out << vertices[index].cpt[k] << ",";
}
out << "END,";
out << endl;
}
writepymoltail(out,objname);
}
// Write out Line Strips (Loops)
void GLSurface::writelinestrips(ofstream &out, const string &objname) {
unsigned i,j,k, size;
int index;
writepymolheader(out);
//out << "LINEWIDTH, 2," << endl;
for (i=0; i<linestrips.size(); i++) {
size=linestrips[i].line.size();
if (size==1)
out << "BEGIN, POINTS," << endl;
else if (size==2)
out << "BEGIN, LINES," << endl;
else if (linestrips[i].loop)
out << "BEGIN, LINE_LOOP," << endl;
else
out << "BEGIN, LINE_STRIP," << endl;
// Output coords, colors, and normals of points
for (j=0; j<linestrips[i].line.size(); j++) {
index=linestrips[i].line[j];
// if (vertices[index].transparency!=1)
out << "ALPHA," << vertices[index].transparency << ",";
out << "COLOR,";
for (k=X; k<=Z; k++)
out << vertices[index].color[k] << ",";
if (vertices[index].valid_normal) {
out << "NORMAL,";
for (k=RED; k<=BLUE; k++)
out << vertices[index].normal[k] << ",";
}
out << "VERTEX,";
for (k=X; k<=Z; k++)
out << vertices[index].cpt[k] << ",";
}
out << "END,";
out << endl;
}
writepymoltail(out,objname);
}
// Add a line
void GLSurface::addline(unsigned v1, unsigned v2) {
GLline line;
line.points[0]=v1;
line.points[1]=v2;
gllines.push_back(line);
}
// Write out GLlines
void GLSurface::writelines(ofstream &out, const string &objname) {
writelines(gllines, out, objname);
}
void GLSurface::writelines(vector<GLline> &l, ofstream &out,
const string &objname) {
unsigned i,j,k;
int index;
writepymolheader(out);
//out << "LINEWIDTH, 2," << endl;
out << "BEGIN, LINES," << endl;
for (i=0; i<l.size(); i++)
for (j=0; j<2; j++) {
index=l[i].points[j];
// if (vertices[index].transparency!=1)
out << "ALPHA," << vertices[index].transparency << ",";
out << "COLOR,";
for (k=X; k<=Z; k++)
out << vertices[index].color[k] << ",";
if (vertices[i].valid_normal) {
out << "NORMAL,";
for (k=RED; k<=BLUE; k++)
out << vertices[index].normal[k] << ",";
}
out << "VERTEX,";
for (k=X; k<=Z; k++)
out << vertices[index].cpt[k] << ",";
out << endl;
}
out << "END,\n";
writepymoltail(out,objname);
}
// Write a set of triangles as an xyzmesh - Requires surface was created on
// a grid of 'resolution' with minimum latice point at 'min'
void GLSurface::writexyzmesh(ofstream &out, const string &objname) {
writelines(xmesh,out,objname+"x");
writelines(ymesh,out,objname+"y");
writelines(zmesh,out,objname+"z");
return;
}
void GLSurface::writepymolheader(ofstream &out) {
out << "from pymol.cgo import *\n"
<< "from pymol import cmd\n"
<< "obj = [\n";
}
void GLSurface::writepymoltail(ofstream &out, const string &objname) {
out << "]\n"
<< "cmd.load_cgo(obj,'" << objname << "')\n\n";
}
// Helper function to set the xyz and the normal for a ellipsoid vertex
void GLSurface::SQE_helper(Vertex &ver, const cPt &rad, const double u,
const double v, const double n,
const double e) {
double sqCun=am::sign(cos(u))*powf(fabs(cos(u)),n);
double sqSun=am::sign(sin(u))*powf(fabs(sin(u)),n);
double sqCve=am::sign(cos(v))*powf(fabs(cos(v)),e);
double sqSve=am::sign(sin(v))*powf(fabs(sin(v)),e);
double sqCu2n=am::sign(cos(u))*powf(fabs(cos(u)),2.0-n);
double sqSu2n=am::sign(sin(u))*powf(fabs(sin(u)),2.0-n);
double sqCv2e=am::sign(cos(v))*powf(fabs(cos(v)),2.0-e);
double sqSv2e=am::sign(sin(v))*powf(fabs(sin(v)),2.0-e);
ver.cpt=rad;
ver.cpt.x*=sqCun*sqCve;
ver.cpt.y*=sqCun*sqSve;
ver.cpt.z*=sqSun;
ver.normal.x=sqCu2n*sqCv2e/rad.x;
ver.normal.y=sqCu2n*sqSv2e/rad.y;
ver.normal.z=sqSu2n/rad.z;
}
void GLSurface::add_super_ellipsoid(const cPt &cen, const cPt &rad,
const Quaternion &q,
const double n, const double e,
const double u1, const double u2,
const double v1, const double v2,
const unsigned u_segs,
const unsigned v_segs,
const colorPt &color, const double alpha){
RotMat rot(q);
Vertex ver;
ver.color=color;
ver.transparency=alpha;
double dU=(u2-u1)/u_segs;
double dV=(v2-v1)/v_segs;
double U=u1;
for (unsigned i=0; i<u_segs; i++) {
double V=v1;
for (unsigned j=0; j<v_segs; j++) {
unsigned offset=vertices.size();
SQE_helper(ver,rad,U,V,n,e);
ver.cpt=rot*ver.cpt+cen;
ver.normal=rot*ver.normal;
addvertex(ver);
SQE_helper(ver,rad,U+dU,V,n,e);
ver.cpt=rot*ver.cpt+cen;
ver.normal=rot*ver.normal;
addvertex(ver);
SQE_helper(ver,rad,U+dU,V+dV,n,e);
ver.cpt=rot*ver.cpt+cen;
ver.normal=rot*ver.normal;
addvertex(ver);
SQE_helper(ver,rad,U,V+dV,n,e);
ver.cpt=rot*ver.cpt+cen;
ver.normal=rot*ver.normal;
addvertex(ver);
Triangle t;
t.point[0]=offset;
t.point[1]=offset+1;
t.point[2]=offset+3;
addtriangle(t);
t.point[0]=offset+1;
t.point[1]=offset+2;
t.point[2]=offset+3;
addtriangle(t);
V+=dV;
}
U+=dU;
}
}
void GLSurface::add_ellipsoid(const cPt &center, const cPt &rad,
const Quaternion &rot, const colorPt &color,
const double alpha, const unsigned res) {
assert(res!=0);
add_super_ellipsoid(center,rad,rot,1.0,1.0,HALFPI*-1.0,HALFPI,PI*-1.0,PI,
res,res,color,alpha);
}
void GLSurface::add_ellipsoid(const cPt &center, const cPt &rad,
const Quaternion &rot, const colorPt &color,
const double alpha) {
add_super_ellipsoid(center,rad,rot,1.0,1.0,HALFPI*-1.0,HALFPI,PI*-1.0,PI,
5,5,color,alpha);
}

View File

@ -0,0 +1,195 @@
/***************************************************************************
glsurface.h
W. Michael Brown
-------------------
Store and manipulate surfaces as OpenGL primitives
begin : Sun Jun 8 2003
copyright : (C) 2003 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#ifndef GLSURFACE_H
#define GLSURFACE_H
#include "miscm.h"
#include "cartesian.h"
#include "colors.h"
//#include "gridnum.h"
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
/// Stores the ID numbers of the vertices making a triangle
struct Triangle {
/// Triangle position
unsigned point[3];
};
/// Vertex information used for all primitives
struct Vertex {
/// True if normal is being set for vertex
bool valid_normal;
/// Cartesian coords
cPt cpt;
// Used for surface area calculations
vectorPt normal;
/// Color
colorPt color;
/// For coloring surface
char marker;
/// For transparency (0 transparent, 1 opaque)
double transparency;
};
/// ID numbers for vertices making a line
struct GLline {
unsigned points[2];
};
// This stuff is used for removing duplicate lines by sorting;
bool operator < (const GLline &one, const GLline &two);
bool operator == (const GLline &one, const GLline &two);
/// Line Strip (loop) primitive (stores vertex indices)
struct LineStrip {
/// True for loop, false for line_strip
bool loop;
vector<unsigned> line;
};
/// Sphere primitive
struct Sphere {
unsigned i;
double radius;
};
/// Class for storage and I/O of a set of OpenGL primitives
class GLSurface {
public:
GLSurface();
~GLSurface();
/// Reserve vector space for specified number of vertices and triangles
void reserve(unsigned num_v, unsigned num_t);
/// Delete all primitives
void clear();
/// Add a triangle
void addtriangle(Triangle &t);
/// Add a vertex
void addvertex(Vertex &v);
/// Add many triangles (via swap)
/** \note triangles are removed from input vector */
void addtriangles(vector<Triangle> &t);
/// Add many lines (via swap)
/** \note lines are removed from input vector */
void addlinestrips(vector<LineStrip> &l);
/// Add a mesh (via swap)
/** \note lines are removed from input vector */
void addxyzmesh(vector<GLline> &x,vector<GLline> &y,vector<GLline> &z);
/// Add a line
void addline(unsigned v1, unsigned v2);
/// Add a sphere based on a current vertex and a radius
void add_sphere(unsigned index, double radius) {
Sphere s;
s.i=index;
s.radius=radius;
spheres.push_back(s);
}
/// Add an ellipsoid with specified resolution
/** The number of triangles is equal to twice the resolution squared **/
void add_ellipsoid(const cPt &center, const cPt &rad,
const Quaternion &rot, const colorPt &color,
const double alpha,const unsigned resolution);
/// Add an ellipsoid with resolution of 10
/** \sa add_ellipsoid **/
void add_ellipsoid(const cPt &center, const cPt &rad,
const Quaternion &rot, const colorPt &color,
const double alpha);
/// Calculate the unit normals for any vertices marked with invalid normals
void calculatenormals();
/// Normalize normals.
void normalize();
/// Flip normals
void flipnormals();
/// Calculate the Area of the Surface
double surfacearea();
/// Calculate the Area of a Triangle
double triarea(Triangle &t);
/// Return the number of spheres
unsigned size_spheres() { return spheres.size(); }
/// Return the number of vertices
unsigned size_vertices() { return vertices.size(); }
/// Solid color a surface
void color(const colorPt &color);
/// Color a surface by using a gradient
void colorbygradient(const colorPt &start, const colorPt &end);
/// Color a surface based on a marker
void colorbymarker(const colorPt &zero, const colorPt &nonzero);
/// Color a surface based on interpolation of values on a grid
/** \param grid Grid with appropriate interpolation scheme set
* \param neg Color for the value at and below minv
* \param mid Color for the value at midv
* \param pos Color for the value at and above posv **/
//void colorbygrid(GridNUM<double> &grid,const colorPt &neg,
// const colorPt &mid, const colorPt &pos, double minv,
// double midv, double maxv);
/// Set the transparency of the entire surface (0-1 [1=no transparency])
void set_transparency(double alpha);
/// Write out triangles as BEGIN,TRIANGLES,END primitives
void writetris(ofstream &out, const string &objname);
/// Write out triangles as TRIANGLE primitives
void writetris_surf(ofstream &out, const string &objname);
/// Write out triangles as POINTS
void writetris_points(ofstream &out, const string &objname);
/// Write out vertices as spheres
void write_vspheres(ofstream &out, const string &objname, double radius);
/// Write out triangles as Mesh
void writetris_mesh(ofstream &out, const string &objname);
/// Write out triangles as an xyzmesh
void writexyzmesh(ofstream &out,const string &objname);
void writelines(ofstream &out, const string &objname);
void writelines(vector<GLline> &l, ofstream &out, const string &objname);
/// Write out Line Strips (Loops)
void writelinestrips(ofstream &out, const string &objname);
void writespheres(ofstream &out, const string &objname);
/// Write header for Python scripts for rendering in PyMol
void writepymolheader(ofstream &out);
/// Write tail for Python script for rendering in Pymol
void writepymoltail(ofstream &out, const string &objname);
private:
vector<Triangle> triangles;
vector<Vertex> vertices;
vector<GLline> gllines;
vector<Sphere> spheres;
// For xyzmesh
vector<GLline> xmesh;
vector<GLline> ymesh;
vector<GLline> zmesh;
vector<LineStrip> linestrips;
void add_super_ellipsoid(const cPt &cen, const cPt &rad,const Quaternion &q,
const double n, const double e, const double u1,
const double u2, const double v1, const double v2,
const unsigned u_segs, const unsigned v_segs,
const colorPt &color, const double alpha);
void SQE_helper(Vertex &ver, const cPt &rad, const double u,
const double v, const double n, const double e);
};
#endif

View File

@ -0,0 +1,67 @@
/***************************************************************************
m_constants.h
-------------------
W. Michael Brown
Misc constants
__________________________________________________________________________
This file is part of the Math Library
__________________________________________________________________________
begin : Wed Aug 10 2005
copyright : (C) 2005 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
/*! \file */
#ifndef CONSTANTS_H
#define CONSTANTS_H
#include <math.h>
using namespace std;
#define MATHLIB_VER "0.15"
#ifndef PI
///\def PI
/// pi
#define PI 3.1415926535897932384626433832795
#endif
///\def TWOPI
/// pi*2
#define TWOPI 6.2831853071795862
///\def HALFPI
/// pi/2
#define HALFPI 1.5707963267948966
///\def DEGTORAD
/// Convert Degrees to Radians (pi/180)
#define DEGTORAD 0.017453292519943295
///\def SQRT_TWO
/// sqrt(2.0)
#define SQRT_TWO 1.4142135623730951
///\def SQRT_PI
/// sqrt(PI)
#define SQRT_PI 1.7724538509055159
///\def INF
/// Infinity
#define INF 1e308
///\def MINUSINF
/// Negative infinity
#define MINUSINF -1e308
#ifndef EPS
///\def EPS
/// Small number
#define EPS 1e-100
#endif
/** \mainpage Math Library
* \section intro Introduction
* Math library with containers and operations for vectors, matrices, graphs,
* cartesian coordinates, quaternions, Euler angles, support vector machine
* models, etc. **/
#endif

View File

@ -0,0 +1,24 @@
#!/bin/tcsh
set execs="asphere_vis"
set execdir="../bin"
if ( -e ../doc ) then
echo Manpage directory exists...
else
echo Creating directory 'manpages'
mkdir ../doc
endif
cd ../doc
foreach exec ($execs)
$execdir/$exec -h > $exec.manpage
eqn $exec.manpage > $exec.1
man -t -p eqn ./$exec.manpage > $exec.ps
ps2pdf $exec.ps $exec.pdf
end
cd ../src

428
tools/pymol_asphere/src/misc.cpp Executable file
View File

@ -0,0 +1,428 @@
/***************************************************************************
misc.cpp
-------------------
W. Michael Brown
Miscellaneous functions that do not deserve their own class
__________________________________________________________________________
This file is part of the "All" Library
__________________________________________________________________________
begin : May 30 2003
copyright : (C) 2003 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#include "misc.h"
void a::copyright(ostream &out, unsigned year) {
out << "Copyright (" << year << ") Sandia Corporation. Under the terms of "
<< "Contract\nDE-AC04-94AL85000, there is a non-exclusive license for "
<< "use of this\nwork by or on behalf of the U.S. Government. Export "
<< "of this program\nmay require a license from the United States "
<< "Government.\n";
}
// Get the SNL Copyright info as a string
string a::copyrightstring(unsigned year) {
return string("Copyright (")+a::itoa(year)+") Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive license for use of this work by or on behalf of the U.S. Government. Export of this program may require a license from the United States Government.";
}
void a::fileopen(ifstream &in, const char *filename, Error &error) {
in.clear();
in.open(filename);
if (!in) {
error.addwarning(1,15,"Misc",
"Could not open "+string(filename)+" for input!");
error.writewarnings();
}
}
void a::fileopen(ifstream &in, const string &filename, Error &error) {
in.clear();
in.open(filename.c_str());
if (!in) {
error.addwarning(1,15,"Misc",
"Could not open "+string(filename)+" for input!");
error.writewarnings();
}
}
void a::fileopenbinary(ifstream &in, const string &filename, Error &error) {
in.clear();
in.open(filename.c_str(), ios::binary);
if (!in) {
error.addwarning(1,15,"Misc",
"Could not open "+string(filename)+" for input!");
error.writewarnings();
}
}
void a::fileopen(ofstream &out, const char *filename, Error &error) {
out.clear();
out.open(filename);
if (!out) {
error.addwarning(2,15,"Misc",
"Could not open "+string(filename)+" for output!");
error.writewarnings();
}
}
void a::fileopen(ofstream &out, const string &filename, Error &error) {
out.clear();
out.open(filename.c_str());
if (!out) {
error.addwarning(2,15,"Misc",
"Could not open "+string(filename)+" for output!");
error.writewarnings();
}
}
void a::fileopenbinary(ofstream &out, const string &filename, Error &error) {
out.clear();
out.open(filename.c_str(),ios::binary);
if (!out) {
error.addwarning(2,15,"Misc",
"Could not open "+string(filename)+" for output!");
error.writewarnings();
}
}
void a::fileopenapp(ofstream &out, const string &filename, Error &error) {
out.clear();
out.open(filename.c_str(),ios::app);
if (!out) {
error.addwarning(2,15,"Misc",
"Could not open "+string(filename)+" for output!");
error.writewarnings();
}
}
void a::fileclose(ifstream &in, Error &error) {
in.close();
}
void a::fileclose(ofstream &out, Error &error) {
if (out.fail()) {
error.addwarning(10,15,"Misc","Error writing to output file!");
error.writewarnings();
}
out.close();
}
// Put a string back into an istream
void a::putback(istream &in, const string &s) {
if (s.size()==0)
return;
unsigned i=s.size()-1;
while (true) {
in.putback(s[i]);
if (i==0)
return;
i--;
}
}
string a::date() {
char datestr[40];
time_t t;
time(&t);
strftime(datestr,40,"%B %d, %Y",localtime(&t));
return string(datestr);
}
// Return the filename without the extension
string a::namewoext(const string &filename) {
return (filename.substr(0,filename.find_last_of('.')));
}
// Return the filename without extension or directory
string a::filenameonly(const string &filename) {
// Find the start of the filename
unsigned start=0;
if (filename.find_last_of('/')<(filename.length()-1))
start=filename.find_last_of('/')+1;
// Find the end of the filename
unsigned end=filename.find_last_of('.')-start;
return(filename.substr(start,end));
}
// Return the extension of a filename
string a::extension(const string &filename) {
// Find the start of the extension
unsigned start=filename.find_last_of('.')+1;
if (start>=filename.length())
return "";
return filename.substr(start,filename.length()-start);
}
// Center a string over the specified length
string a::strcenter(const string &s, unsigned length) {
string empty(" ");
unsigned half=length/2;
unsigned spacer=half-(s.length()/2)-1;
return (empty.substr(0,spacer)+s);
}
// True if a character is whitespace
bool a::whitespace(char c) {
if (c==' ' || c=='\n' || c=='\t' || c=='\f' || c=='\r' || c=='\v')
return true;
return false;
}
// Check if a string is only whitespace
bool a::whitespace(const string &s) {
for (unsigned i=0; i<s.length(); i++)
if (!whitespace(s[i]))
return false;
return true;
}
/// Remove all whitespace from a string
string a::remove_whitespace(const string &s) {
string n;
for (unsigned i=0; i<s.length(); i++)
if (!whitespace(s[i]))
n+=s[i];
return n;
}
void a::str_replace(const string &source, const string &target, string &s) {
unsigned slength=source.length();
unsigned tlength=target.length();
unsigned loc=0;
#ifdef DEBUG
assert(slength>0 && tlength>0);
#endif
while (true) {
if (loc>=s.length())
break;
loc=s.find(source,loc);
if (loc>=s.length())
break;
s.replace(loc,slength,target,0,tlength);
loc+=tlength;
}
}
/// Convert all alpha characters to lower case
string a::tolower(const string &s) {
string r="";
for (unsigned i=0; i<s.length(); i++)
r+=std::tolower(s[i]);
return r;
}
// Return a string of num underscores
string a::underline(unsigned num) {
return string(num,'_');
}
// The tokens parsed from cstring are \e added to the input vector
void a::get_tokens(const char *line, vector<string> &tokens) {
string sline=line;
get_tokens(sline,tokens);
}
void a::get_tokens(const string &sline, vector<string> &tokens) {
string token="";
unsigned i=0;
while (i<sline.length()) {
if (whitespace(sline[i])) {
i++;
continue;
}
while (i<sline.length()) {
if (whitespace(sline[i])) {
tokens.push_back(token);
token="";
break;
}
token+=sline[i];
i++;
}
}
if (token!="")
tokens.push_back(token);
}
// Return the first token in a string
string a::get_first_token(const char *line) {
string sline=line;
string token="";
unsigned i=0;
while (i<sline.length()) {
if (whitespace(sline[i])) {
i++;
continue;
}
while (i<sline.length()) {
if (whitespace(sline[i]))
return token;
token+=sline[i];
i++;
}
}
return token;
}
void a::get_tokens(char delimiter, const string &sline,vector<string> &tokens) {
string token="";
unsigned i=0;
while (i<sline.length()) {
if (delimiter==sline[i]) {
tokens.push_back(token);
token="";
} else
token+=sline[i];
i++;
}
if (token!="")
tokens.push_back(token);
}
// Format a string to fit within a specified column width
void a::format_fit(unsigned column_width, const string &input,
vector<string> &output) {
vector<string> forced;
a::get_tokens('\n',input,forced);
for (unsigned i=0; i<forced.size(); i++) {
string current_line;
vector<string> tokens;
a::get_tokens(forced[i],tokens);
for (unsigned j=0; j<tokens.size(); j++) {
if (current_line.length()+tokens[j].length()<column_width) {
current_line+=tokens[j]+' ';
} else {
if (tokens[j].length()+1>column_width) {
unsigned this_count=column_width-current_line.length();
current_line+=tokens[j].substr(0,this_count);
output.push_back(current_line);
current_line="";
tokens[j]=tokens[j].substr(this_count,tokens[j].length()-this_count);
j--;
} else {
output.push_back(current_line);
current_line=tokens[j]+' ';
}
}
}
output.push_back(current_line);
}
return;
}
string a::itoa(unsigned i) {
ostringstream o;
o << i;
return o.str();
}
string a::itoa(int i) {
ostringstream o;
o << i;
return o.str();
}
string a::ftoa(double i) {
ostringstream o;
o << i;
return o.str();
}
// Seed the random number generator
void a::seedrandom(unsigned seed) {
srand(seed);
}
// Seed the random number generator with the current time
void a::seedrandom_time() {
srand(unsigned(time(0))); //+getpid());
}
// Return an integer between 0 and max
double a::frandom(double max) {
return double(rand())/double(RAND_MAX)*max;
}
// Return an integer between 0 and max
unsigned a::irandom(unsigned max) {
return unsigned(double(rand())/double(RAND_MAX)*max);
}
// Return an integer between 0 and max
long a::lrandom(long max) {
return long(double(rand())/double(RAND_MAX)*max);
}
// Empty constructer with no header, no extension, no lead zeros
FileIterator::FileIterator() {
file_num=0;
digits=0;
header="";
extension="";
}
// Specify the filename format with leading zeros
FileIterator::FileIterator(const string &h,const string &e,unsigned d) {
file_num=0;
digits=d;
header=h;
extension=e;
}
// Specify the filename format without leading zeros
FileIterator::FileIterator(const string &h,const string &e) {
digits=0;
file_num=0;
header=h;
extension=e;
}
// Set the current file number
void FileIterator::set_file_num(unsigned fnum) {
file_num=fnum;
}
// Set the file header
void FileIterator::set_file_header(const string &head) {
header=head;
}
// Set the file extension
void FileIterator::set_file_extensions(const string &ext) {
extension=ext;
}
// Set the number of leading zeros
void FileIterator::set_lead_zeros(unsigned digs) {
digits=digs;
}
// Set the current file number, header, extension, leading zeros
void FileIterator::set(unsigned fnum, const string &head, const string &ext,
unsigned digs) {
file_num=fnum;
header=head;
extension=ext;
digits=digs;
}
string FileIterator::nextfilename() {
// Get an output filename from a string
string filename;
filename=a::itoa(file_num);
while (filename.length()<digits)
filename='0'+filename;
file_num++;
return header+filename+extension;
}

164
tools/pymol_asphere/src/misc.h Executable file
View File

@ -0,0 +1,164 @@
/***************************************************************************
misc.h
-------------------
W. Michael Brown
Miscellaneous functions that do not deserve their own class
__________________________________________________________________________
This file is part of the "All" Library
__________________________________________________________________________
begin : May 30 2003
copyright : (C) 2003 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#ifndef MISC_H
#define MISC_H
#include "error.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
using namespace std;
/// Miscellaneous functions that do not deserve their own class
/** \e a contains functions for \n
* - fileio
* - string manipulation
* - conversion from numbers to strings */
namespace a {
/// Output the SNL Copyright info for publication \e year.
void copyright(ostream &out, unsigned year);
/// Get the SNL Copyright info as a string
string copyrightstring(unsigned year);
/// Open a file for input. Generates error ID \b 1-15 on fail.
void fileopen(ifstream &in, const char *filename, Error &error);
/// Open a file for input. Generates error ID \b 1-15 on fail.
void fileopen(ifstream &in, const string &filename, Error &error);
/// Open a binary file for input. Generates error ID \b 1-15 on fail.
void fileopenbinary(ifstream &in, const string &filename, Error &error);
/// Open a file for output. Generates error ID \b 2-15 on fail.
void fileopen(ofstream &out, const string &filename, Error &error);
/// Open a file for output. Generates error ID \b 2-15 on fail.
void fileopenbinary(ofstream &out, const string &filename, Error &error);
/// Open a file for append. Generates error ID \b 2-15 on fail.
void fileopenapp(ofstream &out, const string &filename, Error &error);
/// Open a file for output. Generates error ID \b 2-15 on fail.
void fileopen(ofstream &out, const char *filename, Error &error);
/// Close an input file. Generates error ID \b 10-15 on fail.
void fileclose(ifstream &in, Error &error);
/// Close an output file. Generates error ID \b 11-15 on fail.
void fileclose(ofstream &out, Error &error);
/// Put a string back into an istream
void putback(istream &in, const string &s);
/// Get the current date in the format "January 1, 2003"
string date();
/// Returns the filename without the extension
string namewoext(const string &filename);
/// Returns the filename without extension or directory
string filenameonly(const string &filename);
/// Return the extension of a filename
string extension(const string &filename);
/// Centers a string over the specified length
string strcenter(const string &s, unsigned length);
/// True if a character is whitespace
bool whitespace(char c);
/// True if a string is only whitespace
bool whitespace(const string &s);
/// Remove all whitespace from a string
string remove_whitespace(const string &s);
/// Replace any instance of \e source with \e target within the string \e s
void str_replace(const string &source, const string &target, string &s);
/// Convert all alpha characters to lower case
string tolower(const string &s);
/// The tokens parsed from cstring are \e added to the input vector
/** \param line The line with 'white space' delimeted tokens
* \param tokens Each token parsed is added to the vector */
void get_tokens(const char *line, vector<string> &tokens);
/// The tokens parsed from string are \e added to the input vector
/** \param line The line with 'white space' delimeted tokens
* \param tokens Each token parsed is added to the vector */
void get_tokens(const string &line, vector<string> &tokens);
/// Parse a string into tokens based on delimiter
/** \param line The line with 'white space' delimeted tokens
* \param tokens Each token parsed is added to the vector */
void get_tokens(char delimiter, const string &line, vector<string> &tokens);
/// Return the first token in a string
string get_first_token(const char *line);
/// Format a string to fit within a specified column width
/** Newlines are inserted between whitespace if possible, otherwise line is
* wrapped. Each string in the vector represents one line of text
* \note The output vector is not emptied! **/
void format_fit(unsigned column_width, const string &input,
vector<string> &output);
/// Return a string of num underscores
string underline(unsigned num);
/// Returns string representation of unsigned number
string itoa(unsigned i);
/// Returns string representation of int number
string itoa(int i);
/// Returns string representation of double number
string ftoa(double i);
/// Seed the random number generator
void seedrandom(unsigned seed);
/// Seed the random number generator with the current time
void seedrandom_time();
/// Returns a random integer between 0 and max
unsigned irandom(unsigned max);
/// Returns a random integer between 0 and max
long lrandom(long max);
/// Returns a random double between 0 and max
double frandom(double max);
}
/// Iterate through file names to give each unique numbers
class FileIterator {
public:
/// Empty constructer with no header, no extension, no lead zeros
FileIterator();
/// Specify the filename format using leading zeros
/** Files are generated according to the following format:
* \verbatim header+%0'digits'file_number+extension \endverbatim */
FileIterator(const string &header, const string &extension, unsigned digits);
/// Specify the filename format without leading zeros
/** Files are generated according to the following format:
* \verbatim header+file_number+extension \endverbatim */
FileIterator(const string &header, const string &extension);
/// Set the current file number
void set_file_num(unsigned fnum);
/// Set the file header
void set_file_header(const string &head);
/// Set the file extension
void set_file_extensions(const string &ext);
/// Set the number of leading zeros
void set_lead_zeros(unsigned digs);
/// Set the current file number, header, extension, leading zeros
void set(unsigned fnum, const string &head, const string &ext, unsigned digs);
/// Returns the next filename.
string nextfilename();
private:
string header,extension;
unsigned digits;
unsigned file_num;
};
#endif

212
tools/pymol_asphere/src/miscm.cpp Executable file
View File

@ -0,0 +1,212 @@
/***************************************************************************
miscm.cpp
-------------------
W. Michael Brown
Miscellaneous functions that do not deserve their own class
__________________________________________________________________________
This file is part of the Math Library
__________________________________________________________________________
begin : May 30 2003
copyright : (C) 2003 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#include "miscm.h"
double am::square(double num) {
return num*num;
}
// Rounds a number
double am::round(double n) {
double r=ceil(n);
if (r-n>0.5)
return floor(n);
return r;
}
// Return the -1 for negative, 0 for zero, and 1 for positive
int am::sign(double v) {
if (v<0)
return -1;
if (v>0)
return 1;
return 0;
}
// Return the range of elements in a vector
double am::range(const vector<double> &v) {
if (v.empty())
return 0;
double min=v[0];
double max=v[0];
for (unsigned i=1; i<v.size(); i++) {
if (v[i]<min)
min=v[i];
if (v[i]>max)
max=v[i];
}
return max-min;
}
// Return the average of elements in a vector
double am::mean(const vector<double> &v) {
double sum=0;
for (unsigned i=0; i<v.size(); i++)
sum+=v[i];
return sum/v.size();
}
// Return the max of two objects
namespace am {
template double max<double>(double,double);
template float max<float>(float,float);
template unsigned max<unsigned>(unsigned,unsigned);
template int max<int>(int,int);
}
template <typename numtyp>
numtyp am::max(numtyp one,numtyp two) {
if (one>two)
return one;
return two;
}
// Return the min of two objects
namespace am {
template double min<double>(double,double);
template float min<float>(float,float);
template unsigned min<unsigned>(unsigned,unsigned);
template int min<int>(int,int);
}
template <typename numtyp>
numtyp am::min(numtyp one,numtyp two) {
if (one<two)
return one;
return two;
}
// Swap two objects
void am::swap(double a, double b) {
double temp=a;
a=b;
b=temp;
}
// --------------------- Finite Precision stuff
double am::epsilon(double number) { // Finite Precision zero
return fabs(DBL_EPSILON*number);
}
// Bring number 1 digit closer to zero
double am::minus_eps(double number) {
return (number-DBL_EPSILON*number);
}
// Bring number 1 digit away from zero
double am::plus_eps(double number) {
return (number+DBL_EPSILON*number);
}
// Bring number m digits away from zero
double am::plus_Meps(double m,double number) {
return (number+m*DBL_EPSILON*number);
}
// Bring number precision/2.0 digits away
double am::plus_2eps(double number) {
return (number+100000000*DBL_EPSILON*number);
}
// Bring number pre/2 digits away
double am::minus_2eps(double number) {
return (number-100000000*DBL_EPSILON*number);
}
// Not a number checks
bool am::not_nan(double number) { // False if NAN
if (number-number!=0)
return false;
return true;
}
// Matrix stuff
// Invert a matrix - from numerical recipes in C
void am::invert(double **a, unsigned n, Error &error) {
int *indxc=new int[n];
int *indxr=new int[n];
int *ipiv=new int[n];
unsigned i,icol,irow,j,k,l,ll;
double big,dum,pivinv;
for (j=0;j<unsigned(n);j++)
ipiv[j]=0;
for(i=0;i<n;i++) { /* *main loop for columns to be reduced */
big = 0.0;
for (j=0;j<n;j++) /* outer loop for search of a pivot element*/
if (ipiv[j] !=1)
for(k=0;k<n;k++) {
if (ipiv[k] ==0) {
if (fabs(a[j][k]) >= big) {
big =fabs(a[j][k]);
irow=j;
icol=k;
}
} else if (ipiv[k] > 1) {
error.addwarning(303,9,"Invert",
"Cannot invert a singular matrix.");
return;
}
}
++(ipiv[icol]);
if (irow !=icol) {
for (l=0;l<n;l++)
swap(a[irow][l],a[icol][l]);
}
indxr[i]=irow;
indxc[i]=icol;
if (a[icol][icol] == 0.0) {
error.addwarning(303,9,"Invert",
"Cannot invert a singular matrix.");
return;
}
pivinv=1.0/a[icol][icol];
a[icol][icol]=1.0;
for (l=0;l<n;l++)
a[icol][l] *=pivinv;
for (ll=0;ll<n;ll++)
if (ll!= icol) {
dum=a[ll][icol];
a[ll][icol]=0.0;
for (l=0;l<n;l++)
a[ll][l] -=a[icol][l]*dum;
}
}
for (l=1;l>=1;l--) {
if (indxr[l] != indxc[l])
for (k=0;k<n;k++)
swap(a[k][indxr[l]],a[k][indxc[l]]);
}
delete []ipiv;
delete []indxr;
delete []indxc;
return;
}
// Move a value from a fraction of one range to a fraction of another
double am::rerange(double one_start, double one_end, double value,
double two_start, double two_end) {
double one_diff=one_end-one_start;
if (one_diff==0)
return two_end;
return (value-one_start)/one_diff*(two_end-two_start)+two_start;
}

89
tools/pymol_asphere/src/miscm.h Executable file
View File

@ -0,0 +1,89 @@
/***************************************************************************
miscm.h
-------------------
W. Michael Brown
Miscellaneous functions that do not deserve their own class
__________________________________________________________________________
This file is part of the Math Library
__________________________________________________________________________
begin : May 30 2003
copyright : (C) 2003 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#ifndef MISCM_H
#define MISCM_H
#include <float.h>
#include <math.h>
#include <vector>
#include "error.h"
using namespace std;
/// Miscellaneous functions that do not deserve their own class
/** \e a contains functions for \n
* - simple math functions
* - finite precision stuff */
namespace am {
/// Returns the square of a number
double square(double);
/// Rounds a number
double round(double);
/// Return the range of elements in a vector (0 if empty)
double range(const vector<double> &v);
/// Return the average of elements in a vector (0 if empty)
double mean(const vector<double> &v);
/// Return the max of two objects
template <class numtyp>
numtyp max(numtyp one,numtyp two);
/// Return the min of two objects
template <class numtyp>
numtyp min(numtyp one,numtyp two);
/// Return the -1 for negative, 0 for zero, and 1 for positive
int sign(double v);
/// Swap two objects
void swap(double a, double b);
// Finite Precision stuff
/// Returns a number representing zero for finite checks
double epsilon(double number);
/// Returns number closer to zero by the smallest interval possible
double minus_eps(double number);
/// Returns number farther from zero by the smallest interval possible
double plus_eps(double number);
/// Returns number farther from zero by smallest interval * \b m
double plus_Meps(double m,double number);
/// Returns number farther from zero by smallest interval * 10^8
double plus_2eps(double number);
/// Returns number closer to zero by smallest interval * 10^8
double minus_2eps(double number);
/// Returns false if the number is stored as NAN
bool not_nan(double number);
// Matrix stuff
/// Invert a matrix (Gauss-Jordan)
/** Generates error 303 L 9 for singular matrix
* No checking for memory limitations **/
void invert(double **matrix, unsigned size, Error &error);
/// Move a value from a fraction of one range to a fraction of another
/** am::rerange(0,1,0.3,0,100) will return 30. No checking to enforce
* that the value actually lies within the range is made. **/
double rerange(double one_start, double one_end, double value,
double two_start, double two_end);
}
#endif

View File

@ -0,0 +1,145 @@
/***************************************************************************
spherical.cpp
W. Michael Brown
-------------------
Stuff for working spherical coordinates
__________________________________________________________________________
Part of the Math Library
__________________________________________________________________________
begin : Tue Aug 29 2006
copyright : (C) 2006 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#include "spherical.h"
template class Ball<double>;
template class Ball<float>;
template ostream & operator<< <double>(ostream &out, const Ball<double> &t);
template ostream & operator<< <float>(ostream &out, const Ball<float> &t);
template istream & operator>> <double>(istream &in, Ball<double> &t);
template istream & operator>> <float>(istream &in, Ball<float> &t);
// Empty construct. Not necessarily initialized to [0 0]
template<class numtyp>
Ball<numtyp>::Ball() {
}
// Assign theta and phi to the value
template<class numtyp>
Ball<numtyp>::Ball(numtyp value) : theta(value), phi(value) {
}
// Assignment Constructor
template<class numtyp>
Ball<numtyp>::Ball(numtyp thet, numtyp ph) : theta(thet), phi(ph) {
}
// Convert from cartesian
template<class numtyp>
Ball<numtyp>::Ball(const ThreeD<numtyp> &pt) {
theta=atan2(pt.y,pt.x);
if (theta<0)
theta+=TWOPI;
phi=acos(pt.z/pt.norm());
}
template<class numtyp>
numtyp & Ball<numtyp>::operator[](unsigned i) {
if (i==THETA)
return theta;
else
return phi;
}
template<class numtyp>
ostream & operator<< (ostream &out, const Ball<numtyp> &t) {
out << t.theta << " " << t.phi;
return out;
}
template<class numtyp>
istream & operator>> (istream &in, Ball<numtyp> &t) {
in >> t.theta >> t.phi;
return in;
}
// Distance between two points (along arc)
template<class numtyp>
numtyp Ball<numtyp>::dist(const Ball &two) const {
double dot=cPt(*this).dot(cPt(two));
if (dot>1.0)
dot=1.0;
return acos(dot);
}
// Distance squared between two points
template<class numtyp>
numtyp Ball<numtyp>::dist2(const Ball &two) const {
numtyp d=dist(two);
return d*d;
}
// Add both angles
template<class numtyp>
void Ball<numtyp>::operator += (const Ball<numtyp> &two) {
theta+=two.theta;
phi+=two.phi;
}
// Add to both angles
template<class numtyp>
Ball<numtyp> Ball<numtyp>::operator + (const numtyp two) const {
return Ball(theta+two,phi+two);
}
// Multiply both angles
template<class numtyp>
Ball<numtyp> Ball<numtyp>::operator * (const numtyp two) const {
return Ball(theta*two,phi*two);
}
// Divide both angles
template<class numtyp>
void Ball<numtyp>::operator /= (const numtyp two) {
theta/=two;
phi/=two;
}
// Add both angles
template<class numtyp>
Ball<numtyp> Ball<numtyp>::operator + (const Ball<numtyp> &two) {
return Ball(theta+two.theta,phi+two.phi);
}
// Move coordinates into array
template<class numtyp>
void Ball<numtyp>::to_array(numtyp *array) {
*array=theta;
array++;
*array=phi;
}
// Set coordinates from array
template<class numtyp>
void Ball<numtyp>::from_array(numtyp *array) {
theta=*array;
array++;
phi=*array;
}
// Returns 2
template<class numtyp>
unsigned Ball<numtyp>::dimensionality() {
return 2;
}
// Returns true
template<class numtyp>
bool Ball<numtyp>::check_bounds(numtyp min,numtyp max) {
return true;
}

View File

@ -0,0 +1,113 @@
/***************************************************************************
spherical.h
W. Michael Brown
-------------------
Stuff for working spherical coordinates
__________________________________________________________________________
Part of the Math Library
__________________________________________________________________________
begin : Tue Aug 29 2006
copyright : (C) 2006 by W. Michael Brown
email : wmbrown@sandia.gov
***************************************************************************/
#ifndef SPHERICAL_H
#define SPHERICAL_H
#include "miscm.h"
#include "m_constants.h"
#include "cartesian.h"
#include <assert.h>
#include <math.h>
#include <iostream>
#include <fstream>
using namespace std;
// Other coordinates
template<class numtyp> class ThreeD;
// Friends
template<class numtyp> class Ball;
template<class numtyp>
ostream & operator<< (ostream &out, const Ball<numtyp> &t);
template<class numtyp>
istream & operator>> (istream &in, Ball<numtyp> &t);
enum { THETA, ///<0
PHI ///<1
};
/// Two dimensional spherical coordinates on a unit sphere
/** The elements can be accessed directly .theta or .phi
* or by using the operator [] ( [THETA], [PHI] )
*
* Input and output are overloaded for element I/O of the form "theta phi"
* <<, >>
**/
template<class numtyp>
class Ball {
public:
/// Empty construct. Not necessarily initialized to [0 0]
Ball();
/// Assignment Constructor
Ball(numtyp theta, numtyp phi);
/// Assign theta and phi to the value
Ball(numtyp value);
/// Convert from cartesian
Ball(const ThreeD<numtyp> &pt);
numtyp theta;
numtyp phi;
numtyp &operator[](unsigned i);
friend ostream & operator<< <>(ostream &out, const Ball &t);
friend istream & operator>> <>(istream &in, Ball &t);
/// Add both angles
void operator += (const Ball<numtyp> &two);
/// Add to both angles
Ball<numtyp> operator + (const numtyp two) const;
/// Multiply both angles
Ball<numtyp> operator * (const numtyp two) const;
/// Divide both angles
void operator /= (const numtyp two);
/// Add both angles
Ball<numtyp> operator + (const Ball<numtyp> &two);
/// Distance between two points (along arc)
/** \note The form of calculation used suffers from round off error
* when points are antipodal **/
numtyp dist(const Ball &two) const;
/// Distance squared between two points (along arc)
/** \note The form of calculation used suffers from round off error
* when points are antipodal **/
numtyp dist2(const Ball &two) const;
/// Move coordinates into array
void to_array(numtyp *array);
/// Set coordinates from array
void from_array(numtyp *array);
// -------------- Weird functions that help with coord templating
/// Returns 2
unsigned dimensionality();
// Returns true
bool check_bounds(numtyp min,numtyp max);
private:
};
///\var typedef Ball<double> BallD
/// Double unit sphere
typedef Ball<double> BallD;
///\var typedef Ball<double> BallF
/// Float unit sphere
typedef Ball<float> BallF;
#endif