Index: trunk/Nebulous-Server/Build.PL
===================================================================
--- trunk/Nebulous-Server/Build.PL	(revision 39907)
+++ trunk/Nebulous-Server/Build.PL	(revision 39926)
@@ -48,4 +48,5 @@
         bin/neb-voladd
         bin/neb-voladm
+        bin/neb-aliasadd
         bin/neb-insedit
         bin/neb-host
Index: trunk/Nebulous-Server/bin/neb-aliasadd
===================================================================
--- trunk/Nebulous-Server/bin/neb-aliasadd	(revision 39926)
+++ trunk/Nebulous-Server/bin/neb-aliasadd	(revision 39926)
@@ -0,0 +1,231 @@
+#!/usr/bin/env perl
+
+# Copyright (C) 2016 Chris Waters
+#
+# $Id: neb-aliasadd
+
+use strict;
+use warnings FATAL => qw( all );
+
+use vars qw( $VERSION );
+$VERSION = '0.02';
+
+use DBI;
+use Nebulous::Server::SQL;
+use URI::file;
+use URI;
+
+use Getopt::Long qw( GetOptions :config auto_help auto_version );
+use Pod::Usage qw( pod2usage );
+
+my ($db, $dbhost, $dbuser, $dbpass, $alias, $target, $update, $alias_id);
+
+$db     = $ENV{'NEB_DB'} unless $db;
+$dbhost = $ENV{'NEB_DBHOST'} || 'localhost';
+$dbuser = $ENV{'NEB_USER'} unless $dbuser;
+$dbpass = $ENV{'NEB_PASS'} unless $dbpass;
+
+GetOptions(
+    'db|d=s'            => \$db,
+    'host=s'            => \$dbhost,
+    'pass|p=s'          => \$dbpass,
+    'user|u=s'          => \$dbuser,
+    'alias_name=s'      => \$alias,
+    'target_name=s'     => \$target,
+    'alias_id=s'        => \$alias_id,
+    'update'            => \$update,
+) || pod2usage( 2 );
+
+pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
+pod2usage( -msg => "Required options: --db --user --pass --alias_name --target_name", -exitval => 2 )
+    unless $db && $dbuser && $dbpass && $alias && $target;
+
+my $dbh = DBI->connect(
+    "DBI:mysql:database=$db:host=$dbhost",
+    $dbuser,
+    $dbpass,
+    {
+        RaiseError => 1,
+        PrintError => 0,
+        AutoCommit => 1,
+    },
+);
+
+my $sql = Nebulous::Server::SQL->new();
+
+
+if ($update) {
+    unless ($alias && $target && $alias_id) {
+	pod2usage( -msg => "Required options for update: --db --user --pass --alias_name --target_name --alias_id", -exitval => 2 );
+    }
+    print "Updating alias...";
+    my ($vol_id, $tmp_name);
+    
+    my $vol_query = $dbh->prepare( $sql->get_volume_by_name );
+    $vol_query->execute( $target );
+    ($vol_id, $tmp_name, undef, undef) = $vol_query->fetchrow_array;
+    $vol_query->finish;
+    
+    unless ( (defined($vol_id))&& ($target eq $tmp_name)) {
+	die "ALIAS NOT CHANGED: ($target != $tmp_name) $vol_id not defined!";
+    }
+    
+    eval {
+	my $query = $dbh->prepare( $sql->update_alias );
+	# CHECK:
+#        UPDATE alias SET
+#          vol_id = ?,
+#          name   = ?
+#        WHERE alias_id = ?
+#        AND   alias    = ?
+	$query->execute( $vol_id, $target, $alias_id, $alias);
+    };
+    if ($@) {
+	die "database error: $@";
+    }
+    
+}
+else {
+    
+    print "Adding alias...";
+    my ($vol_id, $tmp_name);
+    
+    my $vol_query = $dbh->prepare( $sql->get_volume_by_name );
+    $vol_query->execute( $target );
+    ($vol_id, $tmp_name, undef, undef) = $vol_query->fetchrow_array;
+    $vol_query->finish;
+    
+    unless ( (defined($vol_id))&& ($target eq $tmp_name)) {
+	die "ALIAS NOT ADDED: ($target != $tmp_name) $vol_id not defined!";
+    }
+    
+    eval {
+	my $query = $dbh->prepare( $sql->new_alias );
+	$query->execute( $alias, $target, $vol_id);
+    };
+    if ($@) {
+	die "database error: $@";
+    }
+}
+
+print "OK $alias => $target\n";
+
+__END__
+
+=pod
+
+=head1 NAME
+
+neb-aliasadd - Add a volume alias to the aliasvol table
+
+=head1 SYNOPSIS
+
+    neb-cabadd --target_name <target_volume> --alias_name <alias_volume>
+    [--db <database>] [--user <username>] [--pass <password>] [--host <hostname]
+
+=head1 DESCRIPTION
+
+This program creates a volume alias, allowing the database to correctly substitute
+the target volume when the alias volume is requested.  This can be used to ensure
+that Nebulous file reads choose the nearest local copy.
+
+
+=head1 OPTIONS
+
+=over 4
+
+=item * --target_name <target_volume>
+
+Symbolic name of volume the alias should point to.
+
+=item * --alias_name <alias_volume>
+
+Symbolic name of volume the alias should point from.
+
+=item * --db|-d <database>
+
+Name of database (C<namespace>) to create tables in.
+
+Optional if the appropriate environment variable is set.
+
+=item * --user|-u <username>
+
+Username to authenticate with.
+
+Optional if the appropriate environment variable is set.
+
+=item * --pass|-p <password>
+
+Password to authenticate with.
+
+Optional if the appropriate environment variable is set.
+
+=item * --host <database host>
+
+Name of host on which the database resides.
+
+Optional.  Defaults to C<localhost>.
+
+=head1 ENVIRONMENT
+
+These environment variables may be used in place of the specified command line
+options.  All command line option will override the corresponding environment
+value.
+
+=over 4
+
+=item * C<NEB_DB>
+
+Equivalent to --db|-d
+
+=item * C<NEB_HOST>
+
+Equivalent to --host
+
+=item * C<NEB_USER>
+
+Equivalent to --user|-u
+
+=item * C<NEB_PASS>
+
+Equivalent to --pass|-p 
+
+=back
+
+=head1 CREDITS
+
+Josh Hoblitt and Chris Waters 
+
+=head1 SUPPORT
+
+Please contact the author directly via e-mail.
+
+=head1 AUTHOR
+
+IPP
+
+=head1 COPYRIGHT
+
+Copyright (C) 2005-2008  Joshua Hoblitt.  All rights reserved.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA  02111-1307, USA.
+
+The full text of the license can be found in the L<perlgpl> Pod as supplied
+with Perl 5.8.1 and later.
+
+=head1 SEE ALSO
+
+L<Nebulous::Server>, L<neb-initdb>, L<neb-df>, L<nebdiskd>
+
+=cut
Index: trunk/Nebulous-Server/bin/neb-cabadd
===================================================================
--- trunk/Nebulous-Server/bin/neb-cabadd	(revision 39907)
+++ trunk/Nebulous-Server/bin/neb-cabadd	(revision 39926)
@@ -19,5 +19,5 @@
 use Pod::Usage qw( pod2usage );
 
-my ($db, $dbhost, $dbuser, $dbpass, $cname, $location);
+my ($db, $dbhost, $dbuser, $dbpass, $cname, $location, $site_id, $update, $cab_id);
 
 $db     = $ENV{'NEB_DB'} unless $db;
@@ -33,9 +33,12 @@
     'cname|n=s'         => \$cname,
     'location|l=s'      => \$location,
+    'site_id|s=s'       => \$site_id,
+    'cab_id=s'          => \$cab_id,
+    'update|u'          => \$update,
 ) || pod2usage( 2 );
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
-pod2usage( -msg => "Required options: --db --user --pass --cname", -exitval => 2 )
-    unless $db && $dbuser && $dbpass && $cname;
+pod2usage( -msg => "Required options: --db --user --pass --cname --site_id", -exitval => 2 )
+    unless $db && $dbuser && $dbpass && $cname && $site_id;
 
 my $dbh = DBI->connect(
@@ -52,11 +55,30 @@
 my $sql = Nebulous::Server::SQL->new();
 
-print "Adding cabinet...";
-
-my $query = $dbh->prepare( $sql->new_cabinet );
-$query->execute( $cname, $location);
-
-print " OK\n";
-
+if (defined($update)) {
+    unless ($cname && $location && $site_id && $cab_id) {
+	pod2usage( -msg => "Required options for update: --db --user --pass --cname --site_id --location --cab_id", -exitval => 2 );
+    }
+    print "Updating cabinet...";
+    my $query = $dbh->prepare( $sql->update_cabinet );
+    # Check query: 
+#        UPDATE cabinet SET
+#           location = ?,
+#           name     = ?,
+#           site_id  = ? 
+#        WHERE cab_id = ?
+
+    $query->execute( $location, $cname, $site_id, $cab_id );
+    
+    print "OK\n";
+
+}
+else {
+    print "Adding cabinet...";
+    
+    my $query = $dbh->prepare( $sql->new_cabinet );
+    $query->execute( $cname, $location, $site_id);
+    
+    print " OK\n";
+}
 __END__
 
@@ -69,5 +91,5 @@
 =head1 SYNOPSIS
 
-    neb-cabadd --cname <cabinet name> --location <cabinet location>
+    neb-cabadd --cname <cabinet name> --location <cabinet location> --site_id <site_id>
     [--db <database>] [--user <username>] [--pass <password>] [--host <hostname]
 
@@ -89,4 +111,8 @@
 
 Description of the location of the cabinet.
+
+=item * --site_id <site_id>
+
+Numerical value of the location's site.  Default = 0.
 
 =item * --db|-d <database>
Index: trunk/Nebulous-Server/lib/Nebulous/Server.pm
===================================================================
--- trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 39907)
+++ trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 39926)
@@ -1753,5 +1753,5 @@
 }
 
-sub find_instances
+sub find_instances_old
 {
     my $self = shift;
@@ -1820,4 +1820,157 @@
             # ext_id, name, available
             my $rows = $query->execute($key->path, $vol_name, 1);
+            unless ($rows > 0) {
+                $query->finish;
+                die("no instances on storage volume or volume is not avaiable for key: $key volume: $vol_name");
+            }
+        } else {
+            $query = $db->prepare_cached( $sql->get_object_instances );
+	    my $rows;
+            # ext_id, available
+	    if (defined($find_invalid)) {
+		$rows = $query->execute($key->path, 0);
+	    }
+	    else {
+		$rows = $query->execute($key->path, 1);
+	    }
+            unless ($rows > 0) {
+                $query->finish;
+                die("no instances available for key: $key");
+            }
+        }
+
+        while (my $row = $query->fetchrow_hashref) {
+            my $instance = $row->{ 'uri' };
+            push @locations, $instance if $instance;
+        }
+    };
+    if ($@) {
+        $db->rollback;
+        # handle soft volumes
+        if (defined $vol_name and not defined $key->hard_volume) {
+            $log->debug("retrying with 'any' volume");
+            return $self->find_instances($key->path, 'any');
+        }
+        $log->logdie("database error: $@");
+    }
+
+    # XXX remove this?
+    $log->logdie("no instances found") unless (scalar @locations);
+
+    $log->debug("found: @locations");
+
+    $log->debug("leaving");
+
+    return \@locations;
+}
+
+#sub find_instances_by_proximity
+sub find_instances
+{
+    my $self = shift;
+
+    my $log = $self->log;
+    $log->debug("entered - @_");
+
+    my ($key, $vol_name, $find_invalid) = validate_pos(@_,
+        {
+            type        => SCALAR,
+            callbacks   => {
+                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
+            },
+        },
+        {
+            type        => SCALAR|UNDEF,
+#            callbacks   => {
+#                # check that the volume name requested is valid
+#                'is valid volume name' => sub {
+#                    return 1 if not defined $_[0];
+#                    $self->_is_valid_volume_name($_[0])
+#                },
+#            },
+            optional    => 1,
+        },
+	{
+            # find_invalid
+	    type        => SCALAR|UNDEF,
+            optional    => 1,
+        }, 
+    );
+
+    my $sql = $self->sql;
+
+#    unless ($key) {
+#        $log->warn("key was undefined after validate_pos(), trying again...");
+#        return $self->find_instances(@_);
+#    }
+
+    # vol_name overrides the key implied volume
+    my ($h_vol_id, $h_cab_id, $h_site_id);
+    eval {
+        $key = parse_neb_key($key, $vol_name);
+    };
+    $log->logdie("$@") if $@;
+    $vol_name = $key->volume;
+
+    my $db  = $self->db($key);
+
+    # Convert possible alias to real volume.
+    if (defined $vol_name) {
+	my ($tmp_vol_id, $tmp_name, $tmp_host, $tmp_path);
+	eval {
+	    my $query = $db->prepare_cached( $sql->get_volume_by_alias );
+	    $query->execute( $vol_name );
+	    ($tmp_vol_id, $tmp_name, $tmp_host, $tmp_path) = $query->fetchrow_array;
+	    $query->finish;
+	};
+	$log->logdie("$@") if $@;
+#	$log->warn("CZW: find_instance: deref alias: $vol_name => $tmp_vol_id $tmp_name $tmp_host $tmp_path (key vol: $key" . $key->volume . ")");
+	if (defined $tmp_vol_id and defined $tmp_name and defined $tmp_host and defined $tmp_path) {
+	    if ($tmp_name ne $vol_name) {
+		$vol_name = $tmp_name;
+#		$key->volume = $vol_name;
+	    }
+	}
+
+
+    }
+
+    # the key's volume can't be validiated on input for this method so we have
+    # to check it after parsing the key
+    if (defined $vol_name
+        and not $self->_is_valid_volume_name($key, $vol_name)) {
+        if ($key->hard_volume) {
+            $log->logdie("$vol_name is not a valid volume name");
+        } else {
+            $log->warn( "$vol_name is not a known volume name" );
+            $vol_name = undef;
+        }
+    }
+
+    # Get the host volume information encoded in the vol_name.
+    # I am unhappy that we have three different if(defined($vol_name)) entries, but I don't see a better way.
+#    my ($h_vol_id, $h_cab_id, $h_site_id);
+    if (defined $vol_name) {
+	eval {
+	    my $query = $db->prepare_cached( $sql->get_site_info_by_name );
+	    $query->execute( $vol_name );
+	    ($h_vol_id, $h_cab_id, $h_site_id) = $query->fetchrow_array;
+	    $query->finish;
+	};
+	$log->logdie("$@") if $@;
+
+	unless(defined $h_vol_id and defined $h_cab_id and defined $h_site_id) {
+	    $vol_name = undef;
+	}
+    }
+
+    my @locations;
+    eval {
+        my $query;
+        if ($vol_name && $h_vol_id && $h_cab_id && $h_site_id) {
+            $query = $db->prepare_cached( $sql->get_object_instances_by_proximity );
+            # ext_id, name, available
+	    # host_vol_id host_cab_id host_site_id ext_id available
+            my $rows = $query->execute($h_vol_id, $h_cab_id, $h_site_id, $key->path, 1);
             unless ($rows > 0) {
                 $query->finish;
@@ -2341,5 +2494,5 @@
     my $db  = $self->db($key);
 
-    my ($vol_id, $vol_host, $vol_path, $xattr, $forbidden_cabinet);
+    my ($vol_id, $vol_host, $vol_path, $xattr, $forbidden_cabinet, $forbidden_site);
     eval {
         my $rows;
@@ -2352,7 +2505,10 @@
 	}
 	if ($rows == 1) {
-	    ($forbidden_cabinet) = $query->fetchrow_array;
+	    ($forbidden_cabinet, $forbidden_site) = $query->fetchrow_array;
 	    unless (defined($forbidden_cabinet)) {
 		$forbidden_cabinet = 0;
+	    }
+	    unless (defined($forbidden_site)) {
+		$forbidden_site = 0;
 	    }
 	    $query->finish;
@@ -2360,4 +2516,5 @@
 	else {
 	    $forbidden_cabinet = 0;
+	    $forbidden_site    = 0;
 	    $query->finish;
 	}
@@ -2366,9 +2523,15 @@
         $query = $db->prepare_cached( $sql->get_replication_volume_for_ext_id );
         # ext_id, %free, avaiable, allocate
-        $rows = $query->execute($key->path, $max_used_space, 1, 1, $forbidden_cabinet, $topfew_count);
+        $rows = $query->execute($key->path, $max_used_space, 1, 1, $forbidden_cabinet, $forbidden_site, $topfew_count);
         # XXX destinguish between non-existant and unaviable
         unless ($rows > 0) {
             $query->finish;
-            die("can't find a suitable storage volume to replicate $key to");
+	    # CZW: 2016-08-23 This wasn't right.  If we don't get an entry, we may have been too strict.
+	    #      I'm not fully convinced this is complete, as we may want to back out the cabinet criterion as well.
+	    #      In any case, I don't think we're generally in the situation where replication can't find a host.
+	    $rows = $query->execute($key->path, $max_used_space, 1, 1, $forbidden_cabinet, 0, $topfew_count);
+	    unless ($rows > 0) {
+		die("can't find a suitable storage volume to replicate $key to");
+	    }
         }
         # when matching by name we shouldn't ever match more than once
@@ -2490,7 +2653,9 @@
     $log->logdie("database error: $@") if $@;
 
+#    $log->warn("CZW: $vol_id $vol_path for >>$vol_name<<");
     if (defined $vol_id and defined $vol_path) {
         $log->debug( "found volume name $vol_name" );
         $log->debug( "leaving" );
+#	$log->warn("CZW: $vol_id $vol_path for >>$vol_name<<");
         return 1;
     } 
Index: trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm
===================================================================
--- trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 39907)
+++ trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 39926)
@@ -250,4 +250,25 @@
             AND mountedvol.available = ?
     },
+    get_object_instances_by_proximity  => qq{
+        SELECT
+            storage_object.so_id,
+            uri,
+            mountedvol.available,
+            vol_id,
+            cab_id,
+            (ABS(vol_id - ?) + 20 * ABS(cab_id - ?) + 100 * ABS(site_id - ?)) AS vol_idx
+        FROM storage_object
+        JOIN instance
+            USING (so_id)
+        JOIN mountedvol
+            USING(vol_id)
+        JOIN volume
+            USING(vol_id)
+        JOIN cabinet
+            USING(cab_id)
+        WHERE ext_id = ?
+          AND mountedvol.available = ?
+        ORDER BY vol_idx ASC
+    },
     get_object_instances_by_vol_name => qq{
         SELECT
@@ -301,7 +322,8 @@
     get_cabinets_for_ext_id            => qq{
         SELECT DISTINCT 
-            cab_id 
+            volume.cab_id, site_id
         FROM instance 
-        JOIN volume ON instance.vol_id = volume.vol_id 
+        JOIN volume ON (instance.vol_id = volume.vol_id)
+        JOIN cabinet ON (volume.cab_id  = cabinet.cab_id)
         JOIN storage_object USING(so_id) 
         WHERE ext_id = ?
@@ -317,4 +339,5 @@
         FROM mountedvol AS m
         JOIN volume AS v USING(vol_id)
+        JOIN cabinet AS c USING(cab_id)
         LEFT JOIN (
                    SELECT
@@ -336,7 +359,9 @@
              AND m.available = ?
              AND m.allocate = ?
-             AND m.xattr = 0
+--             AND m.xattr = 0
              AND ( (v.cab_id IS NULL) ||
                    (v.cab_id != ?) )
+             AND ( (c.site_id IS NULL) ||
+                   (c.site_id != ?) )
          ORDER BY free DESC
          LIMIT ?) as topfew
@@ -366,10 +391,28 @@
     },
     new_cabinet         => qq{
-        INSERT INTO cabinet (name, location, cab_id)
-        VALUES (?, ?, NULL)
+        INSERT INTO cabinet (name, location, site_id, cab_id)
+        VALUES (?, ?, ?, NULL)
+    },
+    update_cabinet      => qq{
+        UPDATE cabinet SET 
+           location = ?,
+           name     = ?,
+           site_id  = ?
+        WHERE cab_id = ?
     },
     new_volume          => qq{
         INSERT INTO volume (name, host, path, allocate, available, xattr, mountpoint, cab_id, note)
         VALUES (?, ?, ?, TRUE, TRUE, FALSE, ?, NULL, ?)
+    },
+    new_alias          => qq{
+        INSERT INTO aliasvol (alias_id, alias, name, vol_id)
+        VALUES (NULL, ?, ?, ?)
+    },
+    update_alias       => qq{
+        UPDATE alias SET
+          vol_id = ?,
+          name   = ?
+        WHERE alias_id = ?
+        AND   alias    = ?
     },
     get_volume_by_name => qq{
@@ -377,4 +420,16 @@
         FROM volume
         WHERE name = ?
+    },
+    get_volume_by_alias => qq{
+        SELECT vol_id, name, host, path
+        FROM aliasvol
+        JOIN volume USING(vol_id,name)
+        WHERE alias = ?
+    },
+    get_site_info_by_name => qq{
+        SELECT vol_id, cab_id, site_id
+        FROM volume
+        JOIN cabinet USING(cab_id)
+        WHERE volume.name = ?
     },
     get_volumes => qq{
@@ -676,7 +731,9 @@
     cab_id INT NOT NULL AUTO_INCREMENT,
     name VARCHAR(255) NOT NULL,
+    site_id INT NOT NULL DEFAULT 0,
     location VARCHAR(255),
     PRIMARY KEY(cab_id),
     UNIQUE KEY(name),
+    KEY (site_id),
     KEY (location)
 ) ENGINE=innodb DEFAULT CHARSET=latin1;
@@ -735,4 +792,17 @@
 ###
 
+CREATE TABLE aliasvol (
+    alias_id INT NOT NULL AUTO_INCREMENT,
+    alias VARCHAR(255) NOT NULL,
+    name  VARCHAR(255) NOT NULL,
+    vol_id INT NOT NULL,
+    PRIMARY KEY(alias_id),
+    KEY(alias),
+    KEY(name),
+    FOREIGN KEY(vol_id) REFERENCES volume(vol_id)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+
+###
+
 CREATE TABLE instance (
     ins_id BIGINT NOT NULL AUTO_INCREMENT,
Index: trunk/Nebulous/bin/neb-repair
===================================================================
--- trunk/Nebulous/bin/neb-repair	(revision 39907)
+++ trunk/Nebulous/bin/neb-repair	(revision 39926)
@@ -167,5 +167,5 @@
     my $name = shift;                # Filename for which to get the scheme
     my ($scheme) = $name =~ /^(path|neb|file):/; # The scheme, e.g., file://, path://
-    if undef $scheme { $scheme = "none"; }
+#    if undef $scheme { $scheme = "none"; }
     # $scheme may be undef if the input doesn't contain one of the above recognised schemes
     unless (defined($scheme)) { $scheme = "none"; }
Index: trunk/Nebulous/lib/Nebulous/Client.pm
===================================================================
--- trunk/Nebulous/lib/Nebulous/Client.pm	(revision 39907)
+++ trunk/Nebulous/lib/Nebulous/Client.pm	(revision 39926)
@@ -18,4 +18,5 @@
 use Params::Validate qw( validate validate_pos SCALAR UNDEF BOOLEAN );
 #use SOAP::Lite +trace => [qw( debug )];
+use Sys::Hostname;
 use SOAP::Lite;
 use Time::HiRes qw( sleep );
@@ -858,4 +859,9 @@
 
     $log->debug( "entered - @_" );
+    
+    unless(defined($params[0])) {
+	$params[0] = hostname() . ".0";
+#	print STDERR "Setting host to $params[0]\n";
+    }
 
     my $response = $self->{ 'server' }->find_instances( $key, @params );
@@ -980,4 +986,6 @@
     $log->debug( "entered - @_" );
 
+    my $find_volume = hostname() . ".0";
+    $params[0] = $find_volume;
     my $locations = $self->find_instances( $key, @params );
     unless (defined $locations) {
Index: trunk/Nebulous/nebclient/src/nebclient.c
===================================================================
--- trunk/Nebulous/nebclient/src/nebclient.c	(revision 39907)
+++ trunk/Nebulous/nebclient/src/nebclient.c	(revision 39926)
@@ -529,6 +529,22 @@
         return NULL;
     }
+
+    // Construct a dummy volume name to allow nebulous to find the
+    // closest instance available.
+    char hostname[256];
+    char volname[260];
+
+    int v;
+
+    v = gethostname(hostname,256);
+    //    fprintf(stderr, "%s %d\n", hostname, v);
+/*     printf("%s %d\n",hostname,v); */
+    if (v) {
+      nebSetErr(server, "failed to construct hostname");
+      return NULL;
+    }
+    snprintf(volname,260, "%s.0", hostname);
     
-    nebObjectInstances *locations = nebFindInstances(server, key, NULL);
+    nebObjectInstances *locations = nebFindInstances(server, key, volname);
     if (!locations) {
         if (!strstr(nebErr(server), "no instances on storage volume")) {
Index: trunk/Ohana/Makefile.in
===================================================================
--- trunk/Ohana/Makefile.in	(revision 39907)
+++ trunk/Ohana/Makefile.in	(revision 39926)
@@ -138,6 +138,8 @@
 
 rebuild:
+	@date 
 	$(MAKE) clean
 	$(MAKE) install
+	@date 
 
 # standard rules: targets are foo, foo.clean, foo.install, foo.dist
Index: trunk/Ohana/src/addstar/Makefile
===================================================================
--- trunk/Ohana/src/addstar/Makefile	(revision 39907)
+++ trunk/Ohana/src/addstar/Makefile	(revision 39926)
@@ -25,4 +25,5 @@
 load2mass    : $(BIN)/load2mass.$(ARCH)
 loadgalphot  : $(BIN)/loadgalphot.$(ARCH)
+loadgaia     : $(BIN)/loadgaia.$(ARCH)
 loadstarpar  : $(BIN)/loadstarpar.$(ARCH)
 loadstarpar_client : $(BIN)/loadstarpar_client.$(ARCH)
@@ -42,5 +43,5 @@
 # programs in 'SERVER' use the client-server concept and are out of date
 
-INSTALL = addstar addstar_client sedstar loadgalphot loadstarpar loadstarpar_client setobjflags setobjflags_client loadICRF loadICRF_client skycells mkcmf dumpskycells findskycell load2mass loadwise loadtycho loadbsc loadsupercos 
+INSTALL = addstar addstar_client sedstar loadgalphot loadgaia loadstarpar loadstarpar_client setobjflags setobjflags_client loadICRF loadICRF_client skycells mkcmf dumpskycells findskycell load2mass loadwise loadtycho loadbsc loadsupercos 
 SERVER  = addstarc addstard addstart
 
@@ -267,8 +268,20 @@
 $(SRC)/psps_ids.$(ARCH).o
 
-# $(SRC)/SkyRegionUtils.$(ARCH).o 
-# $(SRC)/loadstarpar_io.$(ARCH).o 
-# $(SRC)/loadgalphot_remote_hosts.$(ARCH).o 
-# $(SRC)/loadgalphot_save_remote.$(ARCH).o 
+LOAD-GAIA = \
+$(SRC)/loadgaia.$(ARCH).o \
+$(SRC)/ConfigInit.$(ARCH).o \
+$(SRC)/SetSignals.$(ARCH).o \
+$(SRC)/Shutdown.$(ARCH).o \
+$(SRC)/args_loadgaia.$(ARCH).o \
+$(SRC)/find_matches_gaia.$(ARCH).o \
+$(SRC)/loadgaia_catalog.$(ARCH).o \
+$(SRC)/loadgaia_make_subset.$(ARCH).o \
+$(SRC)/loadgaia_readstars.$(ARCH).o \
+$(SRC)/loadgaia_table.$(ARCH).o \
+$(SRC)/resort_catalog.$(ARCH).o \
+$(SRC)/build_links.$(ARCH).o \
+$(SRC)/strhash.$(ARCH).o \
+$(SRC)/sortIDs.$(ARCH).o \
+$(SRC)/psps_ids.$(ARCH).o
 
 LOAD-STARPAR = \
@@ -493,4 +506,5 @@
 $(LOAD-2MASS)  	       : $(INC)/addstar.h $(INC)/2mass.h
 $(LOAD-GALPHOT)	       : $(INC)/addstar.h $(INC)/loadgalphot.h
+$(LOAD-GAIA)	       : $(INC)/addstar.h $(INC)/gaia.h
 $(LOAD-STARPAR)	       : $(INC)/addstar.h $(INC)/loadstarpar.h
 $(LOAD-STARPAR-CLIENT) : $(INC)/addstar.h $(INC)/loadstarpar.h
@@ -514,4 +528,5 @@
 $(BIN)/loadbsc.$(ARCH)        : $(LOAD-BSC)
 $(BIN)/loadgalphot.$(ARCH)    : $(LOAD-GALPHOT)
+$(BIN)/loadgaia.$(ARCH)       : $(LOAD-GAIA)
 $(BIN)/loadstarpar.$(ARCH)    : $(LOAD-STARPAR)
 $(BIN)/loadstarpar_client.$(ARCH) : $(LOAD-STARPAR-CLIENT)
Index: trunk/Ohana/src/addstar/include/gaia.h
===================================================================
--- trunk/Ohana/src/addstar/include/gaia.h	(revision 39926)
+++ trunk/Ohana/src/addstar/include/gaia.h	(revision 39926)
@@ -0,0 +1,44 @@
+
+typedef struct {
+  double R, D;
+  Measure measure;
+  int flag; // in a subset?
+  int found; // assigned to an object?
+} Gaia_Stars;
+
+int   HOST_ID;
+char *HOSTDIR;
+char *CPT_FILE;
+char *INPUT;
+
+AddstarClientOptions args_loadgaia (int *argc, char **argv, AddstarClientOptions options);
+AddstarClientOptions args_loadgaia_client (int *argc, char **argv, AddstarClientOptions options);
+
+int loadgaia_table (int Nstart, int Nend, SkyList *skylistInput, HostTable *hosts, char **filename, AddstarClientOptions *options);
+
+Gaia_Stars *loadgaia_make_subset (Gaia_Stars *stars, int Nstars, int start, SkyRegion *region, int *nsubset);
+
+int loadgaia_save_remote (Gaia_Stars *stars, int Nstars, HostTable *hosts, SkyRegion *region, char *fullname, AddstarClientOptions *options);
+
+int save_remote_host (HostInfo *host);
+
+int init_remote_hosts (void);
+void free_remote_hosts (void);
+int find_empty_slot (void);
+int harvest_all (void);
+int harvest_host (void);
+
+int loadgaia_catalog (Gaia_Stars *stars, int Nstars, SkyRegion *region, char *filename, AddstarClientOptions *options);
+
+int galactic_to_celestial (double *R, double *D, double l, double b);
+
+int find_matches_gaia (SkyRegion *region, Gaia_Stars *stars, int Nstars, Catalog *catalog, AddstarClientOptions *options);
+
+int loadgaia_save_stars (char *filename, Gaia_Stars *stars, int Nstars);
+Gaia_Stars *loadgaia_load_stars (char *filename, int *nstars);
+
+Gaia_Stars *loadgaia_readstars (char *filename, Gaia_Stars *stars, int *nstars, AddstarClientOptions *options);
+
+int loadgaia_sortStars (Gaia_Stars *stars, int Nstars);
+
+int loadgaia_tmpdir (void);
Index: trunk/Ohana/src/addstar/src/args_loadgaia.c
===================================================================
--- trunk/Ohana/src/addstar/src/args_loadgaia.c	(revision 39926)
+++ trunk/Ohana/src/addstar/src/args_loadgaia.c	(revision 39926)
@@ -0,0 +1,144 @@
+# include "addstar.h"
+# include "gaia.h"
+
+static void help (void);
+
+AddstarClientOptions args_loadgaia (int *argc, char **argv, AddstarClientOptions options) {
+  
+  int N;
+
+  /* check for help request */
+  if (get_argument (*argc, argv, "-help") ||
+      get_argument (*argc, argv, "-h")) {
+    help ();
+  }
+
+  /* basic mode: image, list, refcat */
+  options.mode = ADDSTAR_MODE_REFCAT;
+
+  /* we do not allow a subset to be extracted -- all or nothing, babe */
+  UserPatch.Rmin = 0;
+  UserPatch.Rmax= 360;
+  UserPatch.Dmin = -90;
+  UserPatch.Dmax = +90;
+
+  // XXX for the moment, make this selection manual.  it needs to be automatic 
+  // based on the state of the SkyTable
+  HOST_ID = 0;
+  PARALLEL = FALSE;
+  if ((N = get_argument (*argc, argv, "-parallel"))) {
+    PARALLEL = TRUE;
+    remove_argument (N, argc, argv);
+  }
+  // this is a test mode : rather than launching the remote jobs and waiting for completion,
+  // relphot will simply list the remote command and wait for the user to signal completion
+  PARALLEL_MANUAL = FALSE;
+  if ((N = get_argument (*argc, argv, "-parallel-manual"))) {
+    PARALLEL = TRUE; // -parallel-manual implies -parallel
+    PARALLEL_MANUAL = TRUE;
+    remove_argument (N, argc, argv);
+  }
+  // this is a test mode : rather than launching the relphot_client jobs remotely, they are 
+  // run in serial via 'system'
+  PARALLEL_SERIAL = FALSE;
+  if ((N = get_argument (*argc, argv, "-parallel-serial"))) {
+    if (PARALLEL_MANUAL) {
+      fprintf (stderr, "ERROR: cannot mix -parallel-manual and -parallel-serial\n");
+      exit (1);
+    }
+    PARALLEL = TRUE; // -parallel-serial implies -parallel
+    PARALLEL_SERIAL = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  /* only add to existing regions */
+  options.existing_regions = FALSE;
+  if ((N = get_argument (*argc, argv, "-existing-regions"))) {
+    options.existing_regions = TRUE;
+    remove_argument (N, argc, argv);
+  }
+  /* only add to existing objects */
+  options.only_match = FALSE;
+  if ((N = get_argument (*argc, argv, "-only-match"))) {
+    options.only_match = TRUE;
+    remove_argument (N, argc, argv);
+  }
+  /* replace measurement, don't duplicate (ref/cat only) */
+  options.replace = FALSE;
+  if ((N = get_argument (*argc, argv, "-replace"))) {
+    options.replace = TRUE;
+    remove_argument (N, argc, argv);
+  }
+  /* override any header PHOTCODE values */
+  options.photcode = 0;
+  if ((N = get_argument (*argc, argv, "-p"))) {
+    remove_argument (N, argc, argv);
+    options.photcode = GetPhotcodeCodebyName (argv[N]);
+    remove_argument (N, argc, argv);
+  }
+  if ((N = get_argument (*argc, argv, "-photcode"))) {
+    remove_argument (N, argc, argv);
+    options.photcode = GetPhotcodeCodebyName (argv[N]);
+    remove_argument (N, argc, argv);
+  }
+  if (!options.photcode) {
+    fprintf (stderr, "ERROR: please supply a photcode name with [-p name]\n");
+    exit (2);
+  }
+
+  /* provide a time for dataset */
+  options.timeref = 0; 
+  if ((N = get_argument (*argc, argv, "-time"))) {
+    time_t tmp;
+    remove_argument (N, argc, argv);
+    if (!ohana_str_to_time (argv[N], &tmp)) { 
+      fprintf (stderr, "syntax error in time\n");
+      exit (1);
+    }
+    options.timeref = tmp;
+    remove_argument (N, argc, argv);
+  }
+
+  /* extra error messages */
+  VERBOSE = FALSE;
+  if ((N = get_argument (*argc, argv, "-v"))) {
+    VERBOSE = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  /* other addstar options which cannot be used in loadgaia */
+  // options.timeref = 0; 
+  options.mosaic = FALSE;
+  options.skip_missed = FALSE;
+  options.closest = FALSE;
+  options.nosort = FALSE;
+  options.update = FALSE;
+  options.only_images = FALSE;
+  options.calibrate = FALSE;
+  options.quality_airmass = FALSE;
+  ACCEPT_ASTROM = FALSE;
+  FORCE_READ = FALSE;
+  TEXTMODE = FALSE;
+  SUBPIX = FALSE;
+  DUMP = NULL;
+
+  if (*argc < 2) {
+    fprintf (stderr, "USAGE: loadgaia [options] (fitsfile) [..more files]\n");
+    exit (2);
+  }
+  return (options);
+}
+
+static void help () {
+
+  fprintf (stderr, "USAGE: loadgaia [options] (file) [..more files]\n");
+  fprintf (stderr, "  add data from stellar parameter file to DVO\n\n");
+
+  fprintf (stderr, "  optional flags:\n");
+  fprintf (stderr, "  -only-match           	  : only add measurements to existing objects\n");
+  fprintf (stderr, "  -replace              	  : replace time/photcode measurements (no duplication)\n");
+  fprintf (stderr, "  -v                    	  : verbose mode\n");
+  fprintf (stderr, "  -help                 	  : this list\n");
+  fprintf (stderr, "  -h                    	  : this list\n\n");
+  exit (2);
+}
Index: trunk/Ohana/src/addstar/src/find_matches_gaia.c
===================================================================
--- trunk/Ohana/src/addstar/src/find_matches_gaia.c	(revision 39926)
+++ trunk/Ohana/src/addstar/src/find_matches_gaia.c	(revision 39926)
@@ -0,0 +1,318 @@
+# include "addstar.h"
+# include "gaia.h"
+
+int find_matches_gaia (SkyRegion *region, Gaia_Stars *stars, int NstarsIn, Catalog *tgtcat, AddstarClientOptions *options) {
+
+  int Nsecfilt = GetPhotcodeNsecfilt ();
+  int Nsec     = GetPhotcodeNsec (options->photcode);
+
+  /** allocate local arrays (stars) **/
+  ALLOCATE_PTR (X1, double, NstarsIn);
+  ALLOCATE_PTR (Y1, double, NstarsIn);
+  ALLOCATE_PTR (N1, off_t,  NstarsIn);
+
+  /** allocate local arrays (tgtcat) **/
+  off_t NAVE = tgtcat[0].Naverage;
+  off_t Nave = tgtcat[0].Naverage;
+  ALLOCATE_PTR (X2, double, NAVE);
+  ALLOCATE_PTR (Y2, double, NAVE);
+  ALLOCATE_PTR (N2, off_t,  NAVE);
+
+  /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
+
+  /* internal counters */
+  off_t Nmatch = 0;
+  off_t NMEAS = tgtcat[0].Nmeasure;
+  off_t Nmeas = tgtcat[0].Nmeasure;
+
+  off_t *next_meas = NULL;
+
+  // current max obj ID for this tgtcat
+  unsigned int objID = tgtcat[0].objID;
+  unsigned int catID = tgtcat[0].catID;
+
+  /* project onto rectilinear grid with 1 arcsec pixels. the choice of ARC projection has
+   * the advantage that every point in R,D has a mapping to a unique X,Y.  However, note
+   * that not all possible X,Y points map back to R,D and the local plate scale changes
+   * substantially far from the projection pole. We use the center of the region (tgtcat)
+   * for crval1,2.
+   */
+
+  Coords tcoords;
+  InitCoords (&tcoords, "DEC--ARC");
+  tcoords.crval1 = 0.5*(region[0].Rmin + region[0].Rmax);
+  if ((region[0].Dmax < 90) && (region[0].Dmin > -90)) {
+    tcoords.crval2 = 0.5*(region[0].Dmin + region[0].Dmax);
+  } else {
+    tcoords.crval2 = (region[0].Dmax >= 90) ? 90.0 : -90.0;
+  }
+  tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
+
+  /* build spatial index (RA sort) referencing input array sequence */
+  off_t Nstars = 0;
+  for (off_t i = 0; i < NstarsIn; i++) {
+    int status = RD_to_XY (&X1[Nstars], &Y1[Nstars], stars[i].R, stars[i].D, &tcoords);
+    if (!status) continue;
+    N1[Nstars] = i;
+    Nstars ++;
+  }
+  if (Nstars < 1) {
+    if (VERBOSE) fprintf (stderr, "skipping %s, no overlapping stars\n", tgtcat[0].filename);
+    free (X1);
+    free (Y1);
+    free (N1);
+    free (X2);
+    free (Y2);
+    free (N2);
+    return 0;
+  }
+  if (Nstars > 1) sort_coords_index (X1, Y1, N1, Nstars);
+
+  /* build spatial index (RA sort) */
+  for (off_t i = 0; i < Nave; i++) {
+    RD_to_XY (&X2[i], &Y2[i], tgtcat[0].average[i].R, tgtcat[0].average[i].D, &tcoords);
+    N2[i] = i;
+  }
+  if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
+
+  /* set up pointers for linked list of measure */
+  if (tgtcat[0].sorted && (tgtcat[0].Nmeasure == tgtcat[0].Nmeasure_disk)) {
+    // this version is only valid if we have done a full tgtcat load, and if the tgtcat
+    // is sorted while processed
+    next_meas = init_measure_links (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas);
+  } else {
+    next_meas = build_measure_links (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas);
+  }    
+
+  /* choose a radius for matches */
+  double RADIUS = (options->radius == 0) ? 2.0 : options->radius; /* provided by config */
+  double RADIUS2 = RADIUS*RADIUS;
+
+  /****************** find matched stars ********************/
+
+  for (off_t i = 0, j = 0; (i < Nstars) && (j < Nave); ) {
+    if (!finite(X1[i]) || !finite(Y1[i])) { 
+      i++; 
+      continue;
+    }
+    if (!finite(X2[j]) || !finite(Y2[j])) { 
+      j++; 
+      continue;
+    }
+    
+    /* negative dX: j is too large */
+    double dX = X1[i] - X2[j];
+    if (dX <= -1.02*RADIUS) {
+      i++;
+      continue;
+    }
+    /* positive dX, i is too large */
+    if (dX >= 1.02*RADIUS) {
+      j++;
+      continue;
+    }
+
+    // skip this star if already assigned to an object
+    if (stars[N1[i]].found) {
+        i++;
+        continue;
+    }
+
+    /* this block will match a given detection to the closest object within range of that detection.
+       XXX note that this matches ALL detections within range of the single object to that same object 
+       this is bad, but I cannot just go in linear order (ie, mark off each object as they are
+       used).  I should make a list of all Nobj * Ndet pairs in range and choose the matches
+       based on their separations.  UGH
+     */
+    
+    /* within match range; look for matches */
+    off_t Jmin = -1;
+    double Rmin = RADIUS2;
+    for (off_t J = j; (dX > -1.02*RADIUS) && (J < Nave); J++) {
+      /* find closest match for this detection */
+      dX = X1[i] - X2[J];
+      double dY = Y1[i] - Y2[J];
+      double dR = dX*dX + dY*dY;
+      if (dR > RADIUS2) continue;
+      if (dR < Rmin) {
+	Rmin = dR;
+	Jmin  = J;
+      }
+    }
+
+    /* no match, try next detection */ 
+    if (Jmin == -1) {
+      i++;
+      continue;
+    }
+
+    /*** a match is found, add to average, measure ***/
+    Nmatch ++;
+    off_t n = N2[Jmin];
+    off_t N = N1[i];
+
+    /* make sure there is space for next entry */
+    if (Nmeas >= NMEAS - 1) {
+      NMEAS = Nmeas + 1000;
+      REALLOCATE (next_meas, off_t, NMEAS);
+      REALLOCATE (tgtcat[0].measure, Measure, NMEAS);
+    }
+
+    /** add measurement for this star **/
+
+    /* add to end of measurement list */
+    add_meas_link (&tgtcat[0].average[n], next_meas, Nmeas, NMEAS);
+
+    // set the new measurements
+    tgtcat[0].measure[Nmeas]          = stars[N].measure;
+
+    // measure now carries R,D (not dR,dD) 
+    tgtcat[0].measure[Nmeas].dbFlags  = 0;
+    tgtcat[0].measure[Nmeas].averef   = n;
+    tgtcat[0].measure[Nmeas].objID    = tgtcat[0].average[n].objID;
+    tgtcat[0].measure[Nmeas].catID    = tgtcat[0].catID;
+    
+    float dRoff = dvoOffsetR(&tgtcat[0].measure[Nmeas], &tgtcat[0].average[n]);
+
+    // rationalize dR
+    if (dRoff > +180.0*3600.0) {
+      // average on high end of boundary, move star up
+      tgtcat[0].measure[Nmeas].R += 360.0;
+      dRoff -= 360.0*3600.0;
+    }
+    if (dRoff < -180.0*3600.0) {
+      // average on low end of boundary, move star down
+      tgtcat[0].measure[Nmeas].R -= 360.0;
+      dRoff += 360.0*3600.0;
+    }
+    if (fabs(dRoff) > 10*RADIUS) {
+      // take declination into account and check again.
+      double cosD = cos(RAD_DEG*tgtcat[0].average[n].D);
+      if (fabs(dRoff*cosD) > 10*RADIUS) {
+	fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
+		 tgtcat[0].average[n].R, tgtcat[0].average[n].D, 
+		 stars[N].R, stars[N].D,
+		 X1[i], X2[Jmin], 
+		 Y1[i], Y2[Jmin]);
+	// XXX abort on this? -- this is a bad failure...
+      }
+    }
+
+    /* Nm is updated, but not written out in -update mode (for existing entries)
+       Nm is recalculated in build_meas_links if loaded table is not sorted */
+    tgtcat[0].average[n].Nmeasure ++;
+    Nmeas ++;
+
+    /* if we choose to flag close encounters, see find_matches.c */
+    /* if we choose to calculate RA,DEC averages, see update_coords.c */
+
+    stars[N].found = TRUE;
+    i++;
+  }
+
+  /*************** add unmatched stars *************************/
+
+  /** incorporate unmatched image stars, if this star is in field of this tgtcat **/
+  /* these new entries are all written out in UPDATE mode */ 
+  for (off_t i = 0; (i < Nstars) && !options->only_match; i++) {
+    /* make sure there is space for next entry */
+    if (Nmeas >= NMEAS - 1) {
+      NMEAS = Nmeas + 1000;
+      REALLOCATE (next_meas, off_t, NMEAS);
+      REALLOCATE (tgtcat[0].measure, Measure, NMEAS);
+    }
+    if (Nave >= NAVE) {
+      NAVE = Nave + 1000;
+      REALLOCATE (tgtcat[0].average, Average, NAVE);
+      if (tgtcat[0].secfilt) {
+	// we only update the secfilt table if it has been allocated for output
+	REALLOCATE (tgtcat[0].secfilt, SecFilt, NAVE*tgtcat[0].Nsecfilt);
+      }
+    }
+
+    if (stars[i].found) continue;
+    if (!IN_REGION (stars[i].R, stars[i].D)) continue;
+
+    dvo_average_init (&tgtcat[0].average[Nave]);
+    tgtcat[0].average[Nave].R         	   = stars[i].R;
+    tgtcat[0].average[Nave].D         	   = stars[i].D;
+
+    tgtcat[0].average[Nave].Nmeasure  	   = 1;
+    tgtcat[0].average[Nave].measureOffset  = Nmeas;
+    tgtcat[0].average[Nave].objID     	   = objID;
+    tgtcat[0].average[Nave].catID     	   = catID;
+
+    if (PSPS_ID) {
+        tgtcat[0].average[Nave].extID = CreatePSPSObjectID(tgtcat[0].average[Nave].R, tgtcat[0].average[Nave].D);
+    }
+
+    objID ++;
+
+    // we only update the secfilt table if it has been allocated for output
+    for (int j = 0; tgtcat[0].secfilt && (j < Nsecfilt); j++) {
+      dvo_secfilt_init (&tgtcat[0].secfilt[Nave*Nsecfilt+j], SECFILT_RESET_ALL);
+    }
+
+    // supply the measurements from this detection
+    dvo_measure_init (&tgtcat[0].measure[Nmeas]);
+    tgtcat[0].measure[Nmeas] = stars[i].measure;
+
+    // the following measure elements cannot be set until here:
+    tgtcat[0].measure[Nmeas].dbFlags  = 0;
+    tgtcat[0].measure[Nmeas].averef   = Nave;
+    tgtcat[0].measure[Nmeas].objID    = tgtcat[0].average[Nave].objID;
+    tgtcat[0].measure[Nmeas].catID    = tgtcat[0].catID;
+
+    /* set the average magnitude if not already set and the photcode.equiv is not 0 */
+    /* in UPDATE mode, this value is not saved; use relphot to recalculate */
+    if (Nsec > -1) { 
+      tgtcat[0].secfilt[Nave*Nsecfilt+Nsec].M = PhotCat (&tgtcat[0].measure[Nmeas], MAG_CLASS_PSF);
+    }
+
+    Nmeas ++;
+
+    // update the next_meas pointer for this entry (last one for this star is -1)
+    next_meas[Nmeas-1] = -1;
+    stars[i].found = TRUE;
+    Nave ++;
+  }
+
+  REALLOCATE (tgtcat[0].average, Average, Nave);
+  REALLOCATE (tgtcat[0].measure, Measure, Nmeas);
+ 
+  if (options->nosort) {
+    tgtcat[0].sorted = FALSE;
+  } else {
+    tgtcat[0].sorted = TRUE;
+    tgtcat[0].measure = sort_measure (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas, next_meas);
+  }
+
+  /* check if the tgtcat has changed?  if no change, no need to write */
+  tgtcat[0].objID    = objID; // new max value, save on tgtcat close
+  tgtcat[0].Naverage = Nave;
+  tgtcat[0].Nmeasure = Nmeas;
+  tgtcat[0].Nsecfilt_mem = tgtcat[0].secfilt ? Nave*Nsecfilt : 0;
+  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas, Nmatch);
+
+  free (X1);
+  free (Y1);
+  free (N1);
+  free (X2);
+  free (Y2);
+  free (N2);
+  free (next_meas);
+
+  return (Nmatch);
+}
+
+/* 
+   notes:
+   
+   for finding if a tgtcat star is in an image or an image star is in the tgtcat:
+   
+   tgtcats have boundaries defined by RA and DEC, but they may curve in projection
+   images have boundaries which are lines in pixels coords, but curve in RA and DEC
+   
+   tgtcat[0].found[Ncat] but stars[Nstar].found
+   
+*/
Index: trunk/Ohana/src/addstar/src/loadgaia.c
===================================================================
--- trunk/Ohana/src/addstar/src/loadgaia.c	(revision 39926)
+++ trunk/Ohana/src/addstar/src/loadgaia.c	(revision 39926)
@@ -0,0 +1,44 @@
+# include "addstar.h"
+# include "gaia.h"
+
+/* This is the DVO program to upload gaia detections from D. Finkbeiner into a DVO database.
+   It is modeled on the loadtycho program but the source files are FITS tables.
+
+   USAGE: loadgaia -D CATDIR (catdir) (gaiafile) [...more files]
+
+*/
+
+int main (int argc, char **argv) {
+
+  SkyTable *sky;
+  SkyList *skylist = NULL;
+  AddstarClientOptions options;
+
+  // need to construct these options with args_loadtycho...
+  SetSignals ();
+  options = ConfigInit (&argc, argv);
+  options = args_loadgaia (&argc, argv, options);
+
+  // load the full sky description table:
+  sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+  
+  // generate the subset matching the user-selected region
+  skylist = SkyListByPatch (sky, -1, &UserPatch);
+
+  int Nstart = 1;
+  int Nend = argc;
+  while (Nstart < Nend) {
+    Nstart = loadgaia_table (Nstart, Nend, skylist, NULL, argv, &options);
+  }
+
+  SkyTableFree (sky);
+  SkyListFree(skylist);
+  FreePhotcodeTable();
+  free (CATDIR);
+
+  ohana_memcheck (VERBOSE);
+  ohana_memdump (VERBOSE);
+  exit (0);
+}  
+
Index: trunk/Ohana/src/addstar/src/loadgaia_catalog.c
===================================================================
--- trunk/Ohana/src/addstar/src/loadgaia_catalog.c	(revision 39926)
+++ trunk/Ohana/src/addstar/src/loadgaia_catalog.c	(revision 39926)
@@ -0,0 +1,32 @@
+# include "addstar.h"
+# include "gaia.h"
+
+int loadgaia_catalog (Gaia_Stars *stars, int Nstars, SkyRegion *region, char *filename, AddstarClientOptions *options) {
+
+  Catalog catalog;
+
+  // now we have all of the loaded stars in this catalog
+  dvo_catalog_init (&catalog, TRUE);
+  catalog.filename = filename;
+  catalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
+  catalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
+  catalog.catflags = DVO_LOAD_AVERAGE | DVO_LOAD_SECFILT | DVO_LOAD_MEASURE;
+  catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+    
+  // an error exit status here is a significant error
+  if (!dvo_catalog_open (&catalog, region, VERBOSE, "w")) {
+    fprintf (stderr, "ERROR: failure to open/create catalog file %s\n", catalog.filename);
+    exit (2);
+  }
+
+  find_matches_gaia (region, stars, Nstars, &catalog, options);
+    
+  SetProtect (TRUE);
+  if (!dvo_catalog_save (&catalog, VERBOSE)) { fprintf (stderr, "ERROR: failed to save %s\n", catalog.filename); exit (1); }
+  if (!dvo_catalog_unlock (&catalog)) { fprintf (stderr, "ERROR: failed to unlock %s\n", catalog.filename); exit (1); }
+  SetProtect (FALSE);
+
+  dvo_catalog_free (&catalog);
+
+  return (TRUE);
+}
Index: trunk/Ohana/src/addstar/src/loadgaia_make_subset.c
===================================================================
--- trunk/Ohana/src/addstar/src/loadgaia_make_subset.c	(revision 39926)
+++ trunk/Ohana/src/addstar/src/loadgaia_make_subset.c	(revision 39926)
@@ -0,0 +1,44 @@
+# include "addstar.h"
+# include "gaia.h"
+
+// assign stars in the given region to the subset (NOTE: stars are sorted by RA, start is
+// first entry in stars array in this region)
+
+Gaia_Stars *loadgaia_make_subset (Gaia_Stars *stars, int Nstars, int start, SkyRegion *region, int *nsubset) {
+
+  int i;
+
+  Gaia_Stars *subset = NULL;
+
+  // collect array of (Stars *) stars in a new output catalog
+  int Nsubset = 0;
+  int NSUBSET = 3000;
+  ALLOCATE (subset, Gaia_Stars, NSUBSET);
+
+  // find the rest of the stars in this output region
+  for (i = start; i < Nstars; i++) {
+    if (stars[i].flag) continue;
+
+    // check if in skyregion
+    if (stars[i].R <  region[0].Rmin) continue;
+    if (stars[i].R >= region[0].Rmax) break;
+    if (stars[i].D <  region[0].Dmin) continue;
+    if (stars[i].D >= region[0].Dmax) continue;
+	  
+    // check if in UserPatch (a GLOBAL)
+    if (stars[i].R < UserPatch.Rmin) continue;
+    if (stars[i].R > UserPatch.Rmax) break;
+    if (stars[i].D < UserPatch.Dmin) continue;
+    if (stars[i].D > UserPatch.Dmax) continue;
+	  
+    subset[Nsubset] = stars[i];
+    Nsubset ++;
+
+    stars[i].flag = TRUE;
+
+    CHECK_REALLOCATE (subset, Gaia_Stars, NSUBSET, Nsubset, 10000);
+  }
+
+  *nsubset = Nsubset;
+  return subset;
+}
Index: trunk/Ohana/src/addstar/src/loadgaia_readstars.c
===================================================================
--- trunk/Ohana/src/addstar/src/loadgaia_readstars.c	(revision 39926)
+++ trunk/Ohana/src/addstar/src/loadgaia_readstars.c	(revision 39926)
@@ -0,0 +1,143 @@
+# include "addstar.h"
+# include "gaia.h"
+
+# define GET_COLUMN(OUT,NAME,TYPE) \
+  TYPE *OUT = gfits_get_bintable_column_data (&theader, &ftable, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+Gaia_Stars *loadgaia_readstars (char *filename, Gaia_Stars *stars, int *nstars, AddstarClientOptions *options) {
+
+  // read in the full FITS files
+  FILE *f = fopen (filename, "r");
+  if (f == NULL) Shutdown ("can't read gaia file: %s", filename);
+
+  int i, Ncol;
+  off_t Nrow;
+
+  Header header;
+  Matrix matrix;
+  Header theader;
+  FTable ftable;
+  
+  // load in PHU segment (ignore)
+  if (!gfits_fread_header (f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset header\n");
+    fclose (f);
+    return stars;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset matrix\n");
+    gfits_free_header (&header);
+    fclose (f);
+    return stars;
+  }
+
+  ftable.header = &theader;
+
+  // load data for this header 
+  if (!gfits_load_header (f, &theader)) {
+    fclose (f);
+    return stars;
+  }
+  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) {
+    fclose (f);
+    return stars;
+  }
+
+  char type[16];
+
+  GET_COLUMN (RA,      "RA",              	 double);
+  GET_COLUMN (DEC,     "DEC",             	 double);
+  GET_COLUMN (dRA,     "RA_ERROR",        	 float);
+  GET_COLUMN (dDEC,    "DEC_ERROR",       	 float);
+  GET_COLUMN (gMag,    "PHOT_G_MEAN_MAG", 	 float);
+  GET_COLUMN (dgFlux,  "PHOT_G_MEAN_FLUX_ERROR", float);
+  GET_COLUMN (Nobs,    "PHOT_G_N_OBS",           short);
+
+  int NstarsIn = Nrow;
+
+  // free the memory associated with the FITS files
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table (&ftable);
+
+  fclose (f);
+
+  double Rmin = +360.0;
+  double Rmax = -360.0;
+  double Dmin = +360.0;
+  double Dmax = -360.0;
+
+  // start off where we finished on a previous read
+  int Nstars = *nstars;
+  int NSTARS = Nstars + 0.1*NstarsIn;
+
+  if (!stars) {
+    ALLOCATE (stars, Gaia_Stars, NSTARS);
+  } else {
+    REALLOCATE (stars, Gaia_Stars, NSTARS);
+  }
+
+  for (i = 0; i < NstarsIn; i++) {
+
+    Rmin = MIN (Rmin, RA[i]);
+    Rmax = MAX (Rmax, RA[i]);
+    Dmin = MIN (Dmin, DEC[i]);
+    Dmax = MAX (Dmax, DEC[i]);
+
+    float flux = pow(10.0, -0.4*(gMag[i] - 25.524770));
+
+    stars[Nstars].R = RA[i];
+    stars[Nstars].D = DEC[i];
+    stars[Nstars].flag  = FALSE;
+    stars[Nstars].found = FALSE;
+
+    dvo_measure_init (&stars[Nstars].measure);
+
+    stars[Nstars].measure.R = RA[i];
+    stars[Nstars].measure.D = DEC[i];
+    stars[Nstars].measure.dXccd = (int)(0x7fff*MAX(0.000,MIN(0.999, ((log10(dRA[i]) + 3.0)/6.0)))); 
+    stars[Nstars].measure.dYccd = (int)(0x7fff*MAX(0.000,MIN(0.999, ((log10(dDEC[i]) + 3.0)/6.0)))); 
+    // dXccd,dYccd range from 0 (10^-3) mas to 0x7fff (10^3 mas)
+    stars[Nstars].measure.M = gMag[i];
+    stars[Nstars].measure.dM = dgFlux[i] / flux;
+
+    stars[Nstars].measure.FluxPSF = flux;
+    stars[Nstars].measure.dFluxPSF = dgFlux[i];
+
+    stars[Nstars].measure.photcode = options->photcode;
+    stars[Nstars].measure.t = options->timeref;
+
+    Nstars ++;
+
+    CHECK_REALLOCATE (stars, Gaia_Stars, NSTARS, Nstars, 10000);
+  }
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+
+  free (RA);
+  free (DEC);
+  free (dRA);
+  free (dDEC);
+  free (gMag);
+  free (dgFlux);
+  free (Nobs);
+
+  *nstars = Nstars;
+  return (stars);
+}
+
+int loadgaia_sortStars (Gaia_Stars *stars, int Nstars) {
+
+# define SWAPFUNC(A,B){ Gaia_Stars temp = stars[A]; stars[A] = stars[B]; stars[B] = temp; }
+# define COMPARE(A,B)(stars[A].R < stars[B].R)
+
+  OHANA_SORT (Nstars, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+  
+  return TRUE;
+}
+
Index: trunk/Ohana/src/addstar/src/loadgaia_table.c
===================================================================
--- trunk/Ohana/src/addstar/src/loadgaia_table.c	(revision 39926)
+++ trunk/Ohana/src/addstar/src/loadgaia_table.c	(revision 39926)
@@ -0,0 +1,64 @@
+# include "addstar.h"
+# include "gaia.h"
+# define NSTARS_MAX 1000000
+
+int loadgaia_table (int Nstart, int Nend, SkyList *skylistInput, HostTable *hosts, char **filename, AddstarClientOptions *options) {
+  OHANA_UNUSED_PARAM(hosts);
+  
+  int i;
+
+  int Nstars = 0;
+  Gaia_Stars *stars = NULL;
+  for (i = Nstart; (Nstars < NSTARS_MAX) && (i < Nend); i++) {
+    // read the next file and append to the current set of stars
+    fprintf (stderr, "loading %s\n", filename[i]);
+    stars = loadgaia_readstars (filename[i], stars, &Nstars, options);
+  }
+  Nstart = i; // we pass back the entry for the next file to be read
+  if (!stars) return Nstart;
+
+  fprintf (stderr, "writing %d stars to dvo\n", Nstars);
+
+  // sort the stars by RA
+  loadgaia_sortStars (stars, Nstars);
+
+  // scan through the stars, loading the containing catalogs
+  // skip through table for unsaved stars
+  for (i = 0; i < Nstars; i++) {
+    if (stars[i].flag) continue;
+
+    // scan forward until we read the UserPatch
+    if (stars[i].R < UserPatch.Rmin) continue;
+    if (stars[i].R > UserPatch.Rmax) break;
+    if (stars[i].D < UserPatch.Dmin) continue;
+    if (stars[i].D > UserPatch.Dmax) continue;
+
+    // identify the relevant catalog
+    SkyList *skylist = SkyRegionByPoint_List (skylistInput, -1, stars[i].R, stars[i].D);
+    if (skylist[0].Nregions == 0) {
+      SkyListFree (skylist);
+      continue;
+    }
+    SkyRegion *region = skylist[0].regions[0];
+
+    // select stars matching this region
+    int Nsubset;
+    Gaia_Stars *subset = loadgaia_make_subset (stars, Nstars, i, region, &Nsubset);
+
+    // In parallel mode, write out the subset to a disk file.  Block until a remote host
+    // is available.  In serial mode, just match against the appropriate region and save
+    // NOTE: disable parallel mode for now: 
+    // loadgaia_save_remote (subset, Nsubset, hosts, region, skylist[0].filename[0], options);
+    loadgaia_catalog (subset, Nsubset, region, skylist[0].filename[0], options);
+    free (subset);
+    SkyListFree (skylist);
+  }
+
+  // wait for last remote clients to finish
+  // NOTE: disable parallel mode for now: 
+  // harvest_all ();
+
+  free (stars);
+  return Nstart;
+}
+
Index: trunk/Ohana/src/addstar/src/psps_ids.c
===================================================================
--- trunk/Ohana/src/addstar/src/psps_ids.c	(revision 39907)
+++ trunk/Ohana/src/addstar/src/psps_ids.c	(revision 39926)
@@ -42,5 +42,5 @@
 
     uint64_t part1, part2, part3;
-    part1 = (uint64_t)( izone  * 10000000000000LL) ; 
+    part1 = (uint64_t)( izone  * 10000000000000LL) ; // 10,000,000,000,000
     part2 = ((uint64_t)(ra * 1000000.)) * 10000 ; // 0 - 360*1e6 = 3.6e8 (< 29 bits)
     part3 = (int) (zresid * 10000.0) ; // 0 - 10000 (1 bit == 30/10000 arcsec) (< 14 bits)
@@ -48,2 +48,4 @@
     return part1 + part2 + part3;
 }
+
+// 10 000 000 000 000
Index: trunk/Ohana/src/delstar/include/delstar.h
===================================================================
--- trunk/Ohana/src/delstar/include/delstar.h	(revision 39907)
+++ trunk/Ohana/src/delstar/include/delstar.h	(revision 39926)
@@ -95,4 +95,5 @@
 int   SAVE_DELETES;
 int   SKIP_IMAGES;
+char *BACKUP_EXTNAME;
 
 time_t    START;
@@ -111,4 +112,9 @@
 
 // for DELETE_MEASURES_BY_MATCH, these are the ranges to delete:
+int DELETE_MIN_DET_ID;
+int DELETE_MAX_DET_ID;
+int DELETE_MIN_CAT_ID;
+int DELETE_MAX_CAT_ID;
+
 int DELETE_MIN_IMAGE_ID;
 int DELETE_MAX_IMAGE_ID;
@@ -118,5 +124,4 @@
 int DELETE_MIN_TIME;
 int DELETE_MAX_TIME;
-
 
 /*** delstar prototypes ***/
Index: trunk/Ohana/src/delstar/src/args.c
===================================================================
--- trunk/Ohana/src/delstar/src/args.c	(revision 39907)
+++ trunk/Ohana/src/delstar/src/args.c	(revision 39926)
@@ -202,4 +202,8 @@
   }
 
+  DELETE_MIN_DET_ID = 0;
+  DELETE_MAX_DET_ID = 0;
+  DELETE_MIN_CAT_ID = 0;
+  DELETE_MAX_CAT_ID = 0;
   DELETE_MIN_IMAGE_ID = 0;
   DELETE_MAX_IMAGE_ID = 0;
@@ -209,4 +213,8 @@
   DELETE_MAX_TIME = 0;
 
+  if ((N = get_argument (argc, argv, "-delete-min-detID")))  { remove_argument (N, &argc, argv); DELETE_MIN_DET_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
+  if ((N = get_argument (argc, argv, "-delete-max-detID")))  { remove_argument (N, &argc, argv); DELETE_MAX_DET_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
+  if ((N = get_argument (argc, argv, "-delete-min-catID")))  { remove_argument (N, &argc, argv); DELETE_MIN_CAT_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
+  if ((N = get_argument (argc, argv, "-delete-max-catID")))  { remove_argument (N, &argc, argv); DELETE_MAX_CAT_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
   if ((N = get_argument (argc, argv, "-delete-min-imageID")))  { remove_argument (N, &argc, argv); DELETE_MIN_IMAGE_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
   if ((N = get_argument (argc, argv, "-delete-max-imageID")))  { remove_argument (N, &argc, argv); DELETE_MAX_IMAGE_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
@@ -221,4 +229,13 @@
     remove_argument (N, &argc, argv);
   }
+
+  BACKUP_EXTNAME = NULL;
+  if ((N = get_argument (argc, argv, "-backup-extname"))) {
+    remove_argument (N, &argc, argv);
+    BACKUP_EXTNAME = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!BACKUP_EXTNAME) BACKUP_EXTNAME = strcreate (".bck");
+
   SAVE_DELETES = FALSE;
   if ((N = get_argument (argc, argv, "-save-deletes"))) {
@@ -471,4 +488,5 @@
     remove_argument (N, &argc, argv);
   }
+
   if ((N = get_argument (argc, argv, "-delete-measures-by-match"))) {
     if (MODE != MODE_NONE) usage();
@@ -477,4 +495,9 @@
     SKIP_IMAGES = TRUE; // we do not need to load the images for -dup-measures
   }
+
+  DELETE_MIN_DET_ID = 0;
+  DELETE_MAX_DET_ID = 0;
+  DELETE_MIN_CAT_ID = 0;
+  DELETE_MAX_CAT_ID = 0;
   DELETE_MIN_IMAGE_ID = 0;
   DELETE_MAX_IMAGE_ID = 0;
@@ -484,4 +507,8 @@
   DELETE_MAX_TIME = 0;
 
+  if ((N = get_argument (argc, argv, "-delete-min-detID")))  { remove_argument (N, &argc, argv); DELETE_MIN_DET_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
+  if ((N = get_argument (argc, argv, "-delete-max-detID")))  { remove_argument (N, &argc, argv); DELETE_MAX_DET_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
+  if ((N = get_argument (argc, argv, "-delete-min-catID")))  { remove_argument (N, &argc, argv); DELETE_MIN_CAT_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
+  if ((N = get_argument (argc, argv, "-delete-max-catID")))  { remove_argument (N, &argc, argv); DELETE_MAX_CAT_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
   if ((N = get_argument (argc, argv, "-delete-min-imageID")))  { remove_argument (N, &argc, argv); DELETE_MIN_IMAGE_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
   if ((N = get_argument (argc, argv, "-delete-max-imageID")))  { remove_argument (N, &argc, argv); DELETE_MAX_IMAGE_ID = atoi(argv[N]); remove_argument (N, &argc, argv); }
@@ -496,4 +523,11 @@
     remove_argument (N, &argc, argv);
   }
+  BACKUP_EXTNAME = NULL;
+  if ((N = get_argument (argc, argv, "-backup-extname"))) {
+    remove_argument (N, &argc, argv);
+    BACKUP_EXTNAME = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!BACKUP_EXTNAME) BACKUP_EXTNAME = strcreate (".bck");
 
   if ((N = get_argument (argc, argv, "-fix-LAP"))) {
Index: trunk/Ohana/src/delstar/src/delete_duplicate_measures.c
===================================================================
--- trunk/Ohana/src/delstar/src/delete_duplicate_measures.c	(revision 39907)
+++ trunk/Ohana/src/delstar/src/delete_duplicate_measures.c	(revision 39926)
@@ -111,13 +111,13 @@
 
     // save backup of original cpm file
-    if (!dvo_catalog_subset_backup (&catalog, ".dlx")) {
+    if (!dvo_catalog_subset_backup (&catalog, ".dlz")) {
       fprintf (stderr, "ERROR: failed to make backup cpt table for catalog %s\n", catalog.filename);
       exit (1);
     }
-    if (!dvo_catalog_subset_backup (catalog.measure_catalog, ".d1x")) {
+    if (!dvo_catalog_subset_backup (catalog.measure_catalog, ".d1z")) {
       fprintf (stderr, "ERROR: failed to make backup cpm table for catalog %s\n", catalog.filename);
       exit (1);
     }
-    if (!dvo_catalog_subset_backup (catalog.secfilt_catalog, ".dlx")) {
+    if (!dvo_catalog_subset_backup (catalog.secfilt_catalog, ".dlz")) {
       fprintf (stderr, "ERROR: failed to make backup cps table for catalog %s\n", catalog.filename);
       exit (1);
@@ -377,5 +377,5 @@
   if (SAVE_DUPLICATES) {
     char savename[DVO_MAX_PATH];
-    snprintf (savename, DVO_MAX_PATH, "%s.save.0912", catalog->filename);
+    snprintf (savename, DVO_MAX_PATH, "%s.save.0914", catalog->filename);
     struct stat filestat;
     int myStatus = stat (savename, &filestat);
Index: trunk/Ohana/src/delstar/src/delete_measures_by_match.c
===================================================================
--- trunk/Ohana/src/delstar/src/delete_measures_by_match.c	(revision 39907)
+++ trunk/Ohana/src/delstar/src/delete_measures_by_match.c	(revision 39926)
@@ -13,4 +13,8 @@
 
   int validOptions = FALSE;
+  validOptions |= DELETE_MAX_CAT_ID;
+  validOptions |= DELETE_MIN_CAT_ID;
+  validOptions |= DELETE_MAX_DET_ID;
+  validOptions |= DELETE_MIN_DET_ID;
   validOptions |= DELETE_MAX_IMAGE_ID;
   validOptions |= DELETE_MIN_IMAGE_ID;
@@ -26,4 +30,6 @@
   fprintf (stderr, "deleting measurements matching the following\n");
   fprintf (stderr, "image ID range : %d to %d\n", DELETE_MIN_IMAGE_ID, DELETE_MAX_IMAGE_ID);
+  fprintf (stderr, "det ID range : %d to %d\n", DELETE_MIN_DET_ID, DELETE_MAX_DET_ID);
+  fprintf (stderr, "cat ID range : %d to %d\n", DELETE_MIN_CAT_ID, DELETE_MAX_CAT_ID);
   fprintf (stderr, "photcode range : %d to %d\n", DELETE_MIN_PHOTCODE, DELETE_MAX_PHOTCODE);
   fprintf (stderr, "time range (UNIX) : %d to %d\n", DELETE_MIN_TIME, DELETE_MAX_TIME);
@@ -133,13 +139,13 @@
 
     // save backup of original cpm file
-    if (!dvo_catalog_subset_backup (&catalog, ".dlz")) {
+    if (!dvo_catalog_subset_backup (&catalog, BACKUP_EXTNAME)) {
       fprintf (stderr, "ERROR: failed to make backup cpt table for catalog %s\n", catalog.filename);
       exit (1);
     }
-    if (!dvo_catalog_subset_backup (catalog.measure_catalog, ".d1z")) {
+    if (!dvo_catalog_subset_backup (catalog.measure_catalog, BACKUP_EXTNAME)) {
       fprintf (stderr, "ERROR: failed to make backup cpm table for catalog %s\n", catalog.filename);
       exit (1);
     }
-    if (!dvo_catalog_subset_backup (catalog.secfilt_catalog, ".dlz")) {
+    if (!dvo_catalog_subset_backup (catalog.secfilt_catalog, BACKUP_EXTNAME)) {
       fprintf (stderr, "ERROR: failed to make backup cps table for catalog %s\n", catalog.filename);
       exit (1);
@@ -214,4 +220,9 @@
 	      UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
 
+    if (DELETE_MIN_DET_ID) strextend (&command, "-delete-min-detID %d", DELETE_MIN_DET_ID);
+    if (DELETE_MAX_DET_ID) strextend (&command, "-delete-max-detID %d", DELETE_MAX_DET_ID);
+    if (DELETE_MIN_CAT_ID) strextend (&command, "-delete-min-catID %d", DELETE_MIN_CAT_ID);
+    if (DELETE_MAX_CAT_ID) strextend (&command, "-delete-max-catID %d", DELETE_MAX_CAT_ID);
+
     if (DELETE_MIN_IMAGE_ID) strextend (&command, "-delete-min-imageID %d", DELETE_MIN_IMAGE_ID);
     if (DELETE_MAX_IMAGE_ID) strextend (&command, "-delete-max-imageID %d", DELETE_MAX_IMAGE_ID);
@@ -234,4 +245,6 @@
     if (UPDATE)     	 { strextend (&command, "-update");             }
     if (SAVE_DELETES)    { strextend (&command, "-save-deletes");    }
+
+    if (BACKUP_EXTNAME)  { strextend (&command, "-backup-extname %s", BACKUP_EXTNAME);    }
 
     fprintf (stderr, "command: %s\n", command);
@@ -356,4 +369,10 @@
 
     // does this measure match our selection criteria?
+    if (measure[i].detID > DELETE_MAX_DET_ID) continue;
+    if (measure[i].detID < DELETE_MIN_DET_ID) continue;
+
+    if (measure[i].catID > DELETE_MAX_CAT_ID) continue;
+    if (measure[i].catID < DELETE_MIN_CAT_ID) continue;
+
     if (measure[i].imageID > DELETE_MAX_IMAGE_ID) continue;
     if (measure[i].imageID < DELETE_MIN_IMAGE_ID) continue;
@@ -367,7 +386,7 @@
     measureDrop[i] = TRUE;
     off_t N = measure[i].averef;
-    if (VERBOSE) fprintf (stderr, "0x%08x 0x%08x %8.4f %8.4f %5d\n", measure[i].imageID, measure[i].detID, average[N].R, average[N].D, measure[i].photcode);
+    if (VERBOSE) fprintf (stderr, "0x%08x 0x%08x 0x%08x %8.4f %8.4f %5d\n", measure[i].imageID, measure[i].detID, measure[i].catID, average[N].R, average[N].D, measure[i].photcode);
     if (fsave) {
-      fprintf (fsave, "0x%08x 0x%08x %8.4f %8.4f %5d\n", measure[i].imageID, measure[i].detID, average[N].R, average[N].D, measure[i].photcode);
+      fprintf (fsave, "0x%08x 0x%08x 0x%08x %8.4f %8.4f %5d\n", measure[i].imageID, measure[i].detID, measure[i].catID, average[N].R, average[N].D, measure[i].photcode);
     }
     if (isGPC1chip(measure[i].photcode)) {
Index: trunk/Ohana/src/dvomerge/include/dvomerge.h
===================================================================
--- trunk/Ohana/src/dvomerge/include/dvomerge.h	(revision 39907)
+++ trunk/Ohana/src/dvomerge/include/dvomerge.h	(revision 39926)
@@ -61,4 +61,5 @@
 int    SKIP_MEASURE;
 int    SKIP_LENSING;
+int    SKIP_LENSOBJ;
 int    SKIP_STARPAR;
 int    SKIP_GALPHOT;
@@ -171,24 +172,29 @@
 off_t 	  *build_measure_links    PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
 off_t 	  *init_measure_links     PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
-int   	   add_meas_link     	  PROTO((Average *average, off_t *next, off_t Nmeasure, off_t NMEASURE));
+int   	   add_measure_link    	  PROTO((Average *average, off_t *next, off_t Nmeasure, off_t NMEASURE));
 Measure   *sort_measure     	  PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next));
 
 off_t 	  *build_lensing_links    PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing));
 off_t 	  *init_lensing_links     PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing));
-int   	   add_lens_link     	  PROTO((Average *average, off_t *next, off_t Nlensing, off_t NLENSING));
+int   	   add_lensing_link    	  PROTO((Average *average, off_t *next, off_t Nlensing, off_t NLENSING));
 Lensing   *sort_lensing     	  PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing, off_t *next));
+
+off_t 	  *build_lensobj_links    PROTO((Average *average, off_t Naverage, Lensobj *lensobj, off_t Nlensobj));
+off_t 	  *init_lensobj_links     PROTO((Average *average, off_t Naverage, Lensobj *lensobj, off_t Nlensobj));
+int   	   add_lensobj_link    	  PROTO((Average *average, off_t *next, off_t Nlensobj, off_t NLENSOBJ));
+Lensobj   *sort_lensobj     	  PROTO((Average *average, off_t Naverage, Lensobj *lensobj, off_t Nlensobj, off_t *next));
 
 off_t 	  *build_starpar_links    PROTO((Average *average, off_t Naverage, StarPar *starpar, off_t Nstarpar));
 off_t 	  *init_starpar_links     PROTO((Average *average, off_t Naverage, StarPar *starpar, off_t Nstarpar));
-int   	   add_star_link     	  PROTO((Average *average, off_t *next, off_t Nstarpar, off_t NSTARPAR));
+int   	   add_starpar_link     	  PROTO((Average *average, off_t *next, off_t Nstarpar, off_t NSTARPAR));
 StarPar   *sort_starpar     	  PROTO((Average *average, off_t Naverage, StarPar *starpar, off_t Nstarpar, off_t *next));
 
 off_t 	  *build_galphot_links    PROTO((Average *average, off_t Naverage, GalPhot *galphot, off_t Ngalphot));
 off_t 	  *init_galphot_links     PROTO((Average *average, off_t Naverage, GalPhot *galphot, off_t Ngalphot));
-int   	   add_galp_link     	  PROTO((Average *average, off_t *next, off_t Ngalphot, off_t NGALPHOT));
+int   	   add_galphot_link     	  PROTO((Average *average, off_t *next, off_t Ngalphot, off_t NGALPHOT));
 GalPhot   *sort_galphot     	  PROTO((Average *average, off_t Naverage, GalPhot *galphot, off_t Ngalphot, off_t *next));
 
 off_t 	  *init_missing_links     PROTO((Average *average, off_t Naverage, Missing *missing, off_t Nmissing));
-int   	   add_miss_link     	  PROTO((Average *average, off_t *next, off_t Nmissing));
+int   	   add_missing_link     	  PROTO((Average *average, off_t *next, off_t Nmissing));
 Missing   *sort_missing     	  PROTO((Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next_miss));
 
Index: trunk/Ohana/src/dvomerge/src/LoadCatalog.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/LoadCatalog.c	(revision 39907)
+++ trunk/Ohana/src/dvomerge/src/LoadCatalog.c	(revision 39926)
@@ -9,7 +9,6 @@
 
   // always load all of the data (if any exists)
-  // XXXX TEMP HACK : skip GALPHOT
 
-  catalog[0].catflags = DVO_LOAD_AVERAGE | DVO_LOAD_MISSING | DVO_LOAD_SECFILT | DVO_LOAD_LENSOBJ;
+  catalog[0].catflags = DVO_LOAD_AVERAGE | DVO_LOAD_MISSING | DVO_LOAD_SECFILT;
 
   if (SKIP_MEASURE) {
@@ -23,4 +22,10 @@
   } else {
     catalog[0].catflags = catalog[0].catflags | DVO_LOAD_LENSING;
+  }
+
+  if (SKIP_LENSOBJ)  {
+    catalog[0].catflags = catalog[0].catflags | DVO_SKIP_LENSOBJ;
+  } else {
+    catalog[0].catflags = catalog[0].catflags | DVO_LOAD_LENSOBJ;
   }
 
Index: trunk/Ohana/src/dvomerge/src/args.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/args.c	(revision 39907)
+++ trunk/Ohana/src/dvomerge/src/args.c	(revision 39926)
@@ -56,4 +56,9 @@
   if ((N = get_argument (*argc, argv, "-skip-lensing"))) {
     SKIP_LENSING = TRUE;
+    remove_argument (N, argc, argv);
+  }
+  SKIP_LENSOBJ = FALSE;
+  if ((N = get_argument (*argc, argv, "-skip-lensobj"))) {
+    SKIP_LENSOBJ = TRUE;
     remove_argument (N, argc, argv);
   }
@@ -340,4 +345,9 @@
     remove_argument (N, argc, argv);
   }
+  SKIP_LENSOBJ = FALSE;
+  if ((N = get_argument (*argc, argv, "-skip-lensobj"))) {
+    SKIP_LENSOBJ = TRUE;
+    remove_argument (N, argc, argv);
+  }
   SKIP_STARPAR = FALSE;
   if ((N = get_argument (*argc, argv, "-skip-starpar"))) {
Index: trunk/Ohana/src/dvomerge/src/build_links.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/build_links.c	(revision 39907)
+++ trunk/Ohana/src/dvomerge/src/build_links.c	(revision 39926)
@@ -15,10 +15,10 @@
 data: they refer to the sequence number in the data blocks.
 
-next_meas is a list of the equivalent sequence of the measure block as if it were sorted.
+next_measure is a list of the equivalent sequence of the measure block as if it were sorted.
 
 to find the sequence of measurements for a given average:
 n_0 = average->measureOffset
-n_1 = next_meas[n_0]
-n_i = next_meas[n_i-1]
+n_1 = next_measure[n_0]
+n_i = next_measure[n_i-1]
 
 */
@@ -31,5 +31,5 @@
 
   off_t i, j, N;
-  off_t *next_meas;
+  off_t *next_measure;
 
   if (!measure) return NULL;
@@ -38,5 +38,5 @@
   N = 0;
 
-  ALLOCATE (next_meas, off_t, Nmeasure);
+  ALLOCATE (next_measure, off_t, Nmeasure);
   for (i = 0; i < Naverage; i++) {
     if (!average[i].Nmeasure) continue;
@@ -45,10 +45,10 @@
     for (j = 0; j < average[i].Nmeasure - 1; j++, N++) {
       myAssert (measure[m+j+1].averef == i, "not sorted");
-      next_meas[N] = N + 1;
+      next_measure[N] = N + 1;
       if (N >= Nmeasure) {
 	fprintf (stderr, "WARNING: N out of bounds (1)\n");
       }
     }
-    next_meas[N] = -1;
+    next_measure[N] = -1;
     if (N >= Nmeasure) {
       fprintf (stderr, "WARNING: N out of bounds (2)\n");
@@ -61,5 +61,5 @@
     N++;
   }
-  return (next_meas);
+  return (next_measure);
 }
 
@@ -74,7 +74,7 @@
 
   off_t i, m, k, Nm, averef;
-  off_t *next_meas;
-
-  ALLOCATE (next_meas, off_t, Nmeasure);
+  off_t *next_measure;
+
+  ALLOCATE (next_measure, off_t, Nmeasure);
 
   /* reset the Nm, offset values for average */
@@ -87,5 +87,5 @@
     averef = measure[Nm].averef;
     m = average[averef].measureOffset;  
-    next_meas[Nm] = -1;
+    next_measure[Nm] = -1;
 
     if (m == -1) { /* no links yet for source */
@@ -95,6 +95,6 @@
     }
 
-    for (k = 0; next_meas[m] != -1; k++) {
-      m = next_meas[m];
+    for (k = 0; next_measure[m] != -1; k++) {
+      m = next_measure[m];
       if (m >= Nmeasure) {
 	fprintf (stderr, "WARNING: m out of bounds (1)\n");
@@ -103,22 +103,22 @@
 
     average[averef].Nmeasure = k + 2;
-    next_meas[m] = Nm;
+    next_measure[m] = Nm;
     if (m >= Nmeasure) {
       fprintf (stderr, "WARNING: m out of bounds (2)\n");
     }
   }
-  return (next_meas);
+  return (next_measure);
 }
 
 /* average[].measureOffset, average[].Nmeasure are valid within an addstar run */
-int add_meas_link (Average *average, off_t *next_meas, off_t Nmeasure, off_t NMEASURE) {
+int add_measure_link (Average *average, off_t *next_measure, off_t Nmeasure, off_t NMEASURE) {
 
   off_t k, m;
 
-  /* if we have trouble, check validity of next_meas[m] : m < Nmeasure */
+  /* if we have trouble, check validity of next_measure[m] : m < Nmeasure */
   m = average[0].measureOffset;  
 
   for (k = 0; k < average[0].Nmeasure - 1; k++)  {
-    m = next_meas[m];
+    m = next_measure[m];
     if (m >= NMEASURE) {
       fprintf (stderr, "WARNING: m out of bounds (3)\n");
@@ -127,5 +127,5 @@
 
   /* set up references */
-  next_meas[Nmeasure] = -1;
+  next_measure[Nmeasure] = -1;
   if (Nmeasure >= NMEASURE) {
     fprintf (stderr, "WARNING: Nmeasure out of bounds (1)\n");
@@ -136,5 +136,5 @@
     average[0].measureOffset = Nmeasure;
   } else {
-    next_meas[m] = Nmeasure;
+    next_measure[m] = Nmeasure;
     if (m >= NMEASURE) {
       fprintf (stderr, "WARNING: m out of bounds (4)\n");
@@ -145,5 +145,5 @@
 }
 
-Measure *sort_measure (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next_meas) {
+Measure *sort_measure (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next_measure) {
 
   off_t i, k, n, np, N;
@@ -169,5 +169,5 @@
       tmpmeasure[N].averef = i;
       np = n;
-      n = next_meas[n];
+      n = next_measure[n];
     }
   }
@@ -183,15 +183,15 @@
 
   off_t i, j, N;
-  off_t *next_miss;
+  off_t *next_missing;
 
   N = 0;
 
-  ALLOCATE (next_miss, off_t, Nmissing);
+  ALLOCATE (next_missing, off_t, Nmissing);
   for (i = 0; i < Naverage; i++) {
     for (j = 0; j < average[i].Nmissing - 1; j++, N++) {
-      next_miss[N] = N + 1;
+      next_missing[N] = N + 1;
     }
     if (average[i].Nmissing > 0) {
-      next_miss[N] = -1;
+      next_missing[N] = -1;
       if (N >= Nmissing) {
 	fprintf (stderr, "overflow in init_missing_links");
@@ -202,8 +202,8 @@
 
   }
-  return (next_miss);
-}
-
-int add_miss_link (Average *average, off_t *next_miss, off_t Nmissing) {
+  return (next_missing);
+}
+
+int add_missing_link (Average *average, off_t *next_missing, off_t Nmissing) {
 
   off_t k, m;
@@ -212,13 +212,13 @@
   if (average[0].Nmissing < 1) {
     average[0].missingOffset = Nmissing;
-    next_miss[Nmissing] = -1;
+    next_missing[Nmissing] = -1;
     return (TRUE);
   }
 
   m = average[0].missingOffset;  
-  for (k = 0; k < average[0].Nmissing - 1; k++) m = next_miss[m];
+  for (k = 0; k < average[0].Nmissing - 1; k++) m = next_missing[m];
   /* set up references */
-  next_miss[Nmissing] = -1;
-  next_miss[m] = Nmissing;
+  next_missing[Nmissing] = -1;
+  next_missing[m] = Nmissing;
   return (TRUE);
 }
@@ -227,5 +227,5 @@
    we must always save the missing table, if it exists */
 
-Missing *sort_missing (Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next_miss) {
+Missing *sort_missing (Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next_missing) {
 
   off_t i, k, n, N;
@@ -240,5 +240,5 @@
     for (k = 0; k < average[i].Nmissing; k++, N++) {
       tmpmissing[N] = missing[n]; 
-      n = next_miss[n];
+      n = next_missing[n];
     }
   }
@@ -254,5 +254,5 @@
 
   off_t i, j, N;
-  off_t *next_lens;
+  off_t *next_lensing;
 
   if (!lensing) return NULL;
@@ -261,5 +261,5 @@
   N = 0;
 
-  ALLOCATE (next_lens, off_t, Nlensing);
+  ALLOCATE (next_lensing, off_t, Nlensing);
   for (i = 0; i < Naverage; i++) {
     if (!average[i].Nlensing) continue;
@@ -268,10 +268,10 @@
     for (j = 0; j < average[i].Nlensing - 1; j++, N++) {
       myAssert (lensing[m+j+1].averef == i, "not sorted");
-      next_lens[N] = N + 1;
+      next_lensing[N] = N + 1;
       if (N >= Nlensing) {
 	fprintf (stderr, "WARNING: N out of bounds (1)\n");
       }
     }
-    next_lens[N] = -1;
+    next_lensing[N] = -1;
     if (N >= Nlensing) {
       fprintf (stderr, "WARNING: N out of bounds (2)\n");
@@ -284,5 +284,5 @@
     N++;
   }
-  return (next_lens);
+  return (next_lensing);
 }
 
@@ -297,7 +297,7 @@
 
   off_t i, m, k, Nm, averef;
-  off_t *next_lens;
-
-  ALLOCATE (next_lens, off_t, Nlensing);
+  off_t *next_lensing;
+
+  ALLOCATE (next_lensing, off_t, Nlensing);
 
   /* reset the Nm, offset values for average */
@@ -310,5 +310,5 @@
     averef = lensing[Nm].averef;
     m = average[averef].lensingOffset;  
-    next_lens[Nm] = -1;
+    next_lensing[Nm] = -1;
 
     if (m == -1) { /* no links yet for source */
@@ -318,6 +318,6 @@
     }
 
-    for (k = 0; next_lens[m] != -1; k++) {
-      m = next_lens[m];
+    for (k = 0; next_lensing[m] != -1; k++) {
+      m = next_lensing[m];
       if (m >= Nlensing) {
 	fprintf (stderr, "WARNING: m out of bounds (1)\n");
@@ -326,22 +326,22 @@
 
     average[averef].Nlensing = k + 2;
-    next_lens[m] = Nm;
+    next_lensing[m] = Nm;
     if (m >= Nlensing) {
       fprintf (stderr, "WARNING: m out of bounds (2)\n");
     }
   }
-  return (next_lens);
+  return (next_lensing);
 }
 
 /* average[].lensingOffset, average[].Nlensing are valid within an addstar run */
-int add_lens_link (Average *average, off_t *next_lens, off_t Nlensing, off_t NLENSING) {
+int add_lensing_link (Average *average, off_t *next_lensing, off_t Nlensing, off_t NLENSING) {
 
   off_t k, m;
 
-  /* if we have trouble, check validity of next_lens[m] : m < Nlensing */
+  /* if we have trouble, check validity of next_lensing[m] : m < Nlensing */
   m = average[0].lensingOffset;  
 
   for (k = 0; k < average[0].Nlensing - 1; k++)  {
-    m = next_lens[m];
+    m = next_lensing[m];
     if (m >= NLENSING) {
       fprintf (stderr, "WARNING: m out of bounds (3)\n");
@@ -350,5 +350,5 @@
 
   /* set up references */
-  next_lens[Nlensing] = -1;
+  next_lensing[Nlensing] = -1;
   if (Nlensing >= NLENSING) {
     fprintf (stderr, "WARNING: Nlensing out of bounds (1)\n");
@@ -359,5 +359,5 @@
     average[0].lensingOffset = Nlensing;
   } else {
-    next_lens[m] = Nlensing;
+    next_lensing[m] = Nlensing;
     if (m >= NLENSING) {
       fprintf (stderr, "WARNING: m out of bounds (4)\n");
@@ -368,5 +368,5 @@
 }
 
-Lensing *sort_lensing (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing, off_t *next_lens) {
+Lensing *sort_lensing (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing, off_t *next_lensing) {
 
   off_t i, k, n, np, N;
@@ -392,9 +392,167 @@
       tmplensing[N].averef = i;
       np = n;
-      n = next_lens[n];
+      n = next_lensing[n];
     }
   }
   free (lensing);
   return (tmplensing);
+}
+
+/*** Lensobj ****************************************************************************************/
+
+/* build the initial links assuming the table is sorted, 
+   not partial, and has a correct set of average[].lensobjOffset,Nlensobj values */
+off_t *init_lensobj_links (Average *average, off_t Naverage, Lensobj *lensobj, off_t Nlensobj) {
+
+  off_t i, j, N;
+  off_t *next_lensobj;
+
+  if (!lensobj) return NULL;
+  if (SKIP_LENSOBJ) return NULL;
+
+  N = 0;
+
+  ALLOCATE (next_lensobj, off_t, Nlensobj);
+  for (i = 0; i < Naverage; i++) {
+    if (!average[i].Nlensobj) continue;
+    // off_t m = average[i].lensobjOffset;
+    // myAssert (lensobj[m].averef == i, "not sorted");
+    for (j = 0; j < average[i].Nlensobj - 1; j++, N++) {
+      // myAssert (lensobj[m+j+1].averef == i, "not sorted");
+      next_lensobj[N] = N + 1;
+      if (N >= Nlensobj) {
+	fprintf (stderr, "WARNING: N out of bounds (1)\n");
+      }
+    }
+    next_lensobj[N] = -1;
+    if (N >= Nlensobj) {
+      fprintf (stderr, "WARNING: N out of bounds (2)\n");
+    }
+
+    if (N >= Nlensobj) {
+      fprintf (stderr, "overflow in init_lensobj_links\n");
+      abort ();
+    }
+    N++;
+  }
+  return (next_lensobj);
+}
+
+/* construct lensobj links which are valid FOR THIS LOAD
+ * - if we have a full load, we will get links which can
+ *   be used by other programs (eg, relphot, etc)
+ * - if we have a partial load, the links are only valid
+ *   for that partial load
+ */ 
+
+off_t *build_lensobj_links (Average *average, off_t Naverage, Lensobj *lensobj, off_t Nlensobj) {
+
+  fprintf (stderr, "input is not sorted but contains lensobj -- trouble\n");
+  exit (2);
+
+# if (0)
+
+  off_t i, m, k, Nm, averef;
+  off_t *next_lensobj;
+
+  ALLOCATE (next_lensobj, off_t, Nlensobj);
+
+  /* reset the Nm, offset values for average */
+  for (i = 0; i < Naverage; i++) {
+    average[i].lensobjOffset = -1;
+    average[i].Nlensobj     =  0;
+  }
+
+  for (Nm = 0; Nm < Nlensobj; Nm++) {
+    averef = lensobj[Nm].averef;
+    m = average[averef].lensobjOffset;  
+    next_lensobj[Nm] = -1;
+
+    if (m == -1) { /* no links yet for source */
+      average[averef].lensobjOffset = Nm;
+      average[averef].Nlensobj     = 1;
+      continue;
+    }
+
+    for (k = 0; next_lensobj[m] != -1; k++) {
+      m = next_lensobj[m];
+      if (m >= Nlensobj) {
+	fprintf (stderr, "WARNING: m out of bounds (1)\n");
+      }
+    }
+
+    average[averef].Nlensobj = k + 2;
+    next_lensobj[m] = Nm;
+    if (m >= Nlensobj) {
+      fprintf (stderr, "WARNING: m out of bounds (2)\n");
+    }
+  }
+  return (next_lensobj);
+# endif
+}
+
+/* average[].lensobjOffset, average[].Nlensobj are valid within an addstar run */
+int add_lensobj_link (Average *average, off_t *next_lensobj, off_t Nlensobj, off_t NLENSOBJ) {
+
+  off_t k, m;
+
+  /* if we have trouble, check validity of next_lensobj[m] : m < Nlensobj */
+  m = average[0].lensobjOffset;  
+
+  for (k = 0; k < average[0].Nlensobj - 1; k++)  {
+    m = next_lensobj[m];
+    if (m >= NLENSOBJ) {
+      fprintf (stderr, "WARNING: m out of bounds (3)\n");
+    }
+  }
+
+  /* set up references */
+  next_lensobj[Nlensobj] = -1;
+  if (Nlensobj >= NLENSOBJ) {
+    fprintf (stderr, "WARNING: Nlensobj out of bounds (1)\n");
+  }
+
+  // if Nlensobj is 0, m may have been mis-set; add to the end
+  if ((average[0].Nlensobj == 0) || (m == -1)) {
+    average[0].lensobjOffset = Nlensobj;
+  } else {
+    next_lensobj[m] = Nlensobj;
+    if (m >= NLENSOBJ) {
+      fprintf (stderr, "WARNING: m out of bounds (4)\n");
+    }
+  }
+
+  return (TRUE);
+}
+
+Lensobj *sort_lensobj (Average *average, off_t Naverage, Lensobj *lensobj, off_t Nlensobj, off_t *next_lensobj) {
+
+  off_t i, k, n, np, N;
+  Lensobj *tmplensobj;
+
+  /* fix order of Lensobj (memory intensive, but fast) */
+  np = -1;
+  N = 0; 
+  ALLOCATE (tmplensobj, Lensobj, Nlensobj);
+  for (i = 0; i < Naverage; i++) {
+    if (!average[i].Nlensobj) continue;
+    n = average[i].lensobjOffset;
+    average[i].lensobjOffset = N;
+    int myObjID = average[i].objID;
+    for (k = 0; k < average[i].Nlensobj; k++, N++) {
+      if (n == -1) {
+	fprintf (stderr, "entry after %d has a problem\n", (int) np);
+	abort();
+      }
+      tmplensobj[N] = lensobj[n]; 
+      // myAssert (lensobj[n].averef == i, "error in averef");
+      myAssert ((lensobj[n].objID == myObjID) || (lensobj[n].objID == -1), "error in objID?");
+      // tmplensobj[N].averef = i;
+      np = n;
+      n = next_lensobj[n];
+    }
+  }
+  free (lensobj);
+  return (tmplensobj);
 }
 
@@ -406,5 +564,5 @@
 
   off_t i, j, N;
-  off_t *next_star;
+  off_t *next_starpar;
 
   if (!starpar) return NULL;
@@ -415,6 +573,6 @@
   // NOTE that is we choose DVO_SKIP_STARPAR, catalog.starpar is NULL.
   // this code will let merge_catalogs_old.c do nothing for starpar
-  ALLOCATE (next_star, off_t, Nstarpar);
-  if (!starpar) return next_star;
+  ALLOCATE (next_starpar, off_t, Nstarpar);
+  if (!starpar) return next_starpar;
 
   for (i = 0; i < Naverage; i++) {
@@ -424,10 +582,10 @@
     for (j = 0; j < average[i].Nstarpar - 1; j++, N++) {
       myAssert (starpar[m+j+1].averef == i, "not sorted");
-      next_star[N] = N + 1;
+      next_starpar[N] = N + 1;
       if (N >= Nstarpar) {
 	fprintf (stderr, "WARNING: N out of bounds (1)\n");
       }
     }
-    next_star[N] = -1;
+    next_starpar[N] = -1;
     if (N >= Nstarpar) {
       fprintf (stderr, "WARNING: N out of bounds (2)\n");
@@ -440,5 +598,5 @@
     N++;
   }
-  return (next_star);
+  return (next_starpar);
 }
 
@@ -453,8 +611,8 @@
 
   off_t i, m, k, Nm, averef;
-  off_t *next_star;
-
-  ALLOCATE (next_star, off_t, Nstarpar);
-  if (!starpar) return next_star;
+  off_t *next_starpar;
+
+  ALLOCATE (next_starpar, off_t, Nstarpar);
+  if (!starpar) return next_starpar;
 
   /* reset the Nm, offset values for average */
@@ -467,5 +625,5 @@
     averef = starpar[Nm].averef;
     m = average[averef].starparOffset;  
-    next_star[Nm] = -1;
+    next_starpar[Nm] = -1;
 
     if (m == -1) { /* no links yet for source */
@@ -475,6 +633,6 @@
     }
 
-    for (k = 0; next_star[m] != -1; k++) {
-      m = next_star[m];
+    for (k = 0; next_starpar[m] != -1; k++) {
+      m = next_starpar[m];
       if (m >= Nstarpar) {
 	fprintf (stderr, "WARNING: m out of bounds (1)\n");
@@ -483,22 +641,22 @@
 
     average[averef].Nstarpar = k + 2;
-    next_star[m] = Nm;
+    next_starpar[m] = Nm;
     if (m >= Nstarpar) {
       fprintf (stderr, "WARNING: m out of bounds (2)\n");
     }
   }
-  return (next_star);
+  return (next_starpar);
 }
 
 /* average[].starparOffset, average[].Nstarpar are valid within an addstar run */
-int add_star_link (Average *average, off_t *next_star, off_t Nstarpar, off_t NSTARPAR) {
+int add_starpar_link (Average *average, off_t *next_starpar, off_t Nstarpar, off_t NSTARPAR) {
 
   off_t k, m;
 
-  /* if we have trouble, check validity of next_star[m] : m < Nstarpar */
+  /* if we have trouble, check validity of next_starpar[m] : m < Nstarpar */
   m = average[0].starparOffset;  
 
   for (k = 0; k < average[0].Nstarpar - 1; k++)  {
-    m = next_star[m];
+    m = next_starpar[m];
     if (m >= NSTARPAR) {
       fprintf (stderr, "WARNING: m out of bounds (3)\n");
@@ -507,5 +665,5 @@
 
   /* set up references */
-  next_star[Nstarpar] = -1;
+  next_starpar[Nstarpar] = -1;
   if (Nstarpar >= NSTARPAR) {
     fprintf (stderr, "WARNING: Nstarpar out of bounds (1)\n");
@@ -516,5 +674,5 @@
     average[0].starparOffset = Nstarpar;
   } else {
-    next_star[m] = Nstarpar;
+    next_starpar[m] = Nstarpar;
     if (m >= NSTARPAR) {
       fprintf (stderr, "WARNING: m out of bounds (4)\n");
@@ -525,5 +683,5 @@
 }
 
-StarPar *sort_starpar (Average *average, off_t Naverage, StarPar *starpar, off_t Nstarpar, off_t *next_star) {
+StarPar *sort_starpar (Average *average, off_t Naverage, StarPar *starpar, off_t Nstarpar, off_t *next_starpar) {
 
   off_t i, k, n, np, N;
@@ -552,5 +710,5 @@
       tmpstarpar[N].averef = i;
       np = n;
-      n = next_star[n];
+      n = next_starpar[n];
     }
   }
@@ -566,5 +724,5 @@
 
   off_t i, j, N;
-  off_t *next_galp;
+  off_t *next_galphot;
 
   if (galphot) return NULL;
@@ -573,5 +731,5 @@
   N = 0;
 
-  ALLOCATE (next_galp, off_t, Ngalphot);
+  ALLOCATE (next_galphot, off_t, Ngalphot);
   for (i = 0; i < Naverage; i++) {
     if (!average[i].Ngalphot) continue;
@@ -580,10 +738,10 @@
     for (j = 0; j < average[i].Ngalphot - 1; j++, N++) {
       myAssert (galphot[m+j+1].averef == i, "not sorted");
-      next_galp[N] = N + 1;
+      next_galphot[N] = N + 1;
       if (N >= Ngalphot) {
 	fprintf (stderr, "WARNING: N out of bounds (1)\n");
       }
     }
-    next_galp[N] = -1;
+    next_galphot[N] = -1;
     if (N >= Ngalphot) {
       fprintf (stderr, "WARNING: N out of bounds (2)\n");
@@ -596,5 +754,5 @@
     N++;
   }
-  return (next_galp);
+  return (next_galphot);
 }
 
@@ -609,7 +767,7 @@
 
   off_t i, m, k, Nm, averef;
-  off_t *next_galp;
-
-  ALLOCATE (next_galp, off_t, Ngalphot);
+  off_t *next_galphot;
+
+  ALLOCATE (next_galphot, off_t, Ngalphot);
 
   /* reset the Nm, offset values for average */
@@ -622,5 +780,5 @@
     averef = galphot[Nm].averef;
     m = average[averef].galphotOffset;  
-    next_galp[Nm] = -1;
+    next_galphot[Nm] = -1;
 
     if (m == -1) { /* no links yet for source */
@@ -630,6 +788,6 @@
     }
 
-    for (k = 0; next_galp[m] != -1; k++) {
-      m = next_galp[m];
+    for (k = 0; next_galphot[m] != -1; k++) {
+      m = next_galphot[m];
       if (m >= Ngalphot) {
 	fprintf (stderr, "WARNING: m out of bounds (1)\n");
@@ -638,22 +796,22 @@
 
     average[averef].Ngalphot = k + 2;
-    next_galp[m] = Nm;
+    next_galphot[m] = Nm;
     if (m >= Ngalphot) {
       fprintf (stderr, "WARNING: m out of bounds (2)\n");
     }
   }
-  return (next_galp);
+  return (next_galphot);
 }
 
 /* average[].galphotOffset, average[].Ngalphot are valid within an addstar run */
-int add_galp_link (Average *average, off_t *next_galp, off_t Ngalphot, off_t NGALPHOT) {
+int add_galphot_link (Average *average, off_t *next_galphot, off_t Ngalphot, off_t NGALPHOT) {
 
   off_t k, m;
 
-  /* if we have trouble, check validity of next_galp[m] : m < Ngalphot */
+  /* if we have trouble, check validity of next_galphot[m] : m < Ngalphot */
   m = average[0].galphotOffset;  
 
   for (k = 0; k < average[0].Ngalphot - 1; k++)  {
-    m = next_galp[m];
+    m = next_galphot[m];
     if (m >= NGALPHOT) {
       fprintf (stderr, "WARNING: m out of bounds (3)\n");
@@ -662,5 +820,5 @@
 
   /* set up references */
-  next_galp[Ngalphot] = -1;
+  next_galphot[Ngalphot] = -1;
   if (Ngalphot >= NGALPHOT) {
     fprintf (stderr, "WARNING: Ngalphot out of bounds (1)\n");
@@ -671,5 +829,5 @@
     average[0].galphotOffset = Ngalphot;
   } else {
-    next_galp[m] = Ngalphot;
+    next_galphot[m] = Ngalphot;
     if (m >= NGALPHOT) {
       fprintf (stderr, "WARNING: m out of bounds (4)\n");
@@ -680,5 +838,5 @@
 }
 
-GalPhot *sort_galphot (Average *average, off_t Naverage, GalPhot *galphot, off_t Ngalphot, off_t *next_galp) {
+GalPhot *sort_galphot (Average *average, off_t Naverage, GalPhot *galphot, off_t Ngalphot, off_t *next_galphot) {
 
   off_t i, k, n, np, N;
@@ -704,5 +862,5 @@
       tmpgalphot[N].averef = i;
       np = n;
-      n = next_galp[n];
+      n = next_galphot[n];
     }
   }
Index: trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 39907)
+++ trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 39926)
@@ -336,4 +336,5 @@
     if (SKIP_MEASURE)               { strextend (&command, "-skip-measure"); }
     if (SKIP_LENSING)               { strextend (&command, "-skip-lensing"); }
+    if (SKIP_LENSOBJ)               { strextend (&command, "-skip-lensobj"); }
     if (SKIP_GALPHOT)               { strextend (&command, "-skip-galphot"); }
     if (SKIP_STARPAR)               { strextend (&command, "-skip-starpar"); }
Index: trunk/Ohana/src/dvomerge/src/merge_catalogs_old.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 39907)
+++ trunk/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 39926)
@@ -14,6 +14,6 @@
   double *X1, *Y1, *X2, *Y2;
   double dX, dY, dR;
-  off_t *N1, *N2, *next_meas, *next_lens, *next_star, *next_galp;
-  off_t Nave, NAVE, Nmeas, NMEAS, Nmatch, Nlens, NLENS, Nstar, NSTAR, Ngalp, NGALP;
+  off_t *N1, *N2, *next_measure, *next_lensing, *next_lensobj, *next_starpar, *next_galphot;
+  off_t Nave, NAVE, Nmeasure, NMEASURE, Nmatch, Nlensing, NLENSING, Nlensobj, NLENSOBJ, Nstarpar, NSTARPAR, Ngalphot, NGALPHOT;
   int NsecfiltIn;
   int NsecfiltOut;
@@ -51,8 +51,9 @@
   /* internal counters */
   Nmatch = 0;
-  NMEAS = Nmeas = output[0].Nmeasure;
-  NLENS = Nlens = output[0].Nlensing;
-  NSTAR = Nstar = output[0].Nstarpar;
-  NGALP = Ngalp = output[0].Ngalphot;
+  NMEASURE = Nmeasure = output[0].Nmeasure;
+  NLENSING = Nlensing = output[0].Nlensing;
+  NLENSOBJ = Nlensobj = output[0].Nlensobj;
+  NSTARPAR = Nstarpar = output[0].Nstarpar;
+  NGALPHOT = Ngalphot = output[0].Ngalphot;
 
   // current max obj ID for this catalog
@@ -116,13 +117,15 @@
     // this version is only valid if we have done a full catalog load, and if the catalog
     // is sorted while processed
-    next_meas = init_measure_links (output[0].average, Nave, output[0].measure, Nmeas);
-    next_lens = init_lensing_links (output[0].average, Nave, output[0].lensing, Nlens);
-    next_star = init_starpar_links (output[0].average, Nave, output[0].starpar, Nstar);
-    next_galp = init_galphot_links (output[0].average, Nave, output[0].galphot, Ngalp);
+    next_measure = init_measure_links (output[0].average, Nave, output[0].measure, Nmeasure);
+    next_lensing = init_lensing_links (output[0].average, Nave, output[0].lensing, Nlensing);
+    next_lensobj = init_lensobj_links (output[0].average, Nave, output[0].lensobj, Nlensobj);
+    next_starpar = init_starpar_links (output[0].average, Nave, output[0].starpar, Nstarpar);
+    next_galphot = init_galphot_links (output[0].average, Nave, output[0].galphot, Ngalphot);
   } else {
-    next_meas = build_measure_links (output[0].average, Nave, output[0].measure, Nmeas);
-    next_lens = build_lensing_links (output[0].average, Nave, output[0].lensing, Nlens);
-    next_star = build_starpar_links (output[0].average, Nave, output[0].starpar, Nstar);
-    next_galp = build_galphot_links (output[0].average, Nave, output[0].galphot, Ngalp);
+    next_measure = build_measure_links (output[0].average, Nave, output[0].measure, Nmeasure);
+    next_lensing = build_lensing_links (output[0].average, Nave, output[0].lensing, Nlensing);
+    next_lensobj = build_lensobj_links (output[0].average, Nave, output[0].lensobj, Nlensobj);
+    next_starpar = build_starpar_links (output[0].average, Nave, output[0].starpar, Nstarpar);
+    next_galphot = build_galphot_links (output[0].average, Nave, output[0].galphot, Ngalphot);
   }    
 
@@ -183,23 +186,28 @@
 
     /* make sure there is space for next Nmeasure entries */
-    if (Nmeas + input[0].average[N].Nmeasure >= NMEAS) {
-      NMEAS = Nmeas + input[0].average[N].Nmeasure + 1000;
-      REALLOCATE (next_meas, off_t, NMEAS);
-      REALLOCATE (output[0].measure, Measure, NMEAS);
-    }
-    if (Nlens + input[0].average[N].Nlensing >= NLENS) {
-      NLENS = Nlens + input[0].average[N].Nlensing + 1000;
-      REALLOCATE (next_lens, off_t, NLENS);
-      REALLOCATE (output[0].lensing, Lensing, NLENS);
-    }
-    if (Nstar + input[0].average[N].Nstarpar >= NSTAR) {
-      NSTAR = Nstar + input[0].average[N].Nstarpar + 1000;
-      REALLOCATE (next_star, off_t, NSTAR);
-      REALLOCATE (output[0].starpar, StarPar, NSTAR);
-    }
-    if (Ngalp + input[0].average[N].Ngalphot >= NGALP) {
-      NGALP = Ngalp + input[0].average[N].Ngalphot + 1000;
-      REALLOCATE (next_galp, off_t, NGALP);
-      REALLOCATE (output[0].galphot, GalPhot, NGALP);
+    if (Nmeasure + input[0].average[N].Nmeasure >= NMEASURE) {
+      NMEASURE = Nmeasure + input[0].average[N].Nmeasure + 1000;
+      REALLOCATE (next_measure, off_t, NMEASURE);
+      REALLOCATE (output[0].measure, Measure, NMEASURE);
+    }
+    if (Nlensing + input[0].average[N].Nlensing >= NLENSING) {
+      NLENSING = Nlensing + input[0].average[N].Nlensing + 1000;
+      REALLOCATE (next_lensing, off_t, NLENSING);
+      REALLOCATE (output[0].lensing, Lensing, NLENSING);
+    }
+    if (Nlensobj + input[0].average[N].Nlensobj >= NLENSOBJ) {
+      NLENSOBJ = Nlensobj + input[0].average[N].Nlensobj + 1000;
+      REALLOCATE (next_lensobj, off_t, NLENSOBJ);
+      REALLOCATE (output[0].lensobj, Lensobj, NLENSOBJ);
+    }
+    if (Nstarpar + input[0].average[N].Nstarpar >= NSTARPAR) {
+      NSTARPAR = Nstarpar + input[0].average[N].Nstarpar + 1000;
+      REALLOCATE (next_starpar, off_t, NSTARPAR);
+      REALLOCATE (output[0].starpar, StarPar, NSTARPAR);
+    }
+    if (Ngalphot + input[0].average[N].Ngalphot >= NGALPHOT) {
+      NGALPHOT = Ngalphot + input[0].average[N].Ngalphot + 1000;
+      REALLOCATE (next_galphot, off_t, NGALPHOT);
+      REALLOCATE (output[0].galphot, GalPhot, NGALPHOT);
     }
 
@@ -212,7 +220,7 @@
       if (REPLACE_TYCHO) {
 	int Minp =  input[0].average[N].measureOffset;
-	Nreplace = replace_tycho (&output[0].average[n], output[0].measure, next_meas, &input[0].average[N], &input[0].measure[Minp]);
+	Nreplace = replace_tycho (&output[0].average[n], output[0].measure, next_measure, &input[0].average[N], &input[0].measure[Minp]);
 	if (Nreplace == 6) {
-	  output[0].found_t[n] = Nmeas;
+	  output[0].found_t[n] = Nmeasure;
 	  i++;
 	  continue;
@@ -227,13 +235,13 @@
 	  // index to first measure for this object
 	  // XXX this does not support lensing, starpar, or galphot measurements
-	  if (replace_match (&output[0].average[n], output[0].measure, next_meas, &input[0].average[N], &input[0].measure[offset])) {
+	  if (replace_match (&output[0].average[n], output[0].measure, next_measure, &input[0].average[N], &input[0].measure[offset])) {
 	    continue;
 	  }
 	}
 	/* add to end of measurement list */
-	add_meas_link (&output[0].average[n], next_meas, Nmeas, NMEAS);
+	add_measure_link (&output[0].average[n], next_measure, Nmeasure, NMEASURE);
 	
 	// set the new measurements
-	output[0].measure[Nmeas] = input[0].measure[offset];
+	output[0].measure[Nmeasure] = input[0].measure[offset];
 
 	// old code: find R,D using average_in[0], the get offset relative to average_out[0].  no longer
@@ -241,27 +249,27 @@
 	// Rin = input[0].average[N].R - input[0].measure[offset].dR / 3600.0;
 	// Din = input[0].average[N].D - input[0].measure[offset].dD / 3600.0;
-	// output[0].measure[Nmeas].dR = 3600.0*(output[0].average[n].R - Rin);
-	// output[0].measure[Nmeas].dD = 3600.0*(output[0].average[n].D - Din);
-
-	output[0].measure[Nmeas].dbFlags  = 0;  // XXX why reset these?
-	output[0].measure[Nmeas].averef   = n;
-	output[0].measure[Nmeas].objID    = output[0].average[n].objID;
-	output[0].measure[Nmeas].catID    = output[0].catID;
-
-	assert (output[0].measure[Nmeas].averef < Nave);
-
-	// fprintf (stderr, "Nave : "OFF_T_FMT", Nmeas : "OFF_T_FMT", dR: %f, dD: %f, catID: %d\n",  n,  Nmeas, output[0].measure[Nmeas].dR, output[0].measure[Nmeas].dD, output[0].measure[i].catID);
-
-	float dRoff = dvoOffsetR(&output[0].measure[Nmeas], &output[0].average[n]);
+	// output[0].measure[Nmeasure].dR = 3600.0*(output[0].average[n].R - Rin);
+	// output[0].measure[Nmeasure].dD = 3600.0*(output[0].average[n].D - Din);
+
+	output[0].measure[Nmeasure].dbFlags  = 0;  // XXX why reset these?
+	output[0].measure[Nmeasure].averef   = n;
+	output[0].measure[Nmeasure].objID    = output[0].average[n].objID;
+	output[0].measure[Nmeasure].catID    = output[0].catID;
+
+	assert (output[0].measure[Nmeasure].averef < Nave);
+
+	// fprintf (stderr, "Nave : "OFF_T_FMT", Nmeasure : "OFF_T_FMT", dR: %f, dD: %f, catID: %d\n",  n,  Nmeasure, output[0].measure[Nmeasure].dR, output[0].measure[Nmeasure].dD, output[0].measure[i].catID);
+
+	float dRoff = dvoOffsetR(&output[0].measure[Nmeasure], &output[0].average[n]);
 
 	// rationalize R
 	if (dRoff > +180.0*3600.0) {
 	  // average on high end of boundary, move star up
-	  output[0].measure[Nmeas].R += 360.0;
+	  output[0].measure[Nmeasure].R += 360.0;
 	  dRoff -= 360.0*3600.0;
 	}
 	if (dRoff < -180.0*3600.0) {
 	  // average on low end of boundary, move star down
-	  output[0].measure[Nmeas].R -= 360.0;
+	  output[0].measure[Nmeasure].R -= 360.0;
 	  dRoff += 360.0*3600.0;
 	}
@@ -272,5 +280,5 @@
 	    fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
 		     output[0].average[n].R, output[0].average[n].D, 
-		     output[0].measure[Nmeas].R, output[0].measure[Nmeas].D,
+		     output[0].measure[Nmeasure].R, output[0].measure[Nmeasure].D,
 		     X1[i], X2[Jmin], Y1[i], Y2[Jmin]);
 	    // XXX abort on this? -- this is a bad failure...
@@ -278,5 +286,5 @@
 	}
 	output[0].average[n].Nmeasure ++;
-	Nmeas ++;
+	Nmeasure ++;
       }
     }
@@ -286,15 +294,33 @@
       for (Nin = 0; Nin < input[0].average[N].Nlensing; Nin++) {
 	/* add to end of lensing list */
-	add_lens_link (&output[0].average[n], next_lens, Nlens, NLENS);
+	add_lensing_link (&output[0].average[n], next_lensing, Nlensing, NLENSING);
 	
 	// set the new lensing
 	off_t lensoff = input[0].average[N].lensingOffset + Nin;
-	output[0].lensing[Nlens] = input[0].lensing[lensoff];
-
-	output[0].lensing[Nlens].averef   = n;
-	output[0].lensing[Nlens].objID    = output[0].average[n].objID;
-	output[0].lensing[Nlens].catID    = output[0].catID;
+	output[0].lensing[Nlensing] = input[0].lensing[lensoff];
+
+	output[0].lensing[Nlensing].averef   = n;
+	output[0].lensing[Nlensing].objID    = output[0].average[n].objID;
+	output[0].lensing[Nlensing].catID    = output[0].catID;
 	output[0].average[n].Nlensing ++;
-	Nlens ++;
+	Nlensing ++;
+      }
+    }
+
+    // if lensobj measurements exist, add them too
+    if (output[0].lensobj && !SKIP_LENSOBJ) {
+      for (Nin = 0; Nin < input[0].average[N].Nlensobj; Nin++) {
+	/* add to end of lensobj list */
+	add_lensobj_link (&output[0].average[n], next_lensobj, Nlensobj, NLENSOBJ);
+	
+	// set the new lensobj
+	off_t lensoff = input[0].average[N].lensobjOffset + Nin;
+	output[0].lensobj[Nlensobj] = input[0].lensobj[lensoff];
+
+	// output[0].lensobj[Nlensobj].averef   = n;
+	output[0].lensobj[Nlensobj].objID    = output[0].average[n].objID;
+	output[0].lensobj[Nlensobj].catID    = output[0].catID;
+	output[0].average[n].Nlensobj ++;
+	Nlensobj ++;
       }
     }
@@ -304,15 +330,15 @@
       for (Nin = 0; Nin < input[0].average[N].Nstarpar; Nin++) {
 	/* add to end of lensing list */
-	add_star_link (&output[0].average[n], next_star, Nstar, NSTAR);
+	add_starpar_link (&output[0].average[n], next_starpar, Nstarpar, NSTARPAR);
 	
 	// set the new starpar
 	off_t staroff = input[0].average[N].starparOffset + Nin;
-	output[0].starpar[Nstar] = input[0].starpar[staroff];
-
-	output[0].starpar[Nstar].averef   = n;
-	output[0].starpar[Nstar].objID    = output[0].average[n].objID;
-	output[0].starpar[Nstar].catID    = output[0].catID;
+	output[0].starpar[Nstarpar] = input[0].starpar[staroff];
+
+	output[0].starpar[Nstarpar].averef   = n;
+	output[0].starpar[Nstarpar].objID    = output[0].average[n].objID;
+	output[0].starpar[Nstarpar].catID    = output[0].catID;
 	output[0].average[n].Nstarpar ++;
-	Nstar ++;
+	Nstarpar ++;
       }
     }
@@ -322,15 +348,15 @@
       for (Nin = 0; Nin < input[0].average[N].Ngalphot; Nin++) {
 	/* add to end of galphot list */
-	add_galp_link (&output[0].average[n], next_galp, Ngalp, NGALP);
+	add_galphot_link (&output[0].average[n], next_galphot, Ngalphot, NGALPHOT);
 	
 	// set the new galphot
 	off_t galpoff = input[0].average[N].galphotOffset + Nin;
-	output[0].galphot[Ngalp] = input[0].galphot[galpoff];
-
-	output[0].galphot[Ngalp].averef   = n;
-	output[0].galphot[Ngalp].objID    = output[0].average[n].objID;
-	output[0].galphot[Ngalp].catID    = output[0].catID;
+	output[0].galphot[Ngalphot] = input[0].galphot[galpoff];
+
+	output[0].galphot[Ngalphot].averef   = n;
+	output[0].galphot[Ngalphot].objID    = output[0].average[n].objID;
+	output[0].galphot[Ngalphot].catID    = output[0].catID;
 	output[0].average[n].Ngalphot ++;
-	Ngalp ++;
+	Ngalphot ++;
       }
     }
@@ -373,8 +399,8 @@
     /* Nm is updated, but not written out in -update mode (for existing entries)
        Nm is recalculated in build_meas_links if loaded table is not sorted */
-    output[0].found_t[n] = Nmeas;
+    output[0].found_t[n] = Nmeasure;
     i++;
   }
-  // MARKTIME("find matched stars: %f sec for "OFF_T_FMT","OFF_T_FMT" stars ("OFF_T_FMT" meas)\n", dtime, Nstars, Nave, Nmeas);
+  // MARKTIME("find matched stars: %f sec for "OFF_T_FMT","OFF_T_FMT" stars ("OFF_T_FMT" meas)\n", dtime, Nstars, Nave, Nmeasure);
 
   /** incorporate unmatched image stars, if this star is in field of this catalog **/
@@ -384,23 +410,28 @@
 
     /* make sure there is space for next entry */
-    if (Nmeas + input[0].average[N].Nmeasure >= NMEAS) {
-      NMEAS = Nmeas + input[0].average[N].Nmeasure + 1000;
-      REALLOCATE (next_meas, off_t, NMEAS);
-      REALLOCATE (output[0].measure, Measure, NMEAS);
-    }
-    if (Nlens + input[0].average[N].Nlensing >= NLENS) {
-      NLENS = Nlens + input[0].average[N].Nlensing + 1000;
-      REALLOCATE (next_lens, off_t, NLENS);
-      REALLOCATE (output[0].lensing, Lensing, NLENS);
-    }
-    if (Nstar + input[0].average[N].Nstarpar >= NSTAR) {
-      NSTAR = Nstar + input[0].average[N].Nstarpar + 1000;
-      REALLOCATE (next_star, off_t, NSTAR);
-      REALLOCATE (output[0].starpar, StarPar, NSTAR);
-    }
-    if (Ngalp + input[0].average[N].Ngalphot >= NGALP) {
-      NGALP = Ngalp + input[0].average[N].Ngalphot + 1000;
-      REALLOCATE (next_galp, off_t, NGALP);
-      REALLOCATE (output[0].galphot, GalPhot, NGALP);
+    if (Nmeasure + input[0].average[N].Nmeasure >= NMEASURE) {
+      NMEASURE = Nmeasure + input[0].average[N].Nmeasure + 1000;
+      REALLOCATE (next_measure, off_t, NMEASURE);
+      REALLOCATE (output[0].measure, Measure, NMEASURE);
+    }
+    if (Nlensing + input[0].average[N].Nlensing >= NLENSING) {
+      NLENSING = Nlensing + input[0].average[N].Nlensing + 1000;
+      REALLOCATE (next_lensing, off_t, NLENSING);
+      REALLOCATE (output[0].lensing, Lensing, NLENSING);
+    }
+    if (Nlensobj + input[0].average[N].Nlensobj >= NLENSOBJ) {
+      NLENSOBJ = Nlensobj + input[0].average[N].Nlensobj + 1000;
+      REALLOCATE (next_lensobj, off_t, NLENSOBJ);
+      REALLOCATE (output[0].lensobj, Lensobj, NLENSOBJ);
+    }
+    if (Nstarpar + input[0].average[N].Nstarpar >= NSTARPAR) {
+      NSTARPAR = Nstarpar + input[0].average[N].Nstarpar + 1000;
+      REALLOCATE (next_starpar, off_t, NSTARPAR);
+      REALLOCATE (output[0].starpar, StarPar, NSTARPAR);
+    }
+    if (Ngalphot + input[0].average[N].Ngalphot >= NGALPHOT) {
+      NGALPHOT = Ngalphot + input[0].average[N].Ngalphot + 1000;
+      REALLOCATE (next_galphot, off_t, NGALPHOT);
+      REALLOCATE (output[0].galphot, GalPhot, NGALPHOT);
     }
     if (Nave >= NAVE) {
@@ -465,27 +496,27 @@
     /** add measurements for this input average object **/
     if (output[0].measure && !SKIP_MEASURE && input[0].average[N].Nmeasure) {
-      output[0].average[Nave].measureOffset  = Nmeas;
+      output[0].average[Nave].measureOffset  = Nmeasure;
       for (Nin = 0; Nin < input[0].average[N].Nmeasure; Nin ++) {
 	offset = input[0].average[N].measureOffset + Nin;
 	
 	// supply the measurments from this detection
-	output[0].measure[Nmeas]           = input[0].measure[offset];
+	output[0].measure[Nmeasure]           = input[0].measure[offset];
 	
 	// the following measure elements cannot be set until here:
-	output[0].measure[Nmeas].dbFlags  = 0;
-	output[0].measure[Nmeas].averef   = Nave;
-	output[0].measure[Nmeas].objID    = output[0].average[Nave].objID;
-	output[0].measure[Nmeas].catID    = output[0].catID;
+	output[0].measure[Nmeasure].dbFlags  = 0;
+	output[0].measure[Nmeasure].averef   = Nave;
+	output[0].measure[Nmeasure].objID    = output[0].average[Nave].objID;
+	output[0].measure[Nmeasure].catID    = output[0].catID;
 	
 	// as we add measurements, update Nmeasure to match
 	output[0].average[Nave].Nmeasure ++;
 
-	/* we set next[Nmeas] to -1 here, and update correctly below */
-	next_meas[Nmeas] = -1;
-	Nmeas ++;
+	/* we set next[Nmeasure] to -1 here, and update correctly below */
+	next_measure[Nmeasure] = -1;
+	Nmeasure ++;
       }
       int Ngroup = input[0].average[N].Nmeasure;
       for (j = 0; j < Ngroup - 1; j++) {
-	next_meas[Nmeas - Ngroup + j] = Nmeas - Ngroup + j + 1;
+	next_measure[Nmeasure - Ngroup + j] = Nmeasure - Ngroup + j + 1;
       }
     }
@@ -493,25 +524,51 @@
     /** add lensing for this input average object **/
     if (output[0].lensing && !SKIP_LENSING && input[0].average[N].Nlensing) {
-      output[0].average[Nave].lensingOffset  = Nlens;
+      output[0].average[Nave].lensingOffset  = Nlensing;
       for (Nin = 0; Nin < input[0].average[N].Nlensing; Nin ++) {
 	// supply the lensing values from this detection
 	off_t lensoff = input[0].average[N].lensingOffset + Nin;
-	output[0].lensing[Nlens]           = input[0].lensing[lensoff];
+	output[0].lensing[Nlensing]           = input[0].lensing[lensoff];
 
 	// the following lensing elements cannot be set until here:
-	output[0].lensing[Nlens].averef   = Nave;
-	output[0].lensing[Nlens].objID    = output[0].average[Nave].objID;
-	output[0].lensing[Nlens].catID    = output[0].catID;
+	output[0].lensing[Nlensing].averef   = Nave;
+	output[0].lensing[Nlensing].objID    = output[0].average[Nave].objID;
+	output[0].lensing[Nlensing].catID    = output[0].catID;
 
 	// as we add lensing, update Nlensing to match
 	output[0].average[Nave].Nlensing ++;
 
-	/* we set next[Nlens] to -1 here, and update correctly below */
-	next_lens[Nlens] = -1;
-	Nlens ++;
+	/* we set next[Nlensing] to -1 here, and update correctly below */
+	next_lensing[Nlensing] = -1;
+	Nlensing ++;
       }
       int Ngroup = input[0].average[N].Nlensing;
       for (j = 0; j < Ngroup - 1; j++) {
-	next_lens[Nlens - Ngroup + j] = Nlens - Ngroup + j + 1;
+	next_lensing[Nlensing - Ngroup + j] = Nlensing - Ngroup + j + 1;
+      }
+    }
+
+    /** add lensobj for this input average object **/
+    if (output[0].lensobj && !SKIP_LENSOBJ && input[0].average[N].Nlensobj) {
+      output[0].average[Nave].lensobjOffset  = Nlensobj;
+      for (Nin = 0; Nin < input[0].average[N].Nlensobj; Nin ++) {
+	// supply the lensobj values from this detection
+	off_t lensoff = input[0].average[N].lensobjOffset + Nin;
+	output[0].lensobj[Nlensobj]           = input[0].lensobj[lensoff];
+
+	// the following lensobj elements cannot be set until here:
+	// output[0].lensobj[Nlensobj].averef   = Nave;
+	output[0].lensobj[Nlensobj].objID    = output[0].average[Nave].objID;
+	output[0].lensobj[Nlensobj].catID    = output[0].catID;
+
+	// as we add lensobj, update Nlensobj to match
+	output[0].average[Nave].Nlensobj ++;
+
+	/* we set next[Nlensobj] to -1 here, and update correctly below */
+	next_lensobj[Nlensobj] = -1;
+	Nlensobj ++;
+      }
+      int Ngroup = input[0].average[N].Nlensobj;
+      for (j = 0; j < Ngroup - 1; j++) {
+	next_lensobj[Nlensobj - Ngroup + j] = Nlensobj - Ngroup + j + 1;
       }
     }
@@ -519,25 +576,25 @@
     /** add starpar for this input average object **/
     if (output[0].starpar && !SKIP_STARPAR && input[0].average[N].Nstarpar) {
-      output[0].average[Nave].starparOffset  = Nstar;
+      output[0].average[Nave].starparOffset  = Nstarpar;
       for (Nin = 0; Nin < input[0].average[N].Nstarpar; Nin ++) {
 	// supply the starpar values from this detection
 	off_t staroff = input[0].average[N].starparOffset + Nin;
-	output[0].starpar[Nstar]           = input[0].starpar[staroff];
+	output[0].starpar[Nstarpar]           = input[0].starpar[staroff];
 
 	// the following starpar elements cannot be set until here:
-	output[0].starpar[Nstar].averef   = Nave;
-	output[0].starpar[Nstar].objID    = output[0].average[Nave].objID;
-	output[0].starpar[Nstar].catID    = output[0].catID;
+	output[0].starpar[Nstarpar].averef   = Nave;
+	output[0].starpar[Nstarpar].objID    = output[0].average[Nave].objID;
+	output[0].starpar[Nstarpar].catID    = output[0].catID;
 
 	// as we add starpar, update Nstarpar to match
 	output[0].average[Nave].Nstarpar ++;
 
-	/* we set next[Nstar] to -1 here, and update correctly below */
-	next_star[Nstar] = -1;
-	Nstar ++;
+	/* we set next[Nstarpar] to -1 here, and update correctly below */
+	next_starpar[Nstarpar] = -1;
+	Nstarpar ++;
       }
       int Ngroup = input[0].average[N].Nstarpar;
       for (j = 0; j < Ngroup - 1; j++) {
-	next_star[Nstar - Ngroup + j] = Nstar - Ngroup + j + 1;
+	next_starpar[Nstarpar - Ngroup + j] = Nstarpar - Ngroup + j + 1;
       }
     }
@@ -545,25 +602,25 @@
     /** add galphot for this input average object **/
     if (output[0].galphot && !SKIP_GALPHOT && input[0].average[N].Ngalphot) {
-      output[0].average[Nave].galphotOffset  = Ngalp;
+      output[0].average[Nave].galphotOffset  = Ngalphot;
       for (Nin = 0; Nin < input[0].average[N].Ngalphot; Nin ++) {
 	// supply the galphot values from this detection
 	off_t galpoff = input[0].average[N].galphotOffset + Nin;
-	output[0].galphot[Ngalp]           = input[0].galphot[galpoff];
+	output[0].galphot[Ngalphot]           = input[0].galphot[galpoff];
 
 	// the following galphot elements cannot be set until here:
-	output[0].galphot[Ngalp].averef   = Nave;
-	output[0].galphot[Ngalp].objID    = output[0].average[Nave].objID;
-	output[0].galphot[Ngalp].catID    = output[0].catID;
+	output[0].galphot[Ngalphot].averef   = Nave;
+	output[0].galphot[Ngalphot].objID    = output[0].average[Nave].objID;
+	output[0].galphot[Ngalphot].catID    = output[0].catID;
 
 	// as we add galphot, update Ngalphot to match
 	output[0].average[Nave].Ngalphot ++;
 
-	/* we set next[Ngalp] to -1 here, and update correctly below */
-	next_galp[Ngalp] = -1;
-	Ngalp ++;
+	/* we set next[Ngalphot] to -1 here, and update correctly below */
+	next_galphot[Ngalphot] = -1;
+	Ngalphot ++;
       }
       int Ngroup = input[0].average[N].Ngalphot;
       for (j = 0; j < Ngroup - 1; j++) {
-	next_galp[Ngalp - Ngroup + j] = Ngalp - Ngroup + j + 1;
+	next_galphot[Ngalphot - Ngroup + j] = Ngalphot - Ngroup + j + 1;
       }
     }
@@ -575,8 +632,9 @@
 
   REALLOCATE (output[0].average, Average, Nave);
-  if (!SKIP_MEASURE) { REALLOCATE (output[0].measure, Measure, Nmeas); }
-  if (!SKIP_LENSING) { REALLOCATE (output[0].lensing, Lensing, Nlens); }
-  if (!SKIP_STARPAR) { REALLOCATE (output[0].starpar, StarPar, Nstar); }
-  if (!SKIP_GALPHOT) { REALLOCATE (output[0].galphot, GalPhot, Ngalp); }
+  if (!SKIP_MEASURE) { REALLOCATE (output[0].measure, Measure, Nmeasure); }
+  if (!SKIP_LENSING) { REALLOCATE (output[0].lensing, Lensing, Nlensing); }
+  if (!SKIP_LENSOBJ) { REALLOCATE (output[0].lensobj, Lensobj, Nlensobj); }
+  if (!SKIP_STARPAR) { REALLOCATE (output[0].starpar, StarPar, Nstarpar); }
+  if (!SKIP_GALPHOT) { REALLOCATE (output[0].galphot, GalPhot, Ngalphot); }
  
 # define NOSORT 0
@@ -585,8 +643,9 @@
   } else {
     output[0].sorted = TRUE;
-    if (!SKIP_MEASURE) { output[0].measure = sort_measure (output[0].average, Nave, output[0].measure, Nmeas, next_meas); }
-    if (!SKIP_LENSING) { output[0].lensing = sort_lensing (output[0].average, Nave, output[0].lensing, Nlens, next_lens); }
-    if (!SKIP_STARPAR) { output[0].starpar = sort_starpar (output[0].average, Nave, output[0].starpar, Nstar, next_star); }
-    if (!SKIP_GALPHOT) { output[0].galphot = sort_galphot (output[0].average, Nave, output[0].galphot, Ngalp, next_galp); }
+    if (!SKIP_MEASURE) { output[0].measure = sort_measure (output[0].average, Nave, output[0].measure, Nmeasure, next_measure); }
+    if (!SKIP_LENSING) { output[0].lensing = sort_lensing (output[0].average, Nave, output[0].lensing, Nlensing, next_lensing); }
+    if (!SKIP_LENSOBJ) { output[0].lensobj = sort_lensobj (output[0].average, Nave, output[0].lensobj, Nlensobj, next_lensobj); }
+    if (!SKIP_STARPAR) { output[0].starpar = sort_starpar (output[0].average, Nave, output[0].starpar, Nstarpar, next_starpar); }
+    if (!SKIP_GALPHOT) { output[0].galphot = sort_galphot (output[0].average, Nave, output[0].galphot, Ngalphot, next_galphot); }
   }
 
@@ -594,15 +653,17 @@
   output[0].objID    = objID; // new max value, save on catalog close
   output[0].Naverage = Nave;
-  if (!SKIP_MEASURE) { output[0].Nmeasure = Nmeas; }
-  if (!SKIP_LENSING) { output[0].Nlensing = Nlens; }
-  if (!SKIP_STARPAR) { output[0].Nstarpar = Nstar; }
-  if (!SKIP_GALPHOT) { output[0].Ngalphot = Ngalp; }
+  if (!SKIP_MEASURE) { output[0].Nmeasure = Nmeasure; }
+  if (!SKIP_LENSING) { output[0].Nlensing = Nlensing; }
+  if (!SKIP_LENSOBJ) { output[0].Nlensobj = Nlensobj; }
+  if (!SKIP_STARPAR) { output[0].Nstarpar = Nstarpar; }
+  if (!SKIP_GALPHOT) { output[0].Ngalphot = Ngalphot; }
   output[0].Nsecfilt_mem = Nave*NsecfiltOut;
-  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas, Nlens, Ngalp: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nlens, Ngalp, Nmatch);
-
-  free (next_meas);
-  free (next_lens);
-  free (next_star);
-  free (next_galp);
+  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeasure, Nlensing, Ngalphot: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeasure,  Nlensing, Ngalphot, Nmatch);
+
+  free (next_measure);
+  free (next_lensing);
+  free (next_lensobj);
+  free (next_starpar);
+  free (next_galphot);
 
   free (X2);
@@ -625,5 +686,5 @@
    images have boundaries which are lines in pixels coords, but curve in RA and DEC
    
-   output[0].found_t[Ncat] but stars[Nstar].found
+   output[0].found_t[Ncat] but stars[Nstars].found
    
 */
Index: trunk/Ohana/src/fakeastro/Makefile
===================================================================
--- trunk/Ohana/src/fakeastro/Makefile	(revision 39907)
+++ trunk/Ohana/src/fakeastro/Makefile	(revision 39926)
@@ -53,5 +53,7 @@
 $(SRC)/match_fake_stars.$(ARCH).o \
 $(SRC)/fakeastro_2mass.$(ARCH).o \
+$(SRC)/fakeastro_gaia.$(ARCH).o \
 $(SRC)/make_2mass_measures.$(ARCH).o \
+$(SRC)/make_gaia_measures.$(ARCH).o \
 $(SRC)/remote_hosts.$(ARCH).o 
 
Index: trunk/Ohana/src/fakeastro/include/fakeastro.h
===================================================================
--- trunk/Ohana/src/fakeastro/include/fakeastro.h	(revision 39907)
+++ trunk/Ohana/src/fakeastro/include/fakeastro.h	(revision 39926)
@@ -8,5 +8,5 @@
 # define RESETTIME { gettimeofday (&startTimer, (void *) NULL); }
 
-typedef enum {OP_NONE, OP_GALAXY, OP_IMAGES, OP_2MASS} FakeastroOp;
+typedef enum {OP_NONE, OP_GALAXY, OP_IMAGES, OP_2MASS, OP_GAIA} FakeastroOp;
 
 typedef struct {
@@ -87,6 +87,8 @@
 int    VERBOSE;
 int    VERBOSE2;
-int    TESTING;
 int    ONE_BIG_CHIP;
+
+float  TEST_SCALE;
+char  *GALAXY_MODEL;
 
 int    FORCE;
@@ -101,7 +103,9 @@
 char   FAKEASTRO_REF_EPOCH[80];
 char   FAKEASTRO_2MASS_EPOCH[80];
+char   FAKEASTRO_GAIA_EPOCH[80];
 
 float  RADIUS;
 float  MAX_MAG_2MASS;
+float  MAX_MAG_GAIA;
 
 SkyRegion UserPatch;
@@ -198,2 +202,5 @@
 int fakeastro_2mass ();
 int make_2mass_measures (Catalog *catalog);
+
+int fakeastro_gaia ();
+int make_gaia_measures (Catalog *catalog);
Index: trunk/Ohana/src/fakeastro/src/ConfigInit.c
===================================================================
--- trunk/Ohana/src/fakeastro/src/ConfigInit.c	(revision 39907)
+++ trunk/Ohana/src/fakeastro/src/ConfigInit.c	(revision 39926)
@@ -19,5 +19,5 @@
   // if (!ScanConfig (config, "ADDSTAR_RADIUS",         "%lf", 0, &ADDSTAR_RADIUS))   ADDSTAR_RADIUS = 1.0;
 
-  if ((FAKEASTRO_OP == OP_GALAXY) || (FAKEASTRO_OP == OP_2MASS)) {
+  if ((FAKEASTRO_OP == OP_GALAXY) || (FAKEASTRO_OP == OP_2MASS) || (FAKEASTRO_OP == OP_GAIA)) {
     // force CATDIR to be absolute (so parallel mode will work)
     GetConfig (config, "CATDIR",                 "%s",  0, CATDIR);
@@ -60,4 +60,7 @@
     strcpy (FAKEASTRO_2MASS_EPOCH, "2000/01/01,00:00:00"); // epoch of 2MASS astrometry
   }
+  if (!ScanConfig (config, "FAKEASTRO_GAIA_EPOCH", "%s", 0, FAKEASTRO_GAIA_EPOCH)) {
+    strcpy (FAKEASTRO_GAIA_EPOCH, "2015/01/01,00:00:00"); // epoch of GAIA astrometry
+  }
 
   /* set the default search radius */
@@ -76,5 +79,5 @@
 
   // OP_2MASS is adding detections to an existing db, the others require and empty db
-  if (FAKEASTRO_OP != OP_2MASS) {
+  if ((FAKEASTRO_OP != OP_2MASS) && (FAKEASTRO_OP != OP_GAIA)) {
     // check for existence of CATDIR
     struct stat filestat;
Index: trunk/Ohana/src/fakeastro/src/args.c
===================================================================
--- trunk/Ohana/src/fakeastro/src/args.c	(revision 39907)
+++ trunk/Ohana/src/fakeastro/src/args.c	(revision 39926)
@@ -26,8 +26,22 @@
   }
 
-  TESTING = FALSE;
+  if ((N = get_argument (*argc, argv, "-gaia"))) {
+    remove_argument (N, argc, argv);
+    FAKEASTRO_OP = OP_GAIA;
+  }
+
+  GALAXY_MODEL = NULL;
+  if ((N = get_argument (*argc, argv, "-galaxy-model"))) {
+    remove_argument (N, argc, argv);
+    GALAXY_MODEL = strcreate(argv[N]);
+    remove_argument (N, argc, argv);
+  }
+  if (!GALAXY_MODEL) GALAXY_MODEL = strcreate ("ROESER");
+
+  TEST_SCALE = 1.0;
   if ((N = get_argument (*argc, argv, "-testing"))) {
     remove_argument (N, argc, argv);
-    TESTING = TRUE;
+    TEST_SCALE = atof(argv[N]);
+    remove_argument (N, argc, argv);
   }
   ONE_BIG_CHIP = FALSE;
@@ -114,4 +128,11 @@
   }
 
+  MAX_MAG_GAIA = 21.0;
+  if ((N = get_argument (*argc, argv, "-gaia-limit"))) {
+    remove_argument (N, argc, argv);
+    MAX_MAG_GAIA = atof(argv[N]);
+    remove_argument (N, argc, argv);
+  }
+
   FORCE = FALSE;
   if ((N = get_argument (*argc, argv, "-force"))) {
@@ -250,4 +271,12 @@
   // }
 
+  GALAXY_MODEL = NULL;
+  if ((N = get_argument (*argc, argv, "-galaxy-model"))) {
+    remove_argument (N, argc, argv);
+    GALAXY_MODEL = strcreate(argv[N]);
+    remove_argument (N, argc, argv);
+  }
+  if (!GALAXY_MODEL) GALAXY_MODEL = strcreate ("FEAST-HIPPARCOS");
+
   VERBOSE = VERBOSE2 = FALSE;
   if ((N = get_argument (*argc, argv, "-v"))) {
@@ -273,5 +302,6 @@
   fprintf (stderr, " additional options: \n");
   fprintf (stderr, "  -region RA RA DEC DEC\n");
-  fprintf (stderr, "  -catalog (ra) (dec)\n\n");
+  fprintf (stderr, "  -catalog (ra) (dec)\n");
+  fprintf (stderr, "  -testing (scale)\n\n");
   fprintf (stderr, "  -v\n");
   fprintf (stderr, "  -vv\n");
Index: trunk/Ohana/src/fakeastro/src/fakeastro.c
===================================================================
--- trunk/Ohana/src/fakeastro/src/fakeastro.c	(revision 39907)
+++ trunk/Ohana/src/fakeastro/src/fakeastro.c	(revision 39926)
@@ -41,4 +41,10 @@
       exit (0);
 
+    case OP_GAIA:
+      fakeastro_gaia ();
+      /* make_gaia_measures()
+       */
+      exit (0);
+
     default:
       fprintf (stderr, "impossible!\n");
Index: trunk/Ohana/src/fakeastro/src/fakeastro_gaia.c
===================================================================
--- trunk/Ohana/src/fakeastro/src/fakeastro_gaia.c	(revision 39926)
+++ trunk/Ohana/src/fakeastro/src/fakeastro_gaia.c	(revision 39926)
@@ -0,0 +1,57 @@
+# include "fakeastro.h"
+
+int fakeastro_gaia () {
+
+  INITTIME;
+
+  SkyTable *skyTable = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (skyTable, CATDIR, "cpt");
+
+  SkyList *skylist  = SkyListByPatch (skyTable, -1, &UserPatch);
+
+  Catalog catalog;
+
+  // load stars from database in these regions
+  int i;
+  for (i = 0; i < skylist->Nregions; i++) {
+    dvo_catalog_init (&catalog, TRUE);
+
+    // set the parameters which guide catalog open/load/create
+    dvo_catalog_init (&catalog, TRUE);
+    catalog.filename  = skylist[0].filename[i];
+    catalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
+    catalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
+    catalog.catflags  = DVO_LOAD_AVERAGE | DVO_LOAD_SECFILT | DVO_LOAD_MEASURE | DVO_LOAD_STARPAR;
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
+      fprintf (stderr, "ERROR: failure reading catalog %s\n", catalog.filename);
+      exit (1);
+    }
+    if (!catalog.Naverage_disk) {
+	if (VERBOSE2) { fprintf (stderr, "no data in %s, skipping\n", catalog.filename); }
+	dvo_catalog_unlock (&catalog);
+	dvo_catalog_free (&catalog);
+	continue;
+    }
+
+    make_gaia_measures (&catalog);
+
+    SetProtect (TRUE);
+    if (!dvo_catalog_update (&catalog, VERBOSE)) {
+      fprintf (stderr, "ERROR: failure to update %s\n", catalog.filename);
+      exit (3);
+    }
+    SetProtect (FALSE);
+
+    if (!dvo_catalog_unlock (&catalog)) {
+      fprintf (stderr, "ERROR: failure to unlock %s\n", catalog.filename);
+      exit (2);
+    }
+    dvo_catalog_free (&catalog);
+    if (VERBOSE) MARKTIME ("save cpt: %f sec\n", dtime); RESETTIME; 
+  }
+
+  exit (0);
+}
+
+
Index: trunk/Ohana/src/fakeastro/src/initialize.c
===================================================================
--- trunk/Ohana/src/fakeastro/src/initialize.c	(revision 39907)
+++ trunk/Ohana/src/fakeastro/src/initialize.c	(revision 39926)
@@ -17,6 +17,6 @@
 
   // XXX add to config?
-  if (!InitGalaxyModel ("ROESER")) {
-    fprintf (stderr, "failed to init galaxy model\n");
+  if (!InitGalaxyModel (GALAXY_MODEL)) {
+    fprintf (stderr, "failed to init galaxy model %s\n", GALAXY_MODEL);
     exit (2);
   }
@@ -30,6 +30,6 @@
 
   // XXX add to config?
-  if (!InitGalaxyModel ("ROESER")) {
-    fprintf (stderr, "failed to init galaxy model\n");
+  if (!InitGalaxyModel (GALAXY_MODEL)) {
+    fprintf (stderr, "failed to init galaxy model %s\n", GALAXY_MODEL);
     exit (2);
   }
Index: trunk/Ohana/src/fakeastro/src/make_fake_stars_catalog.c
===================================================================
--- trunk/Ohana/src/fakeastro/src/make_fake_stars_catalog.c	(revision 39907)
+++ trunk/Ohana/src/fakeastro/src/make_fake_stars_catalog.c	(revision 39926)
@@ -116,4 +116,7 @@
     double dDsee = ohana_gaussdev_rnd (0.0, 1.0 / SN);
 
+    // XXX TEST
+    // dDsee = dRsee = 0.0;
+
     double dRoff = (dRpm + dRsee) / 3600.0;
     double dDoff = (dDpm + dDsee) / 3600.0;
Index: trunk/Ohana/src/fakeastro/src/make_fakestars.c
===================================================================
--- trunk/Ohana/src/fakeastro/src/make_fakestars.c	(revision 39907)
+++ trunk/Ohana/src/fakeastro/src/make_fakestars.c	(revision 39926)
@@ -35,4 +35,6 @@
       // we can generate a distribution which is uniform on the sky, in which case
       // we can limit to the selected patch analyically
+
+      // note: r & z are generated in parsec
       r = pow(drand48(), 0.33333) * FAKEASTRO_RGAL;
       z = 0.0;
@@ -48,4 +50,5 @@
       int inPatch = FALSE;
       while (!inPatch) {
+	// note: r & z are generated in parsec
 	z = ohana_gaussdev_rnd (0.0, FAKEASTRO_ZGAL);
 	r = sqrt(drand48()) * FAKEASTRO_RGAL;
@@ -68,4 +71,5 @@
     // double y = r*sin(L);
 
+    // distance here is in parsec
     double distance = sqrt (SQ(r) + SQ(z));
 
@@ -74,5 +78,6 @@
 
     double uL_sol, uB_sol;
-    SolarMotionModel_radians(&uL_sol, &uB_sol, Lrad, Brad, distance);
+    SolarMotionModel_radians(&uL_sol, &uB_sol, Lrad, Brad, distance / 1000.0);
+    // note: SolarMotionModel wants distance in kpc
 
     double uL = uL_gal + uL_sol;
@@ -80,8 +85,6 @@
     
     // XXX: amplify motion to make tests easier:
-    if (TESTING) {
-      uL *= 100.0;
-      uB *= 100.0;
-    }
+    uL *= TEST_SCALE;
+    uB *= TEST_SCALE;
     
     double uR, uD;
Index: trunk/Ohana/src/fakeastro/src/make_gaia_measures.c
===================================================================
--- trunk/Ohana/src/fakeastro/src/make_gaia_measures.c	(revision 39926)
+++ trunk/Ohana/src/fakeastro/src/make_gaia_measures.c	(revision 39926)
@@ -0,0 +1,126 @@
+# include "fakeastro.h"
+
+// region corresponds to the catalog
+int make_gaia_measures (Catalog *catalog) {
+
+  int Nsecfilt = GetPhotcodeNsecfilt ();
+
+  Average *average = catalog->average;
+  SecFilt *secfilt = catalog->secfilt;
+  StarPar *starpar = catalog->starpar;
+  Measure *measure = catalog->measure;
+  
+  // we have starpar.R,D, which represent the true positions at the reference epoch, FAKEASTRO_REF_EPOCH
+  // the GAIA stars are generated at locations for the GAIA EPOCH
+  time_t timeRef = ohana_date_to_sec(FAKEASTRO_REF_EPOCH);
+  time_t tzero_gaia = ohana_date_to_sec(FAKEASTRO_GAIA_EPOCH);
+
+  // tzero, timeRef are in UNIX seconds, Toffset should be in years
+  double Toffset = (tzero_gaia - timeRef) / 365.25 / 86400.0;
+
+  // use photcode to get zero point
+  PhotCode *codeG = GetPhotcodebyName ("GAIA_G_DR1");
+
+  float ZP = MAX_MAG_GAIA + 6.5; // this is chosen to give stars at the limit a flux of 400.0 counts (crude, yes)
+  float SkyCts = 1000.0; // this is chosen to make SN @ limit ~ 10.0 (
+
+  int Nmeasure = catalog->Nmeasure;
+  int NMEASURE = catalog->Nmeasure;
+
+  int Nsec = 2; // i-band
+
+  int i;
+  for (i = 0; i < catalog->Naverage; i++) {
+
+    if (Nmeasure >= NMEASURE) {
+      NMEASURE = Nmeasure + 1000;
+      REALLOCATE (catalog[0].measure, Measure, NMEASURE);
+      measure = catalog[0].measure;
+    }
+
+    int Nstarpar = average[i].starparOffset;
+
+    // make a crude G-i color for now:
+    double G_PS1 = secfilt[i*Nsecfilt + Nsec].M; // make all stars have G-i = 1.0
+    if (G_PS1 > MAX_MAG_GAIA) continue; // only generate GAIA detections for objects with G_PS1 < 21.0
+
+    if (isnan(secfilt[i*Nsecfilt + Nsec].M)) {
+      // look for a non-NAN secfilt mag and just use that (it is not super important)
+      int ns;
+      for (ns = 0; ns < Nsecfilt; ns++) {
+	if (!isnan(secfilt[i*Nsecfilt + ns].M)) break;
+      }
+      if (ns == Nsecfilt) continue; // no non-nan
+
+      G_PS1 = secfilt[i*Nsecfilt + ns].M; // pretend secfilt.M = G
+      if (G_PS1 > MAX_MAG_GAIA) continue; // only generate GAIA detections for objects with G_PS1 < 21.0
+    }
+
+    double Minst = G_PS1 - ZP; 
+
+    double Counts = pow(10.0, -0.4*Minst);
+
+    double SN = Counts / sqrt(SkyCts + Counts);
+
+    // true position from src catalog
+    double Rtru = starpar[Nstarpar].R;
+    double Dtru = starpar[Nstarpar].D;
+
+    // observed position is scattered from true position by:
+    // * proper motion
+    // * gaussian scatter (~ seeing) 
+    double uR = starpar[Nstarpar].uRA; // starpar are in arcsec / year
+    double uD = starpar[Nstarpar].uDEC;
+    
+    // uR,uD in linear (arcsec / yr)
+    double dRpm = uR*Toffset;
+    double dDpm = uD*Toffset;
+
+    // uR,uD in linear arcsec
+    double dRsee = ohana_gaussdev_rnd (0.0, 0.01 / SN);
+    double dDsee = ohana_gaussdev_rnd (0.0, 0.01 / SN);
+
+    // XXX TEST
+    // dDsee = dRsee = 0.0;
+
+    double dRoff = (dRpm + dRsee) / 3600.0;
+    double dDoff = (dDpm + dDsee) / 3600.0;
+
+    double Robs = Rtru + dRoff / cos(Dtru*RAD_DEG);
+    double Dobs = Dtru + dDoff;
+
+    dvo_measure_init (&measure[Nmeasure]);
+
+    measure[Nmeasure].R = Robs;
+    measure[Nmeasure].D = Dobs;
+
+    measure[Nmeasure].M      = G_PS1;
+    measure[Nmeasure].dM     = 1.0 / SN;
+
+    measure[Nmeasure].Sky        = SkyCts;
+    measure[Nmeasure].dSky       = sqrt(SkyCts);
+    measure[Nmeasure].photFlags  = 0;
+    measure[Nmeasure].photFlags2 = 0;
+    measure[Nmeasure].airmass = 1.0;
+    measure[Nmeasure].az      = 0.0; // irrelevant
+    measure[Nmeasure].Mcal    = 0.0;
+    measure[Nmeasure].t       = tzero_gaia;
+    measure[Nmeasure].dt      = 0.0;
+    measure[Nmeasure].photcode = codeG->code;
+
+    measure[Nmeasure].averef   = i;
+    measure[Nmeasure].objID    = average[i].objID;
+    measure[Nmeasure].catID    = average[i].catID;
+
+    measure[Nmeasure].imageID = 0;
+
+    // This is may optionally be replaced by the internal sequence (see FilterStars.c)
+    measure[Nmeasure].detID      = 0;
+    Nmeasure ++;
+  }
+
+  if (VERBOSE) fprintf (stderr, "added %d gaia entries to %d stars\n",  (int) Nmeasure, (int) catalog->Naverage);
+
+  catalog->Nmeasure = Nmeasure;
+  return TRUE;
+}
Index: trunk/Ohana/src/kapa2/include/prototypes.h
===================================================================
--- trunk/Ohana/src/kapa2/include/prototypes.h	(revision 39907)
+++ trunk/Ohana/src/kapa2/include/prototypes.h	(revision 39926)
@@ -32,11 +32,11 @@
 void          DrawLabelsRaw       PROTO((Graphic *graphic, KapaGraphWidget *graph, int color));
 void	      DrawTextlines	  PROTO((KapaGraphWidget *graph));
-void          DrawConnect         PROTO((KapaGraphWidget *graph, Gobjects *objects));
-void          DrawHistogram       PROTO((KapaGraphWidget *graph, Gobjects *objects));
-int           DrawObjectN         PROTO((KapaGraphWidget *graph, Gobjects *objects));
-void          DrawPoints          PROTO((KapaGraphWidget *graph, Gobjects *objects));
-void          ClipLine            PROTO((double x0, double y0, double x1, double y1, double X0, double Y0, double X1, double Y1));
-void          DrawXErrors         PROTO((KapaGraphWidget *graph, Gobjects *objects));
-void          DrawYErrors         PROTO((KapaGraphWidget *graph, Gobjects *objects));
+void          DrawConnect         PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
+void          DrawHistogram       PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
+int           DrawObjectN         PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
+void          DrawPoints          PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
+void          ClipLine            PROTO((Graphic *graphic, double x0, double y0, double x1, double y1, double X0, double Y0, double X1, double Y1));
+void          DrawXErrors         PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
+void          DrawYErrors         PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
 void	      DrawTick		  PROTO((Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis));
 void	      AxisTickScale	  PROTO((Axis *axis, double *range, double *major, double *minor, int *nsignif));
@@ -115,4 +115,5 @@
 void          PSLabels            PROTO((KapaGraphWidget *graph, FILE *f));
 void	      PSTextlines	  PROTO((KapaGraphWidget *graph, FILE *f));
+int           PSObjectsN          PROTO((KapaGraphWidget *graph, Gobjects *objects, FILE *f));
 void          PSConnect           PROTO((KapaGraphWidget *graph, Gobjects *objects, FILE *f));
 void          PSHistogram         PROTO((KapaGraphWidget *graph, Gobjects *objects, FILE *f));
@@ -135,4 +136,5 @@
 void	      bDrawLabels	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph));
 void	      bDrawTextlines	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph));
+int	      bDrawObjectsN	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object));
 void	      bDrawConnect	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object));
 void	      bDrawHistogram	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object));
Index: trunk/Ohana/src/kapa2/src/DrawFrame.c
===================================================================
--- trunk/Ohana/src/kapa2/src/DrawFrame.c	(revision 39907)
+++ trunk/Ohana/src/kapa2/src/DrawFrame.c	(revision 39926)
@@ -12,4 +12,6 @@
 
   graphic = GetGraphic();
+
+  P = 0.5 * (1 + 0.25*graph[0].axis[0].lweight) * (hypot (graph[0].axis[0].dfx, graph[0].axis[0].dfy) + hypot (graph[0].axis[0].dfx, graph[0].axis[0].dfy));
 
   /* each axis is drawn independently, but ticks and labels are placed according to perpendicular distance. */
@@ -30,6 +32,6 @@
     dfy = graph[0].axis[i].dfy + 2*dy;
 
-    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
-    P *= (1 + 0.25*lweight);
+    // P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
+    // P *= (1 + 0.25*lweight);
 
     XSetLineAttributes (graphic->display, graphic->gc, lweight, LineSolid, CapNotLast, JoinMiter);
Index: trunk/Ohana/src/kapa2/src/DrawObjects.c
===================================================================
--- trunk/Ohana/src/kapa2/src/DrawObjects.c	(revision 39907)
+++ trunk/Ohana/src/kapa2/src/DrawObjects.c	(revision 39926)
@@ -8,8 +8,4 @@
 # define FillCircle(X,Y,R) (XFillArc (graphic->display, graphic->window, graphic->gc, (int)(X-R), (int)(Y-R), abs(2*R+1), abs(2*R+1), 0, 23040))
 
-# define CONNECT 0
-# define HISTOGRAM 1
-# define POINTS 2
-
 # define XCENTER 0.0
 # define YCENTER 0.0
@@ -17,5 +13,6 @@
 # define JOINSTYLE JoinMiter
 
-static Graphic *graphic;
+// XXX this is not thread safe, but that is OK
+// static Graphic *graphic;
 
 /* draw all objects for this Graph */
@@ -24,14 +21,20 @@
   int i;
   
+  // the functions below use this global value
+  Graphic *graphic = GetGraphic();
+  
+  // this function calls all of the supporting Draw... functions below
   for (i = 0; i < graph[0].Nobjects; i++) {
     if (DEBUG) fprintf (stderr, "object: %d\n", i);
     if (DEBUG) fprintf (stderr, "Npts: %d\n", graph[0].objects[i].Npts);
-    DrawObjectN (graph, &graph[0].objects[i]);
+    DrawObjectN (graphic, graph, &graph[0].objects[i]);
   }    
+  XSetLineAttributes (graphic->display, graphic->gc, 0, LineSolid, CAPSTYLE, JOINSTYLE);
+  XSetForeground (graphic->display, graphic->gc, graphic->fore);
   return (TRUE);
 }
 
 /* Draw a specific object in the graph */
-int DrawObjectN (KapaGraphWidget *graph, Gobjects *object) {
+int DrawObjectN (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
   
   static char dot[2] = {2,3};
@@ -41,7 +44,4 @@
   int lweight;
   
-  // this function calls all of the supporting Draw... functions below
-  graphic = GetGraphic();
-  
   lweight = MAX (1, MIN (10, object[0].lweight));
 
@@ -58,23 +58,21 @@
   /* set line type */
   switch (object[0].ltype) {
-    case 0:
-      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineSolid, CAPSTYLE, JOINSTYLE);
-      break;
-    case 1:
+    case KAPA_LINE_DOT:
       XSetDashes (graphic->display, graphic->gc, 1, dot, 2);
-      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineOnOffDash, CAPSTYLE, JOINSTYLE);
-      break;
-    case 2:
+      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineDoubleDash, CAPSTYLE, JOINSTYLE);
+      break;
+    case KAPA_LINE_DASH_SHORT:
       XSetDashes (graphic->display, graphic->gc, 1, short_dash, 2);
-      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineOnOffDash, CAPSTYLE, JOINSTYLE);
-      break;
-    case 3:
+      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineDoubleDash, CAPSTYLE, JOINSTYLE);
+      break;
+    case KAPA_LINE_DASH_LONG:
       XSetDashes (graphic->display, graphic->gc, 1, long_dash, 2);
-      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineOnOffDash, CAPSTYLE, JOINSTYLE);
-      break;
-    case 4:
+      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineDoubleDash, CAPSTYLE, JOINSTYLE);
+      break;
+    case KAPA_LINE_DOT_DASH:
       XSetDashes (graphic->display, graphic->gc, 1, dot_dash, 4);
-      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineOnOffDash, CAPSTYLE, JOINSTYLE);
-      break;
+      XSetLineAttributes (graphic->display, graphic->gc, lweight, LineDoubleDash, CAPSTYLE, JOINSTYLE);
+      break;
+    case KAPA_LINE_SOLID:
     default:
       XSetLineAttributes (graphic->display, graphic->gc, lweight, LineSolid, CAPSTYLE, JOINSTYLE);
@@ -88,29 +86,27 @@
 
   switch (object[0].style) {
-    case CONNECT: 
-      DrawConnect (graph, object);
-      break;
-    case HISTOGRAM:
-      DrawHistogram (graph, object);
-      break;
-    case POINTS:
-      DrawPoints (graph, object);
+    case KAPA_PLOT_CONNECT: 
+      DrawConnect (graphic, graph, object);
+      break;
+    case KAPA_PLOT_HISTOGRAM:
+      DrawHistogram (graphic, graph, object);
+      break;
+    case KAPA_PLOT_POINTS:
+    default:
+      DrawPoints (graphic, graph, object);
       break;
   }
     
   if (object[0].etype & 0x01) {
-    DrawYErrors (graph, object);
+    DrawYErrors (graphic, graph, object);
   }
   if (object[0].etype & 0x02) {
-    DrawXErrors (graph, object);
-  }
-
-  XSetLineAttributes (graphic->display, graphic->gc, 0, LineSolid, CAPSTYLE, JOINSTYLE);
-  XSetForeground (graphic->display, graphic->gc, graphic->fore);
+    DrawXErrors (graphic, graph, object);
+  }
   return (TRUE);
 }
 
 /******/
-void DrawConnect (KapaGraphWidget *graph, Gobjects *object) {
+void DrawConnect (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
   
   int i;
@@ -149,5 +145,5 @@
     sy1 = x[i]*myi + y[i]*myj + by + YCENTER;
     
-    ClipLine (sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
+    ClipLine (graphic, sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
     /* DrawLine (sx0, sy0, sx1, sy1); */
     sx0 = sx1; sy0 = sy1;
@@ -156,5 +152,5 @@
 }
 
-void ClipLine (double x0, double y0, double x1, double y1, double X0, double Y1, double X1, double Y0) {
+void ClipLine (Graphic *graphic, double x0, double y0, double x1, double y1, double X0, double Y1, double X1, double Y0) {
 
   /* skip line segement if both points are beyond box */
@@ -212,5 +208,5 @@
 /* simplify the code abit by finding triplets, watch out for a histogram of 2 points */
 # if (1)
-void DrawHistogram (KapaGraphWidget *graph, Gobjects *object) {
+void DrawHistogram (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
 
   int i;
@@ -298,5 +294,5 @@
 # else 
 
-void DrawHistogram (KapaGraphWidget *graph, Gobjects *object) {
+void DrawHistogram (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
 
   int i;
@@ -407,5 +403,5 @@
 
 /******/
-void DrawPoints (KapaGraphWidget *graph, Gobjects *object) {
+void DrawPoints (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
 
   int i;
@@ -427,7 +423,5 @@
   by = byi + byj;
   
-  Graphic *graphic = GetGraphic();
-
-  /**** points are scaled by object.z ***/
+  /**** point sizes are scaled by object.size, colors by object.color ***/
   int scaleSize = (object[0].size < 0);
   int scaleColor = (object[0].color < 0);
@@ -437,315 +431,299 @@
   x = object[0].x; y = object[0].y; z = object[0].z;
 
-  if (object[0].ptype == 0) {	/* filled box */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	FillRectangle (sx - D, sy - D, 2*D + 1, 2*D + 1);
-      }
+  switch (object[0].ptype) {
+    case KAPA_POINT_BOX_OPEN:	/* open box */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawRectangle (sx - D, sy - D, 2*D, 2*D);
+	}
+      }
+      break;
+    case KAPA_POINT_CROSS: /* cross */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx - D, sy, sx + D + 1, sy);
+	  DrawLine (sx, sy - D, sx, sy + D + 1);
+	}
+      }
+      break;
+    case KAPA_POINT_X:	/* x */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx - D, sy + D, sx + D + 1, sy - D - 1);
+	  DrawLine (sx - D, sy - D, sx + D + 1, sy + D + 1);
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_SOLID:	/* filled triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+
+	  XPoint points[4];
+	  points[0].x = sx - D;  points[0].y = sy + 0.58*D;  
+	  points[1].x = sx + D;  points[1].y = sy + 0.58*D;  
+	  points[2].x = sx;      points[2].y = sy - 1.15*D;  
+	  points[3].x = sx - D;  points[3].y = sy + 0.58*D;  
+	  XFillPolygon (graphic->display, graphic->window, graphic->gc, points, 4, Convex, CoordModeOrigin);
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_SOLID_DOWN: /* filled triangle (down) */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+
+	  XPoint points[4];
+	  points[0].x = sx - D;  points[0].y = sy - 0.58*D;  
+	  points[1].x = sx + D;  points[1].y = sy - 0.58*D;  
+	  points[2].x = sx;      points[2].y = sy + 1.15*D;  
+	  points[3].x = sx - D;  points[3].y = sy - 0.58*D;  
+	  XFillPolygon (graphic->display, graphic->window, graphic->gc, points, 4, Convex, CoordModeOrigin);
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_OPEN:	/* open triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx - D, sy + 0.58*D, sx + D, sy + 0.58*D);
+	  DrawLine (sx + D, sy + 0.58*D, sx,     sy - 1.15*D);
+	  DrawLine (sx,     sy - 1.15*D, sx - D, sy + 0.58*D);
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_OPEN_DOWN:	/* upside-down open triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx - D, sy - 0.58*D, sx + D, sy - 0.58*D);
+	  DrawLine (sx + D, sy - 0.58*D, sx,     sy + 1.15*D);
+	  DrawLine (sx,     sy + 1.15*D, sx - D, sy - 0.58*D);
+	}
+      }
+      break;
+    case KAPA_POINT_Y:	/* Y */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx, sy, sx - D, sy - 0.58*D);
+	  DrawLine (sx, sy, sx + D, sy - 0.58*D);
+	  DrawLine (sx, sy, sx,     sy + 1.15*D);
+	}
+      }
+      break;
+    case KAPA_POINT_Y_DOWN:	/* upside-down Y */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx, sy, sx - D, sy + 0.58*D);
+	  DrawLine (sx, sy, sx + D, sy + 0.58*D);
+	  DrawLine (sx, sy, sx,     sy - 1.15*D);
+	}
+      }
+      break;
+    case KAPA_POINT_CIRCLE_OPEN: /* 0 */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawCircle (sx, sy, D);
+	}
+      }
+      break;
+    case KAPA_POINT_CIRCLE_SOLID: /* filled 0 */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  FillCircle (sx, sy, D);
+	  DrawCircle (sx, sy, D);
+	}
+      }
+      break;
+    case KAPA_POINT_PENTAGON:	/* pentagon */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx + 0.00*D, sy - 1.00*D, sx + 0.95*D, sy - 0.31*D);
+	  DrawLine (sx + 0.95*D, sy - 0.31*D, sx + 0.58*D, sy + 0.81*D);
+	  DrawLine (sx + 0.58*D, sy + 0.81*D, sx - 0.58*D, sy + 0.81*D);
+	  DrawLine (sx - 0.58*D, sy + 0.81*D, sx - 0.95*D, sy - 0.31*D);
+	  DrawLine (sx - 0.95*D, sy - 0.31*D, sx + 0.00*D, sy - 1.00*D);
+	}
+      }
+      break;
+    case KAPA_POINT_HEXAGON:	/* hexagon */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx -      D, sy,          sx - 0.50*D, sy + 0.87*D);
+	  DrawLine (sx - 0.50*D, sy + 0.87*D, sx + 0.50*D, sy + 0.87*D);
+	  DrawLine (sx + 0.50*D, sy + 0.87*D, sx +      D, sy);
+
+	  DrawLine (sx +      D, sy,          sx + 0.50*D, sy - 0.87*D);
+	  DrawLine (sx + 0.50*D, sy - 0.87*D, sx - 0.50*D, sy - 0.87*D);
+	  DrawLine (sx - 0.50*D, sy - 0.87*D, sx -      D, sy);
+	}
+      }
+      break;
+    case KAPA_POINT_PAIR_CONNECT: { /* connect pairs of points */
+      double X0 = graph[0].axis[0].fx;
+      double X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+      double Y0 = graph[0].axis[1].fy;
+      double Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+
+      for (i = 0; i + 1 < object[0].Npts; i+=2) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx1 = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy1 = x[i]*myi + y[i]*myj + by + YCENTER;
+	if (!(finite(x[i+1]) && finite(y[i+1]))) continue;
+	sx2 = x[i+1]*mxi + y[i+1]*mxj + bx + XCENTER;
+	sy2 = x[i+1]*myi + y[i+1]*myj + by + YCENTER;
+	ClipLine (graphic, sx1, sy1, sx2, sy2, X0, Y0, X1, Y1);
+      }
+      break;
     }
-  }
-  if (object[0].ptype == 1) {	/* open box */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawRectangle (sx - D, sy - D, 2*D, 2*D);
-      }
-    }
-  }
-  if (object[0].ptype == 2) { /* cross */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx - D, sy, sx + D + 1, sy);
-	DrawLine (sx, sy - D, sx, sy + D + 1);
-      }
-    }
-  }
-  if (object[0].ptype == 3) {	/* x */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx - D, sy + D, sx + D + 1, sy - D - 1);
-	DrawLine (sx - D, sy - D, sx + D + 1, sy + D + 1);
-      }
-    }
-  }
-  if (object[0].ptype == 4) {	/* filled triangle */
-    XPoint points[4];
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	points[0].x = sx - D;  points[0].y = sy + 0.58*D;  
-	points[1].x = sx + D;  points[1].y = sy + 0.58*D;  
-	points[2].x = sx;      points[2].y = sy - 1.15*D;  
-	points[3].x = sx - D;  points[3].y = sy + 0.58*D;  
-	XFillPolygon (graphic->display, graphic->window, graphic->gc, points, 4, Convex, CoordModeOrigin);
-      }
-    }
-  }
-  if (object[0].ptype == 5) {	/* open triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx - D, sy + 0.58*D, sx + D, sy + 0.58*D);
-	DrawLine (sx + D, sy + 0.58*D, sx,     sy - 1.15*D);
-	DrawLine (sx,     sy - 1.15*D, sx - D, sy + 0.58*D);
-      }
-    }
-  }
-  if (object[0].ptype == 6) {	/* Y */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx, sy, sx - D, sy - 0.58*D);
-	DrawLine (sx, sy, sx + D, sy - 0.58*D);
-	DrawLine (sx, sy, sx,     sy + 1.15*D);
-      }
-    }
-  }
-  if (object[0].ptype == 7) {	/* 0 */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawCircle (sx, sy, D);
-      }
-    }
-  }
-  if (object[0].ptype == 8) {	/* pentagon */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx + 0.00*D, sy - 1.00*D, sx + 0.95*D, sy - 0.31*D);
-	DrawLine (sx + 0.95*D, sy - 0.31*D, sx + 0.58*D, sy + 0.81*D);
-	DrawLine (sx + 0.58*D, sy + 0.81*D, sx - 0.58*D, sy + 0.81*D);
-	DrawLine (sx - 0.58*D, sy + 0.81*D, sx - 0.95*D, sy - 0.31*D);
-	DrawLine (sx - 0.95*D, sy - 0.31*D, sx + 0.00*D, sy - 1.00*D);
-      }
-    }
-  }
-  if (object[0].ptype == 9) {	/* hexagon */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx -      D, sy,          sx - 0.50*D, sy + 0.87*D);
-	DrawLine (sx - 0.50*D, sy + 0.87*D, sx + 0.50*D, sy + 0.87*D);
-	DrawLine (sx + 0.50*D, sy + 0.87*D, sx +      D, sy);
-
-	DrawLine (sx +      D, sy,          sx + 0.50*D, sy - 0.87*D);
-	DrawLine (sx + 0.50*D, sy - 0.87*D, sx - 0.50*D, sy - 0.87*D);
-	DrawLine (sx - 0.50*D, sy - 0.87*D, sx -      D, sy);
-      }
-    }
-  }
-  if (object[0].ptype == 10) {	/* filled 0 */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	FillCircle (sx, sy, D);
-      }
-    }
-  }
-  if (object[0].ptype == 12) {	/* filled triangle (down) */
-    XPoint points[4];
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	points[0].x = sx - D;  points[0].y = sy - 0.58*D;  
-	points[1].x = sx + D;  points[1].y = sy - 0.58*D;  
-	points[2].x = sx;      points[2].y = sy + 1.15*D;  
-	points[3].x = sx - D;  points[3].y = sy - 0.58*D;  
-	XFillPolygon (graphic->display, graphic->window, graphic->gc, points, 4, Convex, CoordModeOrigin);
-      }
-    }
-  }
-  if (object[0].ptype == 14) {	/* upside-down filled triangle */
-    XPoint points[4];
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	points[0].x = sx - D;  points[0].y = sy - 0.58*D;  
-	points[1].x = sx + D;  points[1].y = sy - 0.58*D;  
-	points[2].x = sx;      points[2].y = sy + 1.15*D;  
-	points[3].x = sx - D;  points[3].y = sy - 0.58*D;  
-	XFillPolygon (graphic->display, graphic->window, graphic->gc, points, 4, Convex, CoordModeOrigin);
-      }
-    }
-  }
-  if (object[0].ptype == 15) {	/* upside-down open triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx - D, sy - 0.58*D, sx + D, sy - 0.58*D);
-	DrawLine (sx + D, sy - 0.58*D, sx,     sy + 1.15*D);
-	DrawLine (sx,     sy + 1.15*D, sx - D, sy - 0.58*D);
-      }
-    }
-  }
-  if (object[0].ptype == 16) {	/* upside-down Y */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy = x[i]*myi + y[i]*myj + by + YCENTER;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx, sy, sx - D, sy + 0.58*D);
-	DrawLine (sx, sy, sx + D, sy + 0.58*D);
-	DrawLine (sx, sy, sx,     sy - 1.15*D);
-      }
-    }
-  }
-  if (object[0].ptype == 100) {	/* connect a pair of points */
-
-    double X0 = graph[0].axis[0].fx;
-    double X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
-    double Y0 = graph[0].axis[1].fy;
-    double Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
-
-    for (i = 0; i + 1 < object[0].Npts; i+=2) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx1 = x[i]*mxi + y[i]*mxj + bx + XCENTER;
-      sy1 = x[i]*myi + y[i]*myj + by + YCENTER;
-      if (!(finite(x[i+1]) && finite(y[i+1]))) continue;
-      sx2 = x[i+1]*mxi + y[i+1]*mxj + bx + XCENTER;
-      sy2 = x[i+1]*myi + y[i+1]*myj + by + YCENTER;
-      ClipLine (sx1, sy1, sx2, sy2, X0, Y0, X1, Y1);
-    }
+    case KAPA_POINT_BOX_SOLID:	/* filled box */
+    default:
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy = x[i]*myi + y[i]*myj + by + YCENTER;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  FillRectangle (sx - D, sy - D, 2*D + 1, 2*D + 1);
+	}
+      }
+      break;
   }
 }
     
 /******/
-void DrawXErrors (KapaGraphWidget *graph, Gobjects *object) {
+void DrawXErrors (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
   
   int i, bar, dz, ds, D;
@@ -800,9 +778,9 @@
 	 (sy1 < graph[0].axis[1].fy) && (sy1 > graph[0].axis[1].fy + graph[0].axis[1].dfy))) 
     {
-      ClipLine (sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
+      ClipLine (graphic, sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
       if (bar) {
 	sx10 = sy1 - sz;
 	sx11 = sy1 + sz;
-	ClipLine (sx1, sx10, sx1, sx11, X0, Y0, X1, Y1);
+	ClipLine (graphic, sx1, sx10, sx1, sx11, X0, Y0, X1, Y1);
       }
     }
@@ -819,9 +797,9 @@
 	 (sy1 < graph[0].axis[1].fy) && (sy1 > graph[0].axis[1].fy + graph[0].axis[1].dfy)))
     {
-      ClipLine (sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
+      ClipLine (graphic, sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
       if (bar) {
 	sx10 = sy1 - sz;
 	sx11 = sy1 + sz;
-	ClipLine (sx1, sx10, sx1, sx11, X0, Y0, X1, Y1);
+	ClipLine (graphic, sx1, sx10, sx1, sx11, X0, Y0, X1, Y1);
       }
     }
@@ -830,5 +808,5 @@
     
 /******/
-void DrawYErrors (KapaGraphWidget *graph, Gobjects *object) {
+void DrawYErrors (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
 
   int i, bar, dz, ds, D;
@@ -883,9 +861,9 @@
 	 (sy1 < graph[0].axis[1].fy) && (sy1 > graph[0].axis[1].fy + graph[0].axis[1].dfy)))
     {
-      ClipLine (sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
+      ClipLine (graphic, sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
       if (bar) {
 	sx10 = sx1 - sz;
 	sx11 = sx1 + sz;
-	ClipLine (sx10, sy1, sx11, sy1, X0, Y0, X1, Y1);
+	ClipLine (graphic, sx10, sy1, sx11, sy1, X0, Y0, X1, Y1);
       }
     }
@@ -904,9 +882,9 @@
 	 (sy1 < graph[0].axis[1].fy) && (sy1 > graph[0].axis[1].fy + graph[0].axis[1].dfy)))
     {
-      ClipLine (sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
+      ClipLine (graphic, sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
       if (bar) {
 	sx10 = sx1 - sz;
 	sx11 = sx1 + sz;
-	ClipLine (sx10, sy1, sx11, sy1, X0, Y0, X1, Y1);
+	ClipLine (graphic, sx10, sy1, sx11, sy1, X0, Y0, X1, Y1);
       }
     }
Index: trunk/Ohana/src/kapa2/src/LoadObject.c
===================================================================
--- trunk/Ohana/src/kapa2/src/LoadObject.c	(revision 39907)
+++ trunk/Ohana/src/kapa2/src/LoadObject.c	(revision 39926)
@@ -102,5 +102,8 @@
   if (DEBUG) fprintf (stderr, "loaded %d objects, using object %d\n", graph[0].objects[N].Npts, N);
 
-  if (USE_XWINDOW) DrawObjectN (graph, &graph[0].objects[graph[0].Nobjects-1]);
+  if (USE_XWINDOW) {
+    Graphic *graphic = GetGraphic();
+    DrawObjectN (graphic, graph, &graph[0].objects[graph[0].Nobjects-1]);
+  }
   FlushDisplay ();
 
Index: trunk/Ohana/src/kapa2/src/PSFrame.c
===================================================================
--- trunk/Ohana/src/kapa2/src/PSFrame.c	(revision 39907)
+++ trunk/Ohana/src/kapa2/src/PSFrame.c	(revision 39926)
@@ -11,4 +11,6 @@
 
   graphic = GetGraphic();
+
+  P = 0.5 * (1 + 0.25*graph[0].axis[0].lweight) * (hypot (graph[0].axis[0].dfx, graph[0].axis[0].dfy) + hypot (graph[0].axis[0].dfx, graph[0].axis[0].dfy));
 
   /* each axis is drawn independently */
@@ -30,6 +32,6 @@
     dfy = -graph[0].axis[i].dfy + 2*dy;
 
-    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
-    P *= (1 + 0.25*lweight);
+    // P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
+    // P *= (1 + 0.25*lweight);
 
     fprintf (f, "%.1f setlinewidth\n", lweight);
Index: trunk/Ohana/src/kapa2/src/PSObjects.c
===================================================================
--- trunk/Ohana/src/kapa2/src/PSObjects.c	(revision 39907)
+++ trunk/Ohana/src/kapa2/src/PSObjects.c	(revision 39926)
@@ -7,8 +7,9 @@
 # define FillCircle(X1,Y1,R) (fprintf (f, " %6.2f %6.2f %6.2f FC\n", (X1), (graphic->dy - Y1), (R)))
 # define FillTriangle(X1,Y1,X2,Y2, X3, Y3) (fprintf (f, " %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f TF\n", (X1), (graphic->dy-Y1), (X2), (graphic->dy-Y2), (X3), (graphic->dy-Y3)))
-# define CONNECT 0
-# define HISTOGRAM 1
-# define POINTS 2
-
+
+# define CAPSTYLE 1 /* CapButt */
+# define JOINSTYLE 0 /* JoinMiter */
+
+// XXX this is not thread safe, but that is OK
 static Graphic *graphic;
 
@@ -16,51 +17,70 @@
   
   int i;
-  double lweight;
-  static char dash[] = "5";
-  static char dot[] = "3";
-  
+  
+  // the functions below use this global value
   graphic = GetGraphic();
 
+  // this function calls all of the supporting Draw... functions below
   for (i = 0; i < graph[0].Nobjects; i++) {
-    switch (graph[0].objects[i].ltype) {
-    case 0:
-      break;
-    case 1:
-      fprintf (f, "[%s] 0 setdash\n", dash);
-      break;
-    case 2:
+    PSObjectsN (graph, &graph[0].objects[i], f);
+  }
+  // reset to default color and style
+  fprintf (f, "[] 0 setdash\n");
+  fprintf (f, "0.00 0.00 0.00 setrgbcolor\n");
+
+  return (TRUE);
+}
+
+int PSObjectsN (KapaGraphWidget *graph, Gobjects *object, FILE *f) {
+  
+  static char short_dash[] = "4 4";
+  static char long_dash[] = "8 8";
+  static char dot_dash[] = "2 4 4 4";
+  static char dot[] = "2 3";
+  
+  double lweight = MAX (0, MIN (10, object->lweight));
+  fprintf (f, "%.1f setlinewidth\n", lweight);
+  fprintf (f, "%d setlinecap %d setlinejoin\n", CAPSTYLE, JOINSTYLE);
+
+  switch (object->ltype) {
+    case KAPA_LINE_DOT:
       fprintf (f, "[%s] 0 setdash\n", dot);
       break;
+    case KAPA_LINE_DASH_SHORT:
+      fprintf (f, "[%s] 0 setdash\n", short_dash);
+      break;
+    case KAPA_LINE_DASH_LONG: 
+      fprintf (f, "[%s] 0 setdash\n", long_dash);
+      break;
+    case KAPA_LINE_DOT_DASH:
+      fprintf (f, "[%s] 0 setdash\n", dot_dash);
+      break;
+    case KAPA_LINE_SOLID: // no need to call 'setdash' as solid is the default
     default:
       break;
-    }
+  }
     
-    lweight = MAX (0, MIN (10, graph[0].objects[i].lweight));
-    fprintf (f, "%.1f setlinewidth\n", lweight);
-
-    if (graph[0].objects[i].color >= 0) {
-	fprintf (f, "%s setrgbcolor\n", KapaColorRGBString(graph[0].objects[i].color));
-    }
-
-    switch (graph[0].objects[i].style) {
-    case CONNECT: 
-      PSConnect (graph, &graph[0].objects[i], f);
-      break;
-    case HISTOGRAM:
-      PSHistogram (graph, &graph[0].objects[i], f);
-      break;
-    case POINTS:
-      PSPoints (graph, &graph[0].objects[i], f);
-      break;
-    }
-
-    if (graph[0].objects[i].etype & 0x01) {
-      PSYErrors (graph, &graph[0].objects[i], f);
-    }
-    if (graph[0].objects[i].etype & 0x02) {
-      PSXErrors (graph, &graph[0].objects[i], f);
-    }
-    fprintf (f, "[] 0 setdash\n");
-    fprintf (f, "0.00 0.00 0.00 setrgbcolor\n");
+  if (object->color >= 0) {
+    fprintf (f, "%s setrgbcolor\n", KapaColorRGBString(object->color));
+  }
+
+  switch (object->style) {
+    case KAPA_PLOT_CONNECT: 
+      PSConnect (graph, object, f);
+      break;
+    case KAPA_PLOT_HISTOGRAM: 
+      PSHistogram (graph, object, f);
+      break;
+    case KAPA_PLOT_POINTS: 
+    default:
+      PSPoints (graph, object, f);
+      break;
+  }
+
+  if (object->etype & 0x01) {
+    PSYErrors (graph, object, f);
+  }
+  if (object->etype & 0x02) {
+    PSXErrors (graph, object, f);
   }
   return (TRUE);
@@ -303,8 +323,7 @@
   }
 
-  // black, I think
   // fprintf (f, "0.00 0.00 0.00 setrgbcolor\n");
 
-  /**** points are scaled by object.z ***/
+  /**** point sizes are scaled by object.size, colors by object.color ***/
   int scaleSize = (object[0].size < 0);
   int scaleColor = (object[0].color < 0);
@@ -314,292 +333,281 @@
   x = object[0].x; y = object[0].y; z = object[0].z;
 
-  if (object[0].ptype == 0) {	/* filled box */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	FillRectangle (sx, sy, 2*D, 2*D);
-      }
+  switch (object[0].ptype) {
+    case KAPA_POINT_BOX_OPEN:	/* open box */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawRectangle (sx, sy, 2*D, 2*D);
+	}
+      }
+      break;
+    case KAPA_POINT_CROSS: /* cross */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx - D, sy, sx + D, sy);
+	  DrawLine (sx, sy - D, sx, sy + D);
+	}
+      }
+      break;
+    case KAPA_POINT_X:	/* x */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx + D, sy - D, sx - D, sy + D);
+	  DrawLine (sx - D, sy - D, sx + D, sy + D);
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_SOLID:	/* filled triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  FillTriangle (sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_SOLID_DOWN:	/* open triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  FillTriangle (sx - D, sy + 0.58*D, sx + D, sy + 0.58*D, sx, sy - 1.15*D);
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_OPEN:	/* open triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx - D, sy - 0.58*D, sx + D, sy - 0.58*D);
+	  DrawLine (sx + D, sy - 0.58*D, sx,     sy + 1.15*D);
+	  DrawLine (sx,     sy + 1.15*D, sx - D, sy - 0.58*D);
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_OPEN_DOWN:	/* upside-down open triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx - D, sy + 0.58*D, sx + D, sy + 0.58*D);
+	  DrawLine (sx + D, sy + 0.58*D, sx,     sy - 1.15*D);
+	  DrawLine (sx,     sy - 1.15*D, sx - D, sy + 0.58*D);
+	}
+      }
+      break;
+    case KAPA_POINT_Y:	/* Y */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx, sy, sx - D, sy + 0.58*D);
+	  DrawLine (sx, sy, sx + D, sy + 0.58*D);
+	  DrawLine (sx, sy, sx,          sy - 1.15*D);
+	}
+      }
+      break;
+    case KAPA_POINT_Y_DOWN:	/* upside-down Y */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx, sy, sx - D, sy - 0.58*D);
+	  DrawLine (sx, sy, sx + D, sy - 0.58*D);
+	  DrawLine (sx, sy, sx,     sy + 1.15*D);
+	}
+      }
+      break;
+    case KAPA_POINT_CIRCLE_OPEN: /* 0 */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawCircle (sx, sy, D);
+	}
+      }
+      break;
+    case KAPA_POINT_CIRCLE_SOLID: /* filled 0 */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  FillCircle (sx, sy, D);
+	}
+      }
+      break;
+    case KAPA_POINT_PENTAGON:	/* pentagon */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx + 0.00*D, sy + 1.00*D, sx + 0.95*D, sy + 0.31*D);
+	  DrawLine (sx + 0.95*D, sy + 0.31*D, sx + 0.58*D, sy - 0.81*D);
+	  DrawLine (sx + 0.58*D, sy - 0.81*D, sx - 0.58*D, sy - 0.81*D);
+	  DrawLine (sx - 0.58*D, sy - 0.81*D, sx - 0.95*D, sy + 0.31*D);
+	  DrawLine (sx - 0.95*D, sy + 0.31*D, sx + 0.00*D, sy + 1.00*D);
+	}
+      }
+      break;
+    case KAPA_POINT_HEXAGON:	/* hexagon */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (sx -      D, sy,               sx - 0.50*D, sy + 0.87*D);
+	  DrawLine (sx - 0.50*D, sy + 0.87*D, sx + 0.50*D, sy + 0.87*D);
+	  DrawLine (sx + 0.50*D, sy + 0.87*D, sx +      D, sy);
+
+	  DrawLine (sx +      D, sy,               sx + 0.50*D, sy - 0.87*D);
+	  DrawLine (sx + 0.50*D, sy - 0.87*D, sx - 0.50*D, sy - 0.87*D);
+	  DrawLine (sx - 0.50*D, sy - 0.87*D, sx -      D, sy);
+	}
+      }
+      break;
+    case KAPA_POINT_PAIR_CONNECT: { /* connect pairs of points */
+      double X0 = graph[0].axis[0].fx;
+      double X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+      double Y0 = graph[0].axis[1].fy;
+      double Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+
+      for (i = 0; i + 1 < object[0].Npts; i+=2) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx1 = x[i]*mxi + y[i]*mxj + bx;
+	sy1 = x[i]*myi + y[i]*myj + by;
+	sx2 = x[i+1]*mxi + y[i+1]*mxj + bx;
+	sy2 = x[i+1]*myi + y[i+1]*myj + by;
+	ClipLinePS (sx1, sy1, sx2, sy2, X0, Y0, X1, Y1, f);
+      }
+      break;
     }
-  }
-  if (object[0].ptype == 1) {	/* open box */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawRectangle (sx, sy, 2*D, 2*D);
-      }
-    }
-  }
-  if (object[0].ptype == 2) { /* cross */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx - D, sy, sx + D, sy);
-	DrawLine (sx, sy - D, sx, sy + D);
-      }
-    }
-  }
-  if (object[0].ptype == 3) {	/* x */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx + D, sy - D, sx - D, sy + D);
-	DrawLine (sx - D, sy - D, sx + D, sy + D);
-      }
-    }
-  }
-  if (object[0].ptype == 4) {	/* filled triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	FillTriangle (sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
-      }
-    }
-  }
-  if (object[0].ptype == 14) {	/* filled triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	FillTriangle (sx - D, sy + 0.58*D, sx + D, sy + 0.58*D, sx, sy - 1.15*D);
-      }
-    }
-  }
-  if (object[0].ptype == 5) {	/* open triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx - D, sy - 0.58*D, sx + D, sy - 0.58*D);
-	DrawLine (sx + D, sy - 0.58*D, sx,     sy + 1.15*D);
-	DrawLine (sx,     sy + 1.15*D, sx - D, sy - 0.58*D);
-      }
-    }
-  }
-  if (object[0].ptype == 15) {	/* upside-down open triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx - D, sy + 0.58*D, sx + D, sy + 0.58*D);
-	DrawLine (sx + D, sy + 0.58*D, sx,     sy - 1.15*D);
-	DrawLine (sx,     sy - 1.15*D, sx - D, sy + 0.58*D);
-      }
-    }
-  }
-  if (object[0].ptype == 6) {	/* Y */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx, sy, sx - D, sy + 0.58*D);
-	DrawLine (sx, sy, sx + D, sy + 0.58*D);
-	DrawLine (sx, sy, sx,          sy - 1.15*D);
-      }
-    }
-  }
-  if (object[0].ptype == 16) {	/* Y */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx, sy, sx - D, sy - 0.58*D);
-	DrawLine (sx, sy, sx + D, sy - 0.58*D);
-	DrawLine (sx, sy, sx,     sy + 1.15*D);
-      }
-    }
-  }
-  if (object[0].ptype == 7) {	/* 0 */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawCircle (sx, sy, D);
-      }
-    }
-  }
-  if (object[0].ptype == 8) {	/* pentagon */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx + 0.00*D, sy + 1.00*D, sx + 0.95*D, sy + 0.31*D);
-	DrawLine (sx + 0.95*D, sy + 0.31*D, sx + 0.58*D, sy - 0.81*D);
-	DrawLine (sx + 0.58*D, sy - 0.81*D, sx - 0.58*D, sy - 0.81*D);
-	DrawLine (sx - 0.58*D, sy - 0.81*D, sx - 0.95*D, sy + 0.31*D);
-	DrawLine (sx - 0.95*D, sy + 0.31*D, sx + 0.00*D, sy + 1.00*D);
-      }
-    }
-  }
-  if (object[0].ptype == 9) {	/* hexagon */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (sx -      D, sy,               sx - 0.50*D, sy + 0.87*D);
-	DrawLine (sx - 0.50*D, sy + 0.87*D, sx + 0.50*D, sy + 0.87*D);
-	DrawLine (sx + 0.50*D, sy + 0.87*D, sx +      D, sy);
-
-	DrawLine (sx +      D, sy,               sx + 0.50*D, sy - 0.87*D);
-	DrawLine (sx + 0.50*D, sy - 0.87*D, sx - 0.50*D, sy - 0.87*D);
-	DrawLine (sx - 0.50*D, sy - 0.87*D, sx -      D, sy);
-      }
-    }
-  }
-  if (object[0].ptype == 10) {	/* 0 */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	FillCircle (sx, sy, D);
-      }
-    }
-  }
-  if (object[0].ptype == 100) {	/* connect a pair of points */
-    double X0 = graph[0].axis[0].fx;
-    double X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
-    double Y0 = graph[0].axis[1].fy;
-    double Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
-
-    for (i = 0; i + 1 < object[0].Npts; i+=2) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx1 = x[i]*mxi + y[i]*mxj + bx;
-      sy1 = x[i]*myi + y[i]*myj + by;
-      sx2 = x[i+1]*mxi + y[i+1]*mxj + bx;
-      sy2 = x[i+1]*myi + y[i+1]*myj + by;
-      ClipLinePS (sx1, sy1, sx2, sy2, X0, Y0, X1, Y1, f);
-    }
-  }
-
+    case KAPA_POINT_BOX_SOLID:	/* filled box */
+    default:
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    fprintf (f, "%4.2f %4.2f %4.2f setrgbcolor\n", pixel1[pixel], pixel2[pixel], pixel3[pixel]);
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  FillRectangle (sx, sy, 2*D, 2*D);
+	}
+      }
+      break;
+  }
   free (pixel1);
   free (pixel2);
Index: trunk/Ohana/src/kapa2/src/bDrawFrame.c
===================================================================
--- trunk/Ohana/src/kapa2/src/bDrawFrame.c	(revision 39907)
+++ trunk/Ohana/src/kapa2/src/bDrawFrame.c	(revision 39926)
@@ -11,4 +11,6 @@
 
   // don't need graphic, unlink DrawFrame
+
+  P = 0.5 * (1 + 0.25*graph[0].axis[0].lweight) * (hypot (graph[0].axis[0].dfx, graph[0].axis[0].dfy) + hypot (graph[0].axis[0].dfx, graph[0].axis[0].dfy));
 
   /* each axis is drawn independently */
@@ -28,6 +30,7 @@
     dfx = graph[0].axis[i].dfx + 2*dx;
     dfy = graph[0].axis[i].dfy + 2*dy;
-    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
-    P *= (1 + 0.25*lweight);
+
+    // P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
+    // P *= (1 + 0.25*lweight);
 
     bDrawSetStyle (buffer, color, lweight, 0);
Index: trunk/Ohana/src/kapa2/src/bDrawObjects.c
===================================================================
--- trunk/Ohana/src/kapa2/src/bDrawObjects.c	(revision 39907)
+++ trunk/Ohana/src/kapa2/src/bDrawObjects.c	(revision 39926)
@@ -18,39 +18,42 @@
   
   int i;
-  int type;
-  int weight;
-  bDrawColor color;
-  bDrawColor black;
-  
+  
+  // the functions below use this global value
   graphic = GetGraphic();
 
-  black = KapaColorByName ("black");
+  // this function calls all of the supporting bDraw... functions below
   for (i = 0; i < graph[0].Nobjects; i++) {
-
-    weight = MAX (0, MIN (10, graph[0].objects[i].lweight));
-    type = graph[0].objects[i].ltype;    
-    color = graph[0].objects[i].color;
-    bDrawSetStyle (buffer, color, weight, type);
-
-    switch (graph[0].objects[i].style) {
-      case CONNECT: 
-	bDrawConnect (buffer, graph, &graph[0].objects[i]);
-	break;
-      case HISTOGRAM:
-	bDrawHistogram (buffer, graph, &graph[0].objects[i]);
-	break;
-      case POINTS:
-	bDrawPoints (buffer, graph, &graph[0].objects[i]);
-	break;
-    }
-
-    if (graph[0].objects[i].etype & 0x01) {
-      bDrawYErrors (buffer, graph, &graph[0].objects[i]);
-    }
-    if (graph[0].objects[i].etype & 0x02) {
-      bDrawXErrors (buffer, graph, &graph[0].objects[i]);
-    }
-  }
+    bDrawObjectsN (buffer, graph, &graph[0].objects[i]);
+  }
+  bDrawColor black = KapaColorByName ("black");
   bDrawSetStyle (buffer, black, 0, 0);
+  return (TRUE);
+}
+
+int bDrawObjectsN (bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object) {
+  
+  int weight = MAX (0, MIN (10, object->lweight));
+  bDrawSetStyle (buffer, object->color, weight, object->ltype);
+  
+  switch (object->style) {
+    case KAPA_PLOT_CONNECT: 
+      bDrawConnect (buffer, graph, object);
+      break;
+    case KAPA_PLOT_HISTOGRAM:
+      bDrawHistogram (buffer, graph, object);
+      break;
+    case KAPA_PLOT_POINTS:
+    default:
+      bDrawPoints (buffer, graph, object);
+      break;
+  }
+
+  if (object->etype & 0x01) {
+    bDrawYErrors (buffer, graph, object);
+  }
+  if (object->etype & 0x02) {
+    bDrawXErrors (buffer, graph, object);
+  }
+
   return (TRUE);
 }
@@ -298,354 +301,320 @@
   x = object[0].x; y = object[0].y; z = object[0].z;
 
-  if (object[0].ptype == 0) {	/* filled box */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	FillRectangle (buffer, sx, sy, 2*D, 2*D);
-	// plot range saturated by bDrawRectFill
-      }
+  switch (object[0].ptype) {
+    case KAPA_POINT_BOX_OPEN:	/* open box */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawRectangle (buffer, sx, sy, 2*D, 2*D);
+	  // plot range saturated by bDrawRectOpen
+	}
+      }
+      break;
+    case KAPA_POINT_CROSS: /* cross */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (buffer, sx - D, sy, sx + D, sy);
+	  DrawLine (buffer, sx, sy - D, sx, sy + D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_X:	/* x */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (buffer, sx + D, sy - D, sx - D, sy + D);
+	  DrawLine (buffer, sx - D, sy - D, sx + D, sy + D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_SOLID:	/* filled triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  // FillTriangle (buffer, sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
+	  FillTriangle (buffer, sx, sy + 0.58*D, D, -1.73*D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_SOLID_DOWN:	/* open triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  // FillTriangle (buffer, sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
+	  FillTriangle (buffer, sx, sy - 0.58*D, D, +1.73*D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_OPEN:	/* open triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  OpenTriangle (buffer, sx - D, sy + 0.58*D, sx + D, sy + 0.58*D, sx, sy - 1.15*D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_TRIANGLE_OPEN_DOWN:	/* upside-down open triangle */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  OpenTriangle (buffer, sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_Y:	/* Y */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (buffer, sx, sy, sx - D, sy - 0.58*D);
+	  DrawLine (buffer, sx, sy, sx + D, sy - 0.58*D);
+	  DrawLine (buffer, sx, sy, sx,     sy + 1.15*D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_Y_DOWN:	/* upside-down Y */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (buffer, sx, sy, sx - D, sy + 0.58*D);
+	  DrawLine (buffer, sx, sy, sx + D, sy + 0.58*D);
+	  DrawLine (buffer, sx, sy, sx,     sy - 1.15*D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_CIRCLE_OPEN: /* 0 */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawCircle (buffer, sx, sy, D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_CIRCLE_SOLID: /* filled 0 */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  FillCircle (buffer, sx, sy, D);
+	  // out-of-range points skipped by bDrawLineHorizontal
+	}
+      }
+      break;
+    case KAPA_POINT_PENTAGON:	/* pentagon */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (buffer, sx + 0.00*D, sy - 1.00*D, sx + 0.95*D, sy - 0.31*D);
+	  DrawLine (buffer, sx + 0.95*D, sy - 0.31*D, sx + 0.58*D, sy + 0.81*D);
+	  DrawLine (buffer, sx + 0.58*D, sy + 0.81*D, sx - 0.58*D, sy + 0.81*D);
+	  DrawLine (buffer, sx - 0.58*D, sy + 0.81*D, sx - 0.95*D, sy - 0.31*D);
+	  DrawLine (buffer, sx - 0.95*D, sy - 0.31*D, sx + 0.00*D, sy - 1.00*D);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_HEXAGON:	/* hexagon */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  DrawLine (buffer, sx -      D, sy,          sx - 0.50*D, sy + 0.87*D);
+	  DrawLine (buffer, sx - 0.50*D, sy + 0.87*D, sx + 0.50*D, sy + 0.87*D);
+	  DrawLine (buffer, sx + 0.50*D, sy + 0.87*D, sx +      D, sy);
+	  DrawLine (buffer, sx +      D, sy,          sx + 0.50*D, sy - 0.87*D);
+	  DrawLine (buffer, sx + 0.50*D, sy - 0.87*D, sx - 0.50*D, sy - 0.87*D);
+	  DrawLine (buffer, sx - 0.50*D, sy - 0.87*D, sx -      D, sy);
+	  // out-of-range points skipped by bDrawPoint
+	}
+      }
+      break;
+    case KAPA_POINT_PAIR_CONNECT: { /* connect pairs of points */
+
+      double X0 = graph[0].axis[0].fx;
+      double X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+      double Y0 = graph[0].axis[1].fy;
+      double Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+
+      for (i = 0; i + 1 < object[0].Npts; i+=2) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx1 = x[i]*mxi + y[i]*mxj + bx;
+	sy1 = x[i]*myi + y[i]*myj + by;
+	sx2 = x[i+1]*mxi + y[i+1]*mxj + bx;
+	sy2 = x[i+1]*myi + y[i+1]*myj + by;
+	bDrawClipLine (buffer, sx1, sy1, sx2, sy2, X0, Y0, X1, Y1);
+      }
+      break;
     }
-  }
-  if (object[0].ptype == 1) {	/* open box */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawRectangle (buffer, sx, sy, 2*D, 2*D);
-	// plot range saturated by bDrawRectOpen
-      }
-    }
-  }
-  if (object[0].ptype == 2) { /* cross */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (buffer, sx - D, sy, sx + D, sy);
-	DrawLine (buffer, sx, sy - D, sx, sy + D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 3) {	/* x */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (buffer, sx + D, sy - D, sx - D, sy + D);
-	DrawLine (buffer, sx - D, sy - D, sx + D, sy + D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 4) {	/* filled triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	// FillTriangle (buffer, sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
-	FillTriangle (buffer, sx, sy + 0.58*D, D, -1.73*D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 14) {	/* filled triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	// FillTriangle (buffer, sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
-	FillTriangle (buffer, sx, sy - 0.58*D, D, +1.73*D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 5) {	/* open triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	OpenTriangle (buffer, sx - D, sy + 0.58*D, sx + D, sy + 0.58*D, sx, sy - 1.15*D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 15) {	/* open triangle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	OpenTriangle (buffer, sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 6) {	/* Y */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (buffer, sx, sy, sx - D, sy - 0.58*D);
-	DrawLine (buffer, sx, sy, sx + D, sy - 0.58*D);
-	DrawLine (buffer, sx, sy, sx,     sy + 1.15*D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 16) {	/* Y */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (buffer, sx, sy, sx - D, sy + 0.58*D);
-	DrawLine (buffer, sx, sy, sx + D, sy + 0.58*D);
-	DrawLine (buffer, sx, sy, sx,     sy - 1.15*D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 7) {	/* 0 */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawCircle (buffer, sx, sy, D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 8) {	/* pentagon */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (buffer, sx + 0.00*D, sy - 1.00*D, sx + 0.95*D, sy - 0.31*D);
-	DrawLine (buffer, sx + 0.95*D, sy - 0.31*D, sx + 0.58*D, sy + 0.81*D);
-	DrawLine (buffer, sx + 0.58*D, sy + 0.81*D, sx - 0.58*D, sy + 0.81*D);
-	DrawLine (buffer, sx - 0.58*D, sy + 0.81*D, sx - 0.95*D, sy - 0.31*D);
-	DrawLine (buffer, sx - 0.95*D, sy - 0.31*D, sx + 0.00*D, sy - 1.00*D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 9) {	/* hexagon */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	DrawLine (buffer, sx -      D, sy,          sx - 0.50*D, sy + 0.87*D);
-	DrawLine (buffer, sx - 0.50*D, sy + 0.87*D, sx + 0.50*D, sy + 0.87*D);
-	DrawLine (buffer, sx + 0.50*D, sy + 0.87*D, sx +      D, sy);
-	DrawLine (buffer, sx +      D, sy,          sx + 0.50*D, sy - 0.87*D);
-	DrawLine (buffer, sx + 0.50*D, sy - 0.87*D, sx - 0.50*D, sy - 0.87*D);
-	DrawLine (buffer, sx - 0.50*D, sy - 0.87*D, sx -      D, sy);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 10) {	/* filled circle */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	FillCircle (buffer, sx, sy, D);
-	// out-of-range points skipped by bDrawLineHorizontal
-      }
-    }
-  }
-  if (object[0].ptype == 12) {	/* filled triangle (down) */
-    for (i = 0; i < object[0].Npts; i++) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx = x[i]*mxi + y[i]*mxj + bx;
-      sy = x[i]*myi + y[i]*myj + by;
-      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
-	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
-      {
-	if (scaleColor) {
-	  if (!finite(z[i])) continue;
-	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
-	  buffer->bColor_R = pixel1[pixel];
-	  buffer->bColor_G = pixel2[pixel];
-	  buffer->bColor_B = pixel3[pixel];
-	}
-	D = scaleSize ? dz*z[i] : ds;
-	// FillTriangle (buffer, sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
-	FillTriangle (buffer, sx, sy + 0.58*D, D, 1.73*D);
-	// out-of-range points skipped by bDrawPoint
-      }
-    }
-  }
-  if (object[0].ptype == 100) {	/* connect a pair of points */
-
-    double X0 = graph[0].axis[0].fx;
-    double X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
-    double Y0 = graph[0].axis[1].fy;
-    double Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
-
-    for (i = 0; i + 1 < object[0].Npts; i+=2) {
-      if (!(finite(x[i]) && finite(y[i]))) continue;
-      sx1 = x[i]*mxi + y[i]*mxj + bx;
-      sy1 = x[i]*myi + y[i]*myj + by;
-      sx2 = x[i+1]*mxi + y[i+1]*mxj + bx;
-      sy2 = x[i+1]*myi + y[i+1]*myj + by;
-      bDrawClipLine (buffer, sx1, sy1, sx2, sy2, X0, Y0, X1, Y1);
-    }
-  }
-
+    case KAPA_POINT_BOX_SOLID:	/* filled box */
+      for (i = 0; i < object[0].Npts; i++) {
+	if (!(finite(x[i]) && finite(y[i]))) continue;
+	sx = x[i]*mxi + y[i]*mxj + bx;
+	sy = x[i]*myi + y[i]*myj + by;
+	if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	    (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	  if (scaleColor) {
+	    if (!finite(z[i])) continue;
+	    int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	    buffer->bColor_R = pixel1[pixel];
+	    buffer->bColor_G = pixel2[pixel];
+	    buffer->bColor_B = pixel3[pixel];
+	  }
+	  D = scaleSize ? dz*z[i] : ds;
+	  FillRectangle (buffer, sx, sy, 2*D, 2*D);
+	  // plot range saturated by bDrawRectFill
+	}
+      }
+      break;
+  }
   free (pixel1);
   free (pixel2);
Index: trunk/Ohana/src/libdvo/include/dvo.h
===================================================================
--- trunk/Ohana/src/libdvo/include/dvo.h	(revision 39907)
+++ trunk/Ohana/src/libdvo/include/dvo.h	(revision 39926)
@@ -114,30 +114,33 @@
 /* Measure.flags values -- these values are 32 bit (as of PS1_V1) */
 typedef enum {
-  ID_MEAS_NOCAL          = 0x00000001,  // detection ignored for this analysis (photcode, time range) -- internal only 
-  ID_MEAS_POOR_PHOTOM    = 0x00000002,  // detection is photometry outlier					     	  
-  ID_MEAS_SKIP_PHOTOM    = 0x00000004,  // detection was ignored for photometry measurement			     	  
-  ID_MEAS_AREA           = 0x00000008,  // detection near image edge						     
-  ID_MEAS_POOR_ASTROM    = 0x00000010,  // detection is astrometry outlier					     	  
-  ID_MEAS_SKIP_ASTROM    = 0x00000020,  // detection was ignored for astrometry measurement			     	  
-  ID_MEAS_USED_OBJ       = 0x00000040,  // detection was used during update objects  
-  ID_MEAS_USED_CHIP      = 0x00000080,  // detection was used during update chips (XXX this probably does not make it into the db)
-  ID_MEAS_BLEND_MEAS     = 0x00000100,  // detection is within radius of multiple objects 
-  ID_MEAS_BLEND_OBJ      = 0x00000200,  // multiple detections within radius of object 
-  ID_MEAS_WARP_USED      = 0x00000400,  // measurement used to find mean warp photometry
-  ID_MEAS_UNMASKED_ASTRO = 0x00000800,  // measurement was not masked in final astrometry fit
-  ID_MEAS_BLEND_MEAS_X   = 0x00001000,  // detection is within radius of multiple objects across catalogs		     
-  ID_MEAS_ARTIFACT       = 0x00002000,  // detection is thought to be non-astronomical				     
-  ID_MEAS_SYNTH_MAG      = 0x00004000,  // magnitude is synthetic
-  ID_MEAS_PHOTOM_UBERCAL = 0x00008000,  // externally-supplied zero point from ubercal analysis
-  ID_MEAS_STACK_PRIMARY  = 0x00010000,  // this stack measurement is in the primary skycell
-  ID_MEAS_STACK_PHOT_SRC = 0x00020000,  // this measurement supplied the stack photometry
-  ID_MEAS_ICRF_QSO       = 0x00040000,  // this measurement is an ICRF reference position
-  ID_MEAS_IMAGE_EPOCH    = 0x00080000,  // this measurement is registered to the image epoch (not tied to ref catalog epoch)
-  ID_MEAS_PHOTOM_PSF     = 0x00100000,  // this measurement is used for the mean psf mag
-  ID_MEAS_PHOTOM_APER    = 0x00200000,  // this measurement is used for the mean ap mag
-  ID_MEAS_PHOTOM_KRON    = 0x00400000,  // this measurement is used for the mean kron mag
-  ID_MEAS_MASKED_PSF     = 0x01000000,  // this measurement is masked based on IRLS weights for mean psf mag
-  ID_MEAS_MASKED_APER    = 0x02000000,  // this measurement is masked based on IRLS weights for mean ap mag
-  ID_MEAS_MASKED_KRON    = 0x04000000,  // this measurement is masked based on IRLS weights for mean kron mag
+  ID_MEAS_NOCAL            = 0x00000001,  // detection ignored for this analysis (photcode, time range) -- internal only 
+  ID_MEAS_POOR_PHOTOM      = 0x00000002,  // detection is photometry outlier					     	  
+  ID_MEAS_SKIP_PHOTOM      = 0x00000004,  // detection was ignored for photometry measurement			     	  
+  ID_MEAS_AREA             = 0x00000008,  // detection near image edge						     
+  ID_MEAS_POOR_ASTROM      = 0x00000010,  // detection is astrometry outlier					     	  
+  ID_MEAS_SKIP_ASTROM      = 0x00000020,  // detection was ignored for astrometry measurement			     	  
+  ID_MEAS_USED_OBJ         = 0x00000040,  // detection was used during update objects  
+  ID_MEAS_USED_CHIP        = 0x00000080,  // detection was used during update chips (XXX this probably does not make it into the db)
+  ID_MEAS_BLEND_MEAS       = 0x00000100,  // detection is within radius of multiple objects 
+  ID_MEAS_BLEND_OBJ        = 0x00000200,  // multiple detections within radius of object 
+  ID_MEAS_WARP_USED        = 0x00000400,  // measurement used to find mean warp photometry
+  ID_MEAS_UNMASKED_ASTRO   = 0x00000800,  // measurement was not masked in final astrometry fit
+  ID_MEAS_BLEND_MEAS_X     = 0x00001000,  // detection is within radius of multiple objects across catalogs		     
+  ID_MEAS_ARTIFACT         = 0x00002000,  // detection is thought to be non-astronomical				     
+  ID_MEAS_SYNTH_MAG        = 0x00004000,  // magnitude is synthetic
+  ID_MEAS_PHOTOM_UBERCAL   = 0x00008000,  // externally-supplied zero point from ubercal analysis
+  ID_MEAS_STACK_PRIMARY    = 0x00010000,  // this stack measurement is in the primary skycell
+  ID_MEAS_STACK_PHOT_SRC   = 0x00020000,  // this measurement supplied the stack photometry
+  ID_MEAS_ICRF_QSO         = 0x00040000,  // this measurement is an ICRF reference position
+  ID_MEAS_IMAGE_EPOCH      = 0x00080000,  // this measurement is registered to the image epoch (not tied to ref catalog epoch)
+  ID_MEAS_PHOTOM_PSF       = 0x00100000,  // this measurement is used for the mean psf mag
+  ID_MEAS_PHOTOM_APER      = 0x00200000,  // this measurement is used for the mean ap mag
+  ID_MEAS_PHOTOM_KRON      = 0x00400000,  // this measurement is used for the mean kron mag
+  ID_MEAS_MASKED_PSF       = 0x01000000,  // this measurement is masked based on IRLS weights for mean psf mag
+  ID_MEAS_MASKED_APER      = 0x02000000,  // this measurement is masked based on IRLS weights for mean ap mag
+  ID_MEAS_MASKED_KRON      = 0x04000000,  // this measurement is masked based on IRLS weights for mean kron mag
+  ID_MEAS_OBJECT_HAS_2MASS = 0x10000000,  // measurement comes from an object with 2mass data
+  ID_MEAS_OBJECT_HAS_GAIA  = 0x20000000,  // measurement comes from an object with gaia data
+  ID_MEAS_OBJECT_HAS_TYCHO = 0x40000000,  // measurement comes from an object with tycho data
 } DVOMeasureFlags;
 
@@ -233,4 +236,10 @@
   ID_SECF_STACK_BESTDET = 0x00008000, // PS1 stack best measurement is a detection (not forced)
   ID_SECF_STACK_PRIMDET = 0x00010000, // PS1 stack primary measurement is a detection (not forced)
+
+  ID_SECF_HAS_SDSS      = 0x00100000, // this photcode has SDSS photometry
+  ID_SECF_HAS_HSC       = 0x00200000, // this photcode has HSC  photometry
+  ID_SECF_HAS_CFH       = 0x00400000, // this photcode has CFH  photometry (mostly Megacam)
+  ID_SECF_HAS_DES       = 0x00800000, // this photcode has DES  photometry
+
   ID_SECF_OBJ_EXT       = 0x01000000, // extended in this band
 
Index: trunk/Ohana/src/libdvo/src/ImageMetadataSelection.c
===================================================================
--- trunk/Ohana/src/libdvo/src/ImageMetadataSelection.c	(revision 39907)
+++ trunk/Ohana/src/libdvo/src/ImageMetadataSelection.c	(revision 39926)
@@ -59,4 +59,6 @@
 }
 
+// note that this function is called by the dvo clients and uses the 'metadata' table
+// generated by the dvo shell for the mosaic images only.
 Coords *MatchMosaicMetadata (unsigned int imageID) { 
 
@@ -73,4 +75,6 @@
   mosaic.crval2 = image[m].crval2;
 
+  // note that image->theta is calculated based on pc1_1, pc1_2 when the metadata file is
+  // generated
   mosaic.pc1_1 =  cos(RAD_DEG*image[m].theta);
   mosaic.pc1_2 =  sin(RAD_DEG*image[m].theta);
Index: trunk/Ohana/src/libdvo/src/coordops.c
===================================================================
--- trunk/Ohana/src/libdvo/src/coordops.c	(revision 39907)
+++ trunk/Ohana/src/libdvo/src/coordops.c	(revision 39926)
@@ -84,4 +84,5 @@
 
   /** extra polynomial terms **/
+  // for ZPN, these are used to modify the radial distance and not the X,Y coords
   if ((coords[0].Npolyterms > 1) && (proj != PROJ_ZPN)) {
     X2 = X*X;
@@ -126,5 +127,7 @@
     if (proj == PROJ_WRP) {
       if (!coords->mosaic) {
-	myAbort ("missing mosaic element");
+	// myAbort ("missing mosaic element");
+	*ra  = L;
+	*dec = M;
 	return (FALSE);
       }
@@ -157,8 +160,17 @@
 	  ctht = 0.0;
 	} else {
-	  T = DEG_RAD / R;
-	  stht =   T / sqrt ( 1.0 + T*T);
-	  ctht = 1.0 / sqrt ( 1.0 + T*T);
+	  // T = DEG_RAD / R; // T in 1/radians
+	  // stht =   T / sqrt ( 1.0 + T*T);
+	  // ctht = 1.0 / sqrt ( 1.0 + T*T);
+
+	  T = RAD_DEG * R;
+	  stht = 1.0 / sqrt ( 1.0 + T*T);
+	  ctht =   T / sqrt ( 1.0 + T*T);
 	}
+	break;
+      case PROJ_SIN:
+	// R = (180/pi) cos (theta)
+	ctht = RAD_DEG * R;
+	stht = sqrt (1 - ctht*ctht);
 	break;
       case PROJ_STG:
@@ -167,9 +179,4 @@
 	ctht = sqrt (1 - stht*stht);
 	break;
-      case PROJ_SIN:
-	// R = (180/pi) cos (theta)
-	ctht = RAD_DEG * R;
-	stht = sqrt (1 - ctht*ctht);
-	break;
       case PROJ_ARC:
 	// R = 90 - theta (degrees)
@@ -177,36 +184,4 @@
 	stht = cos (RAD_DEG * R);
 	break;
-
-      case PROJ_ZPN:
-	// R = 90 - theta (degrees)
-	// this is wrong because we are ignoring the distortion
-	// XXX For now, just solve for terms up to n = 3
-
-	// Ro = (pi/180)(90 - theta)
-	// R = (180/pi)sum (P_i R^i)
-
-	if (UKIRT_ONLY) {
-	  double Ro = RAD_DEG * R;
-	  double P1 = coords[0].polyterms[0][1];
-	  double P3 = coords[0].polyterms[0][3];
-
-	  // find the roots of f(gamma) = P1 gamma + P3 gamma^3 - Ro
-	  // starting guess for gamma is Ro / P1
-	  double gamma = Ro / P1;
-
-	  int i;
-	  for (i = 0; i < 5; i++) {
-	    double F = P1*gamma + P3*gamma*gamma*gamma - Ro;
-	    double dFdgamma = P1 + 3.0*P3*gamma*gamma;
-
-	    double gamma_new = gamma - F / dFdgamma;
-	    gamma = gamma_new;
-	  }
-	  
-	  double theta = 90.0 - gamma * DEG_RAD ;
-	  ctht = cos (RAD_DEG * theta);
-	  stht = sin (RAD_DEG * theta);
-	  break;
-	}
 
       case PROJ_ZEA:
@@ -220,4 +195,51 @@
 	ctht = sqrt (1 - stht*stht);
 	break;
+
+      case PROJ_ZPN:
+
+	// the forward projection is:
+	// theta = atan2(stht, ctht)
+	// gamma = (pi/2 - theta) : theta in radians
+	// Ro = sum (P_i gamma^i)
+	// R  = (180/pi) Ro
+
+	// given R, we need to find theta:
+	// Ro = R * (pi / 180) = sum (P_i gamma^i)
+	// solve sum (P_i gamma^i) - Ro = 0 using Newton-Raphson
+
+	// use Ro to get a guess for gamma and iterate
+
+	{
+	  double Ro = RAD_DEG * R;
+	  
+	  // find the roots of f(gamma) - Ro = 0
+	  // starting guess for gamma is (Ro - P0) / P1
+	  double gamma = (Ro - coords[0].polyterms[0][0]) / coords[0].polyterms[1][0];
+	  
+	  int iter;
+	  for (iter = 0; iter < 5; iter++) {
+	    
+	    double Rc = 0.0; // this will hold the ander 
+	    double dR = 0.0;
+	    for (int i = coords[0].Npolyterms - 1; i > 1; i--) {
+	      double Pi = (i < 7) ? coords[0].polyterms[i][0] : coords[0].polyterms[i-7][1];
+	      Rc = (Rc + Pi)*gamma;
+	      dR = (dR + i*Pi)*gamma;
+	    }
+	    double P0 = coords[0].polyterms[0][0];
+	    double P1 = coords[0].polyterms[1][0];
+	    Rc = (Rc + P1)*gamma + P0;
+	    dR = (dR + P1);
+
+	    double gamma_new = gamma - (Rc - Ro) / dR;
+	    gamma = gamma_new;
+	  }
+	  
+	  double theta = 90.0 - gamma * DEG_RAD ;
+	  ctht = cos (RAD_DEG * theta);
+	  stht = sin (RAD_DEG * theta);
+	  break;
+	}
+
       default:
 	return (FALSE);
@@ -354,32 +376,30 @@
 
       case PROJ_ZPN:
+	// the forward projection is:
+	// theta = atan2(stht, ctht)
+	// gamma = (pi/2 - theta) : theta in radians
+	// Ro = sum (P_i gamma^i)
+	// R  = (180/pi) Ro
+
 	// Ro = (pi/180)(90 - theta)
 	// R = (180/pi)sum (P_i R^i)
+
+	// is ZPN defined for Npolyterms = 0 or 1?
+
 	ctht = hypot(sphi, cphi);
 	theta = atan2 (stht, ctht);
 
-	double Rc;
-	if (UKIRT_ONLY) {
-	  double P1 = coords[0].polyterms[0][1];
-	  double P3 = coords[0].polyterms[0][3];
-	  double gamma = RAD_DEG * (90 - DEG_RAD * theta);
-	  Rc = P1*gamma + P3*gamma*gamma*gamma;
-	} else {
-	  double Ro = RAD_DEG * (90 - DEG_RAD * theta);
-
-	  // i = 0 .. Npolyterms - 1 (1 <= Npolyterms <= 21)
-	  i = coords[0].Npolyterms - 1;
-	  Rc = 0.0;
-	  while (i > 0) {
-	    if (i < 7) {
-	      Rc = (Rc + coords[0].polyterms[0][i])*Ro;
-	    } else {
-	      Rc = (Rc + coords[0].polyterms[1][i-7])*Ro;
-	    }
-	    i --;
-	  }
-	  Rc += coords[0].polyterms[0][i];
+	double Ro;
+	double gamma = M_PI_2 - theta;
+
+	// i = 0 .. Npolyterms - 1 (1 <= Npolyterms <= 21)
+	Ro = 0.0;
+	for (i = coords[0].Npolyterms - 1; i > 0; i --) {
+	  double Pi = (i < 7) ? coords[0].polyterms[i][0] : coords[0].polyterms[i-7][1];
+	  Ro = (Ro + Pi)*gamma;
 	}
-	Rc = DEG_RAD * Rc;
+	Ro += coords[0].polyterms[0][0];
+
+	Rc = DEG_RAD * Ro;
 
 	*L = (ctht == 0.0) ? 0.0 : +Rc * sphi / ctht ;
@@ -609,7 +629,9 @@
 enum {COORD_TYPE_NONE, COORD_TYPE_PC, COORD_TYPE_ROT, COORD_TYPE_CD, COORD_TYPE_LIN};
 
+int GetRadialZPN (Coords *coords, Header *header);
+
 int GetCoords (Coords *coords, Header *header) {
   
-  int i, status, status1, status2, itmp, Polynomial, Polyterm;
+  int status, status1, status2, itmp, Polynomial, Polyterm;
   double Lambda, rotate, rotate1, rotate2, scale;
   double equinox;
@@ -666,8 +688,16 @@
       status &= gfits_scan (header, "PC002002", "%f",  1, &coords[0].pc2_2);
 
+      ctype = &coords[0].ctype[4];
+
+      // read the ZPN coeffients PV2_i (i = 0 < 14)
+      // ZPN is inconsistent with the other Polynomial types
+      if (!strcmp (ctype, "-ZPN")) { 
+	GetRadialZPN (coords, header);
+	break;
+      }
+
       /* set NPLYTERM based on header.  if NPLYTERM is missing, it should have a 
 	 value of 0, unless the projection type is one of PLY, DIS, WRP, in which
 	 case it should be set to 3 */
-      ctype = &coords[0].ctype[4];
       Polynomial = !strcmp (ctype, "-PLY") || !strcmp (ctype, "-DIS") || !strcmp (ctype, "-WRP");
       Polyterm = gfits_scan (header, "NPLYTERM", "%d", 1, &itmp);
@@ -723,4 +753,7 @@
       coords[0].pc2_1 =  sin(rotate*RAD_DEG) / Lambda;
       coords[0].pc2_2 =  cos(rotate*RAD_DEG);
+
+      // read the ZPN coeffients PV2_i (i = 0 < 14)
+      if (!strcmp (&coords[0].ctype[4], "-ZPN")) GetRadialZPN (coords, header);
       break;
 
@@ -744,28 +777,6 @@
       coords[0].pc2_2 /= scale;
 
-      if (!strcmp (&coords[0].ctype[4], "-ZPN")) {
-	int found;
-	for (i = 0; i < 14; i++) {
-	  char name[64];
-	  snprintf (name, 64, "PV2_%d", i);
-	  if (i < 7) {
-	    found = gfits_scan (header, name, "%f", 1, &coords[0].polyterms[0][i]);
-	  } else {
-	    found = gfits_scan (header, name, "%f", 1, &coords[0].polyterms[1][i-7]);
-	  }
-	  if ((i == 0) && !found) {
-	    coords[0].polyterms[0][0] = 0.0;
-	    continue;
-	  }
-	  if ((i == 1) && !found) {
-	    coords[0].polyterms[0][1] = 1.0;
-	    continue;
-	  }
-	  if (!found) {
-	    coords[0].Npolyterms = i;
-	    break;
-	  }
-	}
-      }
+      // read the ZPN coeffients PV2_i (i = 0 < 14)
+      if (!strcmp (&coords[0].ctype[4], "-ZPN")) GetRadialZPN (coords, header);
       break;
 
@@ -819,4 +830,37 @@
   }
   return (status);
+}
+
+int GetRadialZPN (Coords *coords, Header *header) {
+
+  // RA---ZPN can have up to 14 radial polynomial terms.  these are stored in
+  // polyterms[0][0] - [6][0] for the first 7 and [0][1] - [6][1] for the rest
+  // these terms are coeffients of a polynomial of the radial distances
+
+  // read the ZPN coeffients PV2_i (i = 0 < 14)
+  int found;
+  int Nmax = 0;
+  for (int i = 0; i < 14; i++) {
+    char name[64];
+    snprintf (name, 64, "PV2_%d", i);
+    if (i < 7) {
+      coords[0].polyterms[i][0] = 0.0;
+      found = gfits_scan (header, name, "%f", 1, &coords[0].polyterms[i][0]);
+    } else {
+      coords[0].polyterms[i-7][1] = 0.0;
+      found = gfits_scan (header, name, "%f", 1, &coords[0].polyterms[i-7][1]);
+    }
+    // PV2_1 is implicit if not present
+    if ((i == 1) && !found) {
+      coords[0].polyterms[1][0] = 1.0;
+      continue;
+    }
+    // set Npolyterms based on the largest coefficient found
+    if (found) {
+      Nmax = i;
+    }
+  }
+  coords[0].Npolyterms = Nmax + 1;
+  return TRUE;
 }
 
Index: trunk/Ohana/src/libdvo/src/dbExtractMeasures.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 39907)
+++ trunk/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 39926)
@@ -427,8 +427,8 @@
       break;
     case MEAS_TMEAN: /* OK */
+      value.Flt = TimeValue (average[0].Tmean, TimeReference, TimeFormat);
+      break;
+    case MEAS_TRANGE: /* OK */
       value.Flt = GetTimeRange (average[0].Trange, TimeFormat);
-      break;
-    case MEAS_TRANGE: /* OK */
-      value.Flt = TimeValue (average[0].Trange, 0, TimeFormat);
       break;
     case MEAS_NMEAS: /* OK */
@@ -461,12 +461,15 @@
       break;
     case MEAS_RA_FIT_OFFSET: /* OK */
+      // RA_epoch_fit = RA_mean + uR*(t - Tmean)/cos(dec) + plx*parR 
+      // note that this extraction ignores parallax
       dT = (measure[0].t - average[0].Tmean) / (86400*365.25);
-      dR = dvoOffsetR (measure, average);
-      value.Flt = average[0].uR * dT + dR;
+      dR = dvoOffsetR (measure, average); // RA_epoch - RA_mean (** NOT local linear distance **)
+      value.Flt = dR*cos(RAD_DEG*measure[0].D) - average[0].uR * dT;
+      // this is the local linear distance of the measurement from the fit 
       break;
     case MEAS_DEC_FIT_OFFSET: /* OK */
       dT = (measure[0].t - average[0].Tmean) / (86400*365.25);
       dD = dvoOffsetD (measure, average);
-      value.Flt = average[0].uD * dT + dD;
+      value.Flt = dD - average[0].uD * dT;
       break;
     case MEAS_RA_OFFSET_ERR: /* OK */
Index: trunk/Ohana/src/libdvo/src/galaxy_model.c
===================================================================
--- trunk/Ohana/src/libdvo/src/galaxy_model.c	(revision 39907)
+++ trunk/Ohana/src/libdvo/src/galaxy_model.c	(revision 39926)
@@ -28,4 +28,22 @@
     V_sol  =  11.18; // km/sec
     W_sol  =   7.61; // km/sec
+    return TRUE;
+  }
+  if (!strcmp(version, "TEST-CONSTANT")) {
+    // use for testing
+    A_oort = +47.40; // km/sec/kpc
+    B_oort = -47.40; // km/sec/kpc
+    U_sol  =   0.00; // km/sec
+    V_sol  =   0.00; // km/sec
+    W_sol  =   0.00; // km/sec
+    return TRUE;
+  }
+  if (!strcmp(version, "TEST-ZERO")) {
+    // use for testing
+    A_oort =   0.00; // km/sec/kpc
+    B_oort =   0.00; // km/sec/kpc
+    U_sol  =   0.00; // km/sec
+    V_sol  =   0.00; // km/sec
+    W_sol  =   0.00; // km/sec
     return TRUE;
   }
Index: trunk/Ohana/src/libdvo/test/coords.sh
===================================================================
--- trunk/Ohana/src/libdvo/test/coords.sh	(revision 39926)
+++ trunk/Ohana/src/libdvo/test/coords.sh	(revision 39926)
@@ -0,0 +1,62 @@
+
+macro fakeimage-tan
+
+  mcreate test 1000 1000
+
+  keyword test CTYPE1  -w  RA---TAN               ; keyword test CTYPE1  -wc "Algorithm type for axis 1"
+  keyword test CTYPE2  -w  DEC--TAN               ; keyword test CTYPE2  -wc "Algorithm type for axis 2"
+  keyword test CRPIX1  -wf     2997.03245628555   ; keyword test CRPIX1  -wc "Dither offset Y"
+  keyword test CRPIX2  -wf    -944.140242055343   ; keyword test CRPIX2  -wc "Dither offset Y"
+  keyword test CRVAL1  -wf     207.605373039722   ; keyword test CRVAL1  -wc "[deg] Right ascension at the reference pixel"
+  keyword test CRVAL2  -wf    0.113109076969833   ; keyword test CRVAL2  -wc "[deg] Declination at the reference pixel"
+  keyword test CRUNIT1 -w  deg                    ; keyword test CRUNIT1 -wc "Unit of right ascension co-ordinates"
+  keyword test CRUNIT2 -w  deg                    ; keyword test CRUNIT2 -wc "Unit of declination co-ordinates"
+  keyword test CD1_1   -wf -3.34355087531346E-07  ; keyword test CD1_1   -wc "Transformation matrix element"
+  keyword test CD1_2   -wf -0.000111484161257407  ; keyword test CD1_2   -wc "Transformation matrix element"
+  keyword test CD2_1   -wf  0.000111383424202905  ; keyword test CD2_1   -wc "Transformation matrix element"
+  keyword test CD2_2   -wf -3.65044007533155E-07  ; keyword test CD2_2   -wc "Transformation matrix element"
+  # keyword test PV2_1   -wf         1.000000E+00   ; keyword test -c Pol.coeff. for pixel -> celestial coord       
+  # keyword test PV2_2   -wf         0.000000E+00   ; keyword test -c Pol.coeff. for pixel -> celestial coord       
+  # keyword test PV2_3   -wf                 -50.                                                 
+
+end
+
+macro fakeimage-zpn1
+
+  mcreate test 1000 1000
+
+  keyword test CTYPE1  -w  RA---ZPN               ; keyword test CTYPE1  -wc "Algorithm type for axis 1"
+  keyword test CTYPE2  -w  DEC--ZPN               ; keyword test CTYPE2  -wc "Algorithm type for axis 2"
+  keyword test CRPIX1  -wf     2997.03245628555   ; keyword test CRPIX1  -wc "Dither offset Y"
+  keyword test CRPIX2  -wf    -944.140242055343   ; keyword test CRPIX2  -wc "Dither offset Y"
+  keyword test CRVAL1  -wf     207.605373039722   ; keyword test CRVAL1  -wc "[deg] Right ascension at the reference pixel"
+  keyword test CRVAL2  -wf    0.113109076969833   ; keyword test CRVAL2  -wc "[deg] Declination at the reference pixel"
+  keyword test CRUNIT1 -w  deg                    ; keyword test CRUNIT1 -wc "Unit of right ascension co-ordinates"
+  keyword test CRUNIT2 -w  deg                    ; keyword test CRUNIT2 -wc "Unit of declination co-ordinates"
+  keyword test CD1_1   -wf -3.34355087531346E-07  ; keyword test CD1_1   -wc "Transformation matrix element"
+  keyword test CD1_2   -wf -0.000111484161257407  ; keyword test CD1_2   -wc "Transformation matrix element"
+  keyword test CD2_1   -wf  0.000111383424202905  ; keyword test CD2_1   -wc "Transformation matrix element"
+  keyword test CD2_2   -wf -3.65044007533155E-07  ; keyword test CD2_2   -wc "Transformation matrix element"
+  keyword test PV2_1   -wf         1.000000E+00   ; keyword test PV2_1   -wc "Pol.coeff. for pixel -> celestial coord"
+  keyword test PV2_2   -wf         0.000000E+00   ; keyword test PV2_2   -wc "Pol.coeff. for pixel -> celestial coord"
+  keyword test PV2_3   -wf                 -50. 
+
+end
+
+macro test.coords
+  for ix 50 5000 500
+    for iy 50 5000 500
+      coords test -p $ix $iy
+      coords test -c $RA $DEC
+      if (abs($ix - $Xc) > 0.01) 
+	echo bad
+        break
+      end
+      if (abs($iy - $Yc) > 0.01) 
+	echo bad
+        break
+      end
+    end
+  end
+end
+
Index: trunk/Ohana/src/libfits/header/F_H_field.c
===================================================================
--- trunk/Ohana/src/libfits/header/F_H_field.c	(revision 39907)
+++ trunk/Ohana/src/libfits/header/F_H_field.c	(revision 39926)
@@ -90,4 +90,5 @@
       ptr = buf + 9; // start of following keyword
       if (strncmp (field, ptr, Nfield)) continue;
+      if (ptr[Nfield + 1] != '=') continue; // the strncmp above will match a longer string which matches the subset of field (e.g., FOO will match FOOBAR and FOO).  test for the following '=' sign
       Nfound ++;
       if (Nfound == N) return (ptr);
Index: trunk/Ohana/src/libkapa/Makefile
===================================================================
--- trunk/Ohana/src/libkapa/Makefile	(revision 39907)
+++ trunk/Ohana/src/libkapa/Makefile	(revision 39926)
@@ -34,4 +34,5 @@
 $(SRC)/KapaWindow.$(ARCH).o \
 $(SRC)/KapaColors.$(ARCH).o \
+$(SRC)/KapaStyles.$(ARCH).o \
 $(SRC)/KapaOpen.$(ARCH).o
 
Index: trunk/Ohana/src/libkapa/include/kapa.h
===================================================================
--- trunk/Ohana/src/libkapa/include/kapa.h	(revision 39907)
+++ trunk/Ohana/src/libkapa/include/kapa.h	(revision 39926)
@@ -25,29 +25,45 @@
 typedef struct sockaddr_in KapaSockAddress;
 
-typedef struct {
-  float *data1d;
-  float **data2d;
-  int Nx;
-  int Ny;
-} KiiImage;
-
-typedef struct {
-  float x;
-  float y;
-  float dx;
-  float dy;
-  float angle;
-  int type;
-} KiiOverlayBase;
-
-typedef struct {
-  float x;
-  float y;
-  float dx;
-  float dy;
-  float angle;
-  int type;
-  char *text;
-} KiiOverlay;
+// retain historical numerical definitions:
+typedef enum {
+  KAPA_LINE_INVALID_MIN = -1,
+  KAPA_LINE_SOLID       = 0,
+  KAPA_LINE_DOT         = 1,
+  KAPA_LINE_DASH_SHORT  = 2,
+  KAPA_LINE_DASH_LONG   = 3,
+  KAPA_LINE_DOT_DASH    = 4,
+  KAPA_LINE_INVALID_MAX = 5,
+} KapaLineType;
+
+// retain historical numerical definitions:
+typedef enum {
+  KAPA_PLOT_INVALID_MIN = -1,
+  KAPA_PLOT_CONNECT     =  0,
+  KAPA_PLOT_HISTOGRAM   =  1,
+  KAPA_PLOT_POINTS      =  2,
+  KAPA_PLOT_INVALID_MAX =  3,
+} KapaPlotStyle;
+
+typedef enum {
+  KAPA_POINT_INVALID_MIN         = -1,
+  KAPA_POINT_BOX_SOLID           =  0,
+  KAPA_POINT_BOX_OPEN            =  1,
+  KAPA_POINT_CROSS               =  2, // OR PLUS
+  KAPA_POINT_X                   =  3, 
+  KAPA_POINT_Y                   =  4, 
+  KAPA_POINT_TRIANGLE_SOLID      =  5, 
+  KAPA_POINT_TRIANGLE_OPEN       =  6, 
+  KAPA_POINT_CIRCLE_OPEN         =  7, 
+  KAPA_POINT_PENTAGON            =  8, 
+  KAPA_POINT_HEXAGON             =  9, 
+  KAPA_POINT_CIRCLE_SOLID        = 10, 
+  KAPA_POINT_TRIANGLE_SOLID_DOWN = 11, 
+  KAPA_POINT_TRIANGLE_OPEN_DOWN  = 12, 
+  KAPA_POINT_Y_DOWN              = 13, 
+  KAPA_POINT_INVALID_MAX         = 14,
+  KAPA_POINT_PAIR_CONNECT        = 100, // change to a plot style?
+} KapaPointStyle;
+// note that PAIR_CONNECT was historically 100
+
 
 typedef enum {
@@ -75,4 +91,30 @@
   KAPA_PS_RAWPAGE
 } KapaPSmode;
+
+typedef struct {
+  float *data1d;
+  float **data2d;
+  int Nx;
+  int Ny;
+} KiiImage;
+
+typedef struct {
+  float x;
+  float y;
+  float dx;
+  float dy;
+  float angle;
+  int type;
+} KiiOverlayBase;
+
+typedef struct {
+  float x;
+  float y;
+  float dx;
+  float dy;
+  float angle;
+  int type;
+  char *text;
+} KiiOverlay;
 
 typedef struct {
@@ -219,4 +261,9 @@
 unsigned long *KapaX11colors (Display *display, Colormap colormap, unsigned long default_color, int *Ncolors);
 
+/* KapaStyles.c */
+KapaLineType KapaLineTypeFromString (char *string);
+KapaPlotStyle KapaPlotStyleFromString (char *string);
+KapaPointStyle KapaPointStyleFromString (char *string);
+
 /* RotFont.c */
 void InitRotFonts PROTO((void));
Index: trunk/Ohana/src/libkapa/src/KapaOpen.c
===================================================================
--- trunk/Ohana/src/libkapa/src/KapaOpen.c	(revision 39907)
+++ trunk/Ohana/src/libkapa/src/KapaOpen.c	(revision 39926)
@@ -6,5 +6,5 @@
 # define MY_PORT 2500
 # define MY_PORT_MAX 2520
-# define MY_WAIT 100000
+# define MY_WAIT 1000000
 # define DEBUG 0
 
Index: trunk/Ohana/src/libkapa/src/KapaStyles.c
===================================================================
--- trunk/Ohana/src/libkapa/src/KapaStyles.c	(revision 39926)
+++ trunk/Ohana/src/libkapa/src/KapaStyles.c	(revision 39926)
@@ -0,0 +1,140 @@
+# include <kapa_internal.h>
+
+KapaLineType KapaLineTypeFromString (char *string) {
+
+  char *endptr;
+
+  int iValue = strtol (string, &endptr, 10);
+  if (*endptr == 0) {
+    if ((iValue > KAPA_LINE_INVALID_MIN) && 
+	(iValue < KAPA_LINE_INVALID_MAX)) {
+      return iValue;
+    }
+    // silently return a valid value?
+    return KAPA_LINE_SOLID;
+  }
+
+  if (!strcasecmp (string,  "solid"))     return KAPA_LINE_SOLID;
+  if (!strcasecmp (string,  "dot"))       return KAPA_LINE_DOT;
+  if (!strcasecmp (string,  "longdash"))  return KAPA_LINE_DASH_LONG;
+  if (!strcasecmp (string,  "shortdash")) return KAPA_LINE_DASH_SHORT;
+  if (!strcasecmp (string,  "dotdash"))   return KAPA_LINE_DOT_DASH;
+
+  if (!strcasecmp (string,  "dash"))      return KAPA_LINE_DASH_LONG;
+  if (!strcasecmp (string,  "dashdot"))   return KAPA_LINE_DOT_DASH;
+
+  return KAPA_LINE_SOLID;
+}
+
+KapaPlotStyle KapaPlotStyleFromString (char *string) {
+
+  char *endptr;
+
+  int iValue = strtol (string, &endptr, 10);
+  if (*endptr == 0) {
+    if ((iValue > KAPA_PLOT_INVALID_MIN) && 
+	(iValue < KAPA_PLOT_INVALID_MAX)) {
+      return iValue;
+    }
+    // silently return a valid value?
+    return KAPA_PLOT_POINTS;
+  }
+
+  if (!strcasecmp (string,  "points"))    return KAPA_PLOT_POINTS;
+  if (!strcasecmp (string,  "pts"))       return KAPA_PLOT_POINTS;
+  if (!strcasecmp (string,  "connect"))   return KAPA_PLOT_CONNECT;
+  if (!strcasecmp (string,  "line"))      return KAPA_PLOT_CONNECT;
+  if (!strcasecmp (string,  "histogram")) return KAPA_PLOT_HISTOGRAM;
+
+  if (strlen(string) > 2) {
+    if (!strncasecmp (string, "histogram", strlen(string))) return KAPA_PLOT_HISTOGRAM;
+    if (!strncasecmp (string, "connect",   strlen(string))) return KAPA_PLOT_CONNECT;
+    if (!strncasecmp (string, "points",    strlen(string))) return KAPA_PLOT_POINTS;
+  }
+  // silently return a valid value?
+  return KAPA_PLOT_POINTS;
+}
+
+KapaPointStyle KapaPointStyleFromString (char *string) {
+
+  char *endptr;
+
+  int iValue = strtol (string, &endptr, 10);
+  if (*endptr == 0) {
+    // note that PAIR_CONNECT was historically 100 [outside MIN - MAX]
+    if (iValue == KAPA_POINT_PAIR_CONNECT) return iValue;
+    if ((iValue > KAPA_POINT_INVALID_MIN) && 
+	(iValue < KAPA_POINT_INVALID_MAX)) {
+      return iValue;
+    }
+    // silently return a valid value?
+    return KAPA_POINT_BOX_SOLID;
+  }
+
+  if (!strcasecmp (string,  "box"))              return KAPA_POINT_BOX_SOLID;
+  if (!strcasecmp (string,  "circle"))           return KAPA_POINT_CIRCLE_SOLID        ;
+  if (!strcasecmp (string,  "cross"))            return KAPA_POINT_CROSS               ;
+  if (!strcasecmp (string,  "fbox"))             return KAPA_POINT_BOX_SOLID;
+  if (!strcasecmp (string,  "fcircle"))          return KAPA_POINT_CIRCLE_SOLID        ;
+  if (!strcasecmp (string,  "fhexagon"))         return KAPA_POINT_HEXAGON             ;
+  if (!strcasecmp (string,  "fpentagon"))        return KAPA_POINT_PENTAGON            ;
+  if (!strcasecmp (string,  "ftriangle"))        return KAPA_POINT_TRIANGLE_SOLID      ;
+  if (!strcasecmp (string,  "ftriangledown"))    return KAPA_POINT_TRIANGLE_SOLID_DOWN ;
+  if (!strcasecmp (string,  "ftridown"))         return KAPA_POINT_TRIANGLE_SOLID_DOWN ;
+  if (!strcasecmp (string,  "hexagon"))          return KAPA_POINT_HEXAGON             ;
+  if (!strcasecmp (string,  "obox"))             return KAPA_POINT_BOX_OPEN;
+  if (!strcasecmp (string,  "ocircle"))          return KAPA_POINT_CIRCLE_OPEN         ;
+  if (!strcasecmp (string,  "openbox"))          return KAPA_POINT_BOX_OPEN            ;
+  if (!strcasecmp (string,  "opencircle"))       return KAPA_POINT_CIRCLE_OPEN         ;
+  if (!strcasecmp (string,  "opentriangle"))     return KAPA_POINT_TRIANGLE_OPEN       ;
+  if (!strcasecmp (string,  "opentriangledown")) return KAPA_POINT_TRIANGLE_OPEN_DOWN  ;
+  if (!strcasecmp (string,  "otriangle"))        return KAPA_POINT_TRIANGLE_OPEN       ;
+  if (!strcasecmp (string,  "otriangledown"))    return KAPA_POINT_TRIANGLE_OPEN_DOWN  ;
+  if (!strcasecmp (string,  "otridown"))         return KAPA_POINT_TRIANGLE_OPEN_DOWN  ;
+  if (!strcasecmp (string,  "pairs"))            return KAPA_POINT_PAIR_CONNECT;
+  if (!strcasecmp (string,  "pentagon"))         return KAPA_POINT_PENTAGON            ;
+  if (!strcasecmp (string,  "plus"))             return KAPA_POINT_CROSS               ;
+  if (!strcasecmp (string,  "solidtriangle"))    return KAPA_POINT_TRIANGLE_SOLID      ;
+  if (!strcasecmp (string,  "triangle"))         return KAPA_POINT_TRIANGLE_SOLID      ;
+  if (!strcasecmp (string,  "triangledown"))     return KAPA_POINT_TRIANGLE_SOLID_DOWN ;
+  if (!strcasecmp (string,  "tridown"))          return KAPA_POINT_TRIANGLE_SOLID_DOWN ;
+  if (!strcasecmp (string,  "x"))                return KAPA_POINT_X                   ;
+  if (!strcasecmp (string,  "y"))                return KAPA_POINT_Y                   ;
+  if (!strcasecmp (string,  "ydown"))            return KAPA_POINT_Y_DOWN              ;
+
+  int Nchar = strlen(string);
+  if (Nchar > 2) {
+    if (!strncasecmp (string,  "box", Nchar))              return KAPA_POINT_BOX_SOLID           ;
+    if (!strncasecmp (string,  "circle", Nchar))           return KAPA_POINT_CIRCLE_SOLID        ;
+    if (!strncasecmp (string,  "cross", Nchar))            return KAPA_POINT_CROSS               ;
+    if (!strncasecmp (string,  "fbox", Nchar))             return KAPA_POINT_BOX_SOLID;
+    if (!strncasecmp (string,  "fcircle", Nchar))          return KAPA_POINT_CIRCLE_SOLID        ;
+    if (!strncasecmp (string,  "fhexagon", Nchar))         return KAPA_POINT_HEXAGON             ;
+    if (!strncasecmp (string,  "fpentagon", Nchar))        return KAPA_POINT_PENTAGON            ;
+    if (!strncasecmp (string,  "ftriangle", Nchar))        return KAPA_POINT_TRIANGLE_SOLID      ;
+    if (!strncasecmp (string,  "ftriangledown", Nchar))    return KAPA_POINT_TRIANGLE_SOLID_DOWN ;
+    if (!strncasecmp (string,  "ftridown", Nchar))         return KAPA_POINT_TRIANGLE_SOLID_DOWN ;
+    if (!strncasecmp (string,  "hexagon", Nchar))          return KAPA_POINT_HEXAGON             ;
+    if (!strncasecmp (string,  "obox", Nchar))             return KAPA_POINT_BOX_OPEN;
+    if (!strncasecmp (string,  "ocircle", Nchar))          return KAPA_POINT_CIRCLE_OPEN         ;
+    if (!strncasecmp (string,  "openbox", Nchar))          return KAPA_POINT_BOX_OPEN            ;
+    if (!strncasecmp (string,  "opencircle", Nchar))       return KAPA_POINT_CIRCLE_OPEN         ;
+    if (!strncasecmp (string,  "opentriangle", Nchar))     return KAPA_POINT_TRIANGLE_OPEN       ;
+    if (!strncasecmp (string,  "opentriangledown", Nchar)) return KAPA_POINT_TRIANGLE_OPEN_DOWN  ;
+    if (!strncasecmp (string,  "opentridown", Nchar))      return KAPA_POINT_TRIANGLE_OPEN_DOWN  ;
+    if (!strncasecmp (string,  "otriangle", Nchar))        return KAPA_POINT_TRIANGLE_OPEN       ;
+    if (!strncasecmp (string,  "otriangledown", Nchar))    return KAPA_POINT_TRIANGLE_OPEN_DOWN  ;
+    if (!strncasecmp (string,  "otridown", Nchar))         return KAPA_POINT_TRIANGLE_OPEN_DOWN  ;
+    if (!strncasecmp (string,  "pairs", Nchar))            return KAPA_POINT_PAIR_CONNECT;
+    if (!strncasecmp (string,  "pentagon", Nchar))         return KAPA_POINT_PENTAGON            ;
+    if (!strncasecmp (string,  "plus", Nchar))             return KAPA_POINT_CROSS               ;
+    if (!strncasecmp (string,  "solidtriangle", Nchar))    return KAPA_POINT_TRIANGLE_SOLID      ;
+    if (!strncasecmp (string,  "triangle", Nchar))         return KAPA_POINT_TRIANGLE_SOLID      ;
+    if (!strncasecmp (string,  "triangledown", Nchar))     return KAPA_POINT_TRIANGLE_SOLID_DOWN ;
+    if (!strncasecmp (string,  "tridown", Nchar))          return KAPA_POINT_TRIANGLE_SOLID_DOWN ;
+    if (!strncasecmp (string,  "ydown", Nchar))            return KAPA_POINT_Y_DOWN              ;
+  }
+
+  return KAPA_POINT_BOX_SOLID;
+}
+
Index: trunk/Ohana/src/libkapa/src/KapaWindow.c
===================================================================
--- trunk/Ohana/src/libkapa/src/KapaWindow.c	(revision 39907)
+++ trunk/Ohana/src/libkapa/src/KapaWindow.c	(revision 39926)
@@ -449,2 +449,3 @@
   return (TRUE);
 }
+
Index: trunk/Ohana/src/libkapa/src/bDrawFuncs.c
===================================================================
--- trunk/Ohana/src/libkapa/src/bDrawFuncs.c	(revision 39907)
+++ trunk/Ohana/src/libkapa/src/bDrawFuncs.c	(revision 39926)
@@ -222,6 +222,16 @@
   e = 0;
   for (X = X1, N = 0; X <= X2; X++, N++) {
-    if (buffer->bType == 1) { DashOn = (N % 10) < 5; }
-    if (buffer->bType == 2) { DashOn = (N % 6) < 3; }
+    if (buffer->bType == KAPA_LINE_DOT) {
+      DashOn = (N % 5) == 0 || (N % 5) == 1;
+    }
+    if (buffer->bType == KAPA_LINE_DASH_SHORT) {
+      DashOn = (N % 8) < 4;
+    }
+    if (buffer->bType == KAPA_LINE_DASH_LONG) {
+      DashOn = (N % 16) < 8;
+    }
+    if (buffer->bType == KAPA_LINE_DOT_DASH) {
+      DashOn = ((N % 12) < 2) || ((N % 12 >= 6) && (N % 12 < 10)) ;
+    }
     if (swapcoords) {
       if (DashOn) bDrawPoint (buffer, Y,X);
Index: trunk/Ohana/src/opihi/cmd.astro/csystem.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.astro/csystem.c	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.astro/csystem.c	(revision 39926)
@@ -125,6 +125,6 @@
   opihi_flt *yptr = yvec[0].elements.Flt;
 
-  opihi_flt *uxptr = uxvec ? xvec[0].elements.Flt : NULL;
-  opihi_flt *uyptr = uyvec ? yvec[0].elements.Flt : NULL;
+  opihi_flt *uxptr = uxvec ? uxvec[0].elements.Flt : NULL;
+  opihi_flt *uyptr = uyvec ? uyvec[0].elements.Flt : NULL;
 
   for (i = 0; i < xvec[0].Nelements; i++, xptr++, yptr++) {
Index: trunk/Ohana/src/opihi/cmd.astro/fitplx_irls.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.astro/fitplx_irls.c	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.astro/fitplx_irls.c	(revision 39926)
@@ -158,6 +158,6 @@
     // now that the mask has been updated, we need to recalculate mean epoch and positions
     // XXX make this conditional on actually masking unmasked points above
-    PlxSetMeanEpoch (R, D, T, &Rmean, &Dmean, &Tmean, mask, Ntotal);
-    PlxSetEpochPosition (&fitdata, R, D, dR, dD, T, mask, Ntotal, &coords, Tmean);
+    // PlxSetMeanEpoch (R, D, T, &Rmean, &Dmean, &Tmean, mask, Ntotal);
+    // PlxSetEpochPosition (&fitdata, R, D, dR, dD, T, mask, Ntotal, &coords, Tmean);
 
     PlxFitData sample;
@@ -218,13 +218,37 @@
   // fprintf (stderr, "%f +/- %f | %f %f\n", fit.p, fit.dp, fit.uR, fit.uD);
 
-/*
-  FILE *f = fopen ("test.pf.dat", "w");
+  Vector *dRresPMP, *dDresPMP, *dRresPLX, *dDresPLX;
+
+  // save fit residuals (with only pm removed, and pm and plx removed)
+  if ((dRresPMP = SelectVector ("dRresPMP", ANYVECTOR, TRUE)) == NULL) ESCAPE ("cannot generate vector %s\n", "dRresPMP");
+  if ((dDresPMP = SelectVector ("dDresPMP", ANYVECTOR, TRUE)) == NULL) ESCAPE ("cannot generate vector %s\n", "dDresPMP");
+  if ((dRresPLX = SelectVector ("dRresPLX", ANYVECTOR, TRUE)) == NULL) ESCAPE ("cannot generate vector %s\n", "dRresPLX");
+  if ((dDresPLX = SelectVector ("dDresPLX", ANYVECTOR, TRUE)) == NULL) ESCAPE ("cannot generate vector %s\n", "dDresPLX");
+    
+  ResetVector (dRresPMP, OPIHI_FLT, Ntotal);
+  ResetVector (dDresPMP, OPIHI_FLT, Ntotal);
+  ResetVector (dRresPLX, OPIHI_FLT, Ntotal);
+  ResetVector (dDresPLX, OPIHI_FLT, Ntotal);
+  
   for (i = 0; i < Ntotal; i++) {
-    double Xf = fit.Ro + fit.uR*fitdata.t[i] + fit.p*fitdata.pX[i];
-    double Yf = fit.Do + fit.uD*fitdata.t[i] + fit.p*fitdata.pY[i];
-    fprintf (f, "%f : %f %f : %f %f : %f : %f %f : %f %f\n", T[i], R[i], D[i], Xf, Yf, fitdata.t[i], fitdata.X[i], fitdata.Y[i], fitdata.pX[i], fitdata.pY[i]);
-  }
-  fclose (f);
-*/
+    
+    double x0, y0;
+    RD_to_XY (&x0, &y0, R[i], D[i], &coords);
+
+    double pX0, pY0;
+    ParFactor (&pX0, &pY0, R[i], D[i], T[i]);
+
+    double t0 = (T[i] - Tmean)/365.25;
+
+    double Xpmp = fit.Ro + fit.uR*t0 + fit.p*pX0;
+    double Ypmp = fit.Do + fit.uD*t0 + fit.p*pY0;
+    double Xplx = fit.Ro + fit.uR*t0;
+    double Yplx = fit.Do + fit.uD*t0;
+
+    dRresPMP->elements.Flt[i] = x0 - Xpmp;
+    dDresPMP->elements.Flt[i] = y0 - Ypmp;
+    dRresPLX->elements.Flt[i] = x0 - Xplx;
+    dDresPLX->elements.Flt[i] = y0 - Yplx;
+  }
 
   // fprintf (stderr, "Roff, Doff: %f, %f; dRo, dDo: %f, %f\n", fit.Ro, fit.Do, fit.dRo, fit.dDo);
Index: trunk/Ohana/src/opihi/cmd.astro/spex1dgas.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.astro/spex1dgas.c	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.astro/spex1dgas.c	(revision 39926)
@@ -108,12 +108,7 @@
   IDList = NULL;
   XoList = NULL;
-  { 
-    // init random numbers
-    long A, B;
-    A = time(NULL);
-    for (B = 0; A == time(NULL); B++);
-    srand48(B);
-  }
  
+  // srand48() is called by startup.c
+
   if (argc != 11) goto usage;
 
Index: trunk/Ohana/src/opihi/cmd.astro/spex2dgas.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.astro/spex2dgas.c	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.astro/spex2dgas.c	(revision 39926)
@@ -120,12 +120,6 @@
   float XoMax, YoMax;
 
-  { 
-    // init random numbers
-    long A, B;
-    A = time(NULL);
-    for (B = 0; A == time(NULL); B++);
-    srand48(B);
-  }
- 
+  // srand48() is called by startup.c
+
   if (argc != 9) goto usage;
 
Index: trunk/Ohana/src/opihi/cmd.astro/spexseq.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.astro/spexseq.c	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.astro/spexseq.c	(revision 39926)
@@ -90,13 +90,7 @@
   int Nobject = 0;
 
-  { 
-    // init random numbers
-    long A, B;
-    A = time(NULL);
-    for (B = 0; A == time(NULL); B++);
-    srand48(B);
-  }
- 
   if (argc != 6) goto usage;
+
+  // srand48() is called by startup.c
 
   // XXX enforce matching lengths on the three vectors
Index: trunk/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 39926)
@@ -124,4 +124,5 @@
 $(SRC)/resize.$(ARCH).o		\
 $(SRC)/relocate.$(ARCH).o	\
+$(SRC)/rndseed.$(ARCH).o		\
 $(SRC)/roll.$(ARCH).o		\
 $(SRC)/rotate.$(ARCH).o	\
Index: trunk/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/init.c	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.data/init.c	(revision 39926)
@@ -113,4 +113,5 @@
 int reindex          PROTO((int, char **));
 int relocate         PROTO((int, char **));
+int rndseed          PROTO((int, char **));
 int roll             PROTO((int, char **));
 int rotate           PROTO((int, char **));
@@ -293,4 +294,5 @@
   {1, "relocate",     relocate,         "set graphics/image window position"},
   {1, "roll",         roll,             "roll image to new start point"},
+  {1, "rndseed",      rndseed,          "set the pseudo-random seed"},
   {1, "rotate",       rotate,           "rotate image"},
   {1, "save",         save,             "save an SAOimage style image overlay"},
Index: trunk/Ohana/src/opihi/cmd.data/match2d.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/match2d.c	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.data/match2d.c	(revision 39926)
@@ -1,6 +1,9 @@
 # include "data.h"
 
-int find_matches2d (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2);
+int find_matches2d (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2, Vector *radiusMatch);
 int find_matches2d_closest (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index);
+
+int find_matches2d_sphere (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2, Vector *radiusMatch);
+int find_matches2d_sphere_closest (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index);
 
 // match2d (X1) (Y1) (X2) (Y2) (Radius) [-index1 (index1)] [-index2 (index2)] [-nomatch1 nomatch1] [-nomatch2 nomatch2]
@@ -23,4 +26,14 @@
   }
 
+  int SPHERE_DISTANCE = FALSE;
+  if ((N = get_argument (argc, argv, "-sphere"))) {
+    remove_argument (N, &argc, argv);
+    SPHERE_DISTANCE = TRUE;
+  }
+  if ((N = get_argument (argc, argv, "-sky"))) {
+    remove_argument (N, &argc, argv);
+    SPHERE_DISTANCE = TRUE;
+  }
+
   if ((N = get_argument (argc, argv, "-index1"))) {
     remove_argument (N, &argc, argv);
@@ -37,4 +50,16 @@
   } else {
     if ((index2 = SelectVector ("index2", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+  }
+
+  
+  Vector *radiusMatch = NULL;
+  if ((N = get_argument (argc, argv, "-radius"))) {
+    if (CLOSEST) {
+      gprint (GP_ERR, "error: -radius and -closest are currently incompatible\n");
+      return (FALSE);
+    }
+    remove_argument (N, &argc, argv);
+    if ((radiusMatch = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    remove_argument (N, &argc, argv);
   }
 
@@ -84,11 +109,19 @@
   }
 
-  if (CLOSEST) {
+  if (SPHERE_DISTANCE) {
+    if (CLOSEST) {
+      find_matches2d_sphere_closest (X1vec, Y1vec, X2vec, Y2vec, Radius, index1);
+      find_matches2d_sphere_closest (X2vec, Y2vec, X1vec, Y1vec, Radius, index2);
+    } else {
+      find_matches2d_sphere (X1vec, Y1vec, X2vec, Y2vec, Radius, index1, index2, radiusMatch);
+    }
+  } else {
+    if (CLOSEST) {
       find_matches2d_closest (X1vec, Y1vec, X2vec, Y2vec, Radius, index1);
       find_matches2d_closest (X2vec, Y2vec, X1vec, Y1vec, Radius, index2);
-  } else {
-      find_matches2d (X1vec, Y1vec, X2vec, Y2vec, Radius, index1, index2);
-  }
-
+    } else {
+      find_matches2d (X1vec, Y1vec, X2vec, Y2vec, Radius, index1, index2, radiusMatch);
+    }
+  }
   return (TRUE);
 
@@ -108,9 +141,13 @@
   gprint (GP_ERR, "use 'reindex' to generate new vectors based on these index vectors\n");
 
+  gprint (GP_ERR, "if -sphere or -sky is supplied, (x1,y1) and (x2,y2) are treaded as (ra,dec) or (long,lat) pairs in degrees\n");
+
+  gprint (GP_ERR, "if -radius (vector) is supplied, the vector will be filled with the distance between the matched pairs\n");
+  gprint (GP_ERR, "  not valid with -closest\n");
   return FALSE;
 }
 
 // we are not defining a relative offset DX,DY for now
-int find_matches2d (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2) {
+int find_matches2d (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2, Vector *radiusMatch) {
   
   off_t i, j, first_j, I, J, *N1, *N2, Nmatch, NMATCH, DMATCH;
@@ -122,4 +159,5 @@
   ResetVector (index1, OPIHI_INT, NMATCH);
   ResetVector (index2, OPIHI_INT, NMATCH);
+  if (radiusMatch) ResetVector (radiusMatch, OPIHI_FLT, NMATCH);
 
   ALLOCATE (N1, off_t, X1->Nelements);
@@ -154,4 +192,5 @@
 	index1->elements.Int[Nmatch] = I;
 	index2->elements.Int[Nmatch] = J;
+	if (radiusMatch) radiusMatch->elements.Flt[Nmatch] = dR;
 
 	// XXX track matches 1 and 2 with internal vector, save new nomatch index vectors
@@ -163,4 +202,5 @@
 	  REALLOCATE (index1->elements.Int, opihi_int, NMATCH);
 	  REALLOCATE (index2->elements.Int, opihi_int, NMATCH);
+	  if (radiusMatch) { REALLOCATE (radiusMatch->elements.Flt, opihi_flt, NMATCH); }
 	}
       }
@@ -171,4 +211,5 @@
   index1->Nelements = Nmatch;
   index2->Nelements = Nmatch;
+  if (radiusMatch) radiusMatch->Nelements = Nmatch;
 
   free (N1);
@@ -246,2 +287,231 @@
   return (TRUE);
 }
+
+double gcdist (double r1, double d1, double r2, double d2) {
+  double num,den;
+  r1 *= RAD_DEG;
+  d1 *= RAD_DEG;
+  r2 *= RAD_DEG;
+  d2 *= RAD_DEG;
+
+  num = sqrt(pow((cos(d2) * sin(r2 - r1)),2) +
+	     pow((cos(d1) * sin(d2) -
+		  sin(d1) * cos(d2) * cos(r2 - r1)),2));
+  den = (sin(d1) * sin(d2) + cos(d1) * cos(d2) * cos(r2 - r1));
+  return(atan2(num,den) * (180 / M_PI));
+}
+
+typedef struct {
+  double sD;
+  double cD;
+  double sR;
+  double cR;
+} Match2D_PreCalc;
+
+double gcdist_PreCalc_v0 (Match2D_PreCalc *p1, Match2D_PreCalc *p2) {
+  double num,den;
+
+  num = sqrt(pow((p2->cD * (p2->sR*p1->cR - p1->sR*p2->cR)),2) +
+	     pow((p1->cD * p2->sD -
+		  p1->sD * p2->cD * (p2->cR*p1->cR + p2->sR*p1->sR)),2));
+  den = (p1->sD * p2->sD + p1->cD * p2->cD * (p2->cR*p1->cR + p2->sR*p1->sR));
+  return(atan2(num,den) * (180 / M_PI));
+}
+
+// we are not defining a relative offset DX,DY for now
+double gcdist_PreCalc (Match2D_PreCalc *p1, Match2D_PreCalc *p2) {
+  double num,den;
+
+  // double Qd = p1->sD * p1->cD * p2->sD * p2->cD;
+  // double Qr = p1->sR * p1->cR * p2->sR * p2->cR;
+
+  //  double Xa 
+  //    = SQ(p2->cD * p1->cR * p2->sR) 
+  //    + SQ(p2->cD * p1->sR * p2->cR) -
+  //    - 2 * SQ(p2->cD) * Qr;
+
+  double cdR = (p2->cR*p1->cR + p2->sR*p1->sR);
+
+  double Xa = SQ(p2->cD * p2->sR * p1->cR - p2->cD * p1->sR * p2->cR);
+  double Xb = SQ(p1->cD * p2->sD - p1->sD * p2->cD * cdR);
+
+  num = sqrt(Xa + Xb);
+  den = (p1->sD * p2->sD + p1->cD * p2->cD * cdR);
+  return(atan2(num,den) * (180 / M_PI));
+}
+
+// we are not defining a relative offset DX,DY for now
+int find_matches2d_sphere (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2, Vector *radiusMatch) {
+  
+  off_t i, j, first_j, I, J, *N1, *N2, Nmatch, NMATCH, DMATCH;
+  double dY, dR;
+
+  NMATCH = MAX(MAX(0.05*X1->Nelements, 0.05*X2->Nelements), 1000);
+  DMATCH = NMATCH;
+
+  ResetVector (index1, OPIHI_INT, NMATCH);
+  ResetVector (index2, OPIHI_INT, NMATCH);
+  if (radiusMatch) ResetVector (radiusMatch, OPIHI_FLT, NMATCH);
+
+  ALLOCATE (N1, off_t, X1->Nelements);
+  ALLOCATE (N2, off_t, X2->Nelements);
+
+  ALLOCATE_PTR (A1, Match2D_PreCalc, X1->Nelements);
+  ALLOCATE_PTR (A2, Match2D_PreCalc, X2->Nelements);
+
+  for (i = 0; i < X1->Nelements; i++) { 
+    A1[i].sR = sin(RAD_DEG*X1->elements.Flt[i]);
+    A1[i].cR = cos(RAD_DEG*X1->elements.Flt[i]);
+    A1[i].sD = sin(RAD_DEG*Y1->elements.Flt[i]);
+    A1[i].cD = cos(RAD_DEG*Y1->elements.Flt[i]);
+    N1[i] = i; 
+  }
+  for (i = 0; i < X2->Nelements; i++) { 
+    A2[i].sR = sin(RAD_DEG*X2->elements.Flt[i]);
+    A2[i].cR = cos(RAD_DEG*X2->elements.Flt[i]);
+    A2[i].sD = sin(RAD_DEG*Y2->elements.Flt[i]);
+    A2[i].cD = cos(RAD_DEG*Y2->elements.Flt[i]);
+    N2[i] = i; 
+  }
+
+  // sort from one pole to the other
+  sort_coords_indexonly (Y1->elements.Flt, X1->elements.Flt, N1, X1->Nelements);
+  sort_coords_indexonly (Y2->elements.Flt, X2->elements.Flt, N2, X2->Nelements);
+
+  Nmatch = 0;
+  for (i = j = 0; (i < X1->Nelements) && (j < X2->Nelements);) {
+    I = N1[i];
+    J = N2[j];
+
+    // we can use dY as minimal requirement: if dY > Radius, we are too far apart
+    dY = Y1->elements.Flt[I] - Y2->elements.Flt[J];
+
+    if (dY <= -1.02*Radius) { i++; continue; }
+    if (dY >= +1.02*Radius) { j++; continue; }
+
+    // look for all matches of list2() to list1(i)
+    first_j = j;
+    for (j = first_j; (dY > -1.02*Radius) && (j < X2->Nelements); j++) {
+      J = N2[j];
+
+      dR = gcdist_PreCalc (&A1[I], &A2[J]);
+      // dR = gcdist (X1->elements.Flt[I], Y1->elements.Flt[I], X2->elements.Flt[J], Y2->elements.Flt[J]);
+
+      if (dR < Radius) {
+	index1->elements.Int[Nmatch] = I;
+	index2->elements.Int[Nmatch] = J;
+	if (radiusMatch) radiusMatch->elements.Flt[Nmatch] = dR;
+
+	// XXX track matches 1 and 2 with internal vector, save new nomatch index vectors
+	// after this loop
+
+	Nmatch ++;
+	if (Nmatch >= NMATCH) {
+	  NMATCH += DMATCH;
+	  REALLOCATE (index1->elements.Int, opihi_int, NMATCH);
+	  REALLOCATE (index2->elements.Int, opihi_int, NMATCH);
+	  if (radiusMatch) { REALLOCATE (radiusMatch->elements.Flt, opihi_flt, NMATCH); }
+	}
+      }
+    }
+    j = first_j;
+    i++;
+  }
+  index1->Nelements = Nmatch;
+  index2->Nelements = Nmatch;
+  if (radiusMatch) radiusMatch->Nelements = Nmatch;
+
+  free (A1);
+  free (A2);
+
+  free (N1);
+  free (N2);
+
+  return (TRUE);
+}
+
+// we are not defining a relative offset DX,DY for now
+int find_matches2d_sphere_closest (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index) {
+  
+  off_t i, j, Jmin, Ji, I, J, *N1, *N2;
+  double dY, dR, Rmin;
+
+  ResetVector (index, OPIHI_INT, X1->Nelements);
+  for (i = 0; i < index->Nelements; i++) { index->elements.Int[i] = -1; }
+
+  ALLOCATE (N1, off_t, X1->Nelements);
+  ALLOCATE (N2, off_t, X2->Nelements);
+
+  ALLOCATE_PTR (A1, Match2D_PreCalc, X1->Nelements);
+  ALLOCATE_PTR (A2, Match2D_PreCalc, X2->Nelements);
+
+  for (i = 0; i < X1->Nelements; i++) { 
+    A1[i].sR = sin(RAD_DEG*X1->elements.Flt[i]);
+    A1[i].cR = cos(RAD_DEG*X1->elements.Flt[i]);
+    A1[i].sD = sin(RAD_DEG*Y1->elements.Flt[i]);
+    A1[i].cD = cos(RAD_DEG*Y1->elements.Flt[i]);
+    N1[i] = i; 
+  }
+  for (i = 0; i < X2->Nelements; i++) { 
+    A2[i].sR = sin(RAD_DEG*X2->elements.Flt[i]);
+    A2[i].cR = cos(RAD_DEG*X2->elements.Flt[i]);
+    A2[i].sD = sin(RAD_DEG*Y2->elements.Flt[i]);
+    A2[i].cD = cos(RAD_DEG*Y2->elements.Flt[i]);
+    N2[i] = i; 
+  }
+
+  // sort from one pole to the other
+  sort_coords_indexonly (Y1->elements.Flt, X1->elements.Flt, N1, X1->Nelements);
+  sort_coords_indexonly (Y2->elements.Flt, X2->elements.Flt, N2, X2->Nelements);
+
+  for (i = j = 0; (i < X1->Nelements) && (j < X2->Nelements);) {
+    I = N1[i];
+    J = N2[j];
+
+    // we can use dY as minimal requirement: if dY > Radius, we are too far apart
+    dY = Y1->elements.Flt[I] - Y2->elements.Flt[J];
+
+    if (dY <= -1.02*Radius) { 
+      // no match in list 2 to this entry
+      index->elements.Int[I] = -1; // (probably not needed --- index is init'ed above)o
+      i++; 
+      continue; 
+    }
+    if (dY >= +1.02*Radius) { j++; continue; }
+
+    // look for all matches of list2() to list1(i)
+    Jmin = -1;
+    Rmin = Radius;
+    for (Ji = j; (dY > -1.02*Radius) && (Ji < X2->Nelements); Ji++) {
+      J = N2[Ji];
+
+      dR = gcdist_PreCalc (&A1[I], &A2[J]);
+      // dR = gcdist (X1->elements.Flt[I], Y1->elements.Flt[I], X2->elements.Flt[J], Y2->elements.Flt[J]);
+
+      if (dR < Rmin) {
+	Rmin = dR;
+	Jmin = J;
+      }
+    }
+    
+
+    // no match in list 2 to this entry
+    if (Jmin == -1) {
+      index->elements.Int[I] = -1;
+      i++;
+      continue;
+    }
+    index->elements.Int[I] = Jmin;
+    i++;
+  }
+
+  free (A1);
+  free (A2);
+
+  free (N1);
+  free (N2);
+
+  return (TRUE);
+}
+
+
Index: trunk/Ohana/src/opihi/cmd.data/rndseed.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/rndseed.c	(revision 39926)
+++ trunk/Ohana/src/opihi/cmd.data/rndseed.c	(revision 39926)
@@ -0,0 +1,18 @@
+# include "data.h"
+
+int rndseed (int argc, char **argv) {
+  
+  if (argc < 2) {
+    gprint (GP_ERR, "USAGE: rndseed (value)\n");
+    return (FALSE);
+  }
+
+  /* init srand for rnd numbers elsewhere */
+  long A = atol (argv[1]);
+  srand48(A);
+
+  return (TRUE);
+}
+
+ 
+  
Index: trunk/Ohana/src/opihi/cmd.data/stats-new.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/stats-new.c	(revision 39907)
+++ trunk/Ohana/src/opihi/cmd.data/stats-new.c	(revision 39926)
@@ -129,7 +129,5 @@
   ALLOCATE (values, float, Nsample);
     
-  A = time(NULL);
-  for (B = 0; A == time(NULL); B++);
-  srand48(B);
+  // srand48() is called by startup.c
  
   *buffer = (float *) matrix[0].buffer;
Index: trunk/Ohana/src/opihi/cmd.data/test/fit1d_irls.sh
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/test/fit1d_irls.sh	(revision 39926)
+++ trunk/Ohana/src/opihi/cmd.data/test/fit1d_irls.sh	(revision 39926)
@@ -0,0 +1,347 @@
+
+list tests
+ test1
+ test2
+ test3
+ test4
+ test5
+ test6
+ test7
+ test8
+end
+
+## NOTE: this is not a TAP test
+macro mean.test
+  if ($0 != 2)
+    echo "USAGE: mean.test (errorbar)"
+    break
+  end
+
+  create x 0 100
+
+  delete C0fit dC0fit Cnfit Mfit dMfit
+  for i 0 500
+    gaussdev y x[] 0 1.0   ; # mean of 0, sigma of 1
+    
+    set dy = 1.0 + zero(x) ; # set error to be correct
+    fit1d_irls -q x y 0 -dy dy -wt wt -mask mask -use-median -Nboot 1000
+
+    concat $C0    C0fit
+    concat $dC0  dC0fit
+
+    vstat -q y
+    concat $MEAN Mfit
+    concat {$SIGMA / sqrt($NPTS)} dMfit
+  end
+
+  vstat -q C0fit;  set MeanC  = $MEAN; set StdevC = $SIGMA
+  vstat -q dC0fit; set MeanDC = $MEAN
+  vstat -q Mfit;   set MeanM  = $MEAN; set StdevM = $SIGMA
+  vstat -q dMfit;  set MeanDM = $MEAN
+
+  fprintf "%7.3f %7.3f" $MeanC $MeanM
+  fprintf "%7.3f %7.3f" $StdevC $StdevM
+end
+
+macro cliptest.plot
+  if ($0 != 3)
+    echo "USAGE: cliptest.plot (errorbar) (output)"
+    break
+  end
+
+  set dy = $1 + zero(x) ; # set error to be correct
+  fit1d_irls x y 0 -dy dy -wt wt -mask mask -use-median
+
+  subset ygood = y where not(mask)
+
+  vstat y
+  vstat ygood
+
+  histogram wt Nwt 0 1 0.005 -range dw
+  vstat wt
+
+  subset wts = wt where (wt < 0.3*$MEDIAN)
+  echo "0.3 of MEDIAN : wts[]"
+
+  subset wts = wt where (wt < 0.3*$MEAN)
+  echo "0.3 of MEAN : wts[]"
+
+  dev -n 0; resize 1200 600
+  label -fn courier 24; 
+  section a 0.4 0.0 0.6 1.0; lim x y; clear; box -ypad 0.1 -xpad 3.2 -labelpadx 2.5 -labels 1001; label -x sequence +y value +x "red: clipped, blue: unclipped"; 
+  plot x y; plot -c blue -pt 7 x y where not(mask); plot -c red -pt 7 -lw 2 x y where mask
+
+  section b 0.0 0.0 0.4 1.0; lim dw Nwt; box +ypad 0.1 -xpad 3.2 -labelpadx 2.5; label -x "weight" -y "Npoints"; plot -x 1 dw Nwt
+  png -name $2
+end
+
+## NOTE: this is not a TAP test
+macro cliptest
+
+  create x 0 100
+  gaussdev y x[] 0 1.0   ; # mean of 0, sigma of 1
+
+  if (1)
+    y[10] = 5.0
+    y[20] = 7.0
+    y[30] = 4.0
+  end
+
+  cliptest.plot 1.0 irls.sample.v0.png
+
+  cliptest.plot 0.1 irls.sample.v1.png
+
+  cliptest.plot 0.01 irls.sample.v2.png
+end
+
+## NOTE: this is not a TAP test
+macro outlier.test
+  if ($0 != 2)
+    echo "USAGE: outlier.test (errorbar)"
+    break
+  end
+
+  create x 0 100
+
+  delete C0fit dC0fit Cnfit Mfit dMfit
+  for i 0 300
+    gaussdev y x[] 0 1.0   ; # mean of 0, sigma of 1
+    
+    if (0)
+      y[10] = 5.0
+      y[20] = 7.0
+      y[30] = 4.0
+    end
+    
+    set dy = $1 + zero(x) ; # set error to be correct
+    fit1d_irls -q x y 0 -dy dy -wt wt -mask mask -use-median -Nboot 1000
+    concat $C0 C0fit
+    concat $dC0 dC0fit
+    concat $Cnfit Cnfit
+
+    vstat -q y
+    concat $MEAN Mfit
+    concat {$SIGMA / sqrt($NPTS)} dMfit
+  end
+
+  vstat C0fit
+  vstat dC0fit
+  vstat Cnfit
+  vstat Mfit
+  vstat dMfit
+end
+
+# fit a line without errors
+macro test1
+ $PASS = 1
+ break -auto off
+
+ delete -q x y
+
+ create x 0 100
+ set y = 3 + 5*x
+ fit -q x y 1
+
+ if ($Cn != 1)
+   $PASS = 0
+ end
+ if (abs($C0 - 3) > 1e-5)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 1e-5)
+   $PASS = 0
+ end
+end
+
+# fit a line with errors
+macro test2
+ $PASS = 1
+ break -auto off
+
+ delete -q x y dy
+
+ create x 0 100
+ set dy = 0.1*rnd(x) - 0.05
+ set y = 3 + 5*x + dy
+ fit -q x y 1
+
+ if ($Cn != 1)
+   $PASS = 0
+   echo "wrong number of elements : $Cn"
+ end
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+   echo "wrong value for C0 : $C0"
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+   echo "wrong value for C1 : $C1"
+ end
+end
+
+# fit a line with errors and weights
+macro test3
+ $PASS = 1
+ break -auto off
+
+ delete -q x y dy
+
+ create x 0 100
+ set dy = 0.1*rnd(x) - 0.05
+ set y = 3 + 5*x + dy
+ set dy = 0.1 + zero(x)
+ fit -q x y 1 -dy dy
+
+ if ($Cn != 1)
+   $PASS = 0
+ end
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+ end
+end
+
+# fit a line with errors, weights, and outliers 
+macro test4
+ $PASS = 1
+ break -auto off
+
+ delete -q x y dy
+
+ create x 0 100
+ set dy = 0.1*rnd(x) - 0.05
+ set y = 3 + 5*x + dy
+ set dy = 0.1 + zero(x)
+ y[5] = 23
+ y[20] = -10
+ y[50] = 0.0
+ fit -q x y 1 -dy dy -clip 3 3
+
+ if ($Cn != 1)
+   $PASS = 0
+ end
+ if ($Cnv != 97)
+   $PASS = 0
+ end
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+ end
+end
+
+# fit a quadratic without errors
+macro test5
+ $PASS = 1
+ break -auto off
+
+ delete -q x y
+
+ create x 0 100
+ set y = 3 + 5*x - 4*x^2
+ fit -q x y 2
+
+ if ($Cn != 2)
+   $PASS = 0
+ end
+ if (abs($C0 - 3) > 1e-5)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 1e-5)
+   $PASS = 0
+ end
+ if (abs($C2 + 4) > 1e-5)
+   $PASS = 0
+ end
+end
+
+# fit a quadratic with errors
+macro test6
+ $PASS = 1
+ break -auto off
+
+ delete -q x y dy
+
+ create x 0 100
+ set dy = 0.1*rnd(x) - 0.05
+ set y = 3 + 5*x - 4*x^2 + dy
+ fit -q x y 2
+
+ if ($Cn != 2)
+   $PASS = 0
+ end
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C2 + 4) > 0.06)
+   $PASS = 0
+ end
+end
+
+# fit a quadratic with errors and weights
+macro test7
+ $PASS = 1
+ break -auto off
+
+ delete -q x y dy
+
+ create x 0 100
+ set dy = 0.1*rnd(x) - 0.05
+ set y = 3 + 5*x - 4*x^2 + dy
+ set dy = 0.1 + zero(x)
+ fit -q x y 2 -dy dy
+
+ if ($Cn != 2)
+   $PASS = 0
+ end
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C2 + 4) > 0.06)
+   $PASS = 0
+ end
+end
+
+# fit a quadratic with errors, weights, and outliers 
+macro test8
+ $PASS = 1
+ break -auto off
+
+ delete -q x y dy
+
+ create x 0 100
+ set dy = 0.1*rnd(x) - 0.05
+ set y = 3 + 5*x - 4*x^2 + dy
+ set dy = 0.1 + zero(x)
+ y[5] = 23
+ y[20] = -10
+ y[50] = 0.0
+
+ # it takes 4 iterations to successfully reject the outliers above...
+ fit -q x y 2 -dy dy -clip 3 4
+
+ if ($Cn != 2)
+   $PASS = 0
+ end
+ if ($Cnv != 97)
+   $PASS = 0
+ end
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C2 + 4) > 0.06)
+   $PASS = 0
+ end
+end
Index: trunk/Ohana/src/opihi/dvo/imbox.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/imbox.c	(revision 39907)
+++ trunk/Ohana/src/opihi/dvo/imbox.c	(revision 39926)
@@ -15,4 +15,17 @@
 
   if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
+
+  char *xaxis = NULL;
+  if ((N = get_argument (argc, argv, "-xaxis"))) {
+    remove_argument (N, &argc, argv);
+    xaxis = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  char *yaxis = NULL;
+  if ((N = get_argument (argc, argv, "-yaxis"))) {
+    remove_argument (N, &argc, argv);
+    yaxis = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
 
   SOLO_PHU = FALSE;
@@ -61,14 +74,29 @@
     // XXX currently, image uses an unsigned short for NX,XY. this is rather restrictive
     // and needs to be at least checked.
-    haveNx = gfits_scan (&header, "IMNAXIS1",   "%d", 1, &Nx);
-    haveNy = gfits_scan (&header, "IMNAXIS2",   "%d", 1, &Ny);
+    haveNx = FALSE;
+    if (xaxis) {
+      haveNx = gfits_scan (&header, xaxis, "%d", 1, &Nx);
+    }
+    if (!haveNx) {
+      haveNx = gfits_scan (&header, "IMNAXIS1",   "%d", 1, &Nx);
+    } 
+    if (!haveNx) {
+	haveNx = gfits_scan (&header, "ZNAXIS1",   "%d", 1, &Nx);
+    }
+    if (!haveNx) {
+	haveNx = gfits_scan (&header, "NAXIS1",   "%d", 1, &Nx);
+    }
 
-    if (!haveNx && !haveNy) {
-	haveNx = gfits_scan (&header, "ZNAXIS1",   "%d", 1, &Nx);
+    haveNy = FALSE;
+    if (yaxis) {
+      haveNy = gfits_scan (&header, yaxis, "%d", 1, &Ny);
+    }
+    if (!haveNy) {
+      haveNy = gfits_scan (&header, "IMNAXIS2",   "%d", 1, &Ny);
+    }
+    if (!haveNy) {
 	haveNy = gfits_scan (&header, "ZNAXIS2",   "%d", 1, &Ny);
     }
-
-    if (!haveNx && !haveNy) {
-	haveNx = gfits_scan (&header, "NAXIS1",   "%d", 1, &Nx);
+    if (!haveNy) {
 	haveNy = gfits_scan (&header, "NAXIS2",   "%d", 1, &Ny);
     }
@@ -137,4 +165,6 @@
   free (Xvec.elements.Flt);
   free (Yvec.elements.Flt);
+  if (xaxis) free (xaxis);
+  if (yaxis) free (yaxis);
   return (TRUE);
 
Index: trunk/Ohana/src/opihi/dvo/imdense.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/imdense.c	(revision 39907)
+++ trunk/Ohana/src/opihi/dvo/imdense.c	(revision 39926)
@@ -4,5 +4,4 @@
 int imdense (int argc, char **argv) {
   
-  long A, B;
   off_t i, Nimage;
   int kapa, N, status, NPTS;
@@ -27,7 +26,5 @@
   Rmax = graphmode.coords.crval1 + 182.0;
   
-  A = time(NULL);
-  for (B = 0; A == time(NULL); B++);
-  srand48(B);
+  // srand48() is called by startup.c
 
   N = 0;
Index: trunk/Ohana/src/opihi/dvo/skycat.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/skycat.c	(revision 39907)
+++ trunk/Ohana/src/opihi/dvo/skycat.c	(revision 39926)
@@ -78,6 +78,10 @@
       if (table) {
 	int hostID = (regions[i][0].hostFlags & DATA_USE_BCK) ? regions[i][0].backupID : regions[i][0].hostID;
-	int index = table->index[hostID];
-	snprintf (hostfile, 1024, "%s/%s.cpt", table->hosts[index].pathname, regions[i][0].name);
+	if (hostID) {
+	  int index = table->index[hostID];
+	  snprintf (hostfile, 1024, "%s/%s.cpt", table->hosts[index].pathname, regions[i][0].name);
+	} else {
+	  strcpy (hostfile, skylist[0].filename[i]);
+	}
       } else {
 	strcpy (hostfile, skylist[0].filename[i]);
Index: trunk/Ohana/src/opihi/lib.data/style_args.c
===================================================================
--- trunk/Ohana/src/opihi/lib.data/style_args.c	(revision 39907)
+++ trunk/Ohana/src/opihi/lib.data/style_args.c	(revision 39926)
@@ -29,5 +29,5 @@
   if ((N = get_argument (*argc, argv, "-lt"))) {
     remove_argument (N, argc, argv);
-    graphmode[0].ltype = atof(argv[N]);
+    graphmode[0].ltype = KapaLineTypeFromString(argv[N]);
     remove_argument (N, argc, argv);
   }
@@ -39,5 +39,5 @@
   if ((N = get_argument (*argc, argv, "-pt"))) {
     remove_argument (N, argc, argv);
-    graphmode[0].ptype = atof(argv[N]);
+    graphmode[0].ptype = KapaPointStyleFromString(argv[N]);
     remove_argument (N, argc, argv);
   }
@@ -63,5 +63,5 @@
   if ((N = get_argument (*argc, argv, "-x"))) {
     remove_argument (N, argc, argv);
-    graphmode[0].style = atof(argv[N]);
+    graphmode[0].style = KapaPlotStyleFromString(argv[N]);
     remove_argument (N, argc, argv);
   }
Index: trunk/Ohana/src/opihi/lib.shell/startup.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/startup.c	(revision 39907)
+++ trunk/Ohana/src/opihi/lib.shell/startup.c	(revision 39926)
@@ -51,4 +51,15 @@
     gfits_set_unsign_mode (FALSE);
     
+    set_variable ("M_PI", M_PI);
+    set_variable ("M_E",  M_E);
+    set_variable ("M_c",  299792459.0); // meter / second
+    set_variable ("M_c_cgs", 29979245900.0); // cm / second
+
+    set_variable ("M_h",  6.62607004e-34); // meter^2 kg / second (J s)
+    set_variable ("M_h_cgs",  6.62607004e-27); // erg s
+
+    set_variable ("M_kB",  1.38064853e-23); // J / K
+    set_variable ("M_kB_cgs",  1.38064853e-16); // erg / K
+
   /* check history file permission */
   {
Index: trunk/Ohana/src/photdbc/src/make_subcatalog.c
===================================================================
--- trunk/Ohana/src/photdbc/src/make_subcatalog.c	(revision 39907)
+++ trunk/Ohana/src/photdbc/src/make_subcatalog.c	(revision 39926)
@@ -7,5 +7,5 @@
   int found;
   off_t i, j, k, offset;
-  off_t NAVERAGE, NMEASURE, Naverage, Nmeasure, Nm, Nsecfilt;
+  off_t Nm, Nsecfilt;
   double mag, minMag, minSigma;
   int keep, *secKeep;
@@ -27,10 +27,18 @@
 
   /* we are moving only the subset of measurements from catalog[0] to subcatalog[0] */
-  NAVERAGE = 50;
-  NMEASURE = 1000;
-  Nmeasure = Naverage = 0;
+  off_t NAVERAGE = 50;   off_t Naverage = 0;
+  off_t NMEASURE = 1000; off_t Nmeasure = 0;
+  off_t NLENSING = 1000; off_t Nlensing = 0;
+  off_t NLENSOBJ = 1000; off_t Nlensobj = 0;
+  off_t NSTARPAR = 1000; off_t Nstarpar = 0;
+  off_t NGALPHOT = 1000; off_t Ngalphot = 0;
+
   REALLOCATE (subcatalog[0].average, Average, NAVERAGE);
   REALLOCATE (subcatalog[0].secfilt, SecFilt, NAVERAGE*Nsecfilt);
   REALLOCATE (subcatalog[0].measure, Measure, NMEASURE);
+  REALLOCATE (subcatalog[0].lensing, Lensing, NLENSING);
+  REALLOCATE (subcatalog[0].lensobj, Lensobj, NLENSOBJ);
+  REALLOCATE (subcatalog[0].starpar, StarPar, NSTARPAR);
+  REALLOCATE (subcatalog[0].galphot, GalPhot, NGALPHOT);
 
   for (i = 0; i < catalog[0].Naverage; i++) {
@@ -39,5 +47,5 @@
     // XXX: temporary check make sure that this object belongs in this region
     // used to fix the pole area in the reference catalog
-    {
+    if (0) {
         double R = catalog[0].average[i].R;
         double D = catalog[0].average[i].D;
@@ -177,4 +185,80 @@
     subcatalog[0].average[Naverage].Nmissing = 0;
     subcatalog[0].average[Naverage].Nmeasure = Nm;
+
+    // **** lensing
+    Nm = 0;
+    subcatalog[0].average[Naverage].lensingOffset = Nlensing;
+    for (j = 0; j < catalog[0].average[i].Nlensing; j++) {
+
+      offset = catalog[0].average[i].lensingOffset + j;
+
+      subcatalog[0].lensing[Nlensing]        = catalog[0].lensing[offset];
+      subcatalog[0].lensing[Nlensing].averef = Naverage;
+
+      Nlensing ++;
+      Nm ++;
+      if (Nlensing == NLENSING) {
+	NLENSING += 1000;
+	REALLOCATE (subcatalog[0].lensing, Lensing, NLENSING);
+      }
+    }
+    subcatalog[0].average[Naverage].Nlensing = Nm;
+
+    // **** lensobj
+    Nm = 0;
+    subcatalog[0].average[Naverage].lensobjOffset = Nlensobj;
+    for (j = 0; j < catalog[0].average[i].Nlensobj; j++) {
+
+      offset = catalog[0].average[i].lensobjOffset + j;
+
+      subcatalog[0].lensobj[Nlensobj]        = catalog[0].lensobj[offset];
+
+      Nlensobj ++;
+      Nm ++;
+      if (Nlensobj == NLENSOBJ) {
+	NLENSOBJ += 1000;
+	REALLOCATE (subcatalog[0].lensobj, Lensobj, NLENSOBJ);
+      }
+    }
+    subcatalog[0].average[Naverage].Nlensobj = Nm;
+
+    // **** starpar
+    Nm = 0;
+    subcatalog[0].average[Naverage].starparOffset = Nstarpar;
+    for (j = 0; j < catalog[0].average[i].Nstarpar; j++) {
+
+      offset = catalog[0].average[i].starparOffset + j;
+
+      subcatalog[0].starpar[Nstarpar]        = catalog[0].starpar[offset];
+      subcatalog[0].starpar[Nstarpar].averef = Naverage;
+
+      Nstarpar ++;
+      Nm ++;
+      if (Nstarpar == NSTARPAR) {
+	NSTARPAR += 1000;
+	REALLOCATE (subcatalog[0].starpar, StarPar, NSTARPAR);
+      }
+    }
+    subcatalog[0].average[Naverage].Nstarpar = Nm;
+
+    // **** galphot
+    Nm = 0;
+    subcatalog[0].average[Naverage].galphotOffset = Ngalphot;
+    for (j = 0; j < catalog[0].average[i].Ngalphot; j++) {
+
+      offset = catalog[0].average[i].galphotOffset + j;
+
+      subcatalog[0].galphot[Ngalphot]        = catalog[0].galphot[offset];
+      subcatalog[0].galphot[Ngalphot].averef = Naverage;
+
+      Ngalphot ++;
+      Nm ++;
+      if (Ngalphot == NGALPHOT) {
+	NGALPHOT += 1000;
+	REALLOCATE (subcatalog[0].galphot, GalPhot, NGALPHOT);
+      }
+    }
+    subcatalog[0].average[Naverage].Ngalphot = Nm;
+
     Naverage ++;
     if (Naverage == NAVERAGE) {
@@ -187,7 +271,17 @@
   REALLOCATE (subcatalog[0].measure, Measure, MAX (Nmeasure, 1));
   REALLOCATE (subcatalog[0].secfilt, SecFilt, Nsecfilt*MAX (Naverage, 1));
+  REALLOCATE (subcatalog[0].lensing, Lensing, MAX (Nlensing, 1));
+  REALLOCATE (subcatalog[0].lensobj, Lensobj, MAX (Nlensobj, 1));
+  REALLOCATE (subcatalog[0].starpar, StarPar, MAX (Nstarpar, 1));
+  REALLOCATE (subcatalog[0].galphot, GalPhot, MAX (Ngalphot, 1));
+
   subcatalog[0].Naverage = Naverage;
   subcatalog[0].Nmeasure = Nmeasure;
   subcatalog[0].Nsecfilt = Nsecfilt;
+  subcatalog[0].Nlensing = Nlensing;
+  subcatalog[0].Nlensobj = Nlensobj;
+  subcatalog[0].Nstarpar = Nstarpar;
+  subcatalog[0].Ngalphot = Ngalphot;
+
   subcatalog[0].Nsecfilt_mem = Naverage * Nsecfilt;
 
Index: trunk/Ohana/src/photdbc/src/photdbc_catalogs.c
===================================================================
--- trunk/Ohana/src/photdbc/src/photdbc_catalogs.c	(revision 39907)
+++ trunk/Ohana/src/photdbc/src/photdbc_catalogs.c	(revision 39926)
@@ -26,5 +26,9 @@
     incatalog.filename  = hostID ? hostfile : skylist[0].filename[i];
     incatalog.Nsecfilt = GetPhotcodeNsecfilt ();
-    incatalog.catflags = DVO_LOAD_AVERAGE | DVO_LOAD_MEASURE | DVO_LOAD_SECFILT;
+
+    incatalog.catflags    = DVO_LOAD_AVERAGE | DVO_LOAD_SECFILT;
+    incatalog.catflags   |= DVO_LOAD_MEASURE | DVO_LOAD_MISSING;
+    incatalog.catflags   |= DVO_LOAD_LENSING | DVO_LOAD_LENSOBJ;
+    incatalog.catflags   |= DVO_LOAD_STARPAR | DVO_LOAD_GALPHOT;
 
     // an error exit status here is a significant error
@@ -57,5 +61,9 @@
     outcatalog.catcompress = CATCOMPRESS ? dvo_catalog_catcompress (CATCOMPRESS) : incatalog.catcompress; // set the default catcompress from config data
     outcatalog.Nsecfilt    = incatalog.Nsecfilt;                 // inherit from the incatalog
-    outcatalog.catflags    = DVO_LOAD_AVERAGE | DVO_LOAD_MEASURE | DVO_LOAD_MISSING | DVO_LOAD_SECFILT;
+
+    outcatalog.catflags    = DVO_LOAD_AVERAGE | DVO_LOAD_SECFILT;
+    outcatalog.catflags   |= DVO_LOAD_MEASURE | DVO_LOAD_MISSING;
+    outcatalog.catflags   |= DVO_LOAD_LENSING | DVO_LOAD_LENSOBJ;
+    outcatalog.catflags   |= DVO_LOAD_STARPAR | DVO_LOAD_GALPHOT;
 
     // output catalogs always represent the same skyregions as the input catalogs
Index: trunk/Ohana/src/relastro/include/relastro.h
===================================================================
--- trunk/Ohana/src/relastro/include/relastro.h	(revision 39907)
+++ trunk/Ohana/src/relastro/include/relastro.h	(revision 39926)
@@ -33,5 +33,5 @@
 typedef enum {OP_NONE, OP_IMAGES, OP_HIGH_SPEED, OP_MERGE_SOURCE, OP_UPDATE_OBJECTS, OP_UPDATE_OFFSETS, OP_LOAD_OBJECTS, OP_HPM, OP_PARALLEL_REGIONS, OP_PARALLEL_IMAGES, OP_REPAIR_STACKS, OP_REPAIR_WARPS, OP_REPAIR_OBJECT_ID} RelastroOp;
 
-typedef enum {TARGET_NONE, TARGET_SIMPLE, TARGET_CHIPS, TARGET_MOSAICS} FitTarget;
+typedef enum {TARGET_NONE, TARGET_SIMPLE, TARGET_CHIPS, SET_CHIPS, TARGET_MOSAICS} FitTarget;
 
 typedef enum {
@@ -144,4 +144,6 @@
   int Nfit;
   int converged;
+  int useWeight;
+
 } FitAstromResult;
 
@@ -296,5 +298,5 @@
 } CheckMeasureResult;
 
-# define ID_MEAS_OBJECT_HAS_2MASS ID_MEAS_POOR_PHOTOM
+// # define ID_MEAS_OBJECT_HAS_2MASS ID_MEAS_POOR_PHOTOM
 
 /* global variables set in parameter file */
@@ -315,4 +317,5 @@
 int    PARALLEL_REGIONS_MANUAL;
 char  *MANUAL_UNIQUER;
+int    CATCH_UP;
 
 int          HOST_ID;
@@ -352,4 +355,7 @@
 int    VERBOSE2;
 
+float  TEST_SCALE;
+char  *GALAXY_MODEL;
+
 int    USE_FIXED_PIXCOORDS;
 int    USE_GALAXY_MODEL;
@@ -363,5 +369,18 @@
 int    USE_IMAGE_COORDS_FOR_REPAIR;
 int    USE_ALL_IMAGES;
+int    KEEP_ALL_IMAGES_RA;
 int    CHECK_MEASURE_TO_IMAGE;
+
+int    SKIP_PS1_CHIP;
+int    SKIP_PS1_STACK;
+int    SKIP_HSC;
+int    SKIP_CFH;
+
+int    UPDATE_PS1_STACK_MEASURE;
+int    UPDATE_PS1_CHIP_MEASURE;
+int    UPDATE_HSC_MEASURE;
+int    UPDATE_CFH_MEASURE;
+
+int    APPLY_PROPER_MOTION;
 
 int    RESET;
@@ -383,4 +402,9 @@
 int    CHIPMAP;
 
+int    *ChipMapLoop;
+int    *ChipOrderLoop;
+char   *ChipMapLoopStr;
+char   *ChipOrderLoopStr;
+
 int    N_BOOTSTRAP_SAMPLES;
 
@@ -407,7 +431,11 @@
 
 float *LoopWeight2MASS;
+char *LoopWeight2MASSstr;
+
 float *LoopWeightTycho;
-char *LoopWeight2MASSstr;
 char *LoopWeightTychostr;
+
+float *LoopWeightGAIA;
+char *LoopWeightGAIAstr;
 
 int ImagSelect;
@@ -433,4 +461,6 @@
 
 FitMode FIT_MODE;
+int USE_IRLS;
+int ALLOW_IRLS;
 
 RelastroOp RELASTRO_OP;
@@ -498,5 +528,5 @@
 void          initGridBins        PROTO((Catalog *catalog, int Ncatalog));
 void          initImageBins       PROTO((Catalog *catalog, int Ncatalog, int FULLINIT));
-void          initImages          PROTO((Image *input, off_t *line_number, off_t N));
+void          initImages          PROTO((Image *input, off_t *line_number, off_t N, int isSubset));
 void          freeImages          PROTO((char *dbImagePtr));
 void          initMosaicBins      PROTO((Catalog *catalog, int Ncatalog));
@@ -744,4 +774,6 @@
 int isGPC1stack (int photcode);
 int isGPC1warp (int photcode);
+int isHSCchip (int photcode);
+int isCFHchip (int photcode);
 
 int save_astrom_table ();
Index: trunk/Ohana/src/relastro/src/BootstrapOps.c
===================================================================
--- trunk/Ohana/src/relastro/src/BootstrapOps.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/BootstrapOps.c	(revision 39926)
@@ -77,21 +77,21 @@
     case FIT_RESULT_RA:
       // result->Ro = median;
-      result->dRo = sigma;
+      result->dRo = MAX(sigma, result->dRo);
       break;
     case FIT_RESULT_DEC:
       // result->Do = median;
-      result->dDo = sigma;
+      result->dDo = MAX(sigma, result->dDo);
       break;
     case FIT_RESULT_uR:
       // result->uR = median;
-      result->duR = sigma;
+      result->duR = MAX(sigma, result->duR);
       break;
     case FIT_RESULT_uD:
       // result->uD = median;
-      result->duD = sigma;
+      result->duD = MAX(sigma, result->duD);
       break;
     case FIT_RESULT_PLX:
       // result->p = median;
-      result->dp = sigma;
+      result->dp = MAX(sigma, result->dp);
       break;
     default:
Index: trunk/Ohana/src/relastro/src/BrightCatalog.c
===================================================================
--- trunk/Ohana/src/relastro/src/BrightCatalog.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/BrightCatalog.c	(revision 39926)
@@ -353,8 +353,8 @@
   /*** MeasureTiny ***/
   {
-    ohana_memcheck (1);
+    // ohana_memcheck (1);
     gfits_create_table_header (&theader, "BINTABLE", "MEASURE_TINY");
 
-    ohana_memcheck (1);
+    // ohana_memcheck (1);
 
     gfits_define_bintable_column (&theader, "D", "RA",       "ra",                         "degrees", 1.0, 0.0);
@@ -429,6 +429,6 @@
     gfits_set_bintable_column (&theader, &ftable, "RA",   	R,         catalog->Nmeasure);
 
-    fprintf (stderr, "--------------- after set_bintable RA --------------");
-    ohana_memdump_file (stderr, TRUE);
+    // fprintf (stderr, "--------------- after set_bintable RA --------------");
+    // ohana_memdump_file (stderr, TRUE);
     
     gfits_set_bintable_column (&theader, &ftable, "DEC",  	D,         catalog->Nmeasure);
Index: trunk/Ohana/src/relastro/src/ConfigInit.c
===================================================================
--- trunk/Ohana/src/relastro/src/ConfigInit.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/ConfigInit.c	(revision 39926)
@@ -84,11 +84,4 @@
   SetZeroPoint (25.0);
 
-  if (USE_GALAXY_MODEL) {
-    if (!InitGalaxyModel ("FEAST-HIPPARCOS")) {
-      fprintf (stderr, "failed to init galaxy model\n");
-      exit (2);
-    }
-  }
-
   FreeConfigFile();
   free (config);
Index: trunk/Ohana/src/relastro/src/FitAstromOps.c
===================================================================
--- trunk/Ohana/src/relastro/src/FitAstromOps.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/FitAstromOps.c	(revision 39926)
@@ -257,4 +257,8 @@
   fit->converged = FALSE;
   
+  // this is an input value
+  // if true, use the IRLS modified weight
+  fit->useWeight = FALSE;
+
   return;
 }
Index: trunk/Ohana/src/relastro/src/FitChip.c
===================================================================
--- trunk/Ohana/src/relastro/src/FitChip.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/FitChip.c	(revision 39926)
@@ -78,5 +78,5 @@
       order_use = MIN(MIN(order_use, CHIPMAP), 6); // can only go up to 6th order map (can be user limited)
     } else {
-      order_use = MIN(order_use, 3); // can only go up to 3rd order for polynomials
+      order_use = MIN(MIN(order_use, CHIPORDER), 3); // can only go up to 3rd order for polynomials
     }
 
@@ -206,9 +206,26 @@
   if (VERBOSE2) fprintf (stderr, "fit sigma: %f (%f, %f) : full: %f (%f, %f), scatter limit: %f (%d full, %d bright, %d fit, %d all) (%d %d %d %d %d)\n", dRsig, dLsig, dMsig, dRsigFull, dLsigFull, dMsigFull, dRmax, NstatFull, Nstat, fit[0].Npts, Nmatch, nMask1, nMask2, nMask3, nMask4, nMask5);
 
-  image[0].dXpixSys = dLsig;
-  image[0].dYpixSys = dMsig;
+  // need to convert dLsig, dMsig back to pixel scale (or up to arcsec)
+
+  float plateScale;
+  if (image[0].coords.mosaic) {
+    // NOTE: for the full pixel to sky plate scale, use this:
+    // float plateScaleX = 3600.0*image[0].coords.mosaic->cdelt1*image[0].coords.cdelt1;
+    // float plateScaleY = 3600.0*image[0].coords.mosaic->cdelt2*image[0].coords.cdelt2;
+
+    // since we are compare L,M values, just need to compensate for focal plate to sky:
+    float plateScaleX = 3600.0*fabs(image[0].coords.mosaic->cdelt1);
+    float plateScaleY = 3600.0*fabs(image[0].coords.mosaic->cdelt2);
+    plateScale = 0.5*(plateScaleX + plateScaleY);
+  } else {
+    // since we are compare L,M values, just need to compensate for arcsec vs degrees:
+    plateScale = 3600.0;
+  }
+
+  image[0].dXpixSys = plateScale*dLsig;
+  image[0].dYpixSys = plateScale*dMsig;
   image[0].nFitAstrom = fit[0].Npts;
 
-  // fprintf (stderr, "%s %6.3f %4d %4d\n", image[0].name, image[0].refColor, Ncolor, image[0].nFitAstrom);
+  if (VERBOSE2) fprintf (stderr, "%s | %6.3f %6.3f | %4d %4d | %6.3f %6.3f\n", image[0].name, image[0].refColorRed, image[0].refColorBlue, Ncolor, image[0].nFitAstrom, image[0].dXpixSys, image[0].dYpixSys);
 
   if (fit) fit_free (fit);
Index: trunk/Ohana/src/relastro/src/FitPM.c
===================================================================
--- trunk/Ohana/src/relastro/src/FitPM.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/FitPM.c	(revision 39926)
@@ -25,4 +25,5 @@
   }
 
+  fit->useWeight = FALSE; // Ordinary Least Squares
   if (!FitPM_MinChisq (fit, data, points, Npoints)) return FALSE;
   if (!FitPM_SetChisq (fit, data, points, Npoints)) return FALSE;
@@ -47,4 +48,5 @@
   
   // Solve OLS equation  
+  fit->useWeight = FALSE; // Ordinary Least Squares
   if (!FitPM_MinChisq(fit, data, points, Npoints)) {
     return(FALSE);
@@ -69,5 +71,5 @@
 
   // Iteratively reweight and solve
-  double sigma_hat = 0.0; // save for the error model
+  // double sigma_hat = 0.0; // save for the error model
   int converged = FALSE;
   int iterations = 0;
@@ -90,4 +92,5 @@
 
     // Solve with the new weights
+    fit->useWeight = TRUE; // Reweighted Least Squares
     if (!FitPM_MinChisq(fit, data, points, Npoints)) {
 
@@ -104,5 +107,5 @@
 	points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
       }
-      sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
+      // sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
       break;
     }
@@ -119,5 +122,5 @@
       points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
     }
-    sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
+    // sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
     
     // Check convergence
@@ -159,38 +162,15 @@
   // NOTE EAM: in tests (fitpm.c), they seem to be too large by a factor of ~5.37
   if (data->getError) {
-    double ax = 0.0, ay = 0.0;
-    double bx = 0.0, by = 0.0;
-
-    for (i = 0; i < Npoints; i++) {
-      ax += dpsi_cauchy(points[i].rx / points[i].dX);
-      ay += dpsi_cauchy(points[i].ry / points[i].dY);
-
-      bx += SQ(points[i].Wx);
-      by += SQ(points[i].Wy);
-    }
-    ax /= 1.0 * Npoints;  // mean(psi_dot(r))
-    ay /= 1.0 * Npoints; 
-    bx /= 1.0 * (Npoints - data->Nterms); // mean(psi^2(r)) * (N / (N-p))
-    by /= 1.0 * (Npoints - data->Nterms);
-  
-    double lambda_x = 1.0 + (data->Nterms / Npoints) * (1 - ax) / ax;
-    double lambda_y = 1.0 + (data->Nterms / Npoints) * (1 - ay) / ay;
-  
-    double sigma_robust_x = lambda_x * sqrt(bx) * sigma_hat * 2.385 / ax;
-    double sigma_robust_y = lambda_y * sqrt(by) * sigma_hat * 2.385 / ay;
-
-    // This is actually sigma^2, as that's the factor in the covariance (dumouchel 4.1)
-    double sigma_final_x  = MAX(SQ(sigma_robust_x), (2 * Npoints * SQ(sigma_robust_x) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-    double sigma_final_y  = MAX(SQ(sigma_robust_y), (2 * Npoints * SQ(sigma_robust_y) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-
-    fit[0].dRo = sqrt(data->Cov[0][0]);
-    fit[0].duR = sqrt(data->Cov[1][1]);
-    fit[0].dDo = sqrt(data->Cov[2][2]);
-    fit[0].duD = sqrt(data->Cov[3][3]);
-
-    fit[0].dRo *= sigma_final_x;
-    fit[0].duR *= sigma_final_x;
-    fit[0].dDo *= sigma_final_y;
-    fit[0].duD *= sigma_final_y;
+    FitAstromResult fitErrors;
+    FitAstromResultInit (&fitErrors);
+    fitErrors.useWeight = FALSE; 
+
+    FitPM_MinChisq(&fitErrors, data, points, Npoints);
+
+    // we use the errors from a simple OLS, ignoring masked points
+    fit[0].dRo = fitErrors.dRo;
+    fit[0].duR = fitErrors.duR;
+    fit[0].dDo = fitErrors.dDo;
+    fit[0].duD = fitErrors.duD;
   }
 
@@ -212,6 +192,11 @@
     Nfit ++;
 
-    wx = points[i].qx;
-    wy = points[i].qy;
+    if (fit->useWeight) {
+      wx = points[i].qx;
+      wy = points[i].qy;
+    } else {
+      wx = points[i].Qx;
+      wy = points[i].Qy;
+    }
 
     Wx += wx;
Index: trunk/Ohana/src/relastro/src/FitPM_IRLS.c
===================================================================
--- trunk/Ohana/src/relastro/src/FitPM_IRLS.c	(revision 39907)
+++ 	(revision )
@@ -1,269 +1,0 @@
-# include "relastro.h"
-
-// These should probably be tunable:
-# define MAX_ITERATIONS 10
-# define FIT_TOLERANCE 1e-4
-# define FLT_TOLERANCE 1e-6
-# define WEIGHT_THRESHOLD 0.3
-
-int FitPM_IRLS (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints, int VERBOSE) {
-
-  int i,j;
-
-  int Ndof = 2 * Npoints - data->Nterms;
-  
-  // Convert the measurement errors into initial weights.
-  for (i = 0; i < Npoints; i++) {
-    points[i].Wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1 / SQ(points[i].dX);
-    points[i].Wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1 / SQ(points[i].dY);
-  }
-  
-  // Solve OLS equation  
-  if (!FitPM_MinChisq(fit, data, points, Npoints)) {
-    return(FALSE);
-  }
-
-  // Calculate r vector of residuals and least squares sigma
-  double sigma_ols = 0.0;
-  for (i = 0; i < Npoints; i++) {
-    points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro);
-    points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do);
-    sigma_ols += SQ(points[i].rx) + SQ(points[i].ry);
-  }
-  sigma_ols = sqrt(sigma_ols / (float)Ndof);
-
-  // Save OLS covariance and Beta (solution vector, which is actually also saved in fit)
-  for (i = 0; i < data->Nterms; i++) {
-    for (j = 0; j < data->Nterms; j++) {
-      data->Cov[i][j] = data->A[i][j];
-    }
-    data->Beta[i] = data->B[i][0];
-  }
-
-  // Iteratively reweight and solve
-  double sigma_hat = 0.0; // save for the error model
-  int converged = FALSE;
-  int iterations = 0;
-
-  // modify the weight based on the distance from the previous fit.  try up to MAX_ITERATIONS.
-  // at the end "fit", has the last fit parameters
-  for (iterations = 0; !converged && (iterations < MAX_ITERATIONS); iterations ++) {
-    // Save Beta.
-    for (i = 0; i < data->Nterms; i ++) {
-      data->Beta_prev[i] = data->Beta[i];
-    }
-
-    // Assign weights based on the deviation
-    for (i = 0; i < Npoints; i++) {
-      points[i].Wx = weight_cauchy(points[i].rx / points[i].dX);
-      points[i].Wy = weight_cauchy(points[i].ry / points[i].dY);
-    }    
-
-    // Solve with the new weights
-    if (!FitPM_MinChisq(fit, data, points, Npoints)) {
-
-      // restore the last solution and break
-      fit->Ro = data->Beta_prev[0];
-      fit->uR = data->Beta_prev[1];
-      fit->Do = data->Beta_prev[2];
-      fit->uD = data->Beta_prev[3];
-      
-      // calculate the residuals:
-      for (i = 0; i < Npoints; i++) {
-	points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro);
-	points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do);
-	points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
-      }
-      sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
-      break;
-    }
-
-    // store the new Beta.
-    for (i = 0; i < data->Nterms; i++) {
-      data->Beta[i] = data->B[i][0];
-    }
-
-    // calculate the residuals:
-    for (i = 0; i < Npoints; i++) {
-      points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro);
-      points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do);
-      points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
-    }
-    sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
-    
-    // Check convergence
-    converged = TRUE;
-    for (i = 0; i < data->Nterms; i++) {
-      // if we are within FIT_TOLERANCE as a fractional error or FLT_TOLERANCE as an absolute error, we are good
-      if ((fabs(data->Beta[i] - data->Beta_prev[i]) > FIT_TOLERANCE * fabs(data->Beta[i])) && 
-	  (fabs(data->Beta[i] - data->Beta_prev[i]) > FLT_TOLERANCE)) {
-	converged = FALSE;
-      }
-    }
-  }
-  fit->converged = converged;
-
-  // calculate the weight thresholds to mask the bad points:
-  double Sum_Wx = 0.0;
-  double Sum_Wy = 0.0;
-  for (i = 0; i < Npoints; i++) {
-    points[i].Wx = weight_cauchy(points[i].rx / points[i].dX);
-    points[i].Wy = weight_cauchy(points[i].ry / points[i].dY);
-    
-    Sum_Wx += points[i].Wx;
-    Sum_Wy += points[i].Wy;
-  }
-  double WxThreshold = WEIGHT_THRESHOLD * Sum_Wx / (1.0 * Npoints);
-  double WyThreshold = WEIGHT_THRESHOLD * Sum_Wy / (1.0 * Npoints);
-
-  // set a mask (which can be used by the bootstrap resampling analysis)
-  for (i = 0; i < Npoints; i++) {
-    // keep if either is above threshold?
-    // drop if either is below threshold?
-    // points are marked as keep by default
-    if ((points[i].Wx < WxThreshold) || (points[i].Wy < WyThreshold)) {
-      points[i].mask = 1; // keep point if mask == 0
-    }
-  }
-
-  // this section calculates the formal error on the weighted fit using the covariance values
-  // NOTE EAM: in tests (fitpm.c), they seem to be too large by a factor of ~5.37
-  if (data->getError) {
-    double ax = 0.0, ay = 0.0;
-    double bx = 0.0, by = 0.0;
-
-    for (i = 0; i < Npoints; i++) {
-      ax += dpsi_cauchy(points[i].rx / points[i].dX);
-      ay += dpsi_cauchy(points[i].ry / points[i].dY);
-
-      bx += SQ(points[i].Wx);
-      by += SQ(points[i].Wy);
-    }
-    ax /= 1.0 * Npoints;  // mean(psi_dot(r))
-    ay /= 1.0 * Npoints; 
-    bx /= 1.0 * (Npoints - data->Nterms); // mean(psi^2(r)) * (N / (N-p))
-    by /= 1.0 * (Npoints - data->Nterms);
-  
-    double lambda_x = 1.0 + (data->Nterms / Npoints) * (1 - ax) / ax;
-    double lambda_y = 1.0 + (data->Nterms / Npoints) * (1 - ay) / ay;
-  
-    double sigma_robust_x = lambda_x * sqrt(bx) * sigma_hat * 2.385 / ax;
-    double sigma_robust_y = lambda_y * sqrt(by) * sigma_hat * 2.385 / ay;
-
-    // This is actually sigma^2, as that's the factor in the covariance (dumouchel 4.1)
-    double sigma_final_x  = MAX(SQ(sigma_robust_x), (2 * Npoints * SQ(sigma_robust_x) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-    double sigma_final_y  = MAX(SQ(sigma_robust_y), (2 * Npoints * SQ(sigma_robust_y) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-
-    fit[0].dRo = sqrt(data->Cov[0][0]);
-    fit[0].duR = sqrt(data->Cov[1][1]);
-    fit[0].dDo = sqrt(data->Cov[2][2]);
-    fit[0].duD = sqrt(data->Cov[3][3]);
-
-    fit[0].dRo *= sigma_final_x;
-    fit[0].duR *= sigma_final_x;
-    fit[0].dDo *= sigma_final_y;
-    fit[0].duD *= sigma_final_y;
-  }
-
-  // count unmasked points and (optionally) add up the chi square for the fit
-  double chisq = 0.0;
-  fit[0].Nfit = 0;
-  for (i = 0; i < Npoints; i++) {
-    if (points[i].mask) continue;
-    fit[0].Nfit ++;
-      
-    if (data->getChisq) {
-      double Xf = fit[0].Ro + fit[0].uR*points[i].T;
-      double Yf = fit[0].Do + fit[0].uD*points[i].T;
-      double wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dX);
-      double wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dY);
-      chisq += SQ(points[i].X - Xf) * wx;
-      chisq += SQ(points[i].Y - Yf) * wy;
-    }
-  }
-    
-  // the reduced chisq is divided by (Ndof = 2*Nfit - Nterms)
-  fit[0].chisq = chisq / (2.0*fit[0].Nfit - data->Nterms);
-
-  return (TRUE);
-}
-
-int FitPM_MinChisq (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints) {
-
-  myAssert (data->Nterms == 4, "invalid fit arrays");
-
-  int i;
-  double wx, wy, Wx, Wy, Tx, Ty, Tx2, Ty2, Xs, Ys, XT, YT;
-  Wx = Wy = Tx = Ty = Tx2 = Ty2 = Xs = Ys = XT = YT = 0.0;
-
-  for (i = 0; i < Npoints; i++) {
-    if (points[i].mask) continue; // respect the mask if set
-
-    wx = points[i].Wx;
-    wy = points[i].Wy;
-
-    Wx += wx;
-    Wy += wy;
-
-    double TWx = points[i].T*wx;
-    double TWy = points[i].T*wy;
-
-    Tx += TWx;
-    Ty += TWy;
-    
-    Tx2 += points[i].T*TWx;
-    Ty2 += points[i].T*TWy;
-    
-    Xs += points[i].X*wx;
-    Ys += points[i].Y*wy;
-
-    XT += points[i].X*TWx;
-    YT += points[i].Y*TWy;
-  }
-
-  // X^T W X
-  data->A[0][0] = Wx;
-  data->A[0][1] = Tx;
-  data->A[0][2] = 0.0;
-  data->A[0][3] = 0.0;
-
-  data->A[1][0] = Tx;
-  data->A[1][1] = Tx2;
-  data->A[1][2] = 0.0;
-  data->A[1][3] = 0.0;
-
-  data->A[2][0] = 0.0;
-  data->A[2][1] = 0.0;
-  data->A[2][2] = Wy;
-  data->A[2][3] = Ty;
-
-  data->A[3][0] = 0.0;
-  data->A[3][1] = 0.0;
-  data->A[3][2] = Ty;
-  data->A[3][3] = Ty2;
-
-  // X^T W Y
-  data->B[0][0] = Xs;
-  data->B[1][0] = XT;
-  data->B[2][0] = Ys;
-  data->B[3][0] = YT;
-
-  if (!dgaussjordan (data->A, data->B, 4, 1)) {
-    return FALSE;
-  }
-
-  fit->Ro = data->B[0][0];
-  fit->uR = data->B[1][0];
-  fit->Do = data->B[2][0];
-  fit->uD = data->B[3][0];
-  fit->p  = 0.0;
-
-  fit->dRo = sqrt(data->A[0][0]);
-  fit->duR = sqrt(data->A[1][1]);
-  fit->dDo = sqrt(data->A[2][2]);
-  fit->duD = sqrt(data->A[3][3]);
-  fit->dp  = 0.0;
-
-  return TRUE;
-}
-
Index: trunk/Ohana/src/relastro/src/FitPMandPar.c
===================================================================
--- trunk/Ohana/src/relastro/src/FitPMandPar.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/FitPMandPar.c	(revision 39926)
@@ -25,4 +25,5 @@
   }
 
+  fit->useWeight = FALSE; // Ordinary Least Squares
   if (!FitPMandPar_MinChisq (fit, data, points, Npoints)) return FALSE;
   if (!FitPMandPar_SetChisq (fit, data, points, Npoints)) return FALSE;
@@ -47,4 +48,5 @@
   
   // Solve OLS equation: failure here means the chisq matrix is degenerate, give up entirely
+  fit->useWeight = FALSE; // Ordinary Least Squares
   if (!FitPMandPar_MinChisq(fit, data, points, Npoints)) {
     return(FALSE);
@@ -69,5 +71,5 @@
 
   // Iteratively reweight and solve
-  double sigma_hat = 0.0; // save for the error model
+  // double sigma_hat = 0.0; // save for the error model
   int converged = FALSE;
   int iterations = 0;
@@ -90,4 +92,5 @@
 
     // Solve with the new weights
+    fit->useWeight = TRUE; // Reweighted Least Squares
     if (!FitPMandPar_MinChisq(fit, data, points, Npoints)) {
 
@@ -105,5 +108,5 @@
 	points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
       }
-      sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
+      // sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
       break;
     }
@@ -120,5 +123,5 @@
       points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
     }
-    sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
+    // sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
 
     // Check convergence
@@ -157,43 +160,19 @@
   }
 
-  // this section calculates the formal error on the weighted fit using the covariance values
-  // NOTE EAM: in tests (fitpm.c), they seem to be too large by a factor of ~5.37
+  // this section calculates the formal error on the regular (unweighted) fit using the covariance values
+  // NOTE 20160929 : use only the unmasked points to calculate the error
   if (data->getError) {
-    double ax = 0.0, ay = 0.0;
-    double bx = 0.0, by = 0.0;
-
-    for (i = 0; i < Npoints; i++) {
-      ax += dpsi_cauchy(points[i].rx / points[i].dX);
-      ay += dpsi_cauchy(points[i].ry / points[i].dY);
-
-      bx += SQ(points[i].Wx);
-      by += SQ(points[i].Wy);
-    }
-    ax /= 1.0 * Npoints;  // mean(psi_dot(r))
-    ay /= 1.0 * Npoints; 
-    bx /= 1.0 * (Npoints - data->Nterms); // mean(psi^2(r)) * (N / (N-p))
-    by /= 1.0 * (Npoints - data->Nterms);
-  
-    double lambda_x = 1.0 + (data->Nterms / Npoints) * (1 - ax) / ax;
-    double lambda_y = 1.0 + (data->Nterms / Npoints) * (1 - ay) / ay;
-  
-    double sigma_robust_x = lambda_x * sqrt(bx) * sigma_hat * 2.385 / ax;
-    double sigma_robust_y = lambda_y * sqrt(by) * sigma_hat * 2.385 / ay;
-
-    // This is actually sigma^2, as that's the factor in the covariance (dumouchel 4.1)
-    double sigma_final_x  = MAX(SQ(sigma_robust_x), (2 * Npoints * SQ(sigma_robust_x) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-    double sigma_final_y  = MAX(SQ(sigma_robust_y), (2 * Npoints * SQ(sigma_robust_y) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-
-    fit[0].dRo = sqrt(data->Cov[0][0]);
-    fit[0].duR = sqrt(data->Cov[1][1]);
-    fit[0].dDo = sqrt(data->Cov[2][2]);
-    fit[0].duD = sqrt(data->Cov[3][3]);
-    fit[0].dp  = sqrt(data->Cov[4][4]);
-
-    fit[0].dRo *= sigma_final_x;
-    fit[0].duR *= sigma_final_x;
-    fit[0].dDo *= sigma_final_y;
-    fit[0].duD *= sigma_final_y;
-    fit[0].dp  *= sqrt(sigma_final_x * sigma_final_y);
+    FitAstromResult fitErrors;
+    FitAstromResultInit (&fitErrors);
+    fitErrors.useWeight = FALSE; 
+
+    FitPMandPar_MinChisq(&fitErrors, data, points, Npoints);
+
+    // we use the errors from a simple OLS, ignoring masked points
+    fit[0].dRo = fitErrors.dRo;
+    fit[0].duR = fitErrors.duR;
+    fit[0].dDo = fitErrors.dDo;
+    fit[0].duD = fitErrors.duD;
+    fit[0].dp  = fitErrors.dp;
   }
 
@@ -219,6 +198,11 @@
     Nfit ++;
 
-    wx = points[i].qx;
-    wy = points[i].qy;
+    if (fit->useWeight) {
+      wx = points[i].qx;
+      wy = points[i].qy;
+    } else {
+      wx = points[i].Qx;
+      wy = points[i].Qy;
+    }
 
     Wx += wx;
Index: trunk/Ohana/src/relastro/src/FitPMandPar_IRLS.c
===================================================================
--- trunk/Ohana/src/relastro/src/FitPMandPar_IRLS.c	(revision 39907)
+++ 	(revision )
@@ -1,302 +1,0 @@
-# include "relastro.h"
-# define OLD_METHOD 1
-
-// These should probably be tunable:
-# define MAX_ITERATIONS 10
-# define FIT_TOLERANCE 1e-4
-# define FLT_TOLERANCE 1e-6
-# define WEIGHT_THRESHOLD 0.3
-
-int FitPMandPar_IRLS (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints, int VERBOSE) {
-
-  int i,j;
-
-  int Ndof = 2 * Npoints - data->Nterms;
-  
-  // Convert the measurement errors into initial weights.
-  for (i = 0; i < Npoints; i++) {
-# if (OLD_METHOD)
-    points[i].Wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1 / SQ(points[i].dX);
-    points[i].Wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1 / SQ(points[i].dY);
-# else
-    points[i].Qx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1 / SQ(points[i].dX);
-    points[i].Qy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1 / SQ(points[i].dY);
-# endif
-    points[i].qx = points[i].Wx * points[i].Qx; // Wx, Wy start out at 1.0
-    points[i].qy = points[i].Wy * points[i].Qy; // Wx, Wy start out at 1.0
-  }
-  
-  // Solve OLS equation: failure here means the chisq matrix is degenerate, give up entirely
-  if (!weighted_LS_PLX(fit, data, points, Npoints, VERBOSE)) {
-    return(FALSE);
-  }
-
-  // Calculate r vector of residuals and least squares sigma
-  double sigma_ols = 0.0;
-  for (i = 0; i < Npoints; i++) {
-    points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro + points[i].pR * fit->p);
-    points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do + points[i].pD * fit->p);
-    sigma_ols += SQ(points[i].rx) + SQ(points[i].ry);
-  }
-  sigma_ols = sqrt(sigma_ols / (float)Ndof);
-  
-  // Save OLS covariance and Beta (solution vector, which is actually also saved in fit)
-  for (i = 0; i < data->Nterms; i++) {
-    for (j = 0; j < data->Nterms; j++) {
-      data->Cov[i][j] = data->A[i][j];
-    }
-    data->Beta[i] = data->B[i][0];
-  }
-
-  // Iteratively reweight and solve
-  double sigma_hat = 0.0; // save for the error model
-  int converged = FALSE;
-  int iterations = 0;
-
-  // modify the weight based on the distance from the previous fit.  try up to MAX_ITERATIONS.
-  // at the end "fit", has the last fit parameters
-  for (iterations = 0; !converged && (iterations < MAX_ITERATIONS); iterations ++) {
-    // Save Beta.
-    for (i = 0; i < data->Nterms; i ++) {
-      data->Beta_prev[i] = data->Beta[i];
-    }
-
-    // Assign weights based on the deviation
-    for (i = 0; i < Npoints; i++) {
-      points[i].Wx = weight_cauchy(points[i].rx / points[i].dX);
-      points[i].Wy = weight_cauchy(points[i].ry / points[i].dY);
-      points[i].qx = points[i].Wx * points[i].Qx;
-      points[i].qy = points[i].Wy * points[i].Qy;
-    }    
-
-    // Solve with the new weights
-    if (!weighted_LS_PLX(fit, data, points, Npoints, VERBOSE)) {
-
-      // restore the last solution and break
-      fit->Ro = data->Beta_prev[0];
-      fit->uR = data->Beta_prev[1];
-      fit->Do = data->Beta_prev[2];
-      fit->uD = data->Beta_prev[3];
-      fit->p  = data->Beta_prev[4];
-      
-      // calculate the residuals:
-      for (i = 0; i < Npoints; i++) {
-	points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro + points[i].pR * fit->p);
-	points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do + points[i].pD * fit->p);
-	points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
-      }
-      sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
-      break;
-    }
-
-    // store the new Beta.
-    for (i = 0; i < data->Nterms; i++) {
-      data->Beta[i] = data->B[i][0];
-    }
-
-    // calculate the residuals:
-    for (i = 0; i < Npoints; i++) {
-      points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro + points[i].pR * fit->p);
-      points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do + points[i].pD * fit->p);
-      points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
-    }
-    sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
-
-    // Check convergence
-    converged = TRUE;
-    for (i = 0; i < data->Nterms; i++) {
-      // if we are within FIT_TOLERANCE as a fractional error or FLT_TOLERANCE as an absolute error, we are good
-      if ((fabs(data->Beta[i] - data->Beta_prev[i]) > FIT_TOLERANCE * fabs(data->Beta[i])) && 
-	  (fabs(data->Beta[i] - data->Beta_prev[i]) > FLT_TOLERANCE)) {
-	converged = FALSE;
-      }
-    }
-  }
-  fit->converged = converged;
-
-  // calculate the weight thresholds to mask the bad points:
-  double Sum_Wx = 0.0;
-  double Sum_Wy = 0.0;
-  for (i = 0; i < Npoints; i++) {
-    points[i].Wx = weight_cauchy(points[i].rx / points[i].dX);
-    points[i].Wy = weight_cauchy(points[i].ry / points[i].dY);
-    
-    Sum_Wx += points[i].Wx;
-    Sum_Wy += points[i].Wy;
-  }
-  double WxThreshold = WEIGHT_THRESHOLD * Sum_Wx / (1.0 * Npoints);
-  double WyThreshold = WEIGHT_THRESHOLD * Sum_Wy / (1.0 * Npoints);
-
-  // set a mask (which can be used by the bootstrap resampling analysis)
-  for (i = 0; i < Npoints; i++) {
-    // keep if either is above threshold?
-    // drop if either is below threshold?
-    // points are marked as keep by default
-    if ((points[i].Wx < WxThreshold) || (points[i].Wy < WyThreshold)) {
-      points[i].mask = 1; // keep point if mask == 0
-    }
-  }
-
-  // this section calculates the formal error on the weighted fit using the covariance values
-  // NOTE EAM: in tests (fitpm.c), they seem to be too large by a factor of ~5.37
-  if (data->getError) {
-    double ax = 0.0, ay = 0.0;
-    double bx = 0.0, by = 0.0;
-
-    for (i = 0; i < Npoints; i++) {
-      ax += dpsi_cauchy(points[i].rx / points[i].dX);
-      ay += dpsi_cauchy(points[i].ry / points[i].dY);
-
-      bx += SQ(points[i].qx);
-      by += SQ(points[i].qy);
-    }
-    ax /= 1.0 * Npoints;  // mean(psi_dot(r))
-    ay /= 1.0 * Npoints; 
-    bx /= 1.0 * (Npoints - data->Nterms); // mean(psi^2(r)) * (N / (N-p))
-    by /= 1.0 * (Npoints - data->Nterms);
-  
-    double lambda_x = 1.0 + (data->Nterms / Npoints) * (1 - ax) / ax;
-    double lambda_y = 1.0 + (data->Nterms / Npoints) * (1 - ay) / ay;
-  
-    double sigma_robust_x = lambda_x * sqrt(bx) * sigma_hat * 2.385 / ax;
-    double sigma_robust_y = lambda_y * sqrt(by) * sigma_hat * 2.385 / ay;
-
-    // This is actually sigma^2, as that's the factor in the covariance (dumouchel 4.1)
-    double sigma_final_x  = MAX(SQ(sigma_robust_x), (2 * Npoints * SQ(sigma_robust_x) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-    double sigma_final_y  = MAX(SQ(sigma_robust_y), (2 * Npoints * SQ(sigma_robust_y) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-
-    fit[0].dRo = sqrt(data->Cov[0][0]);
-    fit[0].duR = sqrt(data->Cov[1][1]);
-    fit[0].dDo = sqrt(data->Cov[2][2]);
-    fit[0].duD = sqrt(data->Cov[3][3]);
-    fit[0].dp  = sqrt(data->Cov[4][4]);
-
-    fit[0].dRo *= sigma_final_x;
-    fit[0].duR *= sigma_final_x;
-    fit[0].dDo *= sigma_final_y;
-    fit[0].duD *= sigma_final_y;
-    fit[0].dp  *= sqrt(sigma_final_x * sigma_final_y);
-  }
-
-  // count unmasked points and (optionally) add up the chi square for the fit
-  double chisq = 0.0;
-  fit[0].Nfit = 0;
-  for (i = 0; i < Npoints; i++) {
-    if (points[i].mask) continue;
-    fit[0].Nfit ++;
-      
-    if (data->getChisq) {
-      double Xf = fit[0].Ro + fit[0].uR*points[i].T + fit[0].p*points[i].pR;
-      double Yf = fit[0].Do + fit[0].uD*points[i].T + fit[0].p*points[i].pD;
-      double wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dX);
-      double wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dY);
-      chisq += SQ(points[i].X - Xf) * wx;
-      chisq += SQ(points[i].Y - Yf) * wy;
-    }  
-  }
-    
-  // the reduced chisq is divided by Ndof = (2*Nfit - Nterms)
-  fit[0].chisq = chisq / (2.0*fit[0].Nfit - data->Nterms);
-  
-  return (TRUE);
-}
-
-int weighted_LS_PLX (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints, int VERBOSE) {
-
-  myAssert (data->Nterms == 5, "invalid fit arrays");
-
-  int i;
-  double wx, wy, Wx, Wy, Tx, Ty, Tx2, Ty2, Xs, Ys, XT, YT;
-  double PR, PD, PRT, PDT, PRX, PDY, PR2, PD2;
-
-  PR = PD = PRT = PDT = PRX = PDY = PR2 = PD2 = 0.0;
-  Wx = Wy = Tx = Ty = Tx2 = Ty2 = Xs = Ys = XT = YT = 0.0;
-
-  for (i = 0; i < Npoints; i++) {
-
-    // if (VERBOSE == 2) fprintf (stderr, "%f %f : %f %f : %f : %f %f\n", X[i], WX[i], Y[i], WY[i], T[i], pR[i], pD[i]);
-
-# if (OLD_METHOD)
-    wx = points[i].Wx;
-    wy = points[i].Wy;
-# else 
-    wx = points[i].Wx;
-    wy = points[i].Wy;
-# endif
-
-    Wx += wx;
-    Wy += wy;
-
-    Tx += points[i].T*wx;
-    Ty += points[i].T*wy;
-    
-    Tx2 += SQ(points[i].T)*wx;
-    Ty2 += SQ(points[i].T)*wy;
-    
-    PR += points[i].pR*wx;
-    PD += points[i].pD*wy;
-    
-    PRT += points[i].pR*points[i].T*wx;
-    PDT += points[i].pD*points[i].T*wy;
-    
-    PRX += points[i].pR*points[i].X*wx;
-    PDY += points[i].pD*points[i].Y*wy;
-    
-    PR2 += SQ(points[i].pR)*wx;
-    PD2 += SQ(points[i].pD)*wy;
-
-    Xs += points[i].X*wx;
-    Ys += points[i].Y*wy;
-
-    XT += points[i].X*points[i].T*wx;
-    YT += points[i].Y*points[i].T*wy;
-  }
-
-  data->A[0][0] = Wx;
-  data->A[0][1] = Tx;
-  data->A[0][2] = 0.0;
-  data->A[0][3] = 0.0;
-  data->A[0][4] = PR;
-
-  data->A[1][0] = Tx;
-  data->A[1][1] = Tx2;
-  data->A[1][2] = 0.0;
-  data->A[1][3] = 0.0;
-  data->A[1][4] = PRT;
-
-  data->A[2][0] = 0.0;
-  data->A[2][1] = 0.0;
-  data->A[2][2] = Wy;
-  data->A[2][3] = Ty;
-  data->A[2][4] = PD;
-
-  data->A[3][0] = 0.0;
-  data->A[3][1] = 0.0;
-  data->A[3][2] = Ty;
-  data->A[3][3] = Ty2;
-  data->A[3][4] = PDT;
-
-  data->A[4][0] = PR;
-  data->A[4][1] = PRT;
-  data->A[4][2] = PD;
-  data->A[4][3] = PDT;
-  data->A[4][4] = PR2 + PD2;
-
-  data->B[0][0] = Xs;
-  data->B[1][0] = XT;
-  data->B[2][0] = Ys;
-  data->B[3][0] = YT;
-  data->B[4][0] = PRX + PDY;
-
-  if (!dgaussjordan (data->A, data->B, 5, 1)) {
-    return FALSE;
-  }
-
-  fit->Ro = data->B[0][0];
-  fit->uR = data->B[1][0];
-  fit->Do = data->B[2][0];
-  fit->uD = data->B[3][0];
-  fit->p  = data->B[4][0];
-
-  return TRUE;
-}
Index: trunk/Ohana/src/relastro/src/FitPosPMfixed.c
===================================================================
--- trunk/Ohana/src/relastro/src/FitPosPMfixed.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/FitPosPMfixed.c	(revision 39926)
@@ -54,4 +54,5 @@
   }
 
+  fit->useWeight = FALSE; // Ordinary Least Squares
   if (!FitPosPMfixed_MinChisq (fit, data, points, Npoints)) {
     if (!FitPosPMfixed_Single (fit, points, Npoints)) return FALSE;
@@ -83,4 +84,5 @@
   
   // Solve OLS equation  
+  fit->useWeight = FALSE; // Ordinary Least Squares
   if (!FitPosPMfixed_MinChisq(fit, data, points, Npoints)) {
     return(FALSE);
@@ -105,5 +107,5 @@
 
   // Iteratively reweight and solve
-  double sigma_hat = 0.0; // save for the error model
+  // double sigma_hat = 0.0; // save for the error model
   int converged = FALSE;
   int iterations = 0;
@@ -126,4 +128,5 @@
 
     // Solve with the new weights
+    fit->useWeight = TRUE; // Reweighted Least Squares
     if (!FitPosPMfixed_MinChisq(fit, data, points, Npoints)) {
 
@@ -138,5 +141,5 @@
 	points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
       }
-      sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
+      // sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
       break;
     }
@@ -153,5 +156,5 @@
       points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
     }
-    sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
+    // sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
     
     // Check convergence
@@ -193,34 +196,16 @@
   // NOTE EAM: in tests (fitpm.c), they seem to be too large by a factor of ~5.37
   if (data->getError) {
-    double ax = 0.0, ay = 0.0;
-    double bx = 0.0, by = 0.0;
-
-    for (i = 0; i < Npoints; i++) {
-      ax += dpsi_cauchy(points[i].rx / points[i].dX);
-      ay += dpsi_cauchy(points[i].ry / points[i].dY);
-
-      bx += SQ(points[i].Wx);
-      by += SQ(points[i].Wy);
-    }
-    ax /= 1.0 * Npoints;  // mean(psi_dot(r))
-    ay /= 1.0 * Npoints; 
-    bx /= 1.0 * (Npoints - data->Nterms); // mean(psi^2(r)) * (N / (N-p))
-    by /= 1.0 * (Npoints - data->Nterms);
-  
-    double lambda_x = 1.0 + (data->Nterms / Npoints) * (1 - ax) / ax;
-    double lambda_y = 1.0 + (data->Nterms / Npoints) * (1 - ay) / ay;
-  
-    double sigma_robust_x = lambda_x * sqrt(bx) * sigma_hat * 2.385 / ax;
-    double sigma_robust_y = lambda_y * sqrt(by) * sigma_hat * 2.385 / ay;
-
-    // This is actually sigma^2, as that's the factor in the covariance (dumouchel 4.1)
-    double sigma_final_x  = MAX(SQ(sigma_robust_x), (2 * Npoints * SQ(sigma_robust_x) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-    double sigma_final_y  = MAX(SQ(sigma_robust_y), (2 * Npoints * SQ(sigma_robust_y) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-
-    fit[0].dRo = sqrt(data->Cov[0][0]);
-    fit[0].dDo = sqrt(data->Cov[1][1]);
-
-    fit[0].dRo *= sigma_final_x;
-    fit[0].dDo *= sigma_final_y;
+    FitAstromResult fitErrors;
+    FitAstromResultInit (&fitErrors);
+    fitErrors.useWeight = FALSE; 
+
+    FitPosPMfixed_MinChisq(&fitErrors, data, points, Npoints);
+
+    // we use the errors from a simple OLS, ignoring masked points
+    fit[0].dRo = fitErrors.dRo;
+    fit[0].duR = fitErrors.duR;
+    fit[0].dDo = fitErrors.dDo;
+    fit[0].duD = fitErrors.duD;
+    fit[0].dp  = fitErrors.dp;
   }
 
@@ -242,6 +227,11 @@
     Nfit ++;
 
-    wx = points[i].qx;
-    wy = points[i].qy;
+    if (fit->useWeight) {
+      wx = points[i].qx;
+      wy = points[i].qy;
+    } else {
+      wx = points[i].Qx;
+      wy = points[i].Qy;
+    }
 
     Wx += wx;
Index: trunk/Ohana/src/relastro/src/FitPosPMfixed_IRLS.c
===================================================================
--- trunk/Ohana/src/relastro/src/FitPosPMfixed_IRLS.c	(revision 39907)
+++ 	(revision )
@@ -1,228 +1,0 @@
-# include "relastro.h"
-
-// These should probably be tunable:
-# define MAX_ITERATIONS 10
-# define FIT_TOLERANCE 1e-4
-# define FLT_TOLERANCE 1e-6
-# define WEIGHT_THRESHOLD 0.3
-
-int FitPosPMfixed_IRLS (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints, int VERBOSE) {
-
-  int i,j;
-
-  int Ndof = 2 * Npoints - data->Nterms;
-  
-  // Convert the measurement errors into initial weights.
-  for (i = 0; i < Npoints; i++) {
-    points[i].Wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1 / SQ(points[i].dX);
-    points[i].Wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1 / SQ(points[i].dY);
-  }
-  
-  // Solve OLS equation  
-  if (!weighted_LS_POS(fit, data, points, Npoints, VERBOSE)) {
-    return(FALSE);
-  }
-
-  // Calculate r vector of residuals and least squares sigma
-  double sigma_ols = 0.0;
-  for (i = 0; i < Npoints; i++) {
-    points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro);
-    points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do);
-    sigma_ols += SQ(points[i].rx) + SQ(points[i].ry);
-  }
-  sigma_ols = sqrt(sigma_ols / (float)Ndof);
-
-  // Save OLS covariance and Beta (solution vector, which is actually also saved in fit)
-  for (i = 0; i < data->Nterms; i++) {
-    for (j = 0; j < data->Nterms; j++) {
-      data->Cov[i][j] = data->A[i][j];
-    }
-    data->Beta[i] = data->B[i][0];
-  }
-
-  // Iteratively reweight and solve
-  double sigma_hat = 0.0; // save for the error model
-  int converged = FALSE;
-  int iterations = 0;
-
-  // modify the weight based on the distance from the previous fit.  try up to MAX_ITERATIONS.
-  // at the end "fit", has the last fit parameters
-  for (iterations = 0; !converged && (iterations < MAX_ITERATIONS); iterations ++) {
-    // Save Beta.
-    for (i = 0; i < data->Nterms; i ++) {
-      data->Beta_prev[i] = data->Beta[i];
-    }
-
-    // Assign weights based on the deviation
-    for (i = 0; i < Npoints; i++) {
-      points[i].Wx = weight_cauchy(points[i].rx / points[i].dX);
-      points[i].Wy = weight_cauchy(points[i].ry / points[i].dY);
-    }    
-
-    // Solve with the new weights
-    if (!weighted_LS_POS(fit, data, points, Npoints, VERBOSE)) {
-
-      // restore the last solution and break
-      fit->Ro = data->Beta_prev[0];
-      fit->Do = data->Beta_prev[1];
-      
-      // calculate the residuals:
-      for (i = 0; i < Npoints; i++) {
-	points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro);
-	points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do);
-	points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
-      }
-      sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
-      break;
-    }
-
-    // store the new Beta.
-    for (i = 0; i < data->Nterms; i++) {
-      data->Beta[i] = data->B[i][0];
-    }
-
-    // calculate the residuals:
-    for (i = 0; i < Npoints; i++) {
-      points[i].rx = points[i].X - (points[i].T * fit->uR + fit->Ro);
-      points[i].ry = points[i].Y - (points[i].T * fit->uD + fit->Do);
-      points[i].u = sqrt(SQ(points[i].rx / points[i].dX) + SQ(points[i].ry / points[i].dY));
-    }
-    sigma_hat = MedianAbsDeviation(points, Npoints) / 0.6745;
-    
-    // Check convergence
-    converged = TRUE;
-    for (i = 0; i < data->Nterms; i++) {
-      // if we are within FIT_TOLERANCE as a fractional error or FLT_TOLERANCE as an absolute error, we are good
-      if ((fabs(data->Beta[i] - data->Beta_prev[i]) > FIT_TOLERANCE * fabs(data->Beta[i])) && 
-	  (fabs(data->Beta[i] - data->Beta_prev[i]) > FLT_TOLERANCE)) {
-	converged = FALSE;
-      }
-    }
-  }
-  fit->converged = converged;
-
-  // calculate the weight thresholds to mask the bad points:
-  double Sum_Wx = 0.0;
-  double Sum_Wy = 0.0;
-  for (i = 0; i < Npoints; i++) {
-    points[i].Wx = weight_cauchy(points[i].rx / points[i].dX);
-    points[i].Wy = weight_cauchy(points[i].ry / points[i].dY);
-    
-    Sum_Wx += points[i].Wx;
-    Sum_Wy += points[i].Wy;
-  }
-  double WxThreshold = WEIGHT_THRESHOLD * Sum_Wx / (1.0 * Npoints);
-  double WyThreshold = WEIGHT_THRESHOLD * Sum_Wy / (1.0 * Npoints);
-
-  // set a mask (which can be used by the bootstrap resampling analysis)
-  for (i = 0; i < Npoints; i++) {
-    // keep if either is above threshold?
-    // drop if either is below threshold?
-    // points are marked as keep by default
-    if ((points[i].Wx < WxThreshold) || (points[i].Wy < WyThreshold)) {
-      points[i].mask = 1; // keep point if mask == 0
-    }
-  }
-
-  // this section calculates the formal error on the weighted fit using the covariance values
-  // NOTE EAM: in tests (fitpm.c), they seem to be too large by a factor of ~5.37
-  if (data->getError) {
-    double ax = 0.0, ay = 0.0;
-    double bx = 0.0, by = 0.0;
-
-    for (i = 0; i < Npoints; i++) {
-      ax += dpsi_cauchy(points[i].rx / points[i].dX);
-      ay += dpsi_cauchy(points[i].ry / points[i].dY);
-
-      bx += SQ(points[i].Wx);
-      by += SQ(points[i].Wy);
-    }
-    ax /= 1.0 * Npoints;  // mean(psi_dot(r))
-    ay /= 1.0 * Npoints; 
-    bx /= 1.0 * (Npoints - data->Nterms); // mean(psi^2(r)) * (N / (N-p))
-    by /= 1.0 * (Npoints - data->Nterms);
-  
-    double lambda_x = 1.0 + (data->Nterms / Npoints) * (1 - ax) / ax;
-    double lambda_y = 1.0 + (data->Nterms / Npoints) * (1 - ay) / ay;
-  
-    double sigma_robust_x = lambda_x * sqrt(bx) * sigma_hat * 2.385 / ax;
-    double sigma_robust_y = lambda_y * sqrt(by) * sigma_hat * 2.385 / ay;
-
-    // This is actually sigma^2, as that's the factor in the covariance (dumouchel 4.1)
-    double sigma_final_x  = MAX(SQ(sigma_robust_x), (2 * Npoints * SQ(sigma_robust_x) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-    double sigma_final_y  = MAX(SQ(sigma_robust_y), (2 * Npoints * SQ(sigma_robust_y) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
-
-    fit[0].dRo = sqrt(data->Cov[0][0]);
-    fit[0].dDo = sqrt(data->Cov[1][1]);
-
-    fit[0].dRo *= sigma_final_x;
-    fit[0].dDo *= sigma_final_y;
-  }
-
-  // count unmasked points and (optionally) add up the chi square for the fit
-  double chisq = 0.0;
-  fit[0].Nfit = 0;
-  for (i = 0; i < Npoints; i++) {
-    if (points[i].mask) continue;
-    fit[0].Nfit ++;
-      
-    if (data->getChisq) {
-      double Xf = fit[0].Ro + fit[0].uR*points[i].T;
-      double Yf = fit[0].Do + fit[0].uD*points[i].T;
-      double wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dX);
-      double wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dY);
-      chisq += SQ(points[i].X - Xf) * wx;
-      chisq += SQ(points[i].Y - Yf) * wy;
-    }
-  }
-    
-  // the reduced chisq is divided by (Ndof = 2*Nfit - Nterms)
-  fit[0].chisq = chisq / (2.0*fit[0].Nfit - data->Nterms);
-
-  return (TRUE);
-}
-
-int weighted_LS_POS (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints, int VERBOSE) {
-
-  myAssert (data->Nterms == 2, "invalid fit arrays");
-
-  int i;
-  double wx, wy, Wx, Wy, Tx, Ty, Xs, Ys;
-
-  Wx = Wy = Tx = Ty = Xs = Ys = 0.0;
-
-  for (i = 0; i < Npoints; i++) {
-    wx = points[i].Wx;
-    wy = points[i].Wy;
-
-    Wx += wx;
-    Wy += wy;
-
-    Tx += points[i].T*wx;
-    Ty += points[i].T*wy;
-    
-    Xs += points[i].X*wx;
-    Ys += points[i].Y*wy;
-  }
-
-  // X^T W X
-  data->A[0][0] = Wx;
-  data->A[0][1] = 0.0;
-
-  data->A[1][0] = 0.0;
-  data->A[1][1] = Wy;
-
-  // X^T W Y
-  data->B[0][0] = Xs - fit->uR*Tx;
-  data->B[1][0] = Ys - fit->uD*Ty;
-
-  if (!dgaussjordan (data->A, data->B, 2, 1)) {
-    return FALSE;
-  }
-
-  fit->Ro = data->B[0][0];
-  fit->Do = data->B[1][0];
-  fit->p  = 0.0;
-
-  return TRUE;
-}
Index: trunk/Ohana/src/relastro/src/GetAstromError.c
===================================================================
--- trunk/Ohana/src/relastro/src/GetAstromError.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/GetAstromError.c	(revision 39926)
@@ -48,4 +48,13 @@
   if (isnan(code[0].astromErrSys)) return NAN;
 
+  if (measure[0].photcode == 1030) {
+    if (mode == ERROR_MODE_RA) {
+      dPobs = pow(10.0, (6.0 * measure[0].dXccd - 3.0));  // dXccd is a value in pixels
+    }
+    if (mode == ERROR_MODE_DEC) {
+      dPobs = pow(10.0, (6.0 * measure[0].dYccd - 3.0));  // dXccd is a value in pixels
+    }
+  }
+
   AS   	= code[0].astromErrScale;
   MS   	= code[0].astromErrMagScale;
@@ -69,7 +78,11 @@
   // to match the 2MASS / Tycho / ICRS reference frame.  As Nloop gets higher, the weight
   // needs to drop to allow the ps1 measurements to drive the solution
+  int isGAIA   = USE_GALAXY_MODEL && !isImage && (measure[0].photcode == 1030);
   int is2MASS  = USE_GALAXY_MODEL && !isImage && (measure[0].photcode >= 2011) && (measure[0].photcode <= 2013);
   int isTycho  = USE_GALAXY_MODEL && !isImage && (measure[0].photcode >= 2020) && (measure[0].photcode <= 2021);
+
+  int hasGAIA  = USE_GALAXY_MODEL &&  isImage && (measure[0].dbFlags & ID_MEAS_OBJECT_HAS_GAIA);
   int has2MASS = USE_GALAXY_MODEL &&  isImage && (measure[0].dbFlags & ID_MEAS_OBJECT_HAS_2MASS);
+  int hasTycho = USE_GALAXY_MODEL &&  isImage && (measure[0].dbFlags & ID_MEAS_OBJECT_HAS_TYCHO);
 
   // modest hack: if the object has 2MASS or Tycho, we set this internal bit and adjust the
@@ -79,6 +92,16 @@
     dPtotal = dPtotal / LoopWeight2MASS[Nloop];
   }
+  if (hasGAIA && LoopWeightGAIA && (Nloop >= 0)) {
+    dPtotal = dPtotal / LoopWeightGAIA[Nloop];
+  }
+  if (hasTycho && LoopWeightTycho && (Nloop >= 0)) {
+    dPtotal = dPtotal / LoopWeightTycho[Nloop];
+  }
+
   if (is2MASS && LoopWeight2MASS && (Nloop >= 0)) {
     dPtotal = dPtotal / LoopWeight2MASS[Nloop];
+  }
+  if (isGAIA && LoopWeightGAIA && (Nloop >= 0)) {
+    dPtotal = dPtotal / LoopWeightGAIA[Nloop];
   }
   if (isTycho && LoopWeightTycho && (Nloop >= 0)) {
@@ -120,4 +143,13 @@
   // do not raise an exception, just send back the result
   if (isnan(code[0].astromErrSys)) return NAN;
+
+  if (measure[0].photcode == 1030) {
+    if (mode == ERROR_MODE_RA) {
+      dPobs = pow(10.0, (6.0 * measure[0].dXccd - 3.0));  // dXccd is a value in pixels
+    }
+    if (mode == ERROR_MODE_DEC) {
+      dPobs = pow(10.0, (6.0 * measure[0].dYccd - 3.0));  // dXccd is a value in pixels
+    }
+  }
 
   AS   	= code[0].astromErrScale;
@@ -143,7 +175,11 @@
   // to match the 2MASS / Tycho / ICRS reference frame.  As Nloop gets higher, the weight
   // needs to drop to allow the ps1 measurements to drive the solution
+  int isGAIA   = USE_GALAXY_MODEL && !isImage && (measure[0].photcode == 1030);
   int is2MASS  = USE_GALAXY_MODEL && !isImage && (measure[0].photcode >= 2011) && (measure[0].photcode <= 2013);
   int isTycho  = USE_GALAXY_MODEL && !isImage && (measure[0].photcode >= 2020) && (measure[0].photcode <= 2021);
+
+  int hasGAIA  = USE_GALAXY_MODEL &&  isImage && (measure[0].dbFlags & ID_MEAS_OBJECT_HAS_GAIA);
   int has2MASS = USE_GALAXY_MODEL &&  isImage && (measure[0].dbFlags & ID_MEAS_OBJECT_HAS_2MASS);
+  int hasTycho = USE_GALAXY_MODEL &&  isImage && (measure[0].dbFlags & ID_MEAS_OBJECT_HAS_TYCHO);
 
   // modest hack: if the object has 2MASS or Tycho, we set this internal bit and adjust the
@@ -153,6 +189,16 @@
     dPtotal = dPtotal / LoopWeight2MASS[Nloop];
   }
+  if (hasGAIA && LoopWeightGAIA && (Nloop >= 0)) {
+    dPtotal = dPtotal / LoopWeightGAIA[Nloop];
+  }
+  if (hasTycho && LoopWeightTycho && (Nloop >= 0)) {
+    dPtotal = dPtotal / LoopWeightTycho[Nloop];
+  }
+
   if (is2MASS && LoopWeight2MASS) {
     dPtotal = dPtotal / LoopWeight2MASS[Nloop];
+  }
+  if (isGAIA && LoopWeightGAIA && (Nloop >= 0)) {
+    dPtotal = dPtotal / LoopWeightGAIA[Nloop];
   }
   if (isTycho && LoopWeightTycho) {
Index: trunk/Ohana/src/relastro/src/ImageOps.c
===================================================================
--- trunk/Ohana/src/relastro/src/ImageOps.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/ImageOps.c	(revision 39926)
@@ -6,4 +6,5 @@
 static Image        *image;   // list of available images
 static off_t        Nimage;   // number of available images
+static int         isImageSubset;
 
 // if we read only a subset of the rows from the Image FITS, LineNumber tells us to which row
@@ -78,8 +79,9 @@
 }
 
-void initImages (Image *input, off_t *line_number, off_t N) {
+void initImages (Image *input, off_t *line_number, off_t N, int isSubset) {
 
   off_t i;
 
+  isImageSubset = isSubset;
   image = input;
   LineNumber = line_number;
@@ -136,5 +138,5 @@
   // we call gfits_db_free as well as this function.  sometimes those point at the same
   // memory location, in which case we should only do the free once.
-  if ((void *) dbImagePtr != (void *) image) free (image);
+  if (((void *) dbImagePtr != (void *) image) && isImageSubset) free (image);
   free_astrom_table();
 }
@@ -793,6 +795,13 @@
     ref[i].D = catalog[c].average[n].D;
     
+    int XVERB = FALSE;
+    XVERB |= (catalog[c].average[n].objID == OBJ_ID_SRC) && (catalog[c].average[n].catID == CAT_ID_SRC);
+    XVERB |= (catalog[c].average[n].objID == OBJ_ID_DST) && (catalog[c].average[n].catID == CAT_ID_DST);
+    if (XVERB) {
+      fprintf (stderr, "found test object\n");
+    }
+
     // if we are applying the galaxy model, move the reference position...
-    if (USE_GALAXY_MODEL) {
+    if (APPLY_PROPER_MOTION) {
       // apply proper-motion from average position to measure epoch:
       float dTime = (measure[0].t - catalog[c].average[n].Tmean) / (86400*365.25) ; // time relative to Tmean in years
@@ -934,371 +943,2 @@
 }
 
-# if (0) 
-/** lifted from relphot/StarOps.clean_measures */
-void FlagOutliers2D(Catalog *catalog);
-
-// operates on Full values (not tiny)
-void FlagOutliers (Catalog *catalog) {
-
-  // XXX FlagOutliers is now just using FlagOutliers2D
-  FlagOutliers2D(catalog);
-  return;
-
-  int Ndel, Nave;
-  off_t i, j, k, m, N, Nmax, TOOFEW, Nsecfilt;
-  double Ns, theta, x, y;
-  double *R, *D, *dR, *dD;
-  StatType statsR, statsD;
-
-  Nsecfilt = GetPhotcodeNsecfilt();
-  assert(catalog[0].Nsecfilt == Nsecfilt);
-
-  if (VERBOSE2) fprintf (stderr, "marking poor measures\n");
-  Nmax = 0;
-  for (i = 0; i < catalog[0].Naverage; i++) {
-    Nmax = MAX (Nmax, catalog[0].average[i].Nmeasure);
-  }
-
-  ALLOCATE (R, double, Nmax);
-  ALLOCATE (D, double, Nmax);
-  ALLOCATE (dR, double, Nmax);
-  ALLOCATE (dD, double, Nmax);
-
-  /* it makes no sense to mark 3-sigma outliers with <5 measurements */
-  TOOFEW = MAX (5, SRC_MEAS_TOOFEW);
-
-  Ns = CLIP_THRESH;
-  Ndel = Nave = 0;
-      
-  /* loop over each object in the catalog */
-  for (j = 0; j < catalog[0].Naverage; j++) {
-    
-    // pointer to this set of measurements
-    m = catalog[0].average[j].measureOffset;
-    Measure *measure = &catalog[0].measure[m];
-
-    /* accumulate list of valid measurements */
-    N = 0;
-    for (k = 0; k < catalog[0].average[j].Nmeasure; k++) {
-      // skip measurements based on user selected criteria
-      if (!MeasFilterTest(&measure[k], FALSE)) continue;
-      R[N] = measure[k].R;
-      D[N] = measure[k].D;
-      dR[N] = GetAstromError (&measure[k], ERROR_MODE_RA);
-      dD[N] = GetAstromError (&measure[k], ERROR_MODE_DEC);
-      if (isnan(R[N]) || isnan(D[N])) continue;
-      N++;
-    }
-    if (N <= TOOFEW) continue;
-    
-    /* 3-sigma clip based on stats of inner 50% */
-    initstats ("MEAN");
-    liststats (R, dR, N, &statsR);
-    liststats (D, dD, N, &statsD);
-    
-    statsR.sigma = MAX (MIN_ERROR, statsR.sigma);
-    statsD.sigma = MAX (MIN_ERROR, statsD.sigma);
-    
-    /* compare per-object distance to this standard deviation, and flag outliers*/
-    N = 0;
-    for (k = 0; k < catalog[0].average[j].Nmeasure; k++) {
-      // reset flag on each invocation
-      measure[k].dbFlags &= ~ID_MEAS_POOR_ASTROM;
-
-      // skip measurements based on user selected criteria
-      if (!MeasFilterTest(&measure[k], FALSE)) continue;
-      
-      x = measure[k].R - statsR.median;
-      y = measure[k].D - statsD.median;
-      theta = atan2(y,x);
-      if ((x*x + y*y) > (SQR(statsR.sigma * Ns * cos(theta)) + 
-			 SQR(statsD.sigma * Ns * sin(theta)))) {   
-	measure[k].dbFlags |= ID_MEAS_POOR_ASTROM;
-	Ndel++;
-      }
-      N++;
-      Nave ++;
-    }
-
-    // examine results
-    // relastroVisualPlotOutliers(catalog, catalog[0].average[j].measureOffset, catalog[0].average[j].Nmeasure, statsR, statsD, Ns);
-  }
-  
-  if (VERBOSE) fprintf (stderr, "%d measures marked poor, %d total\n", Ndel, Nave);
-  free (R);
-  free (dR);
-  free (D);
-  free (dD); 
-}
-
-
-/** an alternative outlier rejection scheme */
-void FlagOutliers2D (Catalog *catalog) {
-
-  int Ndel, Nave;
-  off_t i, j, k, m, N, Nmax, TOOFEW, Nsecfilt;
-  double *index;
-  double Ns, theta, x, y;
-  double *R, *D, *dR, *dD, *d2;
-  StatType statsR, statsD;
-
-  // XXX we are not going to use this for now
-  return;
-
-  Nsecfilt = GetPhotcodeNsecfilt();
-  assert(catalog[0].Nsecfilt == Nsecfilt);
-
-  if (VERBOSE2) fprintf (stderr, "marking poor measures\n");
-  Nmax = 0;
-  for (i = 0; i < catalog[0].Naverage; i++) {
-    Nmax = MAX (Nmax, catalog[0].average[i].Nmeasure);
-  }
-
-  ALLOCATE (R, double, Nmax);
-  ALLOCATE (D, double, Nmax);
-  ALLOCATE (dR, double, Nmax);
-  ALLOCATE (dD, double, Nmax);
-  ALLOCATE (d2, double, Nmax);
-  ALLOCATE (index, double, Nmax);
-
-  /* it makes no sense to mark 3-sigma outliers with <5 measurements */
-  TOOFEW = MAX (5, SRC_MEAS_TOOFEW);
-
-  Ns = CLIP_THRESH;
-  Ndel = Nave = 0;
-      
-  /* loop over each object in the catalog */
-  for (j = 0; j < catalog[0].Naverage; j++) {
-    
-    // pointer to this set of measurements
-    m = catalog[0].average[j].measureOffset;
-    Measure *measure = &catalog[0].measure[m];
-
-    /* accumulate list of valid measurements */
-    N = 0;
-    for (k = 0; k < catalog[0].average[j].Nmeasure; k++) {
-
-      // reset flag on each invocation
-      measure[k].dbFlags &= ~ID_MEAS_POOR_ASTROM;
-      
-      // skip measurements based on user selected criteria
-      if (!MeasFilterTest(&measure[k], FALSE)) continue;
-      R[N] = measure[k].R;
-      D[N] = measure[k].D;
-      dR[N] = GetAstromError(&measure[k], ERROR_MODE_RA);
-      dD[N] = GetAstromError(&measure[k], ERROR_MODE_DEC);
-      if (isnan(R[N]) || isnan(D[N])) continue;
-      N++;
-    }
-    if (N <= TOOFEW) continue;
-    
-    /* calculate mean of all points*/
-    initstats ("MEAN");
-    liststats (R, dR, N, &statsR);
-    liststats (D, dD, N, &statsD);
-    statsR.sigma = MAX (MIN_ERROR, statsR.sigma);
-    statsD.sigma = MAX (MIN_ERROR, statsD.sigma);
-    
-    /* calculate deviations of all points*/
-    N = 0;
-    for (k = 0; k < catalog[0].average[j].Nmeasure; k++) {
-      // skip bad measurements
-      if (!MeasFilterTest(&measure[k], FALSE)) continue;  
-      x = measure[k].R - statsR.median;
-      y = measure[k].D - statsD.median;
-      theta = atan2(y,x);
-      d2[N] = (x*x + y*y) / (SQR(statsR.sigma * Ns * cos(theta)) + 
-			     SQR(statsD.sigma * Ns * sin(theta)));      
-      index[N] = k;
-      N++;
-    }
-    
-    // sort d2
-    dsortpair(d2, index, N);
-    N = (N/2 > (N-1)) ? N/2 : N-1;
-
-    // recalculate image center, sigma based on closest 50% of points
-    for (k = 0;  k < N; k++) {
-      off_t ind = (off_t) index[k];
-      R[k] = measure[ind].R;
-      D[k] = measure[ind].D;
-      dR[k] = GetAstromError(&measure[ind], ERROR_MODE_RA);
-      dD[k] = GetAstromError(&measure[ind], ERROR_MODE_DEC);
-    }
-    liststats (R, dR, N, &statsR);
-    liststats (D, dD, N, &statsD);
-    statsR.sigma = MAX (MIN_ERROR, statsR.sigma);
-    statsD.sigma = MAX (MIN_ERROR, statsD.sigma);
-    
-    // use these new statistics to flag outliers 
-    N = 0;
-    for (k = 0; k < catalog[0].average[j].Nmeasure; k++) {
-      //skip bad measurements
-      if (!MeasFilterTest(&measure[k], FALSE)) continue;  
-      x = measure[k].R - statsR.median;
-      y = measure[k].D - statsD.median;
-      theta = atan2(y,x);
-      d2[N] = (x*x + y*y) / (SQR(statsR.sigma * Ns * cos(theta)) + 
-			     SQR(statsD.sigma * Ns * sin(theta)));      
-      if ((d2[N]) > 1) {
-	measure[k].dbFlags |= ID_MEAS_POOR_ASTROM;
-	Ndel ++;
-      }
-      N++;
-      Nave++;
-    }  // done rejecting outliers
-
-    // examine results
-    // relastroVisualPlotOutliers(catalog, catalog[0].average[j].measureOffset, catalog[0].average[j].Nmeasure, statsR, statsD, Ns);
-    
-  } // done looping over objects
-  
-  if (VERBOSE) fprintf (stderr, "%d measures marked poor, %d total\n", Ndel, Nave);
-  free (R);
-  free (dR);
-  free (D);
-  free (dD); 
-  free (d2);
-  free (index);
-}
-
-/** Determine whether a measurement should be included in the analysis, based on supplied filter criteria */ 
-// we only optionally apply the sigma limit: for object averages, this should not be used
-int MeasFilterTestTiny(MeasureTiny *measure, int applySigmaLim) {
-  int found, k;
-  long mask;
-  PhotCode *code;
-  float mag;
-
-  if (!finite(measure[0].R) || !finite(measure[0].D)) return FALSE;
-  if (!finite(measure[0].M)) return FALSE; //XXX is this necessary for all relastro tasks?
-  if (!finite(measure[0].dM)) return FALSE; //XXX is this necessary for all relastro tasks?
-  
-  if ((MinBadQF > 0.0) && (isGPC1chip(measure[0].photcode) || isGPC1stack(measure[0].photcode))) {
-    if (!isfinite(measure[0].psfQF)) { return FALSE; };
-    if (measure[0].psfQF < MinBadQF) { return FALSE; };
-  }
-
-  /* select measurements by photcode, or equiv photcode, if specified */
-  if (NphotcodesKeep > 0) {
-    found = FALSE;
-    for (k = 0; (k < NphotcodesKeep) && !found; k++) {
-      if (photcodesKeep[k][0].code == measure[0].photcode) found = TRUE;
-      if (photcodesKeep[k][0].code == GetPhotcodeEquivCodebyCode(measure[0].photcode)) found = TRUE;
-    }
-    if (!found) return FALSE;
-  }
-  
-  if (NphotcodesSkip > 0) {
-    found = FALSE;
-    for (k = 0; (k < NphotcodesSkip) && !found; k++) {
-      if (photcodesSkip[k][0].code == measure[0].photcode) found = TRUE;
-      if (photcodesSkip[k][0].code == GetPhotcodeEquivCodebyCode(measure[0].photcode)) found = TRUE;
-    }
-    if (found) return FALSE;
-  }  
-  
-  /* select measurements by time */
-  if (TimeSelect) {
-    if (measure[0].t < TSTART) return FALSE;
-    if (measure[0].t > TSTOP) return FALSE;
-  }
-  
-  /* select measurements by quality */
-  if (PhotFlagSelect) {
-    if (PhotFlagBad) {
-      mask = PhotFlagBad;
-    } else {
-      code = GetPhotcodebyCode (measure[0].photcode);
-      if (!code) return FALSE;
-      mask = code[0].astromBadMask;
-    }
-    if (mask & measure[0].photFlags) return FALSE;
-  }
-
-  /* select measurements by measurement error */
-  // this is a bit convoluted: applySigmaLim is only TRUE when this function is
-  // called by bcatalog.  for UpdateObjects, it is FALSE
-  if (applySigmaLim && (SIGMA_LIM > 0) && (measure[0].dM > SIGMA_LIM)) {
-    return FALSE;
-  }
-  
-  /* select measurements by mag limit */
-  if (ImagSelect) {
-    mag = PhotInstTiny (measure, MAG_CLASS_PSF);
-    if (mag < ImagMin || mag > ImagMax) return FALSE;
-  }
-  
-  return TRUE;
-}
-
-# define SUPER_VERBOSE 0
-
-/** Determine whether a measurement should be included in the analysis, based on supplied filter criteria */ 
-// we only optionally apply the sigma limit: for object averages, this should not be used (should it?)
-int MeasFilterTest(Measure *measure, int applySigmaLim) {
-  int found, k;
-  long mask;
-  PhotCode *code;
-  float mag;
-
-  if (!finite(measure[0].R) || !finite(measure[0].D)) { if (SUPER_VERBOSE) fprintf (stderr, "filter 1\n"); return FALSE; };
-  if (!finite(measure[0].M)) { if (SUPER_VERBOSE) fprintf (stderr, "filter 2\n"); return FALSE; }; //XXX is this necessary for all relastro tasks?
-  if (!finite(measure[0].dM)) { if (SUPER_VERBOSE) fprintf (stderr, "filter 3\n"); return FALSE; }; //XXX is this necessary for all relastro tasks?
-  
-  /* select measurements by photcode, or equiv photcode, if specified */
-  if (NphotcodesKeep > 0) {
-    found = FALSE;
-    for (k = 0; (k < NphotcodesKeep) && !found; k++) {
-      if (photcodesKeep[k][0].code == measure[0].photcode) found = TRUE;
-      if (photcodesKeep[k][0].code == GetPhotcodeEquivCodebyCode(measure[0].photcode)) found = TRUE;
-    }
-    if (!found) { if (SUPER_VERBOSE) fprintf (stderr, "filter 4\n"); return FALSE; };
-  }
-  
-  if (NphotcodesSkip > 0) {
-    found = FALSE;
-    for (k = 0; (k < NphotcodesSkip) && !found; k++) {
-      if (photcodesSkip[k][0].code == measure[0].photcode) found = TRUE;
-      if (photcodesSkip[k][0].code == GetPhotcodeEquivCodebyCode(measure[0].photcode)) found = TRUE;
-    }
-    if (found) { if (SUPER_VERBOSE) fprintf (stderr, "filter 5\n"); return FALSE; };
-  }  
-  
-  if ((MinBadQF > 0.0) && isGPC1chip(measure[0].photcode)) {
-    if (!isfinite(measure[0].psfQF)) { if (SUPER_VERBOSE) fprintf (stderr, "filter 6\n"); return FALSE; };
-    if (measure[0].psfQF < MinBadQF) { if (SUPER_VERBOSE) fprintf (stderr, "filter 7\n"); return FALSE; };
-  }
-
-  /* select measurements by time */
-  if (TimeSelect) {
-    if (measure[0].t < TSTART) { if (SUPER_VERBOSE) fprintf (stderr, "filter 8\n"); return FALSE; };
-    if (measure[0].t > TSTOP) { if (SUPER_VERBOSE) fprintf (stderr, "filter 9\n"); return FALSE; };
-  }
-  
-  /* select measurements by quality */
-  if (PhotFlagSelect) {
-    if (PhotFlagBad) {
-      mask = PhotFlagBad;
-    } else {
-      code = GetPhotcodebyCode (measure[0].photcode);
-      if (!code) { if (SUPER_VERBOSE) fprintf (stderr, "filter 10\n"); return FALSE; };
-      mask = code[0].astromBadMask;
-    }
-    if (mask & measure[0].photFlags) { if (SUPER_VERBOSE) fprintf (stderr, "filter 11\n"); return FALSE; };
-  }
-
-  /* select measurements by measurement error */
-  if (applySigmaLim && (SIGMA_LIM > 0) && (measure[0].dM > SIGMA_LIM)) {
-    { if (SUPER_VERBOSE) fprintf (stderr, "filter 12\n"); return FALSE; };
-  }
-  
-  /* select measurements by mag limit */
-  if (ImagSelect) {
-    mag = PhotInst (measure, MAG_CLASS_PSF);
-    if (mag < ImagMin || mag > ImagMax) { if (SUPER_VERBOSE) fprintf (stderr, "filter 13\n"); return FALSE; };
-  }
-  
-  return TRUE;
-}
-# endif
Index: trunk/Ohana/src/relastro/src/StarMaps.c
===================================================================
--- trunk/Ohana/src/relastro/src/StarMaps.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/StarMaps.c	(revision 39926)
@@ -166,4 +166,19 @@
   dLmax = dMmax = 0.0;
 
+  float plateScale;
+  if (images[N].coords.mosaic) {
+    // NOTE: for the full pixel to sky plate scale, use this:
+    // float plateScaleX = 3600.0*images[N].coords.mosaic->cdelt1*images[N].coords.cdelt1;
+    // float plateScaleY = 3600.0*images[N].coords.mosaic->cdelt2*images[N].coords.cdelt2;
+
+    // since we are compare L,M values, just need to compensate for focal plate to sky:
+    float plateScaleX = 3600.0*fabs(images[N].coords.mosaic->cdelt1);
+    float plateScaleY = 3600.0*fabs(images[N].coords.mosaic->cdelt2);
+    plateScale = 0.5*(plateScaleX + plateScaleY);
+  } else {
+    // since we are compare L,M values, just need to compensate for arcsec vs degrees:
+    plateScale = 3600.0;
+  }
+
   for (i = 0; i < starmap[N].Npoints; i++) {
 
@@ -171,6 +186,6 @@
     XY_to_LM (&L, &M, starmap[N].points[i].X, starmap[N].points[i].Y, &images[N].coords);
 
-    starmap[N].points[i].dL = starmap[N].points[i].L - L;
-    starmap[N].points[i].dM = starmap[N].points[i].M - M;
+    starmap[N].points[i].dL = plateScale*(starmap[N].points[i].L - L);
+    starmap[N].points[i].dM = plateScale*(starmap[N].points[i].M - M);
 
     dLmax = MAX(fabs(starmap[N].points[i].dL), dLmax);
Index: trunk/Ohana/src/relastro/src/UpdateChips.c
===================================================================
--- trunk/Ohana/src/relastro/src/UpdateChips.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/UpdateChips.c	(revision 39926)
@@ -42,4 +42,8 @@
   AstromErrorSetLoop (Nloop, TRUE);
 
+  // if ChipMapLoop or ChipOrderLoop is set use that to define the value of CHIPMAP and/or CHIPORDER this loop
+  if (ChipMapLoop) { CHIPMAP = ChipMapLoop[Nloop]; }
+  if (ChipOrderLoop) { CHIPORDER = ChipOrderLoop[Nloop]; }
+  
   if (NTHREADS) {
     UpdateChips_threaded (catalog, Ncatalog);
@@ -60,9 +64,18 @@
   for (i = 0; i < Nimage; i++) {
 
-    VERBOSE_IMAGE = !strcmp(image[i].name, "o5745g0516o.356887.cm.982631.smf[XY54]");
+    VERBOSE = FALSE;
+    VERBOSE_IMAGE |= !strcmp(image[i].name, "o5745g0516o.356887.cm.982631.smf[XY45]");
+    VERBOSE_IMAGE |= !strcmp(image[i].name, "o5745g0526o.356899.cm.982643.smf[XY45]");
+    VERBOSE_IMAGE |= !strcmp(image[i].name, "o5748g0436o.358811.cm.982690.smf[XY34]");
 
     // XXX looks like everything below is thread safe : we can unroll this into a set of
     // helper functions that grab the next available chip....
 
+    // allow certain cameras to stay static
+    if (SKIP_PS1_CHIP  && isGPC1chip (image[i].photcode)) { Nskip ++;  mode[i] = 0; continue; }
+    if (SKIP_PS1_STACK && isGPC1stack(image[i].photcode)) { Nskip ++;  mode[i] = 0; continue; }
+    if (SKIP_HSC       && isHSCchip  (image[i].photcode)) { Nskip ++;  mode[i] = 0; continue; }
+    if (SKIP_CFH       && isCFHchip  (image[i].photcode)) { Nskip ++;  mode[i] = 0; continue; }
+    
     /* skip all except WRP images */
     if (strcmp(&image[i].coords.ctype[4], "-WRP")) {
@@ -160,5 +173,5 @@
     setImageRaw (catalog, Ncatalog, i, raw, Nraw, MODE_MOSAIC);
     if (USE_GALAXY_MODEL) {
-      // XXX DEPRECATE?
+      // the image calibration was calculated using a galaxy motion model
       image[i].flags |= ID_IMAGE_ASTROM_GMM;
     }
@@ -281,4 +294,10 @@
     }
 
+    // allow certain cameras to stay static
+    if (SKIP_PS1_CHIP  && isGPC1chip (image[i].photcode)) { threadinfo->Nskip ++;  threadinfo->mode[i] = 0; continue; }
+    if (SKIP_PS1_STACK && isGPC1stack(image[i].photcode)) { threadinfo->Nskip ++;  threadinfo->mode[i] = 0; continue; }
+    if (SKIP_HSC       && isHSCchip  (image[i].photcode)) { threadinfo->Nskip ++;  threadinfo->mode[i] = 0; continue; }
+    if (SKIP_CFH       && isCFHchip  (image[i].photcode)) { threadinfo->Nskip ++;  threadinfo->mode[i] = 0; continue; }
+    
     /* skip all except WRP images */
     if (strcmp(&image[i].coords.ctype[4], "-WRP")) {
Index: trunk/Ohana/src/relastro/src/UpdateMeasures.c
===================================================================
--- trunk/Ohana/src/relastro/src/UpdateMeasures.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/UpdateMeasures.c	(revision 39926)
@@ -115,5 +115,32 @@
 
       // only modify the chip coordinates
-      if (isGPC1chip (measureT->photcode)) {
+      if (UPDATE_PS1_STACK_MEASURE && isGPC1stack (measureT->photcode)) {
+	measureT->R = R;
+	measureT->D = D;
+	if (measureB) {
+	  measureB->R = R;
+	  measureB->D = D;
+	}
+      }
+      // only modify the chip coordinates
+      if (UPDATE_PS1_CHIP_MEASURE && isGPC1chip (measureT->photcode)) {
+	measureT->R = R;
+	measureT->D = D;
+	if (measureB) {
+	  measureB->R = R;
+	  measureB->D = D;
+	}
+      }
+      // only modify the chip coordinates
+      if (UPDATE_HSC_MEASURE && isGPC1chip (measureT->photcode)) {
+	measureT->R = R;
+	measureT->D = D;
+	if (measureB) {
+	  measureB->R = R;
+	  measureB->D = D;
+	}
+      }
+      // only modify the chip coordinates
+      if (UPDATE_CFH_MEASURE && isGPC1chip (measureT->photcode)) {
 	measureT->R = R;
 	measureT->D = D;
Index: trunk/Ohana/src/relastro/src/UpdateObjectOffsets.c
===================================================================
--- trunk/Ohana/src/relastro/src/UpdateObjectOffsets.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/UpdateObjectOffsets.c	(revision 39926)
@@ -167,10 +167,14 @@
     strextend (&command, "relastro_client -update-offsets");
     strextend (&command, "-hostID %d", group->hosts[i][0].hostID);
+    strextend (&command, "-hostdir %s", group->hosts[i][0].pathname);
+
     strextend (&command, "-D CATDIR %s", CATDIR);
-    strextend (&command, "-hostdir %s", group->hosts[i][0].pathname);
     strextend (&command, "-region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     strextend (&command, "-statmode %s", STATMODE);
     strextend (&command, "-minerror %f", MIN_ERROR);
 
+    strextend (&command, "-D RELASTRO_SIGMA_LIM %f", SIGMA_LIM);
+    strextend (&command, "-D RELASTRO_SRC_MEAS_TOOFEW %d", SRC_MEAS_TOOFEW);
+
     if (FIT_MODE == FIT_PM_ONLY)  	 strextend (&command, "-pm");
     if (FIT_MODE == FIT_PAR_ONLY) 	 strextend (&command, "-par");
@@ -180,21 +184,11 @@
     if (VERBOSE2)      strextend (&command, "-vv");
     if (RESET)         strextend (&command, "-reset");
-    if (UPDATE)        strextend (&command, "-update");
-
-    if (RESET_BAD_IMAGES) strextend (&command, "-reset-bad-images");
 
     if (ImagSelect)    strextend (&command, "-instmag %f %f", ImagMin, ImagMax);
     if (MaxDensityUse) strextend (&command, "-max-density %f", MaxDensityValue);
-    
-    if (USE_BASIC_CHECK) strextend (&command, "-basic-image-search");
     if (FlagOutlier)     strextend (&command, "-clip %d", CLIP_THRESH);
     if (ExcludeBogus)    strextend (&command, "-exclude-bogus %f", ExcludeBogusRadius);
     
-    if (USE_ALL_IMAGES)      strextend (&command, "-use-all-images");
     if (USE_FIXED_PIXCOORDS) strextend (&command, "-D USE_FIXED_PIXCOORDS 1"); 
-
-    if (REPAIR_STACKS)          strextend (&command, "-repair-stacks-on-update");
-    if (CHECK_MEASURE_TO_IMAGE) strextend (&command, "-check-measures");
-
     if (PHOTCODE_KEEP_LIST) strextend (&command, "+photcode %s", PHOTCODE_KEEP_LIST);
     if (PHOTCODE_SKIP_LIST) strextend (&command, "-photcode %s", PHOTCODE_SKIP_LIST);
@@ -204,6 +198,4 @@
     // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
 
-    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES); 
-
     if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
       strextend (&command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
@@ -213,6 +205,20 @@
     }
 
+    if (REPAIR_STACKS)          strextend (&command, "-repair-stacks-on-update");
+    if (CHECK_MEASURE_TO_IMAGE) strextend (&command, "-check-measures");
+
+    if (UPDATE_PS1_STACK_MEASURE) strextend (&command, "-update-ps1-stack");
+    if (UPDATE_PS1_CHIP_MEASURE) strextend (&command, "-update-ps1-chip");
+    if (UPDATE_HSC_MEASURE)    	 strextend (&command, "-update-hsc");
+    if (UPDATE_CFH_MEASURE)    	 strextend (&command, "-update-cfh");
+
+    if (UPDATE)        strextend (&command, "-update");
+    if (RESET_BAD_IMAGES) strextend (&command, "-reset-bad-images");
+    if (USE_BASIC_CHECK) strextend (&command, "-basic-image-search");
+    if (USE_ALL_IMAGES)      strextend (&command, "-use-all-images");
+
     if (MinBadQF > 0.0)        strextend (&command, "-min-bad-psfqf %f", MinBadQF); 
     if (MaxMeanOffset != 10.0) strextend (&command, "-max-mean-offset  %f", MaxMeanOffset);
+    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES); 
 
     if (TimeSelect) { 
@@ -300,10 +306,14 @@
     strextend (&command, "relastro_client -update-offsets");
     strextend (&command, "-hostID %d", table->hosts[i].hostID);
+    strextend (&command, "-hostdir %s", table->hosts[i].pathname);
+
     strextend (&command, "-D CATDIR %s", CATDIR);
-    strextend (&command, "-hostdir %s", table->hosts[i].pathname);
     strextend (&command, "-region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     strextend (&command, "-statmode %s", STATMODE);
     strextend (&command, "-minerror %f", MIN_ERROR);
 
+    strextend (&command, "-D RELASTRO_SIGMA_LIM %f", SIGMA_LIM);
+    strextend (&command, "-D RELASTRO_SRC_MEAS_TOOFEW %d", SRC_MEAS_TOOFEW);
+
     if (FIT_MODE == FIT_PM_ONLY)  	 strextend (&command, "-pm");
     if (FIT_MODE == FIT_PAR_ONLY) 	 strextend (&command, "-par");
@@ -313,21 +323,11 @@
     if (VERBOSE2)      strextend (&command, "-vv");
     if (RESET)         strextend (&command, "-reset");
-    if (UPDATE)        strextend (&command, "-update");
-
-    if (RESET_BAD_IMAGES) strextend (&command, "-reset-bad-images");
 
     if (ImagSelect)    strextend (&command, "-instmag %f %f", ImagMin, ImagMax);
     if (MaxDensityUse) strextend (&command, "-max-density %f", MaxDensityValue);
-    
-    if (USE_BASIC_CHECK) strextend (&command, "-basic-image-search");
     if (FlagOutlier)     strextend (&command, "-clip %d", CLIP_THRESH);
     if (ExcludeBogus)    strextend (&command, "-exclude-bogus %f", ExcludeBogusRadius);
     
-    if (USE_ALL_IMAGES)      strextend (&command, "-use-all-images");
     if (USE_FIXED_PIXCOORDS) strextend (&command, "-D USE_FIXED_PIXCOORDS 1"); 
-
-    if (REPAIR_STACKS)          strextend (&command, "-repair-stacks-on-update");
-    if (CHECK_MEASURE_TO_IMAGE) strextend (&command, "-check-measures");
-
     if (PHOTCODE_KEEP_LIST) strextend (&command, "+photcode %s", PHOTCODE_KEEP_LIST);
     if (PHOTCODE_SKIP_LIST) strextend (&command, "-photcode %s", PHOTCODE_SKIP_LIST);
@@ -337,6 +337,4 @@
     // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
 
-    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES); 
-
     if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
       strextend (&command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
@@ -345,4 +343,19 @@
       strextend (&command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
     }
+
+    if (REPAIR_STACKS)          strextend (&command, "-repair-stacks-on-update");
+    if (CHECK_MEASURE_TO_IMAGE) strextend (&command, "-check-measures");
+
+    if (UPDATE_PS1_STACK_MEASURE) strextend (&command, "-update-ps1-stack");
+    if (UPDATE_PS1_CHIP_MEASURE) strextend (&command, "-update-ps1-chip");
+    if (UPDATE_HSC_MEASURE)    	 strextend (&command, "-update-hsc");
+    if (UPDATE_CFH_MEASURE)    	 strextend (&command, "-update-cfh");
+
+    if (UPDATE)        strextend (&command, "-update");
+    if (RESET_BAD_IMAGES) strextend (&command, "-reset-bad-images");
+    if (USE_BASIC_CHECK) strextend (&command, "-basic-image-search");
+    if (USE_ALL_IMAGES)      strextend (&command, "-use-all-images");
+
+    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES); 
 
     if (MinBadQF > 0.0)        strextend (&command, "-min-bad-psfqf %f", MinBadQF); 
Index: trunk/Ohana/src/relastro/src/UpdateObjects.c
===================================================================
--- trunk/Ohana/src/relastro/src/UpdateObjects.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/UpdateObjects.c	(revision 39926)
@@ -5,13 +5,15 @@
 # define PAR_MIN_NPTS 7
 # define PAR_MIN_NPTS_BOOT 6
-# define PM_MIN_NPTS 4
-# define PM_MIN_NPTS_BOOT 3
-# define POS_MIN_NPTS 3
-# define POS_MIN_NPTS_BOOT 2
+# define PM_MIN_NPTS 5
+# define PM_MIN_NPTS_BOOT 4
+# define POS_MIN_NPTS 4
+# define POS_MIN_NPTS_BOOT 4
 
 typedef enum {
-  SELECT_MEAS_HAS_DATA  = 1,
-  SELECT_MEAS_HAS_STACK = 2,
-  SELECT_MEAS_HAS_2MASS = 4,
+  SELECT_MEAS_HAS_DATA  = 0x01,
+  SELECT_MEAS_HAS_STACK = 0x02,
+  SELECT_MEAS_HAS_2MASS = 0x04,
+  SELECT_MEAS_HAS_GAIA  = 0x08,
+  SELECT_MEAS_HAS_TYCHO = 0x10,
 } SelectMeasureStatus;
 
@@ -181,34 +183,39 @@
     if (Trange < PM_DT_MIN) {
       // not enough baseline for proper motion, only set mean position
-      mode = FIT_AVERAGE;
       goto justPosition;
     }
     if (parRange < PAR_FACTOR_MIN) {
       // not enough parallax factor range, skip parallax
-      mode = FIT_PM_ONLY;
       goto skipParallax;
     }
     if (fitStats->Npoints < PAR_MIN_NPTS) {
       // not enough data, skip parallax
-      mode = FIT_PM_ONLY;
       goto skipParallax;
     }
 
     // we are going to use the IRLS analysis to calculate the mean solution and the masking
-    // then run N_BOOTSTRAP_SAMPLES to measure the errors
-    fitStats->fitdataPar->getError = !N_BOOTSTRAP_SAMPLES;
-    if (!FitPMandPar_IRLS (&fitPar, fitStats->fitdataPar, fitStats->points, fitStats->Npoints)) {
-      mode = FIT_PM_ONLY;
-      goto skipParallax;
-    }
-
-    if (N_BOOTSTRAP_SAMPLES) {
+    // then run N_BOOTSTRAP_SAMPLES to measure the errors.  We first measure the OLS error,
+    // and choose the max of the OLS and bootstrap errors
+    fitStats->fitdataPar->getError = TRUE;
+    if (USE_IRLS) {
+      if (!FitPMandPar_IRLS (&fitPar, fitStats->fitdataPar, fitStats->points, fitStats->Npoints)) {
+	goto skipParallax;
+      }
+    } else {
+      if (!FitPMandPar_Basic (&fitPar, fitStats->fitdataPar, fitStats->points, fitStats->Npoints)) {
+	goto skipParallax;
+      }
+    }
+
+    // in the fits above, we have saved the formal error for the unmasked points.  
+    // if we do not have enough points for bootstrap, we will keep those errors
+    if (N_BOOTSTRAP_SAMPLES && (fitPar.Nfit >= PAR_MIN_NPTS_BOOT)) {
       fitStats->Nfit = 0;
       int Nnomask = BootstrapSaveUnmasked (fitStats->nomask, fitStats->points, fitStats->Npoints);
-      if (Nnomask < PAR_MIN_NPTS_BOOT) {
-	// if we do not have enough points to assess parallax error, we cannot do the bootstrap analysis.
-	mode = FIT_PM_ONLY;
-	goto skipParallax;
-      }
+
+      // if we do not have enough points to assess parallax error, skip the bootstrap analysis.
+      // (I think the test above means we never do this skip)
+      if (Nnomask < PAR_MIN_NPTS_BOOT) goto skipParallaxBootstrap;
+
       for (k = 0; k < fitStats->NfitAlloc; k++) {
 	BootstrapResample (fitStats->sample, fitStats->nomask, Nnomask);
@@ -216,5 +223,8 @@
 	fitStats->Nfit ++;
       }
-      // these calls set the ERRORS on the fit parameters, not the fit values (set in IRLS above)
+
+      // These calls set the ERRORS on the fit parameters, not the fit values (set in IRLS above)
+      // this call expects the fitted parameters to have the formal error set: it will apply the 
+      // max of the formal and bootstrap errors
       BootstrapRobustStats (&fitPar, fitStats->fit, fitStats->Nfit, FIT_RESULT_RA);
       BootstrapRobustStats (&fitPar, fitStats->fit, fitStats->Nfit, FIT_RESULT_DEC);
@@ -224,4 +234,5 @@
     }
 
+  skipParallaxBootstrap:
     // project Ro, Do back to RA,DEC
     XY_to_RD (&fitPar.Ro, &fitPar.Do, fitPar.Ro, fitPar.Do, &fitStats->coords);
@@ -242,7 +253,5 @@
     valid = valid && (fabs(fitPar.uD) < 4.0);
     valid = valid && (fabs(fitPar.p) < 2.0);
-    if (!valid) {
-      mode = FIT_PM_ONLY;
-    } else {
+    if (valid) {
       average[0].flags |= ID_OBJ_USE_PAR;
     }
@@ -254,44 +263,55 @@
   if ((mode == FIT_PM_ONLY) || (mode == FIT_PM_AND_PAR)) {
     if (Trange < PM_DT_MIN) {
-      mode = FIT_AVERAGE;
       goto justPosition;
     }
     if (fitStats->Npoints < PM_MIN_NPTS) {
-      mode = FIT_AVERAGE;
       goto justPosition;
     }
 
     // if we have fitted (and accepted) a parallax model, get the best pm fit and chisq
-    // given the set of points (mask is respected)
-    if (average[0].flags & ID_OBJ_USE_PAR) {
+    // given the set of points (mask is respected).  Alternatively, if we do not request
+    // IRLS fitting, the just use OLS fitting (skip bootstrap)
+    if ((average[0].flags & ID_OBJ_USE_PAR) || !USE_IRLS) {
       if (!FitPM_Basic (&fitPM, fitStats->fitdataPM, fitStats->points, fitStats->Npoints)) {
 	average[0].flags |= ID_OBJ_BAD_PM;
 	goto justPosition;
       }
-    } else {
-      fitStats->fitdataPM->getError = !N_BOOTSTRAP_SAMPLES;
-      if (!FitPM_IRLS (&fitPM, fitStats->fitdataPM, fitStats->points, fitStats->Npoints)) {
-	mode = FIT_AVERAGE;
-	goto justPosition;
-      }
-      if (N_BOOTSTRAP_SAMPLES) {
-	fitStats->Nfit = 0;
-	int Nnomask = BootstrapSaveUnmasked (fitStats->nomask, fitStats->points, fitStats->Npoints);
-	if (Nnomask < PM_MIN_NPTS_BOOT) {
-	  mode = FIT_AVERAGE;
-	  goto justPosition;
-	}
-	for (k = 0; k < fitStats->NfitAlloc; k++) {
-	  BootstrapResample (fitStats->sample, fitStats->nomask, Nnomask);
-	  if (!FitPM_Basic (&fitStats->fit[k], fitStats->fitdataPM, fitStats->sample, Nnomask)) continue;
-	  fitStats->Nfit ++;
-	}
-	BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_RA);
-	BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_DEC);
-	BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_uR);
-	BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_uD);
-      }
-    }
-
+      goto skipProperMotionBootstrap;
+    } 
+
+    // we are going to use the IRLS analysis to calculate the mean solution and the masking
+    // then run N_BOOTSTRAP_SAMPLES to measure the errors.  We first measure the OLS error,
+    // and choose the max of the OLS and bootstrap errors
+    fitStats->fitdataPM->getError = TRUE;
+    if (!FitPM_IRLS (&fitPM, fitStats->fitdataPM, fitStats->points, fitStats->Npoints)) {
+      goto justPosition;
+    }
+
+    // in the fits above, we have saved the formal error for the unmasked points.  
+    // if we do not have enough points for bootstrap, we will keep those errors
+    if (N_BOOTSTRAP_SAMPLES && (fitPM.Nfit >= PM_MIN_NPTS_BOOT)) {
+      fitStats->Nfit = 0;
+      int Nnomask = BootstrapSaveUnmasked (fitStats->nomask, fitStats->points, fitStats->Npoints);
+	
+      // if we do not have enough points to assess p.m. error, skip the bootstrap analysis.
+      // (I think the test above means we never do this skip)
+      if (Nnomask < PM_MIN_NPTS_BOOT) goto skipProperMotionBootstrap;
+
+      for (k = 0; k < fitStats->NfitAlloc; k++) {
+	BootstrapResample (fitStats->sample, fitStats->nomask, Nnomask);
+	if (!FitPM_Basic (&fitStats->fit[k], fitStats->fitdataPM, fitStats->sample, Nnomask)) continue;
+	fitStats->Nfit ++;
+      }
+
+      // These calls set the ERRORS on the fit parameters, not the fit values (set in IRLS above)
+      // this call expects the fitted parameters to have the formal error set: it will apply the 
+      // max of the formal and bootstrap errors
+      BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_RA);
+      BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_DEC);
+      BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_uR);
+      BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_uD);
+    }
+
+skipProperMotionBootstrap:
     // project Ro, Do back to RA,DEC
     XY_to_RD (&fitPM.Ro, &fitPM.Do, fitPM.Ro, fitPM.Do, &fitStats->coords);
@@ -300,4 +320,5 @@
     fitStats->Npm ++;
 
+    // XXX a hard-wired hack...
     // unless there is a clear problems (below) with the proper-motion fit or we have a parallax fit, we will use pm fit
     int valid = TRUE;
@@ -309,5 +330,4 @@
     valid = valid && (fabs(fitPM.uD) < 4.0);
     if (!valid) {
-      mode = FIT_AVERAGE;
       average[0].flags |= ID_OBJ_BAD_PM;
     } else {
@@ -323,59 +343,56 @@
     // if we only have one point, this is silly...
 
+    // set the proper motion (to the galaxy model or average value, if desired; else to 0,0)
     FitAstromResultSetPM (&fitPos, 1, average);
-    // fprintf (stderr, "fit 1: %f %f : %f %f\n", fitPos.Ro, fitPos.Do, fitPos.uR, fitPos.uD);
-    if (average[0].flags & (ID_OBJ_USE_PAR | ID_OBJ_USE_PM)) {
+
+    // if we already have a valid fit (pm or par), use OLS to fit the position
+    // alternatively, if we do not request IRLS, use OLS
+    // alternatively, if we do not have enough points, use OLS
+    if ((average[0].flags & (ID_OBJ_USE_PAR | ID_OBJ_USE_PM)) || (fitStats->Npoints < POS_MIN_NPTS) || !USE_IRLS) {
       if (!FitPosPMfixed_Basic (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints)) { 
-	// if this fails, stick with the PM and/or PAR fit from above
+	// if this fails, stick with the PM and/or PAR fit from above, or use a single value
 	goto doneWithFit;
       }
-    } else {
-      if (fitStats->Npoints < POS_MIN_NPTS) {
-	// I will not try to outlier-reject, just calculate the weighted average
-	if (!FitPosPMfixed_Basic (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints)) { 
-	  // if we have tried this, we have not masked any points; we will find a single unmasked point below
-	  goto doneWithFit;
-	}
+      // if we have not already gotten a good fit, use this fit
+      if (!(average[0].flags & (ID_OBJ_USE_PAR | ID_OBJ_USE_PM))) {
 	average[0].flags |= ID_OBJ_USE_AVE;
 	average[0].flags |= ID_OBJ_RAW_AVE;
-	goto useBasic;
-      }
-      if (!FitPosPMfixed_IRLS (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints)) {
-	// if the above fails, we need to clear the masks and try again below
-	FitPointsClearMasks (fitStats->points, fitStats->Npoints); 
-	// just calculate the weighted average
-	if (!FitPosPMfixed_Basic (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints)) { 
-	  // if this fails, find a single unmasked point below
-	  goto doneWithFit;
-	}
-	average[0].flags |= ID_OBJ_USE_AVE;
-	average[0].flags |= ID_OBJ_RAW_AVE;
-	goto useBasic;
-      }
-      // fprintf (stderr, "fit 2: %f %f : %f %f\n", fitPos.Ro, fitPos.Do, fitPos.uR, fitPos.uD);
-      if (N_BOOTSTRAP_SAMPLES) {
-	fitStats->Nfit = 0;
-	int Nnomask = BootstrapSaveUnmasked (fitStats->nomask, fitStats->points, fitStats->Npoints);
-	if (Nnomask < POS_MIN_NPTS_BOOT) {
-	  // if the above fails, we need to clear the masks and try again below
-	  FitPointsClearMasks (fitStats->points, fitStats->Npoints); 
-	  if (!FitPosPMfixed_Basic (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints)) { 
-	    // if this fails, find a single unmasked point below
-	    goto doneWithFit;
-	  }
-	  average[0].flags |= ID_OBJ_USE_AVE;
-	  average[0].flags |= ID_OBJ_RAW_AVE;
-	  goto useBasic;
-	}
-	FitAstromResultSetPM (fitStats->fit, fitStats->NfitAlloc, average);
-	for (k = 0; k < fitStats->NfitAlloc; k++) {
-	  BootstrapResample (fitStats->sample, fitStats->nomask, Nnomask);
-	  if (!FitPosPMfixed_Basic (&fitStats->fit[k], fitStats->fitdataPos, fitStats->sample, Nnomask)) continue;
-	  fitStats->Nfit ++;
-	}
-	BootstrapRobustStats (&fitPos, fitStats->fit, fitStats->Nfit, FIT_RESULT_RA);
-	BootstrapRobustStats (&fitPos, fitStats->fit, fitStats->Nfit, FIT_RESULT_DEC);
+      }
+      goto useBasic;
+    } 
+    
+    // try the IRLS fitting, otherwise give up and use OLS
+    if (!FitPosPMfixed_IRLS (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints)) {
+      // if the above fails, we need to clear the masks and try again below
+      FitPointsClearMasks (fitStats->points, fitStats->Npoints); 
+      // just calculate the weighted average
+      if (!FitPosPMfixed_Basic (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints)) { 
+	// if this fails, find a single unmasked point below
+	goto doneWithFit;
       }
       average[0].flags |= ID_OBJ_USE_AVE;
+      average[0].flags |= ID_OBJ_RAW_AVE;
+      goto useBasic;
+    }
+    average[0].flags |= ID_OBJ_USE_AVE;
+
+    if (N_BOOTSTRAP_SAMPLES && (fitPos.Nfit >= POS_MIN_NPTS_BOOT)) {
+      fitStats->Nfit = 0;
+      int Nnomask = BootstrapSaveUnmasked (fitStats->nomask, fitStats->points, fitStats->Npoints);
+      
+      if (Nnomask < POS_MIN_NPTS_BOOT) goto useBasic;
+      
+      FitAstromResultSetPM (fitStats->fit, fitStats->NfitAlloc, average);
+      for (k = 0; k < fitStats->NfitAlloc; k++) {
+	BootstrapResample (fitStats->sample, fitStats->nomask, Nnomask);
+	if (!FitPosPMfixed_Basic (&fitStats->fit[k], fitStats->fitdataPos, fitStats->sample, Nnomask)) continue;
+	fitStats->Nfit ++;
+      }
+      
+      // These calls set the ERRORS on the fit parameters, not the fit values (set in IRLS above)
+      // this call expects the fitted parameters to have the formal error set: it will apply the 
+      // max of the formal and bootstrap errors
+      BootstrapRobustStats (&fitPos, fitStats->fit, fitStats->Nfit, FIT_RESULT_RA);
+      BootstrapRobustStats (&fitPos, fitStats->fit, fitStats->Nfit, FIT_RESULT_DEC);
     }
 
@@ -544,4 +561,5 @@
   average[0].dP         = fit.dp; // parallax error in arcsec
 
+
   average[0].ChiSqAve   = fitPos.chisq;
   average[0].ChiSqPM    = fitPM.chisq;
@@ -666,4 +684,6 @@
 
   int has2MASS = FALSE;
+  int hasGAIA  = FALSE;
+  int hasTycho = FALSE;
   int hasStack = FALSE;
   if (stackEntry) *stackEntry = -1;
@@ -774,7 +794,7 @@
     Npoints++;
 
-    if ((measure[k].photcode >= 2011) && (measure[k].photcode <= 2013)) {
-      has2MASS = TRUE;
-    }
+    hasGAIA  =  (measure[k].photcode == 1030);
+    has2MASS = ((measure[k].photcode >= 2011) && (measure[k].photcode <= 2013));
+    hasTycho = ((measure[k].photcode >= 2020) && (measure[k].photcode <= 2021));
 
     myAssert (Npoints <= fit->NpointsAlloc, "oops");
@@ -796,4 +816,14 @@
       measure[k].dbFlags &= ~ID_MEAS_OBJECT_HAS_2MASS;
     }
+    if (hasGAIA) {
+      measure[k].dbFlags |=  ID_MEAS_OBJECT_HAS_GAIA;
+    } else {
+      measure[k].dbFlags &= ~ID_MEAS_OBJECT_HAS_GAIA;
+    }
+    if (hasTycho) {
+      measure[k].dbFlags |=  ID_MEAS_OBJECT_HAS_TYCHO;
+    } else {
+      measure[k].dbFlags &= ~ID_MEAS_OBJECT_HAS_TYCHO;
+    }
   }
 
@@ -803,4 +833,6 @@
   if (hasStack) status |= SELECT_MEAS_HAS_STACK; 
   if (has2MASS) status |= SELECT_MEAS_HAS_2MASS; 
+  if (hasGAIA)  status |= SELECT_MEAS_HAS_GAIA; 
+  if (hasTycho) status |= SELECT_MEAS_HAS_TYCHO; 
   return status;
 }
@@ -822,4 +854,6 @@
 
   int i;
+
+  myAbort ("this should not be called anymore");
 
   // add up the chi square for the fit
@@ -852,8 +886,13 @@
   int i;
 
-  if (USE_GALAXY_MODEL) {
+  if (APPLY_PROPER_MOTION) {
     for (i = 0; i < Nfit; i++) {
-      fit[i].uR = average->uRgal;
-      fit[i].uD = average->uDgal;
+      if (USE_GALAXY_MODEL) {
+	fit[i].uR = average->uRgal;
+	fit[i].uD = average->uDgal;
+      } else {
+	fit[i].uR = average->uR;
+	fit[i].uD = average->uD;
+      }
     }
   } else {
Index: trunk/Ohana/src/relastro/src/UpdateStacks.c
===================================================================
--- trunk/Ohana/src/relastro/src/UpdateStacks.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/UpdateStacks.c	(revision 39926)
@@ -3,4 +3,6 @@
 // NOTE: we only measure the systematic floor of the astrometric scatter per stack, no change to the calibration
 int UpdateStacks (Catalog *catalog, int Ncatalog) {
+
+  if (SKIP_PS1_STACK) return TRUE;
 
   off_t Nimage;
@@ -46,6 +48,6 @@
 
     // XXX: I need to convert dLsig, dMsig from degrees to pixels
-    dLsig *= 3600.0 / 0.25;
-    dMsig *= 3600.0 / 0.25;
+    dLsig *= 3600.0;
+    dMsig *= 3600.0;
 
     image[i].dXpixSys = dLsig;
Index: trunk/Ohana/src/relastro/src/args.c
===================================================================
--- trunk/Ohana/src/relastro/src/args.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/args.c	(revision 39926)
@@ -1,8 +1,9 @@
 # include "relastro.h"
-void usage (void);
-void usage_client (void);
+void usage (int argc, char **argv);
+void usage_client (int argc, char **argv);
 void usage_merge_source (void);
 void usage_merge_source_id (char *name);
 float *ParseLoopWeights (char *rawlist);
+int *ParseLoopOrder (char *rawlist, int minValue);
 
 int args (int argc, char **argv) {
@@ -39,5 +40,5 @@
     remove_argument (N, &argc, argv);
 
-    if (argc != 1) usage ();
+    if (argc != 1) usage (argc, argv);
     return TRUE;
   }
@@ -76,4 +77,11 @@
     remove_argument (N, &argc, argv);
     CHECK_MEASURE_TO_IMAGE = TRUE;
+  }
+
+  // catch-up mode : for a re-run, allow the sync file to be ahead of the desired location:
+  CATCH_UP = FALSE;
+  if ((N = get_argument (argc, argv, "-catch-up"))) {
+    remove_argument (N, &argc, argv);
+    CATCH_UP = TRUE;
   }
 
@@ -105,8 +113,8 @@
     remove_argument (N, &argc, argv);
     RELASTRO_OP = OP_PARALLEL_IMAGES;
-    if (N >= argc) usage();
+    if (N >= argc) usage (argc, argv);
     IMAGE_TABLE = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
-    if (!REGION_FILE) usage();
+    if (!REGION_FILE) usage (argc, argv);
   }
 
@@ -114,4 +122,81 @@
     remove_argument (N, &argc, argv);
     RELASTRO_OP = OP_IMAGES;
+  }
+
+  // used to decide if changes to the image parameters get applied to the measures
+  APPLY_OFFSETS = FALSE;
+  if ((N = get_argument (argc, argv, "-apply-offsets"))) {
+    remove_argument (N, &argc, argv);
+    APPLY_OFFSETS = TRUE;
+  }
+
+  APPLY_PROPER_MOTION = FALSE;
+  if ((N = get_argument (argc, argv, "-apply-proper-motion"))) {
+    remove_argument (N, &argc, argv);
+    APPLY_PROPER_MOTION = TRUE;
+  }
+
+  SKIP_PS1_CHIP = FALSE;
+  if ((N = get_argument (argc, argv, "-skip-ps1-chip"))) {
+    remove_argument (N, &argc, argv);
+    SKIP_PS1_CHIP = TRUE;
+  }
+  SKIP_PS1_STACK = FALSE;
+  if ((N = get_argument (argc, argv, "-skip-ps1-stack"))) {
+    remove_argument (N, &argc, argv);
+    SKIP_PS1_STACK = TRUE;
+  }
+  SKIP_HSC = FALSE;
+  if ((N = get_argument (argc, argv, "-skip-hsc"))) {
+    remove_argument (N, &argc, argv);
+    SKIP_HSC = TRUE;
+  }
+  SKIP_CFH = FALSE;
+  if ((N = get_argument (argc, argv, "-skip-cfh"))) {
+    remove_argument (N, &argc, argv);
+    SKIP_CFH = TRUE;
+  }
+
+  UPDATE_PS1_STACK_MEASURE = FALSE;
+  if ((N = get_argument (argc, argv, "-update-ps1-stack"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE_PS1_STACK_MEASURE = TRUE;
+  }
+  UPDATE_PS1_CHIP_MEASURE = FALSE;
+  if ((N = get_argument (argc, argv, "-update-ps1-chip"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE_PS1_CHIP_MEASURE = TRUE;
+  }
+  UPDATE_HSC_MEASURE = FALSE;
+  if ((N = get_argument (argc, argv, "-update-hsc"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE_HSC_MEASURE = TRUE;
+  }
+  UPDATE_CFH_MEASURE = FALSE;
+  if ((N = get_argument (argc, argv, "-update-cfh"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE_CFH_MEASURE = TRUE;
+  }
+  if (RELASTRO_OP == OP_UPDATE_OFFSETS) {
+    if (!UPDATE_PS1_STACK_MEASURE && !UPDATE_PS1_CHIP_MEASURE && !UPDATE_HSC_MEASURE && !UPDATE_CFH_MEASURE) {
+      fprintf (stderr, "for -update-offsets, need to select at least one of -update-ps1-stack, -update-ps1-chip, -update-hsc, -update-cfh\n");
+      exit (2);
+    }
+  }
+  if ((RELASTRO_OP == OP_PARALLEL_IMAGES) || (RELASTRO_OP == OP_IMAGES)) {
+    if (APPLY_OFFSETS && !UPDATE_PS1_STACK_MEASURE && !UPDATE_PS1_CHIP_MEASURE && !UPDATE_HSC_MEASURE && !UPDATE_CFH_MEASURE) {
+      fprintf (stderr, "for [-images or -parallel-images] with -apply-offsets, need to select at least one of -update-ps1-stack, -update-ps1-chip, -update-hsc, -update-cfh\n");
+      exit (2);
+    }
+  }
+
+  // for fitting objects, this is always the same as 'ALLOW_IRLS' below, but for fitting
+  // images, this is set to FALSE while doing the fit for the image parameters
+  USE_IRLS = TRUE;  
+  ALLOW_IRLS = TRUE;
+  if ((N = get_argument (argc, argv, "-no-irls"))) {
+    remove_argument (N, &argc, argv);
+    USE_IRLS = FALSE;
+    ALLOW_IRLS = FALSE;
   }
 
@@ -120,5 +205,5 @@
     remove_argument (N, &argc, argv);
     RELASTRO_OP = OP_PARALLEL_REGIONS;
-    if (!REGION_FILE) usage();
+    if (!REGION_FILE) usage (argc, argv);
     if ((N = get_argument (argc, argv, "-parallel-regions-manual"))) {
       remove_argument (N, &argc, argv);
@@ -128,22 +213,22 @@
 
   if ((N = get_argument (argc, argv, "-testobj1"))) {
-    if (N > argc - 3) usage ();
+    if (N > argc - 3) usage (argc, argv);
     remove_argument (N, &argc, argv);
     OBJ_ID_SRC = strtol(argv[N], &endptr, 0);
-    if (*endptr) usage ();
+    if (*endptr) usage (argc, argv);
     remove_argument (N, &argc, argv);
     CAT_ID_SRC = strtol(argv[N], &endptr, 0);
-    if (*endptr) usage (); 
+    if (*endptr) usage (argc, argv); 
     remove_argument (N, &argc, argv);
   }
 
   if ((N = get_argument (argc, argv, "-testobj2"))) {
-    if (N > argc - 3) usage ();
+    if (N > argc - 3) usage (argc, argv);
     remove_argument (N, &argc, argv);
     OBJ_ID_DST = strtol(argv[N], &endptr, 0);
-    if (*endptr) usage ();
+    if (*endptr) usage (argc, argv);
     remove_argument (N, &argc, argv);
     CAT_ID_DST = strtol(argv[N], &endptr, 0);
-    if (*endptr) usage (); 
+    if (*endptr) usage (argc, argv); 
     remove_argument (N, &argc, argv);
   }
@@ -167,5 +252,5 @@
   if ((N = get_argument (argc, argv, "-high-speed"))) {
     // XXX include a parallax / no-parallax option
-    if (N >= argc - 4) usage();
+    if (N >= argc - 4) usage (argc, argv);
     RELASTRO_OP = OP_HIGH_SPEED;
     remove_argument (N, &argc, argv);
@@ -181,5 +266,5 @@
 
   if ((N = get_argument (argc, argv, "-hpm"))) {
-    if (N >= argc - 2) usage();
+    if (N >= argc - 2) usage (argc, argv);
     RELASTRO_OP = OP_HPM;
     remove_argument (N, &argc, argv);
@@ -212,4 +297,8 @@
     FIT_TARGET = TARGET_MOSAICS;
   }
+  if ((N = get_argument (argc, argv, "-set-chips"))) {
+    remove_argument (N, &argc, argv);
+    FIT_TARGET = SET_CHIPS;
+  }
 
   FlagOutlier = FALSE;
@@ -231,7 +320,7 @@
   }
 
-  if (RELASTRO_OP == OP_NONE) usage();
-
-  if (((RELASTRO_OP == OP_IMAGES) || (RELASTRO_OP == OP_PARALLEL_REGIONS) || (RELASTRO_OP == OP_PARALLEL_IMAGES)) && (FIT_TARGET == TARGET_NONE)) usage();
+  if (RELASTRO_OP == OP_NONE) usage (argc, argv);
+
+  if (((RELASTRO_OP == OP_IMAGES) || (RELASTRO_OP == OP_PARALLEL_REGIONS) || (RELASTRO_OP == OP_PARALLEL_IMAGES)) && (FIT_TARGET == TARGET_NONE)) usage (argc, argv);
 
   /* specify portion of the sky : allow default of all sky? */
@@ -303,4 +392,10 @@
   }
 
+  KEEP_ALL_IMAGES_RA = FALSE;
+  if ((N = get_argument (argc, argv, "-keep-all-images-ra"))) {
+    remove_argument (N, &argc, argv);
+    KEEP_ALL_IMAGES_RA = TRUE;
+  }
+
   USE_BASIC_CHECK = FALSE;
   if ((N = get_argument (argc, argv, "-basic-image-search"))) {
@@ -315,10 +410,4 @@
     remove_argument (N, &argc, argv);
     MaxDensityUse = TRUE;
-  }
-
-  APPLY_OFFSETS = FALSE;
-  if ((N = get_argument (argc, argv, "-apply-offsets"))) {
-    remove_argument (N, &argc, argv);
-    APPLY_OFFSETS = TRUE;
   }
 
@@ -439,19 +528,4 @@
   }
 
-  CHIPORDER = 0;
-  if ((N = get_argument (argc, argv, "-chiporder"))) {
-    remove_argument (N, &argc, argv);
-    CHIPORDER = atoi(argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-
-  CHIPMAP = 0;
-  if ((N = get_argument (argc, argv, "-chipmap"))) {
-    remove_argument (N, &argc, argv);
-    CHIPMAP = atoi(argv[N]);
-    remove_argument (N, &argc, argv);
-
-  }
-
   SAVEPLOT = FALSE;
   PLOTSTUFF = FALSE;
@@ -580,4 +654,38 @@
   }
 
+  // e.g., -chiporderloop 3,4,5
+  // NOTE: this must come after -nloop above
+  ChipOrderLoop = NULL;
+  ChipOrderLoopStr = NULL;
+  CHIPORDER = 1;
+  if ((N = get_argument (argc, argv, "-chiporder"))) {
+    remove_argument (N, &argc, argv);
+    CHIPORDER = atoi(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-chiporderloop"))) {
+    remove_argument (N, &argc, argv);
+    ChipOrderLoopStr = strcreate(argv[N]);
+    ChipOrderLoop = ParseLoopOrder (argv[N], 1);
+    remove_argument (N, &argc, argv);
+  }
+
+  ChipMapLoop = NULL;
+  ChipMapLoopStr = NULL;
+  CHIPMAP = 0;
+  if ((N = get_argument (argc, argv, "-chipmap"))) {
+    remove_argument (N, &argc, argv);
+    CHIPMAP = atoi(argv[N]);
+    remove_argument (N, &argc, argv);
+
+  }
+  if ((N = get_argument (argc, argv, "-chipmaploop"))) {
+    remove_argument (N, &argc, argv);
+    ChipMapLoopStr = strcreate(argv[N]);
+    ChipMapLoop = ParseLoopOrder (argv[N], 0);
+    remove_argument (N, &argc, argv);
+  }
+  
+
   // e.g., -loop-weights-2mass 1000,300,300,200,200,100
   // NOTE: this must come after -nloop above
@@ -591,4 +699,5 @@
   }
   LoopWeightTycho = NULL;
+  LoopWeightTychostr = NULL;
   if ((N = get_argument (argc, argv, "-loop-weights-tycho"))) {
     remove_argument (N, &argc, argv);
@@ -597,4 +706,28 @@
     remove_argument (N, &argc, argv);
   }
+  LoopWeightGAIA = NULL;
+  LoopWeightGAIAstr = NULL;
+  if ((N = get_argument (argc, argv, "-loop-weights-gaia"))) {
+    remove_argument (N, &argc, argv);
+    LoopWeightGAIAstr = strcreate(argv[N]);
+    LoopWeightGAIA = ParseLoopWeights (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  GALAXY_MODEL = NULL;
+  if ((N = get_argument (argc, argv, "-galaxy-model"))) {
+    remove_argument (N, &argc, argv);
+    GALAXY_MODEL = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!GALAXY_MODEL) GALAXY_MODEL = strcreate ("FEAST-HIPPARCOS");
+
+  // for testing, allow the galaxy model scale to be non-unity
+  TEST_SCALE = 1.0;
+  if ((N = get_argument (argc, argv, "-testing"))) {
+    remove_argument (N, &argc, argv);
+    TEST_SCALE = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
 
   NTHREADS = 0;
@@ -605,5 +738,5 @@
   }
 
-  if (argc != 1) usage ();
+  if (argc != 1) usage (argc, argv);
   return TRUE;
 }
@@ -614,4 +747,13 @@
   FREE (LoopWeight2MASSstr);
   FREE (LoopWeightTychostr);
+  FREE (LoopWeightGAIAstr);
+  FREE (LoopWeight2MASS);
+  FREE (LoopWeightTycho);
+  FREE (LoopWeightGAIA);
+
+  FREE (ChipMapLoop);
+  FREE (ChipMapLoopStr);
+  FREE (ChipOrderLoop);
+  FREE (ChipOrderLoopStr);
 
   FREE (PHOTCODE_SKIP_LIST);
@@ -628,4 +770,5 @@
   FREE (BCATALOG);
   FREE (HOSTDIR);
+  FREE (GALAXY_MODEL);
 
   // these are set in initialize
@@ -673,5 +816,5 @@
     remove_argument (N, &argc, argv);
   }
-  if (!HOST_ID) usage_client();
+  if (!HOST_ID) usage_client (argc, argv);
 
   HOSTDIR = NULL;
@@ -681,5 +824,5 @@
     remove_argument (N, &argc, argv);
   }
-  if (!HOSTDIR) usage_client();
+  if (!HOSTDIR) usage_client (argc, argv);
 
   if ((N = get_argument (argc, argv, "-load-objects"))) {
@@ -726,4 +869,52 @@
   }
 
+  SKIP_PS1_CHIP = FALSE;
+  if ((N = get_argument (argc, argv, "-skip-ps1-chip"))) {
+    remove_argument (N, &argc, argv);
+    SKIP_PS1_CHIP = TRUE;
+  }
+  SKIP_PS1_STACK = FALSE;
+  if ((N = get_argument (argc, argv, "-skip-ps1-stack"))) {
+    remove_argument (N, &argc, argv);
+    SKIP_PS1_STACK = TRUE;
+  }
+  SKIP_HSC = FALSE;
+  if ((N = get_argument (argc, argv, "-skip-hsc"))) {
+    remove_argument (N, &argc, argv);
+    SKIP_HSC = TRUE;
+  }
+  SKIP_CFH = FALSE;
+  if ((N = get_argument (argc, argv, "-skip-cfh"))) {
+    remove_argument (N, &argc, argv);
+    SKIP_CFH = TRUE;
+  }
+
+  UPDATE_PS1_STACK_MEASURE = FALSE;
+  if ((N = get_argument (argc, argv, "-update-ps1-stack"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE_PS1_STACK_MEASURE = TRUE;
+  }
+  UPDATE_PS1_CHIP_MEASURE = FALSE;
+  if ((N = get_argument (argc, argv, "-update-ps1-chip"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE_PS1_CHIP_MEASURE = TRUE;
+  }
+  UPDATE_HSC_MEASURE = FALSE;
+  if ((N = get_argument (argc, argv, "-update-hsc"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE_HSC_MEASURE = TRUE;
+  }
+  UPDATE_CFH_MEASURE = FALSE;
+  if ((N = get_argument (argc, argv, "-update-cfh"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE_CFH_MEASURE = TRUE;
+  }
+  if (RELASTRO_OP == OP_UPDATE_OFFSETS) {
+    if (!UPDATE_PS1_STACK_MEASURE && !UPDATE_PS1_CHIP_MEASURE && !UPDATE_HSC_MEASURE && !UPDATE_CFH_MEASURE) {
+      fprintf (stderr, "for -update-offsets, need to select at least one of -update-ps1-stack, -update-ps1-chip, -update-hsc, -update-cfh\n");
+      exit (2);
+    }
+  }
+
   // check for object fitting modes
   if ((N = get_argument (argc, argv, "-pm"))) {
@@ -742,5 +933,5 @@
   if ((N = get_argument (argc, argv, "-high-speed"))) {
     // XXX include a parallax / no-parallax option
-    if (N >= argc - 5) usage_client();
+    if (N >= argc - 5) usage_client (argc, argv);
     RELASTRO_OP = OP_HIGH_SPEED;
     remove_argument (N, &argc, argv);
@@ -756,5 +947,5 @@
 
   if ((N = get_argument (argc, argv, "-hpm"))) {
-    if (N >= argc - 3) usage();
+    if (N >= argc - 3) usage_client (argc, argv);
     RELASTRO_OP = OP_HPM;
     remove_argument (N, &argc, argv);
@@ -766,22 +957,22 @@
 
   if ((N = get_argument (argc, argv, "-testobj1"))) {
-    if (N > argc - 3) usage ();
+    if (N > argc - 3) usage_client (argc, argv);
     remove_argument (N, &argc, argv);
     OBJ_ID_SRC = strtol(argv[N], &endptr, 0);
-    if (*endptr) usage ();
+    if (*endptr) usage_client (argc, argv);
     remove_argument (N, &argc, argv);
     CAT_ID_SRC = strtol(argv[N], &endptr, 0);
-    if (*endptr) usage (); 
+    if (*endptr) usage_client (argc, argv); 
     remove_argument (N, &argc, argv);
   }
 
   if ((N = get_argument (argc, argv, "-testobj2"))) {
-    if (N > argc - 3) usage ();
+    if (N > argc - 3) usage_client (argc, argv);
     remove_argument (N, &argc, argv);
     OBJ_ID_DST = strtol(argv[N], &endptr, 0);
-    if (*endptr) usage ();
+    if (*endptr) usage_client (argc, argv);
     remove_argument (N, &argc, argv);
     CAT_ID_DST = strtol(argv[N], &endptr, 0);
-    if (*endptr) usage (); 
+    if (*endptr) usage_client (argc, argv); 
     remove_argument (N, &argc, argv);
   }
@@ -805,5 +996,21 @@
   }
 
-  if (RELASTRO_OP == OP_NONE) usage_client();
+  GALAXY_MODEL = NULL;
+  if ((N = get_argument (argc, argv, "-galaxy-model"))) {
+    remove_argument (N, &argc, argv);
+    GALAXY_MODEL = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!GALAXY_MODEL) GALAXY_MODEL = strcreate ("FEAST-HIPPARCOS");
+
+  // for testing, allow the galaxy model scale to be non-unity
+  TEST_SCALE = 1.0;
+  if ((N = get_argument (argc, argv, "-testing"))) {
+    remove_argument (N, &argc, argv);
+    TEST_SCALE = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (RELASTRO_OP == OP_NONE) usage_client (argc, argv);
 
   /* specify portion of the sky : allow default of all sky? */
@@ -1032,5 +1239,5 @@
   }
 
-  if (argc != 1) usage_client ();
+  if (argc != 1) usage_client (argc, argv);
   return TRUE;
 }
@@ -1049,5 +1256,6 @@
   FREE(HIGH_SPEED_DIR);
   FREE(BCATALOG);
-  FREE (HOSTDIR);
+  FREE(HOSTDIR);
+  FREE(GALAXY_MODEL);
 
   // these are set in initialize
@@ -1066,5 +1274,5 @@
 }
 
-void usage () {
+void usage (int argc, char **argv) {
   fprintf (stderr, "ERROR: USAGE: relastro -images -update-simple [options]\n");
   fprintf (stderr, "       OR:    relastro -images -update-chips [options]\n");
@@ -1116,8 +1324,15 @@
   fprintf (stderr, "  -v\n");
   fprintf (stderr, "  \n");
+
+  fprintf (stderr, "remaining args: ");
+  for (int i = 0; i < argc; i++) {
+    fprintf (stderr, "%s ", argv[i]);
+  }
+  fprintf (stderr, "\n");
+
   exit (2);
 } 
 
-void usage_client () {
+void usage_client (int argc, char **argv) {
   fprintf (stderr, "ERROR: USAGE: relastro_client -load\n");
   fprintf (stderr, "       OR:    relastro_client -update-offsets\n");
@@ -1150,4 +1365,11 @@
   fprintf (stderr, "  -v\n");
   fprintf (stderr, "  \n");
+
+  fprintf (stderr, "remaining args: ");
+  for (int i = 0; i < argc; i++) {
+    fprintf (stderr, "%s ", argv[i]);
+  }
+  fprintf (stderr, "\n");
+
   exit (2);
 } 
@@ -1189,8 +1411,49 @@
   }
 
+  // this sets the last loops to match the last value...
   while (Nloop < NLOOP) {
     weights[Nloop] = weights[Nloop - 1];
     Nloop ++;
   }
+
   return weights;
 }
+
+int *ParseLoopOrder (char *rawlist, int minValue) {
+
+  int *orders = NULL;
+  ALLOCATE (orders, int, NLOOP);
+
+  int Nloop = 0;
+
+  /* parse the comma-separated list of photcodes */
+  char *myList = strcreate(rawlist);
+  char *list = myList;
+  char *entry = NULL;
+  char *ptr = NULL;
+  while ((Nloop < NLOOP) && ((entry = strtok_r (list, ",", &ptr)) != NULL)) {
+    list = NULL; // pass NULL on successive strtok_r calls
+
+    orders[Nloop] = atoi(entry);
+    if (orders[Nloop] < minValue) {
+      fprintf (stderr, "order cannot be < %d: %s\n", minValue, rawlist);
+      exit (3);
+    }
+
+    Nloop ++;
+  }
+  free (myList);
+
+  if (Nloop == 0) {
+    fprintf (stderr, "syntax error parsing orders: %s\n", rawlist);
+    exit (3);
+  }
+
+  // this sets the last loops to match the last value...
+  while (Nloop < NLOOP) {
+    orders[Nloop] = orders[Nloop - 1];
+    Nloop ++;
+  }
+
+  return orders;
+}
Index: trunk/Ohana/src/relastro/src/assign_images.c
===================================================================
--- trunk/Ohana/src/relastro/src/assign_images.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/assign_images.c	(revision 39926)
@@ -40,5 +40,5 @@
 
   // register the image array with ImageOps.c for later getimageByID calls
-  initImages (image, NULL, Nimage);
+  initImages (image, NULL, Nimage, FALSE);
 
   if (VERBOSE) fprintf (stderr, "finding images\n");
@@ -72,4 +72,10 @@
 
   for (j = 0; j < Nimage; j++) {
+    
+    // allow certain cameras to stay static
+    if (SKIP_PS1_CHIP  && isGPC1chip (image[j].photcode)) continue;
+    if (SKIP_PS1_STACK && isGPC1stack(image[j].photcode)) continue;
+    if (SKIP_HSC       && isHSCchip  (image[j].photcode)) continue;
+    if (SKIP_CFH       && isCFHchip  (image[j].photcode)) continue;
     
     /* select images by photcode, or equiv photcode, if specified */
Index: trunk/Ohana/src/relastro/src/bcatalog.c
===================================================================
--- trunk/Ohana/src/relastro/src/bcatalog.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/bcatalog.c	(revision 39926)
@@ -72,4 +72,6 @@
 
   int myNskip1 = 0, myNskip2 = 0, myNskip3 = 0, myNskip4 = 0, myNskip5 = 0, myNskip6 = 0;
+
+  int NgaiaObject = 0;
 
   /* exclude stars not in range or with too few measurements */
@@ -187,4 +189,10 @@
       if (isGPC1warp(catalog[0].measure[offset].photcode)) continue;
 
+      // allow certain cameras to stay static
+      if (SKIP_PS1_CHIP  && isGPC1chip(catalog[0].measure[offset].photcode)) continue;
+      if (SKIP_PS1_STACK && isGPC1stack(catalog[0].measure[offset].photcode)) continue;
+      if (SKIP_HSC       && isHSCchip(catalog[0].measure[offset].photcode)) continue;
+      if (SKIP_CFH       && isCFHchip(catalog[0].measure[offset].photcode)) continue;
+
       // filter objects based on user supplied criteria, including SIGMA_LIM
       if (!MeasFilterTest(&catalog[0].measure[offset], TRUE)) {
@@ -250,4 +258,6 @@
       }
 
+      if (catalog[0].measure[offset].photcode == 1030) { NgaiaObject ++; }
+
       CopyMeasureToTiny (&subcatalog[0].measureT[Nmeasure], &catalog[0].measure[offset]);
       // subcatalog[0].measure[Nmeasure] = catalog[0].measure[offset];
@@ -281,5 +291,5 @@
     }
   }
-  fprintf (stderr, "skips: %d %d %d %d %d %d\n", myNskip1, myNskip2, myNskip3, myNskip4, myNskip5, myNskip6);
+  fprintf (stderr, "skips: %d %d %d %d %d %d, Ngaia: %d\n", myNskip1, myNskip2, myNskip3, myNskip4, myNskip5, myNskip6, NgaiaObject);
   REALLOCATE (subcatalog[0].average,  Average,     MAX (Naverage, 1));
   REALLOCATE (subcatalog[0].measureT, MeasureTiny, MAX (Nmeasure, 1));
Index: trunk/Ohana/src/relastro/src/extra.c
===================================================================
--- trunk/Ohana/src/relastro/src/extra.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/extra.c	(revision 39926)
@@ -39,2 +39,26 @@
   return FALSE;
 }
+
+// for now (20160925) I need to identify HSC chips explicitly.  generalize in the future
+int isHSCchip (int photcode) {
+
+  if ((photcode >= 20000) && (photcode <= 20111)) return TRUE; // g-band
+  if ((photcode >= 21000) && (photcode <= 21111)) return TRUE; // r-band
+  if ((photcode >= 22000) && (photcode <= 22111)) return TRUE; // i-band
+  if ((photcode >= 23000) && (photcode <= 23111)) return TRUE; // z-band
+  if ((photcode >= 24000) && (photcode <= 24111)) return TRUE; // y-band
+
+  return FALSE;
+}
+
+// for now (20160925) I need to identify CFH chips explicitly.  generalize in the future
+int isCFHchip (int photcode) {
+
+  if ((photcode >= 100) && (photcode <= 152)) return TRUE; // g-band
+  if ((photcode >= 200) && (photcode <= 252)) return TRUE; // r-band
+  if ((photcode >= 300) && (photcode <= 352)) return TRUE; // i-band
+  if ((photcode >= 400) && (photcode <= 452)) return TRUE; // z-band
+  if ((photcode >= 500) && (photcode <= 552)) return TRUE; // y-band
+
+  return FALSE;
+}
Index: trunk/Ohana/src/relastro/src/initialize.c
===================================================================
--- trunk/Ohana/src/relastro/src/initialize.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/initialize.c	(revision 39926)
@@ -11,4 +11,11 @@
   ConfigInit (&argc, argv);
   args (argc, argv);
+
+  if (USE_GALAXY_MODEL) {
+    if (!InitGalaxyModel (GALAXY_MODEL)) {
+      fprintf (stderr, "failed to init galaxy model %s\n", GALAXY_MODEL);
+      exit (2);
+    }
+  }
 
   if (RELASTRO_OP == OP_MERGE_SOURCE) return;
Index: trunk/Ohana/src/relastro/src/launch_region_hosts.c
===================================================================
--- trunk/Ohana/src/relastro/src/launch_region_hosts.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/launch_region_hosts.c	(revision 39926)
@@ -81,10 +81,26 @@
     strextend (&command, "-region-hosts %s", REGION_FILE);
     strextend (&command, "-region-hostID %d", host->hostID);
+
     strextend (&command, "-D CATDIR %s", CATDIR);
     strextend (&command, "-region %f %f %f %f", host->RminCat, host->RmaxCat, host->DminCat, host->DmaxCat);
     strextend (&command, "-statmode %s", STATMODE);
     strextend (&command, "-minerror %f", MIN_ERROR);
-    strextend (&command, "-nloop %d", NLOOP);
-    strextend (&command, "-threads %d", NTHREADS);
+
+    strextend (&command, "-D RELASTRO_SIGMA_LIM %f", SIGMA_LIM);
+    strextend (&command, "-D RELASTRO_SRC_MEAS_TOOFEW %d", SRC_MEAS_TOOFEW);
+
+    strextend (&command, " -D RELASTRO_MIN_DISTANCE_MOD %f",     MIN_DISTANCE_MOD);
+    strextend (&command, " -D RELASTRO_MAX_DISTANCE_MOD %f",     MAX_DISTANCE_MOD);
+    strextend (&command, " -D RELASTRO_MAX_DISTANCE_MOD_ERR %f", MAX_DISTANCE_MOD_ERR);
+
+    strextend (&command, "-D USE_GALAXY_MODEL %d", USE_GALAXY_MODEL);
+    strextend (&command, "-D USE_ICRF_CORRECT %d", USE_ICRF_CORRECT);
+
+    strextend (&command, "-D RELASTRO_DPOS_MAX %f", DPOS_MAX);
+    strextend (&command, "-D ADDSTAR_RADIUS %f", ADDSTAR_RADIUS);
+
+    strextend (&command, "-D USE_ICRF_LOCAL %d",   USE_ICRF_LOCAL);
+    strextend (&command, "-D USE_ICRF_SHFIT %d",   USE_ICRF_SHFIT);
+    strextend (&command, "-D USE_ICRF_POLE %d",    USE_ICRF_POLE);
 
     switch (FIT_TARGET) {
@@ -98,4 +114,7 @@
 	strextend (&command, "-update-mosaics");
 	break;
+      case SET_CHIPS:
+	strextend (&command, "-set-chips");
+	break;
       case TARGET_NONE:
 	abort();
@@ -105,28 +124,46 @@
     if (VERBOSE2)      	    strextend (&command, "-vv");
     if (RESET)         	    strextend (&command, "-reset");
+
+    if (ImagSelect)         strextend (&command, "-instmag %f %f", ImagMin, ImagMax);
+    if (MaxDensityUse) 	    strextend (&command, "-max-density %f", MaxDensityValue);
+    if (FlagOutlier)        strextend (&command, "-clip %d", CLIP_THRESH);
+    if (ExcludeBogus)       strextend (&command, "-exclude-bogus %f", ExcludeBogusRadius);
+
+    if (USE_FIXED_PIXCOORDS) strextend (&command, "-D USE_FIXED_PIXCOORDS 1");
+    if (PHOTCODE_KEEP_LIST) strextend (&command, "+photcode %s", PHOTCODE_KEEP_LIST); 
+    if (PHOTCODE_SKIP_LIST) strextend (&command, "-photcode %s", PHOTCODE_SKIP_LIST);
+    if (PhotFlagSelect)     strextend (&command, "+photflags"); 
+    if (PhotFlagBad)        strextend (&command, "+photflagbad %d", PhotFlagBad); 
+    if (PhotFlagPoor)       strextend (&command, "+photflagpoor %d", PhotFlagPoor); 
+
+    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
+      strextend (&command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
+    }
+    if (DCR_RED_COLOR_POS && DCR_RED_COLOR_NEG) {
+      strextend (&command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
+    }
+
+    if (TEST_SCALE != 1.0)   strextend (&command, "-testing %f", TEST_SCALE);
+
+    if (SKIP_PS1_CHIP)       strextend (&command, "-skip-ps1-chip");
+    if (SKIP_PS1_STACK)      strextend (&command, "-skip-ps1-stack");
+    if (SKIP_HSC)            strextend (&command, "-skip-hsc");
+    if (SKIP_CFH)            strextend (&command, "-skip-cfh");
+
+    strextend (&command, "-nloop %d", NLOOP);
+    strextend (&command, "-threads %d", NTHREADS);
+    
+    if (PHOTCODE_RESET_LIST) strextend (&command, "-reset-to-photcode %s", PHOTCODE_RESET_LIST);
+
     if (UPDATE)        	    strextend (&command, "-update");
     if (PARALLEL)      	    strextend (&command, "-parallel");
     if (PARALLEL_MANUAL)    strextend (&command, "-parallel-manual");
     if (PARALLEL_SERIAL)    strextend (&command, "-parallel-serial");
-    if (PHOTCODE_KEEP_LIST) strextend (&command, "+photcode %s", PHOTCODE_KEEP_LIST); 
-    if (PHOTCODE_SKIP_LIST) strextend (&command, "-photcode %s", PHOTCODE_SKIP_LIST);
-    if (PHOTCODE_RESET_LIST) strextend (&command, "-reset-to-photcode %s", PHOTCODE_RESET_LIST);
-
-    if (MaxDensityUse) 	    strextend (&command, "-max-density %f", MaxDensityValue);
-    if (ImagSelect)         strextend (&command, "-instmag %f %f", ImagMin, ImagMax);
-    if (ExcludeBogus)       strextend (&command, "-exclude-bogus %f", ExcludeBogusRadius);
-
-    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
-      strextend (&command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
-    }
-    if (DCR_RED_COLOR_POS && DCR_RED_COLOR_NEG) {
-      strextend (&command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
-    }
-
-    if (PhotFlagSelect)     strextend (&command, "+photflags"); 
-    if (PhotFlagBad)        strextend (&command, "+photflagbad %d", PhotFlagBad); 
-    if (PhotFlagPoor)       strextend (&command, "+photflagpoor %d", PhotFlagPoor); 
-
+
+    strextend (&command, "-chiporder %d", CHIPORDER); 
     if (CHIPMAP)            strextend (&command, "-chipmap %d", CHIPMAP); 
+    if (ChipMapLoop)        strextend (&command, "-chipmaploop %s", ChipMapLoopStr); 
+    if (ChipOrderLoop)      strextend (&command, "-chiporderloop %s", ChipOrderLoopStr); 
+
     if (RESET_IMAGES)       strextend (&command, "-reset-images"); 
 
@@ -136,18 +173,6 @@
     if (LoopWeight2MASS) {  strextend (&command, "-loop-weights-2mass %s", LoopWeight2MASSstr); }
     if (LoopWeightTycho) {  strextend (&command, "-loop-weights-tycho %s", LoopWeightTychostr); }
-
-    strextend (&command, "-D RELASTRO_SRC_MEAS_TOOFEW %d", SRC_MEAS_TOOFEW);
-    strextend (&command, "-D RELASTRO_SIGMA_LIM %f", SIGMA_LIM);
-    strextend (&command, "-D RELASTRO_DPOS_MAX %f", DPOS_MAX);
-    strextend (&command, "-D ADDSTAR_RADIUS %f", ADDSTAR_RADIUS);
-
-    strextend (&command, "-D USE_GALAXY_MODEL %d", USE_GALAXY_MODEL);
-
-    strextend (&command, "-D USE_ICRF_CORRECT %d", USE_ICRF_CORRECT);
-    strextend (&command, "-D USE_ICRF_LOCAL %d",   USE_ICRF_LOCAL);
-    strextend (&command, "-D USE_ICRF_SHFIT %d",   USE_ICRF_SHFIT);
-    strextend (&command, "-D USE_ICRF_POLE %d",    USE_ICRF_POLE);
-
-    if (USE_FIXED_PIXCOORDS) strextend (&command, "-D USE_FIXED_PIXCOORDS 1");
+    if (LoopWeightGAIA)  {  strextend (&command, "-loop-weights-gaia %s", LoopWeightGAIAstr); }
+    if (APPLY_PROPER_MOTION) strextend (&command, "-apply-proper-motion");
 
     if (TimeSelect) { 
Index: trunk/Ohana/src/relastro/src/load_catalogs.c
===================================================================
--- trunk/Ohana/src/relastro/src/load_catalogs.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/load_catalogs.c	(revision 39926)
@@ -178,37 +178,34 @@
     strextend (&command, "relastro_client -load-objects %s", table->hosts[i].results);
     strextend (&command, " -hostID %d", table->hosts[i].hostID);
+    strextend (&command, " -hostdir %s", table->hosts[i].pathname);
+
     strextend (&command, " -D CATDIR %s", CATDIR);
-    strextend (&command, " -hostdir %s", table->hosts[i].pathname);
     strextend (&command, " -region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     strextend (&command, " -statmode %s", STATMODE);
     strextend (&command, " -minerror %f", MIN_ERROR);
+
     strextend (&command, " -D RELASTRO_SIGMA_LIM %f", SIGMA_LIM);
+    strextend (&command, " -D RELASTRO_SRC_MEAS_TOOFEW %d", SRC_MEAS_TOOFEW);
+
     strextend (&command, " -D RELASTRO_MIN_DISTANCE_MOD %f",     MIN_DISTANCE_MOD);
     strextend (&command, " -D RELASTRO_MAX_DISTANCE_MOD %f",     MAX_DISTANCE_MOD);
     strextend (&command, " -D RELASTRO_MAX_DISTANCE_MOD_ERR %f", MAX_DISTANCE_MOD_ERR);
 
+    strextend (&command, "-D USE_GALAXY_MODEL %d", USE_GALAXY_MODEL);
+    strextend (&command, "-D USE_ICRF_CORRECT %d", USE_ICRF_CORRECT);
+
     if (FIT_MODE == FIT_PM_ONLY)  	 strextend (&command, "-pm");
     if (FIT_MODE == FIT_PAR_ONLY) 	 strextend (&command, "-par");
     if (FIT_MODE == FIT_PM_AND_PAR)      strextend (&command, "-pmpar");
 
-    if (VERBOSE)       strextend (&command, "-v");
-    if (VERBOSE2)      strextend (&command, "-vv");
-    if (RESET)         strextend (&command, "-reset");
-    if (ImagSelect)    strextend (&command, "-instmag %f %f", ImagMin, ImagMax);
-    if (MaxDensityUse) strextend (&command, "-max-density %f", MaxDensityValue);
-    if (FlagOutlier)   strextend (&command, "-clip %d", CLIP_THRESH);
-    if (ExcludeBogus)  strextend (&command, "-exclude-bogus %f", ExcludeBogusRadius);
-
-    if (USE_ICRF_CORRECT) strextend (&command, "-D USE_ICRF_CORRECT %d", USE_ICRF_CORRECT);
-    if (USE_GALAXY_MODEL) strextend (&command, "-D USE_GALAXY_MODEL %d", USE_GALAXY_MODEL);
-    
-    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
-      strextend (&command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
-    }
-    if (DCR_RED_COLOR_POS && DCR_RED_COLOR_NEG) {
-      strextend (&command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
-    }
-
-    if (USE_ALL_IMAGES)      strextend (&command, "-use-all-images");
+    if (VERBOSE)             strextend (&command, "-v");
+    if (VERBOSE2)            strextend (&command, "-vv");
+    if (RESET)               strextend (&command, "-reset");
+		             
+    if (ImagSelect)          strextend (&command, "-instmag %f %f", ImagMin, ImagMax);
+    if (MaxDensityUse)       strextend (&command, "-max-density %f", MaxDensityValue);
+    if (FlagOutlier)         strextend (&command, "-clip %d", CLIP_THRESH);
+    if (ExcludeBogus)        strextend (&command, "-exclude-bogus %f", ExcludeBogusRadius);
+
     if (USE_FIXED_PIXCOORDS) strextend (&command, "-D USE_FIXED_PIXCOORDS 1");
     if (PHOTCODE_KEEP_LIST)  strextend (&command, "+photcode %s", PHOTCODE_KEEP_LIST);
@@ -217,4 +214,19 @@
     if (PhotFlagBad)         strextend (&command, "+photflagbad %d", PhotFlagBad); 
     if (PhotFlagPoor)        strextend (&command, "+photflagpoor %d", PhotFlagPoor);
+
+    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
+      strextend (&command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
+    }
+    if (DCR_RED_COLOR_POS && DCR_RED_COLOR_NEG) {
+      strextend (&command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
+    }
+
+    if (SKIP_PS1_CHIP)       strextend (&command, "-skip-ps1-chip");
+    if (SKIP_PS1_STACK)      strextend (&command, "-skip-ps1-stack");
+    if (SKIP_HSC)            strextend (&command, "-skip-hsc");
+    if (SKIP_CFH)            strextend (&command, "-skip-cfh");
+
+    if (USE_ALL_IMAGES)      strextend (&command, "-use-all-images");
+
     // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
 
@@ -282,4 +294,6 @@
   CatalogSplitter *catalogs = BrightCatalogSplitInit (Nsecfilt);
 
+  ohana_memstats (TRUE);
+
   for (i = 0; i < table->Nhosts; i++) {
 
@@ -296,4 +310,6 @@
     free (bcatalog->secfilt);
     free (bcatalog);
+
+    ohana_memstats (TRUE);
   }
 
@@ -320,4 +336,5 @@
 
   BrightCatalogSplitFree (catalogs);
+  ohana_memstats (TRUE);
 
   return (catalog);
Index: trunk/Ohana/src/relastro/src/load_images.c
===================================================================
--- trunk/Ohana/src/relastro/src/load_images.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/load_images.c	(revision 39926)
@@ -66,5 +66,5 @@
   }
 
-  initImages (subset, LineNumber, Nsubset);
+  initImages (subset, LineNumber, Nsubset, !USE_ALL_IMAGES);
   MARKTIME("  init images: %f sec\n", dtime);
   
Index: trunk/Ohana/src/relastro/src/relastro_images.c
===================================================================
--- trunk/Ohana/src/relastro/src/relastro_images.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/relastro_images.c	(revision 39926)
@@ -16,4 +16,7 @@
   int finalPassMode = FIT_MODE; // start with the globally-defined fit mode
   FIT_MODE = FIT_AVERAGE;
+
+  int RESET_ON_UPDATE = RESET;  
+  RESET = TRUE; // we need to reset when we load the bright catalog subset 
 
   /* lock and load the image db table */
@@ -65,4 +68,6 @@
   // XXX NOTE : for 2mass reset, photcodesKeep should now limit to 2MASS measurements
 
+  USE_IRLS = FALSE;  // do not use IRLS yet -- leads to excessive outlier rejections in the loops
+
   /* major modes */
   switch (FIT_TARGET) {
@@ -90,4 +95,11 @@
       break;
 
+    case SET_CHIPS:
+      // we just want to fit the selected chips to the mean positions
+      UpdateChips (catalog, Ncatalog, 0);   // measure.X,Y -> R,D, fit image.coords
+      MARKTIME("update chips: %f sec\n", dtime);
+
+      break;
+
     case TARGET_MOSAICS:
       for (i = 0; i < NLOOP; i++) {
@@ -102,12 +114,4 @@
   }
 
-  if (!UPDATE) { 
-    freeStarMaps();
-    gfits_db_free (&db);
-    ohana_memcheck (VERBOSE);
-    ohana_memdump (VERBOSE);
-    exit (0);
-  }
-
   // free the image / measurement pointers
   freeImageBins (Ncatalog);
@@ -117,4 +121,12 @@
   free (catalog);
   freeMosaics ();
+
+  if (!UPDATE) { 
+    freeStarMaps();
+    dvo_image_unlock (&db); 
+    freeImages (db.ftable.buffer);
+    gfits_db_free (&db);
+    return TRUE;
+  }
 
   // If we did NOT use all images, then we applied the measured corrections to a subset of
@@ -154,4 +166,6 @@
   // iterate over catalogs to make detection coordinates consistant
   if (APPLY_OFFSETS) {
+    USE_IRLS = ALLOW_IRLS;  // now that we have fitted the images, choose the user's option
+    RESET = RESET_ON_UPDATE;
     UpdateObjectOffsets (skylist, 0, NULL);
   }
Index: trunk/Ohana/src/relastro/src/relastro_objects.c
===================================================================
--- trunk/Ohana/src/relastro/src/relastro_objects.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/relastro_objects.c	(revision 39926)
@@ -159,8 +159,13 @@
     strextend (&command, "relastro_client -update-objects");
     strextend (&command, "-hostID %d", table->hosts[i].hostID);
+    strextend (&command, "-hostdir %s", table->hosts[i].pathname);
+
     strextend (&command, "-D CATDIR %s", CATDIR);
-    strextend (&command, "-hostdir %s", table->hosts[i].pathname);
     strextend (&command, "-region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     strextend (&command, "-statmode %s", STATMODE);
+    strextend (&command, "-minerror %f", MIN_ERROR);
+
+    strextend (&command, "-D RELASTRO_SIGMA_LIM %f", SIGMA_LIM);
+    strextend (&command, "-D RELASTRO_SRC_MEAS_TOOFEW %d", SRC_MEAS_TOOFEW);
 
     if (FIT_MODE == FIT_PM_ONLY)  	 { strextend (&command, "-pm"); }
@@ -171,10 +176,10 @@
     if (VERBOSE2)      { strextend (&command, "-vv"); }
     if (RESET)         { strextend (&command, "-reset"); }
-    if (UPDATE)        { strextend (&command, "-update"); }
+
     if (ImagSelect)    { strextend (&command, "-instmag %f %f", ImagMin, ImagMax); }
     if (MaxDensityUse) { strextend (&command, "-max-density %f", MaxDensityValue); }
     if (FlagOutlier)   { strextend (&command, "-clip %d", CLIP_THRESH); }
-
-    if (USE_ALL_IMAGES)      { strextend (&command, "-use-all-images"); }
+    if (ExcludeBogus)    strextend (&command, "-exclude-bogus %f", ExcludeBogusRadius);
+
     if (USE_FIXED_PIXCOORDS) { strextend (&command, "-D USE_FIXED_PIXCOORDS 1"); }
     if (PHOTCODE_KEEP_LIST)  { strextend (&command, "+photcode %s", PHOTCODE_KEEP_LIST); }
@@ -185,4 +190,14 @@
     // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
 
+    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
+      strextend (&command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
+    }
+    if (DCR_RED_COLOR_POS && DCR_RED_COLOR_NEG) {
+      strextend (&command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
+    }
+
+    if (UPDATE)        { strextend (&command, "-update"); }
+    if (USE_ALL_IMAGES)      { strextend (&command, "-use-all-images"); }
+
     if (MinBadQF > 0.0)          strextend (&command, "-min-bad-psfqf %f", MinBadQF); 
     if (MaxMeanOffset != 10.0)   strextend (&command, "-max-mean-offset  %f", MaxMeanOffset); 
Index: trunk/Ohana/src/relastro/src/relastro_parallel_images.c
===================================================================
--- trunk/Ohana/src/relastro/src/relastro_parallel_images.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/relastro_parallel_images.c	(revision 39926)
@@ -61,5 +61,5 @@
   initMosaics (image, Nimage);
 
-  initImages (image, NULL, Nimage);
+  initImages (image, NULL, Nimage, FALSE);
 
   SkyTable *sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
@@ -103,4 +103,8 @@
 
   client_logger_message ("starting the loops: %s\n", myHostName);
+
+  RESET = TRUE; // we need to reset when we load the bright catalog subset 
+  FIT_MODE = FIT_AVERAGE; // we need to only fit the average
+  USE_IRLS = FALSE;  // do not use IRLS yet -- leads to excessive outlier rejections in the loops
 
   /* major modes */
Index: trunk/Ohana/src/relastro/src/select_images.c
===================================================================
--- trunk/Ohana/src/relastro/src/select_images.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/select_images.c	(revision 39926)
@@ -121,4 +121,10 @@
     }
 
+    // allow certain cameras to stay static
+    if (SKIP_PS1_CHIP  && isGPC1chip (timage[i].photcode)) continue;
+    if (SKIP_PS1_STACK && isGPC1stack(timage[i].photcode)) continue;
+    if (SKIP_HSC       && isHSCchip  (timage[i].photcode)) continue;
+    if (SKIP_CFH       && isCFHchip  (timage[i].photcode)) continue;
+    
     /* select images by photcode, or equiv photcode, if specified */
     if (NphotcodesKeep > 0) {
@@ -187,4 +193,6 @@
     if (DmaxImage < DminSkyRegion) continue;
     
+    if (KEEP_ALL_IMAGES_RA) goto found_it;
+
     // the sky region RA is defined to be 0 - 360.0
     if (RminImage > RmaxSkyRegion) continue;
Index: trunk/Ohana/src/relastro/src/syncfile.c
===================================================================
--- trunk/Ohana/src/relastro/src/syncfile.c	(revision 39907)
+++ trunk/Ohana/src/relastro/src/syncfile.c	(revision 39926)
@@ -39,4 +39,5 @@
     int loop;
     sscanf (message, "%*s %d", &loop);
+    if (CATCH_UP && (nloop < loop)) return TRUE; // if I am behind this machine, I need to catch up!
     if (loop != nloop) {
       usleep (2000000);
Index: trunk/Ohana/src/relphot/include/relphot.h
===================================================================
--- trunk/Ohana/src/relphot/include/relphot.h	(revision 39907)
+++ trunk/Ohana/src/relphot/include/relphot.h	(revision 39926)
@@ -309,4 +309,5 @@
 int    RESET_ZEROPTS;
 int    REPAIR_WARPS;
+int    PRESERVE_PS1;
 int    UPDATE;
 int    SAVE_IMAGE_UPDATES;
@@ -616,4 +617,7 @@
 int isTYCHO (int photcode);
 
+int isHSCchip  (int photcode);
+int isCFHchip  (int photcode);
+
 int magStatsByRanking (StatDataSet *dataset, StatType *stats);
 
Index: trunk/Ohana/src/relphot/src/args.c
===================================================================
--- trunk/Ohana/src/relphot/src/args.c	(revision 39907)
+++ trunk/Ohana/src/relphot/src/args.c	(revision 39926)
@@ -226,4 +226,10 @@
     remove_argument (N, &argc, argv);
     REPAIR_WARPS = TRUE;
+  }
+
+  PRESERVE_PS1 = FALSE;
+  if ((N = get_argument (argc, argv, "-preserve-ps1"))) {
+    remove_argument (N, &argc, argv);
+    PRESERVE_PS1 = TRUE;
   }
 
@@ -672,4 +678,10 @@
   }
 
+  PRESERVE_PS1 = FALSE;
+  if ((N = get_argument (argc, argv, "-preserve-ps1"))) {
+    remove_argument (N, &argc, argv);
+    PRESERVE_PS1 = TRUE;
+  }
+
   REPAIR_WARPS = FALSE;
   if ((N = get_argument (argc, argv, "-repair-warps"))) {
Index: trunk/Ohana/src/relphot/src/extra.c
===================================================================
--- trunk/Ohana/src/relphot/src/extra.c	(revision 39907)
+++ trunk/Ohana/src/relphot/src/extra.c	(revision 39926)
@@ -2,7 +2,8 @@
 
 // for now (20140710) I need to identify gpc1 chips explicitly.  generalize in the future
+// note that the 4000, 14000, 15000 sets are SIMTEST (*not* synthetic) 
 int whichGPC1filter (int photcode) {
 
-  if (((photcode > 10000) && (photcode < 10077)) || (photcode == 4100)) return PS1_g; // g-band
+  if (((photcode > 10000) && (photcode < 10077)) || (photcode == 4100)) return PS1_g; // g-band 
   if (((photcode > 10100) && (photcode < 10177)) || (photcode == 4200)) return PS1_r; // r-band
   if (((photcode > 10200) && (photcode < 10277)) || (photcode == 4300)) return PS1_i; // i-band
@@ -83,2 +84,26 @@
 }
 
+// for now (20160925) I need to identify HSC chips explicitly.  generalize in the future
+int isHSCchip (int photcode) {
+
+  if ((photcode >= 20000) && (photcode <= 20111)) return TRUE; // g-band
+  if ((photcode >= 21000) && (photcode <= 21111)) return TRUE; // r-band
+  if ((photcode >= 22000) && (photcode <= 22111)) return TRUE; // i-band
+  if ((photcode >= 23000) && (photcode <= 23111)) return TRUE; // z-band
+  if ((photcode >= 24000) && (photcode <= 24111)) return TRUE; // y-band
+
+  return FALSE;
+}
+
+// for now (20160925) I need to identify CFH chips explicitly.  generalize in the future
+int isCFHchip (int photcode) {
+
+  if ((photcode >= 100) && (photcode <= 152)) return TRUE; // g-band
+  if ((photcode >= 200) && (photcode <= 252)) return TRUE; // r-band
+  if ((photcode >= 300) && (photcode <= 352)) return TRUE; // i-band
+  if ((photcode >= 400) && (photcode <= 452)) return TRUE; // z-band
+  if ((photcode >= 500) && (photcode <= 552)) return TRUE; // y-band
+
+  return FALSE;
+}
+
Index: trunk/Ohana/src/relphot/src/reload_catalogs.c
===================================================================
--- trunk/Ohana/src/relphot/src/reload_catalogs.c	(revision 39907)
+++ trunk/Ohana/src/relphot/src/reload_catalogs.c	(revision 39926)
@@ -239,4 +239,5 @@
     if (RESET)             { strextend (&command, "-reset"); }
     if (RESET_ZEROPTS)     { strextend (&command, "-reset-zpts"); }
+    if (PRESERVE_PS1)      { strextend (&command, "-preserve-ps1"); }
     if (UPDATE)            { strextend (&command, "-update"); }
     if (IS_DIFF_DB)        { strextend (&command, "-is-diff-db"); }
Index: trunk/Ohana/src/relphot/src/relphot_objects.c
===================================================================
--- trunk/Ohana/src/relphot/src/relphot_objects.c	(revision 39907)
+++ trunk/Ohana/src/relphot/src/relphot_objects.c	(revision 39926)
@@ -243,4 +243,5 @@
     if (RESET_ZEROPTS) 	   { strextend (&command, "-reset-zpts"); }
     if (REPAIR_WARPS)      { strextend (&command, "-repair-warps"); }
+    if (PRESERVE_PS1)      { strextend (&command, "-preserve-ps1"); }
     if (IS_DIFF_DB)        { strextend (&command, "-is-diff-db"); }
     if (UPDATE)        	   { strextend (&command, "-update"); }
Index: trunk/Ohana/src/relphot/src/setMrelCatalog.c
===================================================================
--- trunk/Ohana/src/relphot/src/setMrelCatalog.c	(revision 39907)
+++ trunk/Ohana/src/relphot/src/setMrelCatalog.c	(revision 39926)
@@ -142,4 +142,6 @@
   int Galaxy2MASS = FALSE;
   int haveTYCHO = FALSE;
+  int haveHSC = FALSE;
+  int haveCFH = FALSE;
 
   float stargalmax = 0.0;
@@ -163,4 +165,6 @@
     
     if (isTYCHO(measureT[k].photcode)) { haveTYCHO = TRUE; }
+    if (isHSCchip(measureT[k].photcode)) { haveHSC = TRUE; }
+    if (isCFHchip(measureT[k].photcode)) { haveCFH = TRUE; }
 
     if (is2MASS(measureT[k].photcode)) {
@@ -317,5 +321,22 @@
   // now calculate the mean stats for the Nsec bands.
   for (Nsec = 0; Nsec < Nsecfilt; Nsec++) {
-    dvo_secfilt_init (&secfilt[Nsec], SECFILT_RESET_CHIP); // this does not reset astrometry or STACK bits
+
+    // if we detected this object in PS1, or do not request -preserve-ps1, keep the mean photometry values
+    if (!PRESERVE_PS1 || !(secfilt[Nsec].flags & ID_SECF_HAS_PS1)) {
+      dvo_secfilt_init (&secfilt[Nsec], SECFILT_RESET_CHIP); // this does not reset astrometry or STACK bits
+    }
+
+    if (haveTYCHO) {
+      secfilt[Nsec].flags |= ID_SECF_HAS_TYCHO;
+    }
+    if (haveHSC) {
+      secfilt[Nsec].flags |= ID_SECF_HAS_HSC;
+    }
+    if (haveCFH) {
+      secfilt[Nsec].flags |= ID_SECF_HAS_CFH;
+    }
+
+    if (PRESERVE_PS1 && (secfilt[Nsec].flags & ID_SECF_HAS_PS1)) continue;
+    // if -preserve-ps1 is set and this object has PS1 data, skip the rest of the steps:
 
     // XXX hardwired grizy = (01234) JHK = (567) w = (8)
@@ -324,8 +345,4 @@
     } else {
       secfilt[Nsec].Ncode = results->Nmeas[Nsec]; // 2MASS data if it exists
-    }
-
-    if (haveTYCHO) {
-      secfilt[Nsec].flags |= ID_SECF_HAS_TYCHO;
     }
 
Index: trunk/Ohana/src/uniphot/include/setgalmodel.h
===================================================================
--- trunk/Ohana/src/uniphot/include/setgalmodel.h	(revision 39907)
+++ trunk/Ohana/src/uniphot/include/setgalmodel.h	(revision 39926)
@@ -10,5 +10,4 @@
 char        *HOSTDIR;
 int          VERBOSE;
-int          TESTING;
 int          UPDATE;
 int          PARALLEL;
@@ -18,4 +17,6 @@
 char        *SINGLE_CPT;
 
+float        TEST_SCALE;
+char        *GALAXY_MODEL;
 SkyRegion    UserPatch;
 
Index: trunk/Ohana/src/uniphot/include/setphot.h
===================================================================
--- trunk/Ohana/src/uniphot/include/setphot.h	(revision 39907)
+++ trunk/Ohana/src/uniphot/include/setphot.h	(revision 39926)
@@ -67,4 +67,6 @@
 int          VERBOSE;
 int          RESET;
+int          PHOTCODE_MIN;
+int          PHOTCODE_MAX;
 int          UBERCAL; // load the supplied ubercal zero point fits table (with flat-field corrections)
 int          NO_METADATA; // the supplied ubercal data has no descriptive metadata
Index: trunk/Ohana/src/uniphot/src/initialize_setgalmodel.c
===================================================================
--- trunk/Ohana/src/uniphot/src/initialize_setgalmodel.c	(revision 39907)
+++ trunk/Ohana/src/uniphot/src/initialize_setgalmodel.c	(revision 39926)
@@ -45,6 +45,6 @@
 
   // XXX add to config?
-  if (!InitGalaxyModel ("FEAST-HIPPARCOS")) {
-    fprintf (stderr, "failed to init galaxy model\n");
+  if (!InitGalaxyModel (GALAXY_MODEL)) {
+    fprintf (stderr, "failed to init galaxy model %s\n", GALAXY_MODEL);
     exit (2);
   }
@@ -92,7 +92,16 @@
   }
 
-  TESTING = FALSE;
+  GALAXY_MODEL = NULL;
+  if ((N = get_argument (argc, argv, "-galaxy-model"))) {
+    remove_argument (N, &argc, argv);
+    GALAXY_MODEL = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!GALAXY_MODEL) GALAXY_MODEL = strcreate ("FEAST-HIPPARCOS");
+
+  TEST_SCALE = 1.0;
   if ((N = get_argument (argc, argv, "-testing"))) {
-    TESTING = TRUE;
+    remove_argument (N, &argc, argv);
+    TEST_SCALE = atof(argv[N]);
     remove_argument (N, &argc, argv);
   }
@@ -171,6 +180,6 @@
   }
 
-  // XXX add to config?
-  if (!InitGalaxyModel ("ROESER")) {
+  // from args
+  if (!InitGalaxyModel (GALAXY_MODEL)) {
     fprintf (stderr, "failed to init galaxy model\n");
     exit (2);
@@ -212,7 +221,16 @@
   }
 
-  TESTING = FALSE;
+  GALAXY_MODEL = NULL;
+  if ((N = get_argument (argc, argv, "-galaxy-model"))) {
+    remove_argument (N, &argc, argv);
+    GALAXY_MODEL = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!GALAXY_MODEL) GALAXY_MODEL = strcreate ("FEAST-HIPPARCOS");
+
+  TEST_SCALE = 1.0;
   if ((N = get_argument (argc, argv, "-testing"))) {
-    TESTING = TRUE;
+    remove_argument (N, &argc, argv);
+    TEST_SCALE = atof(argv[N]);
     remove_argument (N, &argc, argv);
   }
Index: trunk/Ohana/src/uniphot/src/initialize_setphot.c
===================================================================
--- trunk/Ohana/src/uniphot/src/initialize_setphot.c	(revision 39907)
+++ trunk/Ohana/src/uniphot/src/initialize_setphot.c	(revision 39926)
@@ -109,4 +109,14 @@
   if ((N = get_argument (argc, argv, "-reset"))) {
     RESET = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  PHOTCODE_MIN = 0;
+  PHOTCODE_MAX = 0;
+  if ((N = get_argument (argc, argv, "-photcode-range"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_MIN = atoi (argv[N]);    
+    remove_argument (N, &argc, argv);
+    PHOTCODE_MAX = atoi (argv[N]);    
     remove_argument (N, &argc, argv);
   }
Index: trunk/Ohana/src/uniphot/src/initialize_setphot_client.c
===================================================================
--- trunk/Ohana/src/uniphot/src/initialize_setphot_client.c	(revision 39907)
+++ trunk/Ohana/src/uniphot/src/initialize_setphot_client.c	(revision 39926)
@@ -96,4 +96,14 @@
   }
 
+  PHOTCODE_MIN = 0;
+  PHOTCODE_MAX = 0;
+  if ((N = get_argument (argc, argv, "-photcode-range"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_MIN = atoi (argv[N]);    
+    remove_argument (N, &argc, argv);
+    PHOTCODE_MAX = atoi (argv[N]);    
+    remove_argument (N, &argc, argv);
+  }
+
   // region of interest
   UserPatch.Rmin = 0;
Index: trunk/Ohana/src/uniphot/src/update_catalog_setgalmodel.c
===================================================================
--- trunk/Ohana/src/uniphot/src/update_catalog_setgalmodel.c	(revision 39907)
+++ trunk/Ohana/src/uniphot/src/update_catalog_setgalmodel.c	(revision 39926)
@@ -33,7 +33,13 @@
 
     // fake or real QSOs are marked with FeH = +/- 100.0
-    if (fabs(starpar->FeH) > 99.0) continue;
+    if (fabs(starpar->FeH) > 99.0) { 
+      starpar->uRA  = 0.0;
+      starpar->uDEC = 0.0;
+      average[i].uRgal = 0.0;
+      average[i].uDgal = 0.0;
+      continue;
+    }
 
-    // NOTE: distance is in kiloparsec
+    // NOTE: DistMag is standard (10pc reference).  SolarMotionModel wants distance in kiloparsec:
     double distance = pow(10.0, 0.2*(starpar->DistMag + 5.0)) / 1000.0;
 
@@ -51,8 +57,6 @@
 
     // XXX: amplify motion to make tests easier:
-    if (TESTING) {
-      uL *= 100.0;
-      uB *= 100.0;
-    }
+    uL *= TEST_SCALE;
+    uB *= TEST_SCALE;
     
     double uR, uD;
Index: trunk/Ohana/src/uniphot/src/update_catalog_setphot.c
===================================================================
--- trunk/Ohana/src/uniphot/src/update_catalog_setphot.c	(revision 39907)
+++ trunk/Ohana/src/uniphot/src/update_catalog_setphot.c	(revision 39926)
@@ -1,3 +1,7 @@
 # include "setphot.h"
+
+// XXX I need to add a few things for HSC + MC + GPC1:
+// * I can generate a zpt table for the MC exposures using the nominal zero points
+// * for the HSC data, I need to add a function to define Mflat as a function of Xmos, Ymos
 
 void update_catalog_setphot (Catalog *catalog, Image *image, off_t *index, off_t Nimage, CamPhotomCorrection *camcorr) {
@@ -14,8 +18,19 @@
     Measure *measure = &catalog[0].measure[i];
 
-    // only do GPC1 data for now
-    if (measure[0].photcode < 10000) continue;
-    if (measure[0].photcode > 10600) continue;
+    // XXX deprecated 2016.09.22 : only do GPC1 data for now
+    // if (measure[0].photcode < 10000) continue;
+    // if (measure[0].photcode > 10600) continue;
       
+    // only do DEP photcodes (skip REF, etc)
+    PhotCode *code = GetPhotcodebyCode (measure[0].photcode);
+    if (!code) continue; // invalid photcode
+    if (code->type != PHOT_DEP) continue;
+
+    // allow a restriction on the modified zpts:
+    if (PHOTCODE_MAX) {
+      if (measure[0].photcode < PHOTCODE_MIN) continue;
+      if (measure[0].photcode > PHOTCODE_MAX) continue;
+    }
+
     off_t idx = measure[0].imageID;
     if (idx <= 0) continue; // detections with imageID == 0 do not have a valid image (eg, ref photcode)
@@ -33,4 +48,16 @@
       Mflat = CamPhotomCorrectionValue (camcorr, flat_id, measure[0].Xccd, measure[0].Yccd);
     }
+
+# if (0)
+    // the mosaic lookup is broken : fix it then redo this block
+    if (radialZP) {
+      mosaic = MatchMosaicMetadata (measure[0].imageID);
+      if (mosaic == NULL) break;
+      double Rm = measure[0].R;
+      double Dm = measure[0].D;
+      RD_to_XY (&XMOS_MEAS, &YMOS_MEAS, Rm, Dm, mosaic);
+      Mflat = RadialZPtrend (XMOS_MEAS, XMOS_MEAS);
+    }
+# endif
 
     measure[0].Mcal = Mcal;
Index: trunk/Ohana/src/uniphot/src/update_dvo_setgalmodel.c
===================================================================
--- trunk/Ohana/src/uniphot/src/update_dvo_setgalmodel.c	(revision 39907)
+++ trunk/Ohana/src/uniphot/src/update_dvo_setgalmodel.c	(revision 39926)
@@ -98,5 +98,5 @@
 
     if (VERBOSE)       	  { strextend (&command, "-v"); }
-    if (TESTING)       	  { strextend (&command, "-testing"); }
+    if (TEST_SCALE != 1.0){ strextend (&command, "-testing %f", TEST_SCALE); }
     if (UPDATE)        	  { strextend (&command, "-update"); }
     if (UPDATE_CATFORMAT) { strextend (&command, "-update-catformat %s", UPDATE_CATFORMAT); }
Index: trunk/Ohana/src/uniphot/src/update_dvo_setphot.c
===================================================================
--- trunk/Ohana/src/uniphot/src/update_dvo_setphot.c	(revision 39907)
+++ trunk/Ohana/src/uniphot/src/update_dvo_setphot.c	(revision 39926)
@@ -179,4 +179,6 @@
     if (DCR_RESET)     	  { strextend (&command, "-DCR-reset"); }
     if (CAM_RESET)     	  { strextend (&command, "-CAM-reset"); }
+
+    if (PHOTCODE_MAX) 	  { strextend (&command, "-photcode-range %d %d", PHOTCODE_MIN, PHOTCODE_MAX); }
 
     fprintf (stderr, "command: %s\n", command);
Index: trunk/ippScripts/scripts/camera_exp.pl
===================================================================
--- trunk/ippScripts/scripts/camera_exp.pl	(revision 39907)
+++ trunk/ippScripts/scripts/camera_exp.pl	(revision 39926)
@@ -404,5 +404,5 @@
 
     # Construct FPA continuity corrected background images
-    if ($camera =~ /ISP/) {
+    if (($camera =~ /ISP/)||($camera =~ /HSC/)) {
 	print "Skipping FPA continuity corrected background images for ISP\n";
     } elsif ($do_bkg) {
Index: trunk/ippTools/src/stacktool.c
===================================================================
--- trunk/ippTools/src/stacktool.c	(revision 39907)
+++ trunk/ippTools/src/stacktool.c	(revision 39926)
@@ -1328,4 +1328,8 @@
     psFree(where);
 
+    // This needs to be sorted by skycell_id, or the ppSkycell calls to mosaic things
+    // don't work properly.
+    psStringAppend(&query, " ORDER BY stackRun.skycell_id ");
+    
     // treat limit == 0 as "no limit"
     if (limit) {
Index: trunk/ippconfig/dvo.photcodes
===================================================================
--- trunk/ippconfig/dvo.photcodes	(revision 39907)
+++ trunk/ippconfig/dvo.photcodes	(revision 39926)
@@ -152,4 +152,6 @@
   2022  TYCHO_B_2MASS        ref   0.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
   2023  TYCHO_V_2MASS        ref   0.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+
+  1030  GAIA_G_DR1           ref   0.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
 
   2025  BSC_U        	     ref   0.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
@@ -988,452 +990,453 @@
   566   MOSAIC2.I.06         dep  24.887  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 1.000  0.000   0x0000 0x3888  0x0000 0x0000
   567   MOSAIC2.I.07         dep  24.912  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 1.000  0.000   0x0000 0x3888  0x0000 0x0000
-  20000 HSC.g.00             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20001 HSC.g.01             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20002 HSC.g.02             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20003 HSC.g.03             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20004 HSC.g.04             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20005 HSC.g.05             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20006 HSC.g.06             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20007 HSC.g.07             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20008 HSC.g.08             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20009 HSC.g.09             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20010 HSC.g.10             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20011 HSC.g.11             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20012 HSC.g.12             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20013 HSC.g.13             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20014 HSC.g.14             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20015 HSC.g.15             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20016 HSC.g.16             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20017 HSC.g.17             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20018 HSC.g.18             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20019 HSC.g.19             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20020 HSC.g.20             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20021 HSC.g.21             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20022 HSC.g.22             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20023 HSC.g.23             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20024 HSC.g.24             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20025 HSC.g.25             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20026 HSC.g.26             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20027 HSC.g.27             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20028 HSC.g.28             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20029 HSC.g.29             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20030 HSC.g.30             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20031 HSC.g.31             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20032 HSC.g.32             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20033 HSC.g.33             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20034 HSC.g.34             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20035 HSC.g.35             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20036 HSC.g.36             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20037 HSC.g.37             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20038 HSC.g.38             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20039 HSC.g.39             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20040 HSC.g.40             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20041 HSC.g.41             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20042 HSC.g.42             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20043 HSC.g.43             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20044 HSC.g.44             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20045 HSC.g.45             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20046 HSC.g.46             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20047 HSC.g.47             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20048 HSC.g.48             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20049 HSC.g.49             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20050 HSC.g.50             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20051 HSC.g.51             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20052 HSC.g.52             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20053 HSC.g.53             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20054 HSC.g.54             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20055 HSC.g.55             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20056 HSC.g.56             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20057 HSC.g.57             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20058 HSC.g.58             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20059 HSC.g.59             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20060 HSC.g.60             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20061 HSC.g.61             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20062 HSC.g.62             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20063 HSC.g.63             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20064 HSC.g.64             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20065 HSC.g.65             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20066 HSC.g.66             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20067 HSC.g.67             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20068 HSC.g.68             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20069 HSC.g.69             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20070 HSC.g.70             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20071 HSC.g.71             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20072 HSC.g.72             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20073 HSC.g.73             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20074 HSC.g.74             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20075 HSC.g.75             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20076 HSC.g.76             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20077 HSC.g.77             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20078 HSC.g.78             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20079 HSC.g.79             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20080 HSC.g.80             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20081 HSC.g.81             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20082 HSC.g.82             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20083 HSC.g.83             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20084 HSC.g.84             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20085 HSC.g.85             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20086 HSC.g.86             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20087 HSC.g.87             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20088 HSC.g.88             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20089 HSC.g.89             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20090 HSC.g.90             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20091 HSC.g.91             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20092 HSC.g.92             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20093 HSC.g.93             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20094 HSC.g.94             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20095 HSC.g.95             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20096 HSC.g.96             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20097 HSC.g.97             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20098 HSC.g.98             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20099 HSC.g.99             dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20100 HSC.g.100            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20101 HSC.g.101            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20102 HSC.g.102            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20103 HSC.g.103            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20104 HSC.g.104            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20105 HSC.g.105            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20106 HSC.g.106            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20107 HSC.g.107            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20108 HSC.g.108            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20109 HSC.g.109            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20110 HSC.g.110            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  20111 HSC.g.111            dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21000 HSC.r.00             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21001 HSC.r.01             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21002 HSC.r.02             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21003 HSC.r.03             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21004 HSC.r.04             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21005 HSC.r.05             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21006 HSC.r.06             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21007 HSC.r.07             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21008 HSC.r.08             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21009 HSC.r.09             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21010 HSC.r.10             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21011 HSC.r.11             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21012 HSC.r.12             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21013 HSC.r.13             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21014 HSC.r.14             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21015 HSC.r.15             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21016 HSC.r.16             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21017 HSC.r.17             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21018 HSC.r.18             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21019 HSC.r.19             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21020 HSC.r.20             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21021 HSC.r.21             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21022 HSC.r.22             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21023 HSC.r.23             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21024 HSC.r.24             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21025 HSC.r.25             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21026 HSC.r.26             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21027 HSC.r.27             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21028 HSC.r.28             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21029 HSC.r.29             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21030 HSC.r.30             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21031 HSC.r.31             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21032 HSC.r.32             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21033 HSC.r.33             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21034 HSC.r.34             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21035 HSC.r.35             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21036 HSC.r.36             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21037 HSC.r.37             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21038 HSC.r.38             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21039 HSC.r.39             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21040 HSC.r.40             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21041 HSC.r.41             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21042 HSC.r.42             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21043 HSC.r.43             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21044 HSC.r.44             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21045 HSC.r.45             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21046 HSC.r.46             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21047 HSC.r.47             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21048 HSC.r.48             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21049 HSC.r.49             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21050 HSC.r.50             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21051 HSC.r.51             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21052 HSC.r.52             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21053 HSC.r.53             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21054 HSC.r.54             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21055 HSC.r.55             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21056 HSC.r.56             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21057 HSC.r.57             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21058 HSC.r.58             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21059 HSC.r.59             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21060 HSC.r.60             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21061 HSC.r.61             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21062 HSC.r.62             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21063 HSC.r.63             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21064 HSC.r.64             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21065 HSC.r.65             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21066 HSC.r.66             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21067 HSC.r.67             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21068 HSC.r.68             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21069 HSC.r.69             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21070 HSC.r.70             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21071 HSC.r.71             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21072 HSC.r.72             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21073 HSC.r.73             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21074 HSC.r.74             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21075 HSC.r.75             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21076 HSC.r.76             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21077 HSC.r.77             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21078 HSC.r.78             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21079 HSC.r.79             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21080 HSC.r.80             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21081 HSC.r.81             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21082 HSC.r.82             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21083 HSC.r.83             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21084 HSC.r.84             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21085 HSC.r.85             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21086 HSC.r.86             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21087 HSC.r.87             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21088 HSC.r.88             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21089 HSC.r.89             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21090 HSC.r.90             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21091 HSC.r.91             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21092 HSC.r.92             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21093 HSC.r.93             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21094 HSC.r.94             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21095 HSC.r.95             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21096 HSC.r.96             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21097 HSC.r.97             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21098 HSC.r.98             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21099 HSC.r.99             dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21100 HSC.r.100            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21101 HSC.r.101            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21102 HSC.r.102            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21103 HSC.r.103            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21104 HSC.r.104            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21105 HSC.r.105            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21106 HSC.r.106            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21107 HSC.r.107            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21108 HSC.r.108            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21109 HSC.r.109            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21110 HSC.r.110            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  21111 HSC.r.111            dep  25.000  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22000 HSC.i.00             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22001 HSC.i.01             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22002 HSC.i.02             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22003 HSC.i.03             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22004 HSC.i.04             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22005 HSC.i.05             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22006 HSC.i.06             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22007 HSC.i.07             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22008 HSC.i.08             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22009 HSC.i.09             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22010 HSC.i.10             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22011 HSC.i.11             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22012 HSC.i.12             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22013 HSC.i.13             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22014 HSC.i.14             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22015 HSC.i.15             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22016 HSC.i.16             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22017 HSC.i.17             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22018 HSC.i.18             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22019 HSC.i.19             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22020 HSC.i.20             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22021 HSC.i.21             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22022 HSC.i.22             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22023 HSC.i.23             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22024 HSC.i.24             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22025 HSC.i.25             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22026 HSC.i.26             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22027 HSC.i.27             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22028 HSC.i.28             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22029 HSC.i.29             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22030 HSC.i.30             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22031 HSC.i.31             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22032 HSC.i.32             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22033 HSC.i.33             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22034 HSC.i.34             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22035 HSC.i.35             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22036 HSC.i.36             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22037 HSC.i.37             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22038 HSC.i.38             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22039 HSC.i.39             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22040 HSC.i.40             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22041 HSC.i.41             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22042 HSC.i.42             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22043 HSC.i.43             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22044 HSC.i.44             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22045 HSC.i.45             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22046 HSC.i.46             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22047 HSC.i.47             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22048 HSC.i.48             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22049 HSC.i.49             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22050 HSC.i.50             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22051 HSC.i.51             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22052 HSC.i.52             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22053 HSC.i.53             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22054 HSC.i.54             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22055 HSC.i.55             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22056 HSC.i.56             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22057 HSC.i.57             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22058 HSC.i.58             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22059 HSC.i.59             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22060 HSC.i.60             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22061 HSC.i.61             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22062 HSC.i.62             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22063 HSC.i.63             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22064 HSC.i.64             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22065 HSC.i.65             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22066 HSC.i.66             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22067 HSC.i.67             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22068 HSC.i.68             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22069 HSC.i.69             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22070 HSC.i.70             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22071 HSC.i.71             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22072 HSC.i.72             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22073 HSC.i.73             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22074 HSC.i.74             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22075 HSC.i.75             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22076 HSC.i.76             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22077 HSC.i.77             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22078 HSC.i.78             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22079 HSC.i.79             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22080 HSC.i.80             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22081 HSC.i.81             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22082 HSC.i.82             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22083 HSC.i.83             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22084 HSC.i.84             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22085 HSC.i.85             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22086 HSC.i.86             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22087 HSC.i.87             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22088 HSC.i.88             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22089 HSC.i.89             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22090 HSC.i.90             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22091 HSC.i.91             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22092 HSC.i.92             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22093 HSC.i.93             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22094 HSC.i.94             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22095 HSC.i.95             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22096 HSC.i.96             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22097 HSC.i.97             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22098 HSC.i.98             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22099 HSC.i.99             dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22100 HSC.i.100            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22101 HSC.i.101            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22102 HSC.i.102            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22103 HSC.i.103            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22104 HSC.i.104            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22105 HSC.i.105            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22106 HSC.i.106            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22107 HSC.i.107            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22108 HSC.i.108            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22109 HSC.i.109            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22110 HSC.i.110            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  22111 HSC.i.111            dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23000 HSC.z.00             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23001 HSC.z.01             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23002 HSC.z.02             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23003 HSC.z.03             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23004 HSC.z.04             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23005 HSC.z.05             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23006 HSC.z.06             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23007 HSC.z.07             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23008 HSC.z.08             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23009 HSC.z.09             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23010 HSC.z.10             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23011 HSC.z.11             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23012 HSC.z.12             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23013 HSC.z.13             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23014 HSC.z.14             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23015 HSC.z.15             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23016 HSC.z.16             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23017 HSC.z.17             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23018 HSC.z.18             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23019 HSC.z.19             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23020 HSC.z.20             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23021 HSC.z.21             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23022 HSC.z.22             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23023 HSC.z.23             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23024 HSC.z.24             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23025 HSC.z.25             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23026 HSC.z.26             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23027 HSC.z.27             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23028 HSC.z.28             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23029 HSC.z.29             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23030 HSC.z.30             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23031 HSC.z.31             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23032 HSC.z.32             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23033 HSC.z.33             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23034 HSC.z.34             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23035 HSC.z.35             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23036 HSC.z.36             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23037 HSC.z.37             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23038 HSC.z.38             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23039 HSC.z.39             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23040 HSC.z.40             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23041 HSC.z.41             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23042 HSC.z.42             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23043 HSC.z.43             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23044 HSC.z.44             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23045 HSC.z.45             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23046 HSC.z.46             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23047 HSC.z.47             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23048 HSC.z.48             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23049 HSC.z.49             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23050 HSC.z.50             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23051 HSC.z.51             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23052 HSC.z.52             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23053 HSC.z.53             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23054 HSC.z.54             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23055 HSC.z.55             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23056 HSC.z.56             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23057 HSC.z.57             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23058 HSC.z.58             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23059 HSC.z.59             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23060 HSC.z.60             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23061 HSC.z.61             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23062 HSC.z.62             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23063 HSC.z.63             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23064 HSC.z.64             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23065 HSC.z.65             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23066 HSC.z.66             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23067 HSC.z.67             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23068 HSC.z.68             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23069 HSC.z.69             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23070 HSC.z.70             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23071 HSC.z.71             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23072 HSC.z.72             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23073 HSC.z.73             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23074 HSC.z.74             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23075 HSC.z.75             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23076 HSC.z.76             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23077 HSC.z.77             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23078 HSC.z.78             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23079 HSC.z.79             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23080 HSC.z.80             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23081 HSC.z.81             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23082 HSC.z.82             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23083 HSC.z.83             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23084 HSC.z.84             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23085 HSC.z.85             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23086 HSC.z.86             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23087 HSC.z.87             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23088 HSC.z.88             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23089 HSC.z.89             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23090 HSC.z.90             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23091 HSC.z.91             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23092 HSC.z.92             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23093 HSC.z.93             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23094 HSC.z.94             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23095 HSC.z.95             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23096 HSC.z.96             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23097 HSC.z.97             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23098 HSC.z.98             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23099 HSC.z.99             dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23100 HSC.z.100            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23101 HSC.z.101            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23102 HSC.z.102            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23103 HSC.z.103            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23104 HSC.z.104            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23105 HSC.z.105            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23106 HSC.z.106            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23107 HSC.z.107            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23108 HSC.z.108            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23109 HSC.z.109            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23110 HSC.z.110            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
-  23111 HSC.z.111            dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+
+  20000 HSC.g.00             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20001 HSC.g.01             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20002 HSC.g.02             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20003 HSC.g.03             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20004 HSC.g.04             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20005 HSC.g.05             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20006 HSC.g.06             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20007 HSC.g.07             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20008 HSC.g.08             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20009 HSC.g.09             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20010 HSC.g.10             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20011 HSC.g.11             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20012 HSC.g.12             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20013 HSC.g.13             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20014 HSC.g.14             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20015 HSC.g.15             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20016 HSC.g.16             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20017 HSC.g.17             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20018 HSC.g.18             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20019 HSC.g.19             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20020 HSC.g.20             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20021 HSC.g.21             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20022 HSC.g.22             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20023 HSC.g.23             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20024 HSC.g.24             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20025 HSC.g.25             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20026 HSC.g.26             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20027 HSC.g.27             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20028 HSC.g.28             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20029 HSC.g.29             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20030 HSC.g.30             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20031 HSC.g.31             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20032 HSC.g.32             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20033 HSC.g.33             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20034 HSC.g.34             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20035 HSC.g.35             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20036 HSC.g.36             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20037 HSC.g.37             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20038 HSC.g.38             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20039 HSC.g.39             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20040 HSC.g.40             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20041 HSC.g.41             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20042 HSC.g.42             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20043 HSC.g.43             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20044 HSC.g.44             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20045 HSC.g.45             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20046 HSC.g.46             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20047 HSC.g.47             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20048 HSC.g.48             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20049 HSC.g.49             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20050 HSC.g.50             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20051 HSC.g.51             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20052 HSC.g.52             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20053 HSC.g.53             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20054 HSC.g.54             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20055 HSC.g.55             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20056 HSC.g.56             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20057 HSC.g.57             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20058 HSC.g.58             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20059 HSC.g.59             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20060 HSC.g.60             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20061 HSC.g.61             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20062 HSC.g.62             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20063 HSC.g.63             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20064 HSC.g.64             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20065 HSC.g.65             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20066 HSC.g.66             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20067 HSC.g.67             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20068 HSC.g.68             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20069 HSC.g.69             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20070 HSC.g.70             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20071 HSC.g.71             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20072 HSC.g.72             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20073 HSC.g.73             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20074 HSC.g.74             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20075 HSC.g.75             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20076 HSC.g.76             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20077 HSC.g.77             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20078 HSC.g.78             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20079 HSC.g.79             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20080 HSC.g.80             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20081 HSC.g.81             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20082 HSC.g.82             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20083 HSC.g.83             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20084 HSC.g.84             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20085 HSC.g.85             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20086 HSC.g.86             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20087 HSC.g.87             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20088 HSC.g.88             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20089 HSC.g.89             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20090 HSC.g.90             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20091 HSC.g.91             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20092 HSC.g.92             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20093 HSC.g.93             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20094 HSC.g.94             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20095 HSC.g.95             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20096 HSC.g.96             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20097 HSC.g.97             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20098 HSC.g.98             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20099 HSC.g.99             dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20100 HSC.g.100            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20101 HSC.g.101            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20102 HSC.g.102            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20103 HSC.g.103            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20104 HSC.g.104            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20105 HSC.g.105            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20106 HSC.g.106            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20107 HSC.g.107            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20108 HSC.g.108            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20109 HSC.g.109            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20110 HSC.g.110            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  20111 HSC.g.111            dep  26.750 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21000 HSC.r.00             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21001 HSC.r.01             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21002 HSC.r.02             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21003 HSC.r.03             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21004 HSC.r.04             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21005 HSC.r.05             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21006 HSC.r.06             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21007 HSC.r.07             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21008 HSC.r.08             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21009 HSC.r.09             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21010 HSC.r.10             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21011 HSC.r.11             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21012 HSC.r.12             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21013 HSC.r.13             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21014 HSC.r.14             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21015 HSC.r.15             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21016 HSC.r.16             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21017 HSC.r.17             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21018 HSC.r.18             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21019 HSC.r.19             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21020 HSC.r.20             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21021 HSC.r.21             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21022 HSC.r.22             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21023 HSC.r.23             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21024 HSC.r.24             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21025 HSC.r.25             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21026 HSC.r.26             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21027 HSC.r.27             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21028 HSC.r.28             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21029 HSC.r.29             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21030 HSC.r.30             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21031 HSC.r.31             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21032 HSC.r.32             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21033 HSC.r.33             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21034 HSC.r.34             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21035 HSC.r.35             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21036 HSC.r.36             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21037 HSC.r.37             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21038 HSC.r.38             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21039 HSC.r.39             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21040 HSC.r.40             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21041 HSC.r.41             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21042 HSC.r.42             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21043 HSC.r.43             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21044 HSC.r.44             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21045 HSC.r.45             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21046 HSC.r.46             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21047 HSC.r.47             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21048 HSC.r.48             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21049 HSC.r.49             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21050 HSC.r.50             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21051 HSC.r.51             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21052 HSC.r.52             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21053 HSC.r.53             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21054 HSC.r.54             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21055 HSC.r.55             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21056 HSC.r.56             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21057 HSC.r.57             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21058 HSC.r.58             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21059 HSC.r.59             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21060 HSC.r.60             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21061 HSC.r.61             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21062 HSC.r.62             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21063 HSC.r.63             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21064 HSC.r.64             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21065 HSC.r.65             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21066 HSC.r.66             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21067 HSC.r.67             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21068 HSC.r.68             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21069 HSC.r.69             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21070 HSC.r.70             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21071 HSC.r.71             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21072 HSC.r.72             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21073 HSC.r.73             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21074 HSC.r.74             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21075 HSC.r.75             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21076 HSC.r.76             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21077 HSC.r.77             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21078 HSC.r.78             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21079 HSC.r.79             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21080 HSC.r.80             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21081 HSC.r.81             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21082 HSC.r.82             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21083 HSC.r.83             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21084 HSC.r.84             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21085 HSC.r.85             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21086 HSC.r.86             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21087 HSC.r.87             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21088 HSC.r.88             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21089 HSC.r.89             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21090 HSC.r.90             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21091 HSC.r.91             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21092 HSC.r.92             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21093 HSC.r.93             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21094 HSC.r.94             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21095 HSC.r.95             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21096 HSC.r.96             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21097 HSC.r.97             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21098 HSC.r.98             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21099 HSC.r.99             dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21100 HSC.r.100            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21101 HSC.r.101            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21102 HSC.r.102            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21103 HSC.r.103            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21104 HSC.r.104            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21105 HSC.r.105            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21106 HSC.r.106            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21107 HSC.r.107            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21108 HSC.r.108            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21109 HSC.r.109            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21110 HSC.r.110            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  21111 HSC.r.111            dep  27.100 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22000 HSC.i.00             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22001 HSC.i.01             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22002 HSC.i.02             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22003 HSC.i.03             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22004 HSC.i.04             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22005 HSC.i.05             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22006 HSC.i.06             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22007 HSC.i.07             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22008 HSC.i.08             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22009 HSC.i.09             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22010 HSC.i.10             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22011 HSC.i.11             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22012 HSC.i.12             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22013 HSC.i.13             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22014 HSC.i.14             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22015 HSC.i.15             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22016 HSC.i.16             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22017 HSC.i.17             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22018 HSC.i.18             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22019 HSC.i.19             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22020 HSC.i.20             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22021 HSC.i.21             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22022 HSC.i.22             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22023 HSC.i.23             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22024 HSC.i.24             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22025 HSC.i.25             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22026 HSC.i.26             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22027 HSC.i.27             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22028 HSC.i.28             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22029 HSC.i.29             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22030 HSC.i.30             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22031 HSC.i.31             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22032 HSC.i.32             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22033 HSC.i.33             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22034 HSC.i.34             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22035 HSC.i.35             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22036 HSC.i.36             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22037 HSC.i.37             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22038 HSC.i.38             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22039 HSC.i.39             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22040 HSC.i.40             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22041 HSC.i.41             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22042 HSC.i.42             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22043 HSC.i.43             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22044 HSC.i.44             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22045 HSC.i.45             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22046 HSC.i.46             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22047 HSC.i.47             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22048 HSC.i.48             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22049 HSC.i.49             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22050 HSC.i.50             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22051 HSC.i.51             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22052 HSC.i.52             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22053 HSC.i.53             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22054 HSC.i.54             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22055 HSC.i.55             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22056 HSC.i.56             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22057 HSC.i.57             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22058 HSC.i.58             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22059 HSC.i.59             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22060 HSC.i.60             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22061 HSC.i.61             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22062 HSC.i.62             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22063 HSC.i.63             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22064 HSC.i.64             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22065 HSC.i.65             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22066 HSC.i.66             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22067 HSC.i.67             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22068 HSC.i.68             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22069 HSC.i.69             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22070 HSC.i.70             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22071 HSC.i.71             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22072 HSC.i.72             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22073 HSC.i.73             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22074 HSC.i.74             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22075 HSC.i.75             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22076 HSC.i.76             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22077 HSC.i.77             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22078 HSC.i.78             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22079 HSC.i.79             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22080 HSC.i.80             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22081 HSC.i.81             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22082 HSC.i.82             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22083 HSC.i.83             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22084 HSC.i.84             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22085 HSC.i.85             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22086 HSC.i.86             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22087 HSC.i.87             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22088 HSC.i.88             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22089 HSC.i.89             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22090 HSC.i.90             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22091 HSC.i.91             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22092 HSC.i.92             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22093 HSC.i.93             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22094 HSC.i.94             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22095 HSC.i.95             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22096 HSC.i.96             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22097 HSC.i.97             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22098 HSC.i.98             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22099 HSC.i.99             dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22100 HSC.i.100            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22101 HSC.i.101            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22102 HSC.i.102            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22103 HSC.i.103            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22104 HSC.i.104            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22105 HSC.i.105            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22106 HSC.i.106            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22107 HSC.i.107            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22108 HSC.i.108            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22109 HSC.i.109            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22110 HSC.i.110            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  22111 HSC.i.111            dep  27.000 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23000 HSC.z.00             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23001 HSC.z.01             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23002 HSC.z.02             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23003 HSC.z.03             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23004 HSC.z.04             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23005 HSC.z.05             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23006 HSC.z.06             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23007 HSC.z.07             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23008 HSC.z.08             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23009 HSC.z.09             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23010 HSC.z.10             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23011 HSC.z.11             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23012 HSC.z.12             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23013 HSC.z.13             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23014 HSC.z.14             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23015 HSC.z.15             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23016 HSC.z.16             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23017 HSC.z.17             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23018 HSC.z.18             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23019 HSC.z.19             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23020 HSC.z.20             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23021 HSC.z.21             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23022 HSC.z.22             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23023 HSC.z.23             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23024 HSC.z.24             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23025 HSC.z.25             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23026 HSC.z.26             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23027 HSC.z.27             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23028 HSC.z.28             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23029 HSC.z.29             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23030 HSC.z.30             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23031 HSC.z.31             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23032 HSC.z.32             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23033 HSC.z.33             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23034 HSC.z.34             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23035 HSC.z.35             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23036 HSC.z.36             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23037 HSC.z.37             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23038 HSC.z.38             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23039 HSC.z.39             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23040 HSC.z.40             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23041 HSC.z.41             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23042 HSC.z.42             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23043 HSC.z.43             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23044 HSC.z.44             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23045 HSC.z.45             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23046 HSC.z.46             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23047 HSC.z.47             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23048 HSC.z.48             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23049 HSC.z.49             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23050 HSC.z.50             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23051 HSC.z.51             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23052 HSC.z.52             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23053 HSC.z.53             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23054 HSC.z.54             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23055 HSC.z.55             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23056 HSC.z.56             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23057 HSC.z.57             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23058 HSC.z.58             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23059 HSC.z.59             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23060 HSC.z.60             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23061 HSC.z.61             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23062 HSC.z.62             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23063 HSC.z.63             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23064 HSC.z.64             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23065 HSC.z.65             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23066 HSC.z.66             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23067 HSC.z.67             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23068 HSC.z.68             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23069 HSC.z.69             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23070 HSC.z.70             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23071 HSC.z.71             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23072 HSC.z.72             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23073 HSC.z.73             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23074 HSC.z.74             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23075 HSC.z.75             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23076 HSC.z.76             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23077 HSC.z.77             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23078 HSC.z.78             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23079 HSC.z.79             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23080 HSC.z.80             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23081 HSC.z.81             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23082 HSC.z.82             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23083 HSC.z.83             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23084 HSC.z.84             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23085 HSC.z.85             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23086 HSC.z.86             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23087 HSC.z.87             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23088 HSC.z.88             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23089 HSC.z.89             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23090 HSC.z.90             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23091 HSC.z.91             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23092 HSC.z.92             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23093 HSC.z.93             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23094 HSC.z.94             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23095 HSC.z.95             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23096 HSC.z.96             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23097 HSC.z.97             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23098 HSC.z.98             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23099 HSC.z.99             dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23100 HSC.z.100            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23101 HSC.z.101            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23102 HSC.z.102            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23103 HSC.z.103            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23104 HSC.z.104            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23105 HSC.z.105            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23106 HSC.z.106            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23107 HSC.z.107            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23108 HSC.z.108            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23109 HSC.z.109            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23110 HSC.z.110            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  23111 HSC.z.111            dep  26.200 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
   24000 HSC.y.00             dep  25.000  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
   24001 HSC.y.01             dep  25.000  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
@@ -1548,2 +1551,115 @@
   24110 HSC.y.110            dep  25.000  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
   24111 HSC.y.111            dep  25.000  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25000 HSC.NB921.00             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25001 HSC.NB921.01             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25002 HSC.NB921.02             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25003 HSC.NB921.03             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25004 HSC.NB921.04             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25005 HSC.NB921.05             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25006 HSC.NB921.06             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25007 HSC.NB921.07             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25008 HSC.NB921.08             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25009 HSC.NB921.09             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25010 HSC.NB921.10             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25011 HSC.NB921.11             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25012 HSC.NB921.12             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25013 HSC.NB921.13             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25014 HSC.NB921.14             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25015 HSC.NB921.15             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25016 HSC.NB921.16             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25017 HSC.NB921.17             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25018 HSC.NB921.18             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25019 HSC.NB921.19             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25020 HSC.NB921.20             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25021 HSC.NB921.21             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25022 HSC.NB921.22             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25023 HSC.NB921.23             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25024 HSC.NB921.24             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25025 HSC.NB921.25             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25026 HSC.NB921.26             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25027 HSC.NB921.27             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25028 HSC.NB921.28             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25029 HSC.NB921.29             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25030 HSC.NB921.30             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25031 HSC.NB921.31             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25032 HSC.NB921.32             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25033 HSC.NB921.33             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25034 HSC.NB921.34             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25035 HSC.NB921.35             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25036 HSC.NB921.36             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25037 HSC.NB921.37             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25038 HSC.NB921.38             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25039 HSC.NB921.39             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25040 HSC.NB921.40             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25041 HSC.NB921.41             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25042 HSC.NB921.42             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25043 HSC.NB921.43             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25044 HSC.NB921.44             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25045 HSC.NB921.45             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25046 HSC.NB921.46             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25047 HSC.NB921.47             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25048 HSC.NB921.48             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25049 HSC.NB921.49             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25050 HSC.NB921.50             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25051 HSC.NB921.51             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25052 HSC.NB921.52             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25053 HSC.NB921.53             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25054 HSC.NB921.54             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25055 HSC.NB921.55             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25056 HSC.NB921.56             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25057 HSC.NB921.57             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25058 HSC.NB921.58             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25059 HSC.NB921.59             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25060 HSC.NB921.60             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25061 HSC.NB921.61             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25062 HSC.NB921.62             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25063 HSC.NB921.63             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25064 HSC.NB921.64             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25065 HSC.NB921.65             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25066 HSC.NB921.66             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25067 HSC.NB921.67             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25068 HSC.NB921.68             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25069 HSC.NB921.69             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25070 HSC.NB921.70             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25071 HSC.NB921.71             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25072 HSC.NB921.72             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25073 HSC.NB921.73             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25074 HSC.NB921.74             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25075 HSC.NB921.75             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25076 HSC.NB921.76             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25077 HSC.NB921.77             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25078 HSC.NB921.78             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25079 HSC.NB921.79             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25080 HSC.NB921.80             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25081 HSC.NB921.81             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25082 HSC.NB921.82             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25083 HSC.NB921.83             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25084 HSC.NB921.84             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25085 HSC.NB921.85             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25086 HSC.NB921.86             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25087 HSC.NB921.87             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25088 HSC.NB921.88             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25089 HSC.NB921.89             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25090 HSC.NB921.90             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25091 HSC.NB921.91             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25092 HSC.NB921.92             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25093 HSC.NB921.93             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25094 HSC.NB921.94             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25095 HSC.NB921.95             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25096 HSC.NB921.96             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25097 HSC.NB921.97             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25098 HSC.NB921.98             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25099 HSC.NB921.99             dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25100 HSC.NB921.100            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25101 HSC.NB921.101            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25102 HSC.NB921.102            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25103 HSC.NB921.103            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25104 HSC.NB921.104            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25105 HSC.NB921.105            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25106 HSC.NB921.106            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25107 HSC.NB921.107            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25108 HSC.NB921.108            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25109 HSC.NB921.109            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25110 HSC.NB921.110            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+  25111 HSC.NB921.111            dep  25.000  0.000 0.000     -     - 0.0000     0     -   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000
+
Index: trunk/ippconfig/hsc/Makefile.am
===================================================================
--- trunk/ippconfig/hsc/Makefile.am	(revision 39907)
+++ trunk/ippconfig/hsc/Makefile.am	(revision 39926)
@@ -7,8 +7,10 @@
 	format_raw.config \
 	format_mef.config \
+	format_cmf.config \
 	ppImage.config \
 	ppMerge.config \
 	psastro.config \
-	ppStats.config
+	ppStats.config \
+	ppStack.config
 
 install_DATA = $(install_files)
Index: trunk/ippconfig/hsc/camera.config
===================================================================
--- trunk/ippconfig/hsc/camera.config	(revision 39907)
+++ trunk/ippconfig/hsc/camera.config	(revision 39926)
@@ -5,4 +5,5 @@
         MEF     STR     hsc/format_mef.config  # for output cmfs from, e.g., camera
         RAW     STR     hsc/format_raw.config
+        CMF     STR     hsc/format_cmf.config  # chip output cmfs
 #       SPLIT   STR     hsc/format_split.config
 END
@@ -139,4 +140,5 @@
    z        STR   HSC-z
    y	    STR   HSC-Y
+   NB921    STR   NB0921
 END
 
@@ -176,4 +178,5 @@
 #	PPSTACK		STR	hsc/ppStack.config          # ppStack recipe
         PPSTATS         STR     hsc/ppStats.config
+	PPSTACK         STR     hsc/ppStack.config
 END
 
Index: trunk/ippconfig/hsc/dvo.config
===================================================================
--- trunk/ippconfig/hsc/dvo.config	(revision 39907)
+++ trunk/ippconfig/hsc/dvo.config	(revision 39926)
@@ -1,4 +1,3 @@
 
-# location of DVO database tables
 MOSAICNAME              HSC
 
@@ -15,8 +14,8 @@
 EXPTIME-KEYWORD		EXPTIME
 AIRMASS-KEYWORD		AIRMASS
-CCDNUM-KEYWORD		T_CCDSN
+CCDNUM-KEYWORD		EXTNAME
 ST-KEYWORD		NONE
-OBSERVATORY-LATITUDE	19.825555556
-OBSERVATORY-LONGITUDE	10.365074074
+OBSERVATORY-LATITUDE	19.825391
+OBSERVATORY-LONGITUDE	10.3650651
 
 SUBPIX_DATAFILE		NONE
Index: trunk/ippconfig/hsc/format_cmf.config
===================================================================
--- trunk/ippconfig/hsc/format_cmf.config	(revision 39926)
+++ trunk/ippconfig/hsc/format_cmf.config	(revision 39926)
@@ -0,0 +1,740 @@
+# The split MecaCam data is stored as single files for each chip, each a simple fits image
+
+# How to recognise this type
+RULE	METADATA
+	TELESCOP	STR	Subaru
+	INSTRUME	STR	Hyper Suprime-Cam
+ 	NAXIS           S32     0 # with 2 this is an image (with 0, this is an output smf)
+END
+
+FILE	METADATA
+	# How to read this data
+	PHU		STR	CHIP	# The FITS file represents an entire FPA
+	EXTENSIONS	STR	NONE	# The extensions represent chips
+	FPA.OBS		STR	EXP-ID	# A PHU keyword for unique identifier
+	CONTENT		STR	DET-ID	# Key to the CONTENTS menu (use DET-ID or T_CCDSN?)
+	CONTENT.RULE	STR	{CHIP.ID} # How to derive the CONTENT when writing
+END
+
+# What's in the FITS file?
+CONTENTS	METADATA
+    # Content name, chipType
+      0 STR      x000:S10892
+      1 STR      x001:S10892
+      2 STR      x002:S10892
+      3 STR      x003:S10892
+      4 STR      x004:S10892
+      5 STR      x005:S10892
+      6 STR      x006:S10892
+      7 STR      x007:S10892
+      8 STR      x008:S10892
+      9 STR      x009:S10892
+     10 STR      x010:S10892
+     11 STR      x011:S10892
+     12 STR      x012:S10892
+     13 STR      x013:S10892
+     14 STR      x014:S10892
+     15 STR      x015:S10892
+     16 STR      x016:S10892
+     17 STR      x017:S10892
+     18 STR      x018:S10892
+     19 STR      x019:S10892
+     20 STR      x020:S10892
+     21 STR      x021:S10892
+     22 STR      x022:S10892
+     23 STR      x023:S10892
+     24 STR      x024:S10892
+     25 STR      x025:S10892
+     26 STR      x026:S10892
+     27 STR      x027:S10892
+     28 STR      x028:S10892
+     29 STR      x029:S10892
+     30 STR      x030:S10892
+     31 STR      x031:S10892
+     32 STR      x032:S10892
+     33 STR      x033:S10892
+     34 STR      x034:S10892
+     35 STR      x035:S10892
+     36 STR      x036:S10892
+     37 STR      x037:S10892
+     38 STR      x038:S10892
+     39 STR      x039:S10892
+     40 STR      x040:S10892
+     41 STR      x041:S10892
+     42 STR      x042:S10892
+     43 STR      x043:S10892
+     44 STR      x044:S10892
+     45 STR      x045:S10892
+     46 STR      x046:S10892
+     47 STR      x047:S10892
+     48 STR      x048:S10892
+     49 STR      x049:S10892
+     50 STR      x050:S10892
+     51 STR      x051:S10892
+     52 STR      x052:S10892
+     53 STR      x053:S10892
+     54 STR      x054:S10892
+     55 STR      x055:S10892
+     56 STR      x056:S10892
+     57 STR      x057:S10892
+     58 STR      x058:S10892
+     59 STR      x059:S10892
+     60 STR      x060:S10892
+     61 STR      x061:S10892
+     62 STR      x062:S10892
+     63 STR      x063:S10892
+     64 STR      x064:S10892
+     65 STR      x065:S10892
+     66 STR      x066:S10892
+     67 STR      x067:S10892
+     68 STR      x068:S10892
+     69 STR      x069:S10892
+     70 STR      x070:S10892
+     71 STR      x071:S10892
+     72 STR      x072:S10892
+     73 STR      x073:S10892
+     74 STR      x074:S10892
+     75 STR      x075:S10892
+     76 STR      x076:S10892
+     77 STR      x077:S10892
+     78 STR      x078:S10892
+     79 STR      x079:S10892
+     80 STR      x080:S10892
+     81 STR      x081:S10892
+     82 STR      x082:S10892
+     83 STR      x083:S10892
+     84 STR      x084:S10892
+     85 STR      x085:S10892
+     86 STR      x086:S10892
+     87 STR      x087:S10892
+     88 STR      x088:S10892
+     89 STR      x089:S10892
+     90 STR      x090:S10892
+     91 STR      x091:S10892
+     92 STR      x092:S10892
+     93 STR      x093:S10892
+     94 STR      x094:S10892
+     95 STR      x095:S10892
+     96 STR      x096:S10892
+     97 STR      x097:S10892
+     98 STR      x098:S10892
+     99 STR      x099:S10892
+    100 STR      x100:S10892
+    101 STR      x101:S10892
+    102 STR      x102:S10892
+    103 STR      x103:S10892
+    104 STR      x104:S10892
+    105 STR      x105:S10892
+    106 STR      x106:S10892
+    107 STR      x107:S10892
+    108 STR      x108:S10892
+    109 STR      x109:S10892
+    110 STR      x110:S10892
+    111 STR      x111:S10892
+END
+
+# Specify the chips
+CHIPS		METADATA
+	# Chip type, cellName:cellType
+	S10892	STR	CH1:channel_1 CH2:channel_2 CH3:channel_3 CH4:channel_4
+END
+
+
+# Specify the cells
+CELLS		METADATA
+	# Cell type, concepts for this type
+	channel_1	METADATA
+		CELL.BIASSEC.SOURCE	STR	VALUE
+		CELL.TRIMSEC.SOURCE	STR	VALUE
+		CELL.BIASSEC		STR	[521:536,50:4225]
+		CELL.TRIMSEC		STR	[9:520,50:4225]
+		CELL.GAIN.SOURCE	STR	HEADER
+		CELL.GAIN		STR	T_GAIN1
+		CELL.X0			S32	0
+		CELL.Y0			S32	0
+	END
+	channel_2	METADATA
+		CELL.BIASSEC.SOURCE	STR	VALUE
+		CELL.TRIMSEC.SOURCE	STR	VALUE
+		CELL.BIASSEC		STR	[537:552,50:4225]
+		CELL.TRIMSEC		STR	[553:1064,50:4225]
+		CELL.GAIN.SOURCE	STR	HEADER
+		CELL.GAIN		STR	T_GAIN2
+		CELL.X0			S32	512
+		CELL.Y0			S32	0
+	END
+	channel_3	METADATA
+		CELL.BIASSEC.SOURCE	STR	VALUE
+		CELL.TRIMSEC.SOURCE	STR	VALUE
+		CELL.BIASSEC		STR	[1593:1608,50:4225]
+		CELL.TRIMSEC		STR	[1081:1592,50:4225]
+		CELL.GAIN.SOURCE	STR	HEADER
+		CELL.GAIN		STR	T_GAIN3
+		CELL.X0			S32	1024
+		CELL.Y0			S32	0
+	END
+	channel_4	METADATA
+		CELL.BIASSEC.SOURCE	STR	VALUE
+		CELL.TRIMSEC.SOURCE	STR	VALUE
+		CELL.BIASSEC		STR	[1609:1624,50:4225]
+		CELL.TRIMSEC		STR	[1625:2136,50:4225]
+		CELL.GAIN.SOURCE	STR	HEADER
+		CELL.GAIN		STR	T_GAIN4
+		CELL.X0			S32	1536
+		CELL.Y0			S32	0
+	END
+END
+
+# How to translate PS concepts into FITS headers
+TRANSLATION	METADATA
+        FPA.OBS         STR     EXP-ID
+        FPA.AIRMASS     STR     AIRMASS
+        FPA.FILTER      STR     FILTER01
+        FPA.FILTERID    STR     FILTER01
+#       FPA.POSANGLE    STR     INR-STR
+        FPA.POSANGLE    STR     INST-PA
+        FPA.RA          STR     RA
+        FPA.DEC         STR     DEC
+        FPA.RADECSYS    STR     RADESYS
+	FPA.OBSTYPE	STR	DATA-TYP
+	FPA.OBJECT	STR	OBJECT
+        FPA.OBS.MODE    STR     OBS-MOD
+#       FPA.COMMENT     STR     CMMTOBS
+	FPA.FOCUS	STR	FOC-VAL
+	FPA.TIME	STR	MJD-STR
+	FPA.TIMESYS	STR	TIMESYS
+	FPA.ALT		STR	ALTITUDE
+	FPA.AZ		STR	AZIMUTH
+	FPA.TEMP	STR	DET-TMP
+	FPA.EXPOSURE	STR	EXPTIME
+        FPA.M2X         STR     M2-POS1
+        FPA.M2Y         STR     M2-POS2
+        FPA.M2Z         STR     M2-POS3
+        FPA.M2TIP       STR     M2-ANG1
+        FPA.M2TILT      STR     M2-ANG2
+        FPA.ENV.TEMP    STR     OUT-TMP
+        FPA.ENV.HUMID   STR     OUT-HUM
+        FPA.ENV.WIND    STR     OUT-WND
+#       FPA.ENV.DIR     STR     OUT-TMP
+        FPA.TELTEMP.TRUSS  STR  DOM-TMP # Mid truss temperatures (C
+
+	CHIP.TEMP	STR	DET-TMP
+	CHIP.ID		STR	DET-ID
+        CELL.EXPOSURE   STR     EXPTIME
+        CELL.DARKTIME   STR     EXPTIME
+	CELL.TIME	STR	MJD-STR
+	CELL.TIMESYS	STR	TIMESYS
+        CELL.XBIN       STR     BIN-FCT1
+        CELL.YBIN       STR     BIN-FCT2
+END
+
+# Default PS concepts that may be specified by value
+DEFAULTS        METADATA
+	FPA.TELESCOPE		STR	SUBARU
+	FPA.INSTRUMENT		STR	HYPERSUPRIME
+	FPA.DETECTOR	        STR	HSC
+        FPA.LONGITUDE   	STR     10:25:01.417 # XXX haleakla
+        FPA.LATITUDE    	STR     20:42:25.558 # XXX haleakla
+        FPA.ELEVATION   	F32     3048.0       # altitude in meters
+#	FPA.TIMESYS	        STR	TAI
+	CHIP.XSIZE		S32	2048
+	CHIP.YSIZE		S32	4096
+	CELL.XSIZE		S32	512
+	CELL.YSIZE		S32	4176		# XXX: or 4096?
+	CELL.XWINDOW		S32	0
+	CELL.YWINDOW		S32	0
+        CELL.SATURATION         S32     60000
+	CELL.READDIR		S32	1		# Cell is read in x direction
+        CELL.READNOISE          F32     1.0		# XXX: set based on bias stats
+        CELL.BAD                F32     0
+	CELL.XPARITY		S32	1		# XXX may need to flip some of the cells
+	CELL.YPARITY		S32	1
+#	CELL.X0			S32	0
+#	CELL.Y0			S32	0
+#	CELL.TIMESYS	        STR	TAI
+	CHIP.XPARITY		S32	1		# XXX may need to flip some of the cells
+	CHIP.YPARITY		S32	1
+	CHIP.X0.DEPEND		STR	CHIP.NAME
+	CHIP.X0		METADATA
+          x000 S32  4165
+          x001 S32  4165
+          x002 S32  4165
+          x003 S32  4165
+          x004 S32  6288
+          x005 S32  6288
+          x006 S32  6288
+          x007 S32  6288
+          x008 S32  6288
+          x009 S32  6288
+          x010 S32  8411
+          x011 S32  8411
+          x012 S32  8411
+          x013 S32  8411
+          x014 S32  8411
+          x015 S32  8411
+          x016 S32  8484
+          x017 S32  8484
+          x018 S32  8484
+          x019 S32 10533
+          x020 S32 10533
+          x021 S32 10533
+          x022 S32 10607
+          x023 S32 10607
+          x024 S32 10607
+          x025 S32 10607
+          x026 S32 12656
+          x027 S32 12656
+          x028 S32 12656
+          x029 S32 12656
+          x030 S32 12730
+          x031 S32 12730
+          x032 S32 12730
+          x033 S32 12730
+          x034 S32 14779
+          x035 S32 14779
+          x036 S32 14779
+          x037 S32 14779
+          x038 S32 14852
+          x039 S32 14852
+          x040 S32 14852
+          x041 S32 14852
+          x042 S32 16901
+          x043 S32 16901
+          x044 S32 16901
+          x045 S32 16901
+          x046 S32 16975
+          x047 S32 16975
+          x048 S32 16975
+          x049 S32 16975
+          x050 S32 19024
+          x051 S32 19024
+          x052 S32 19024
+          x053 S32 19024
+          x054 S32 19098
+          x055 S32 19098
+          x056 S32 19098
+          x057 S32 19098
+          x058 S32 21147
+          x059 S32 21147
+          x060 S32 21147
+          x061 S32 21147
+          x062 S32 21220
+          x063 S32 21220
+          x064 S32 21220
+          x065 S32 21220
+          x066 S32 23269
+          x067 S32 23269
+          x068 S32 23269
+          x069 S32 23269
+          x070 S32 23343
+          x071 S32 23343
+          x072 S32 23343
+          x073 S32 23343
+          x074 S32 25392
+          x075 S32 25392
+          x076 S32 25392
+          x077 S32 25392
+          x078 S32 25466
+          x079 S32 25466
+          x080 S32 25466
+          x081 S32 27515
+          x082 S32 27515
+          x083 S32 27515
+          x084 S32 27588
+          x085 S32 27588
+          x086 S32 27588
+          x087 S32 27588
+          x088 S32 27588
+          x089 S32 27588
+          x090 S32 29711
+          x091 S32 29711
+          x092 S32 29711
+          x093 S32 29711
+          x094 S32 29711
+          x095 S32 29711
+          x096 S32 31834
+          x097 S32 31834
+          x098 S32 31834
+          x099 S32 31834
+          x100 S32  8484
+          x101 S32 10533
+          x102 S32 25466 # was 33357
+          x103 S32 27515 # was 4424
+          x104 S32  2043
+          x105 S32  2043
+          x106 S32  4165
+          x107 S32  4165
+          x108 S32 31834
+          x109 S32 31834
+          x110 S32 33956
+          x111 S32 33956
+	END
+	CHIP.Y0.DEPEND		STR	CHIP.NAME
+	CHIP.Y0		METADATA
+          x000 S32 13457
+          x001 S32 17926
+          x002 S32 22395
+          x003 S32 26863
+          x004 S32  8989
+          x005 S32 13457
+          x006 S32 17926
+          x007 S32 22395
+          x008 S32 26863
+          x009 S32 31332
+          x010 S32  8989
+          x011 S32 13457
+          x012 S32 17926
+          x013 S32 22395
+          x014 S32 26863
+          x015 S32 31332
+          x016 S32  4934
+          x017 S32  9402
+          x018 S32 13871
+          x019 S32 22395
+          x020 S32 26863
+          x021 S32 31332
+          x022 S32   465
+          x023 S32  4934
+          x024 S32  9402
+          x025 S32 13871
+          x026 S32 22395
+          x027 S32 26863
+          x028 S32 31332
+          x029 S32 35801
+          x030 S32   465
+          x031 S32  4934
+          x032 S32  9402
+          x033 S32 13871
+          x034 S32 22395
+          x035 S32 26863
+          x036 S32 31332
+          x037 S32 35801
+          x038 S32   465
+          x039 S32  4934
+          x040 S32  9402
+          x041 S32 13871
+          x042 S32 22395
+          x043 S32 26863
+          x044 S32 31332
+          x045 S32 35801
+          x046 S32   465
+          x047 S32  4934
+          x048 S32  9402
+          x049 S32 13871
+          x050 S32 22395
+          x051 S32 26863
+          x052 S32 31332
+          x053 S32 35801
+          x054 S32   465
+          x055 S32  4934
+          x056 S32  9402
+          x057 S32 13871
+          x058 S32 22395
+          x059 S32 26863
+          x060 S32 31332
+          x061 S32 35801
+          x062 S32   465
+          x063 S32  4934
+          x064 S32  9402
+          x065 S32 13871
+          x066 S32 22395
+          x067 S32 26863
+          x068 S32 31332
+          x069 S32 35801
+          x070 S32   465
+          x071 S32  4934
+          x072 S32  9402
+          x073 S32 13871
+          x074 S32 22395
+          x075 S32 26863
+          x076 S32 31332
+          x077 S32 35801
+          x078 S32  4934
+          x079 S32  9402
+          x080 S32 13871
+          x081 S32 22395
+          x082 S32 26863
+          x083 S32 31332
+          x084 S32  4934
+          x085 S32  9402
+          x086 S32 13871
+          x087 S32 18340
+          x088 S32 22808
+          x089 S32 27277
+          x090 S32  4934
+          x091 S32  9402
+          x092 S32 13871
+          x093 S32 18340
+          x094 S32 22808
+          x095 S32 27277
+          x096 S32  9402
+          x097 S32 13871
+          x098 S32 18340
+          x099 S32 22808
+          x100 S32   465 # was 4934 (rotated, false location)
+          x101 S32 35801 # was 31332
+          x102 S32   465 # was 29691 (rotated, false location)
+          x103 S32 35801 # was 29691
+          x104 S32 13457
+          x105 S32 26863
+          x106 S32  8989
+          x107 S32 31332
+          x108 S32  4934
+          x109 S32 27277
+          x110 S32  9402
+          x111 S32 22808
+	END
+	CHIP.XPARITY.DEPEND	STR	CHIP.NAME
+	CHIP.XPARITY	METADATA
+          x000 S32 -1
+          x001 S32 -1
+          x002 S32 -1
+          x003 S32 -1
+          x004 S32 -1
+          x005 S32 -1
+          x006 S32 -1
+          x007 S32 -1
+          x008 S32 -1
+          x009 S32 -1
+          x010 S32 -1
+          x011 S32 -1
+          x012 S32 -1
+          x013 S32 -1
+          x014 S32 -1
+          x015 S32 -1
+          x016 S32 +1
+          x017 S32 +1
+          x018 S32 +1
+          x019 S32 -1
+          x020 S32 -1
+          x021 S32 -1
+          x022 S32 +1
+          x023 S32 +1
+          x024 S32 +1
+          x025 S32 +1
+          x026 S32 -1
+          x027 S32 -1
+          x028 S32 -1
+          x029 S32 -1
+          x030 S32 +1
+          x031 S32 +1
+          x032 S32 +1
+          x033 S32 +1
+          x034 S32 -1
+          x035 S32 -1
+          x036 S32 -1
+          x037 S32 -1
+          x038 S32 +1
+          x039 S32 +1
+          x040 S32 +1
+          x041 S32 +1
+          x042 S32 -1
+          x043 S32 -1
+          x044 S32 -1
+          x045 S32 -1
+          x046 S32 +1
+          x047 S32 +1
+          x048 S32 +1
+          x049 S32 +1
+          x050 S32 -1
+          x051 S32 -1
+          x052 S32 -1
+          x053 S32 -1
+          x054 S32 +1
+          x055 S32 +1
+          x056 S32 +1
+          x057 S32 +1
+          x058 S32 -1
+          x059 S32 -1
+          x060 S32 -1
+          x061 S32 -1
+          x062 S32 +1
+          x063 S32 +1
+          x064 S32 +1
+          x065 S32 +1
+          x066 S32 -1
+          x067 S32 -1
+          x068 S32 -1
+          x069 S32 -1
+          x070 S32 +1
+          x071 S32 +1
+          x072 S32 +1
+          x073 S32 +1
+          x074 S32 -1
+          x075 S32 -1
+          x076 S32 -1
+          x077 S32 -1
+          x078 S32 +1
+          x079 S32 +1
+          x080 S32 +1
+          x081 S32 -1
+          x082 S32 -1
+          x083 S32 -1
+          x084 S32 +1
+          x085 S32 +1
+          x086 S32 +1
+          x087 S32 +1
+          x088 S32 +1
+          x089 S32 +1
+          x090 S32 +1
+          x091 S32 +1
+          x092 S32 +1
+          x093 S32 +1
+          x094 S32 +1
+          x095 S32 +1
+          x096 S32 +1
+          x097 S32 +1
+          x098 S32 +1
+          x099 S32 +1
+          x100 S32 +1
+          x101 S32 -1
+          x102 S32 +1
+          x103 S32 -1
+          x104 S32 -1
+          x105 S32 -1
+          x106 S32 -1
+          x107 S32 -1
+          x108 S32 +1
+          x109 S32 +1
+          x110 S32 +1
+          x111 S32 +1
+	END
+	CHIP.YPARITY.DEPEND	STR	CHIP.NAME
+	CHIP.YPARITY	METADATA
+          x000 S32 -1
+          x001 S32 -1
+          x002 S32 -1
+          x003 S32 -1
+          x004 S32 -1
+          x005 S32 -1
+          x006 S32 -1
+          x007 S32 -1
+          x008 S32 -1
+          x009 S32 -1
+          x010 S32 -1
+          x011 S32 -1
+          x012 S32 -1
+          x013 S32 -1
+          x014 S32 -1
+          x015 S32 -1
+          x016 S32 +1
+          x017 S32 +1
+          x018 S32 +1
+          x019 S32 -1
+          x020 S32 -1
+          x021 S32 -1
+          x022 S32 +1
+          x023 S32 +1
+          x024 S32 +1
+          x025 S32 +1
+          x026 S32 -1
+          x027 S32 -1
+          x028 S32 -1
+          x029 S32 -1
+          x030 S32 +1
+          x031 S32 +1
+          x032 S32 +1
+          x033 S32 +1
+          x034 S32 -1
+          x035 S32 -1
+          x036 S32 -1
+          x037 S32 -1
+          x038 S32 +1
+          x039 S32 +1
+          x040 S32 +1
+          x041 S32 +1
+          x042 S32 -1
+          x043 S32 -1
+          x044 S32 -1
+          x045 S32 -1
+          x046 S32 +1
+          x047 S32 +1
+          x048 S32 +1
+          x049 S32 +1
+          x050 S32 -1
+          x051 S32 -1
+          x052 S32 -1
+          x053 S32 -1
+          x054 S32 +1
+          x055 S32 +1
+          x056 S32 +1
+          x057 S32 +1
+          x058 S32 -1
+          x059 S32 -1
+          x060 S32 -1
+          x061 S32 -1
+          x062 S32 +1
+          x063 S32 +1
+          x064 S32 +1
+          x065 S32 +1
+          x066 S32 -1
+          x067 S32 -1
+          x068 S32 -1
+          x069 S32 -1
+          x070 S32 +1
+          x071 S32 +1
+          x072 S32 +1
+          x073 S32 +1
+          x074 S32 -1
+          x075 S32 -1
+          x076 S32 -1
+          x077 S32 -1
+          x078 S32 +1
+          x079 S32 +1
+          x080 S32 +1
+          x081 S32 -1
+          x082 S32 -1
+          x083 S32 -1
+          x084 S32 +1
+          x085 S32 +1
+          x086 S32 +1
+          x087 S32 +1
+          x088 S32 +1
+          x089 S32 +1
+          x090 S32 +1
+          x091 S32 +1
+          x092 S32 +1
+          x093 S32 +1
+          x094 S32 +1
+          x095 S32 +1
+          x096 S32 +1
+          x097 S32 +1
+          x098 S32 +1
+          x099 S32 +1
+          x100 S32 +1
+          x101 S32 -1
+          x102 S32 +1
+          x103 S32 -1
+          x104 S32 -1
+          x105 S32 -1
+          x106 S32 -1
+          x107 S32 -1
+          x108 S32 +1
+          x109 S32 +1
+          x110 S32 +1
+          x111 S32 +1
+	END
+END
+
+
+# How to translation PS concepts into database lookups
+DATABASE	METADATA
+	TYPE		dbEntry		TABLE		COLUMN		GIVENDBCOL	GIVENPS
+#	CELL.GAIN	dbEntry		Camera		gain		chipId,cellId	CHIP.NAME,CELL.NAME
+#	CELL.READNOISE	dbEntry		Camera		readNoise	chipId,cellId	CHIP.NAME,CELL.NAME
+
+# A database entry refers to a particular column (COLUMN) in a
+# particular table (TABLE), given certain PS concepts (GIVENPS) that
+# match certain database columns (GIVENDBCOL).
+END		
+
+# Where there might be some ambiguity, specify the format
+FORMATS		METADATA
+	FPA.RA		STR	HOURS
+	FPA.DEC		STR	DEGREES
+	FPA.TIME	STR	MJD
+	CELL.TIME	STR	MJD
+	FPA.LONGITUDE	STR	HOURS
+	FPA.LATITUDE	STR	DEGREES
+END
+ 
Index: trunk/ippconfig/hsc/format_mef.config
===================================================================
--- trunk/ippconfig/hsc/format_mef.config	(revision 39907)
+++ trunk/ippconfig/hsc/format_mef.config	(revision 39926)
@@ -193,6 +193,6 @@
         FPA.FILTER      STR     FILTER01
         FPA.FILTERID    STR     FILTER01
-        FPA.POSANGLE    STR     INR-STR
-#       FPA.POSANGLE    STR     INST-PA (not sure which is right)
+#       FPA.POSANGLE    STR     INR-STR -- this is equivalent to the GPC1 ROT, not POS
+        FPA.POSANGLE    STR     INST-PA
         FPA.RA          STR     RA
         FPA.DEC         STR     DEC
@@ -219,4 +219,6 @@
 #       FPA.ENV.DIR     STR     OUT-TMP
         FPA.TELTEMP.TRUSS  STR  DOM-TMP # Mid truss temperatures (C
+	FPA.ZP          STR     ZPT_OBS
+
 
 	CHIP.TEMP	STR	DET-TMP
Index: trunk/ippconfig/hsc/format_raw.config
===================================================================
--- trunk/ippconfig/hsc/format_raw.config	(revision 39907)
+++ trunk/ippconfig/hsc/format_raw.config	(revision 39926)
@@ -5,5 +5,5 @@
 	TELESCOP	STR	Subaru
 	INSTRUME	STR	Hyper Suprime-Cam
-#	NAXIS           S32     2 # with 2 this is an image (with 0, this is an output smf)
+	NAXIS           S32     2 # with 2 this is an image (with 0, this is an output smf)
 END
 
@@ -192,6 +192,6 @@
         FPA.FILTER      STR     FILTER01
         FPA.FILTERID    STR     FILTER01
-        FPA.POSANGLE    STR     INR-STR
-#       FPA.POSANGLE    STR     INST-PA (not sure which is right)
+#       FPA.POSANGLE    STR     INR-STR
+        FPA.POSANGLE    STR     INST-PA
         FPA.RA          STR     RA
         FPA.DEC         STR     DEC
Index: trunk/ippconfig/hsc/ppImage.config
===================================================================
--- trunk/ippconfig/hsc/ppImage.config	(revision 39907)
+++ trunk/ippconfig/hsc/ppImage.config	(revision 39926)
@@ -14,5 +14,12 @@
     FILTER  STR FPA.FILTERID
   END
+
+  FRINGE METADATA
+    FILTER  STR FPA.FILTERID
+  END
 END   
+
+FRINGE.FILTERS MULTI
+FRINGE.FILTERS STR HSC-Y
 
 # Standard chip processing
@@ -31,5 +38,5 @@
   FLAT               BOOL    TRUE            # Flat-field normalisation
   MASK               BOOL    TRUE            # Mask bad pixels
-  FRINGE             BOOL    FALSE           # Fringe subtraction
+  FRINGE             BOOL    TRUE            # Fringe subtraction
   BIN1.FITS          BOOL    TRUE            # Save 1st binned chip image?
   BIN2.FITS          BOOL    TRUE            # Save 2nd binned chip image?
@@ -91,4 +98,28 @@
 END
 
+# This is the processing recipe for fringes
+PPIMAGE_OBDSF       METADATA
+  BASE.FITS          BOOL    TRUE            # Save base detrended image?
+  BASE.MASK.FITS     BOOL    TRUE            # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    TRUE            # Save base detrended image?
+  CHIP.FITS          BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS     BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
+  OVERSCAN           BOOL    TRUE            # Overscan subtraction
+  NONLIN             BOOL    FALSE           # Non-linearity correction; not implemented
+  BIAS               BOOL    TRUE            # Bias subtraction
+  DARK               BOOL    FALSE           # Dark subtraction
+  SHUTTER            BOOL    FALSE           # Shutter correction
+  FLAT               BOOL    TRUE            # Flat-field normalisation
+  MASK               BOOL    TRUE            # Mask bad pixels
+  MASK.BUILD         BOOL    FALSE	     # Build internal mask?
+  FRINGE             BOOL    FALSE           # Fringe subtraction
+  PHOTOM             BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP        BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC      BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS          BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS          BOOL    TRUE            # Save 2nd binned chip image?
+END
+
 # Overscan, bias, dark, shutter, flat-field -- use FLAT_PREMASK
 PPIMAGE_FLATMASK_PROCESS      METADATA
Index: trunk/ippconfig/hsc/ppMerge.config
===================================================================
--- trunk/ippconfig/hsc/ppMerge.config	(revision 39907)
+++ trunk/ippconfig/hsc/ppMerge.config	(revision 39926)
@@ -1,2 +1,10 @@
+
+FRINGE.NUM              S32     6250     # number of fringe regions per cell
+FRINGE.SIZE             S32     5        # Half-size of fringe regions
+FRINGE.XSMOOTH          S32     3        # Number of smoothing regions per cell in x
+FRINGE.YSMOOTH          S32     3        # Number of smoothing regions per cell in y
+FRINGE.SMOOTH           BOOL    T        # Smooth the output image?
+FRINGE.SMOOTH.SIGMA     F32     2.0      # Sigma of smoothing Gaussian
+
 
 # Bias combination --- don't want min/max rejection
@@ -12,2 +20,4 @@
         STDEV           STR     ROBUST_STDEV    # Statistic to use to measure the stdev
 END
+
+
Index: trunk/ippconfig/hsc/ppStack.config
===================================================================
--- trunk/ippconfig/hsc/ppStack.config	(revision 39926)
+++ trunk/ippconfig/hsc/ppStack.config	(revision 39926)
@@ -0,0 +1,46 @@
+PSF.MODEL       STR     PS_MODEL_QGAUSS # Model for PSF generation
+BACKGROUND.MODEL BOOL   F
+
+ZP.AIRMASS      METADATA                # Airmass terms by filter
+        HSC-g       F32     0.0
+        HSC-r       F32     0.0
+	HSC-r2	    F32	    0.0
+	HSC-i	    F32	    0.0
+	HSC-i2	    F32	    0.0
+	HSC-z	    F32	    0.0
+	HSC-Y	    F32	    0.0
+	NB0921	    F32	    0.0
+END
+
+ZP.TARGET       METADATA                # Target zero point by filter
+        HSC-g       F32     30.0
+        HSC-r       F32     30.0
+	HSC-r2	    F32	    30.0
+	HSC-i	    F32	    30.0
+	HSC-i2	    F32	    30.0
+	HSC-z	    F32	    30.0
+	HSC-Y	    F32	    30.0
+	NB0921	    F32	    30.0
+END
+
+STACK_DEEP    METADATA                  # N>>20 inputs, typically MD fields
+    OUTPUT.NOCOMP           BOOL  TRUE
+    OUTPUT.LOGFLUX          BOOL  FALSE
+#    OUTPUT.REPLICATE        BOOL  TRUE
+    PSF.INPUT.MAX           F32   10.0
+    PSF.INPUT.CLIP.NSIGMA   F32   1.5
+    PSF.INPUT.THRESH        F32   5.0
+    PSF.INPUT.ASYMMETRY     F32   0.2
+END
+
+STACK_THREEPI  METADATA
+    OUTPUT.NOCOMP           BOOL  FALSE
+    OUTPUT.LOGFLUX          BOOL  TRUE
+    PSF.INPUT.MAX           F32   10.0  # input cut more restrictive now 12->10 pix, limit target PSF in convolved stacks 
+    PSF.INPUT.CLIP.NSIGMA   F32   1.5   # additional cut if majority of inputs much smaller than INPUT.MAX
+    PSF.INPUT.THRESH        F32   10.0
+    PSF.INPUT.ASYMMETRY     F32   0.2
+    PSF.TARGET.AS.MAX       BOOL  TRUE
+   MATCH.REJ        F32    4.0
+   SAFE          BOOL   F
+END
Index: trunk/ippconfig/hsc/psastro.config
===================================================================
--- trunk/ippconfig/hsc/psastro.config	(revision 39907)
+++ trunk/ippconfig/hsc/psastro.config	(revision 39926)
@@ -6,5 +6,5 @@
 DVO.GETSTAR.OUTFORMAT         STR      PS1_DEV_0
 DVO.GETSTAR.PHOTCODE          STR      i
-DVO.GETSTAR.MAX.RHO           F32      10000.0
+DVO.GETSTAR.MAX.RHO           F32      30000.0
 DVO.GETSTAR.MIN.MAG           F32      12.0
 DVO.GETSTAR.MIN.MAG.INST      F32     -15.0
@@ -13,5 +13,5 @@
 PHOTCODE.DATA METADATA
   FILTER   STR g
-  ZEROPT   F32 28.0
+  ZEROPT   F32 26.75
   PHOTCODE STR g
   GHOST_MAX_MAG                   F32 -16.5
@@ -19,5 +19,5 @@
 PHOTCODE.DATA METADATA
   FILTER   STR r
-  ZEROPT   F32 28.0
+  ZEROPT   F32 27.1
   PHOTCODE STR r
   GHOST_MAX_MAG                   F32 -20.0
@@ -25,5 +25,5 @@
 PHOTCODE.DATA METADATA
   FILTER   STR i
-  ZEROPT   F32 26.9
+  ZEROPT   F32 27.0
   PHOTCODE STR i
   GHOST_MAX_MAG                   F32 -25.0
@@ -31,23 +31,85 @@
 PHOTCODE.DATA METADATA
   FILTER   STR z
-  ZEROPT   F32 28.0
+  ZEROPT   F32 26.2
+  PHOTCODE STR z
+  GHOST_MAX_MAG                   F32 -25.0
+END
+PHOTCODE.DATA METADATA
+  FILTER   STR y
+  ZEROPT   F32 25.1
+  PHOTCODE STR y
+  GHOST_MAX_MAG                   F32 -25.0
+END
+PHOTCODE.DATA METADATA
+  FILTER   STR NB921
+  ZEROPT   F32 25.4
   PHOTCODE STR z
   GHOST_MAX_MAG                   F32 -25.0
 END
 
+
+PSASTRO.USE.MODEL            BOOL TRUE
+
+# extra field for ref stars:
+PSASTRO.PHOTOM.WINDOW.SIGMA  F32 0.0
+
+PSASTRO.GRID.MIN.ANGLE F32 -2.0 # start angle (degrees)
+PSASTRO.GRID.MAX.ANGLE F32 +2.0
+PSASTRO.GRID.DEL.ANGLE F32  1.0
+
+PSASTRO.GRID.NREF.MAX  S32   1000 # max stars accepted for fitting
+PSASTRO.GRID.NRAW.MAX  S32   1000 # max stars accepted for fitting
+
+PSASTRO.GRID.MIN.INST.MAG.RAW       F32      -14
+PSASTRO.GRID.MAX.INST.MAG.RAW       F32       -9
+
 # pmAstromMatchFit
-PSASTRO.CHIP.ORDER     S32      3  # fit order
+PSASTRO.CHIP.ORDER     S32      1  # fit order
 PSASTRO.CHIP.NITER     S32      3  # fit clipping iterations
 PSASTRO.CHIP.NSIGMA    F32      3  # fit clipping sigmas
 
 # single-chip radius match in pixels
-PSASTRO.MATCH.RADIUS.N0 F32    90
-PSASTRO.MATCH.RADIUS.N1 F32    60
-PSASTRO.MATCH.RADIUS.N2 F32    30
-PSASTRO.MATCH.RADIUS.N3 F32    20
-PSASTRO.MATCH.RADIUS.N4 F32    20
-PSASTRO.MATCH.RADIUS.N5 F32    10
-PSASTRO.MATCH.RADIUS.N6 F32    10
-PSASTRO.MATCH.RADIUS.N7 F32    5
-PSASTRO.MATCH.FIT.NITER S32    8
+PSASTRO.MATCH.RADIUS.N0 F32    30
+PSASTRO.MATCH.RADIUS.N1 F32    20
+PSASTRO.MATCH.RADIUS.N2 F32    20
+PSASTRO.MATCH.RADIUS.N3 F32    10
+PSASTRO.MATCH.RADIUS.N4 F32    10
+PSASTRO.MATCH.RADIUS.N5 F32     8 # was 5
+PSASTRO.MATCH.RADIUS.N6 F32     2
+PSASTRO.MATCH.RADIUS.N7 F32     0
+PSASTRO.MATCH.FIT.NITER S32     6 # was 7
 
+# Mosaic Astrometry options
+PSASTRO.MOSAIC.MODE         BOOL   TRUE
+
+# for iterations >= N, require a single match per reference
+PSASTRO.MOSAIC.CHIP.NITER     S32      5  # fit clipping iterations (NOTE: last iteration is NITER, not NITER - 1)
+PSASTRO.MOSAIC.CHIP.NSIGMA    F32      3  # fit clipping sigmas
+PSASTRO.MOSAIC.UNIQ.ITER      S32      3  # for iterations >= N, require a single match per reference
+
+PSASTRO.MOSAIC.MAX.ERROR.N0 F32    0.00 # max allow error for valid solution (arcsec)
+PSASTRO.MOSAIC.MAX.ERROR.N1 F32    0.00 # max allow error for valid solution (arcsec)
+PSASTRO.MOSAIC.MAX.ERROR.N2 F32    0.00 # max allow error for valid solution (arcsec)
+PSASTRO.MOSAIC.MAX.ERROR.N3 F32    0.00 # max allow error for valid solution (arcsec)
+PSASTRO.MOSAIC.MAX.ERROR.N4 F32    0.00 # max allow error for valid solution (arcsec)
+PSASTRO.MOSAIC.MAX.ERROR.N5 F32    0.30 # max allow error for valid solution (arcsec)
+
+# mosaic radius match in pixels (do these make sense?)
+PSASTRO.MOSAIC.RADIUS.N0    F32    15
+PSASTRO.MOSAIC.RADIUS.N1    F32    10
+PSASTRO.MOSAIC.RADIUS.N2    F32    10
+PSASTRO.MOSAIC.RADIUS.N3    F32    5
+PSASTRO.MOSAIC.RADIUS.N4    F32    5
+PSASTRO.MOSAIC.RADIUS.N5    F32    3
+
+PSASTRO.MOSAIC.CHIP.ORDER     S32      1  # limit chip-fit order to 1
+PSASTRO.MOSAIC.CHIP.ORDER.N0  S32      0 # fit order (-1 means use default)
+PSASTRO.MOSAIC.CHIP.ORDER.N1  S32      0 # fit order (-1 means use default)
+PSASTRO.MOSAIC.CHIP.ORDER.N2  S32      1 # fit order (-1 means use default)
+PSASTRO.MOSAIC.CHIP.ORDER.N3  S32      1 # fit order (-1 means use default)
+PSASTRO.MOSAIC.CHIP.ORDER.N4  S32      3 # fit order (-1 means use default)
+PSASTRO.MOSAIC.CHIP.ORDER.N5  S32      3 # fit order (-1 means use default)
+
+PSASTRO.MODEL.REF.CHIP        STR      x050
+PSASTRO.MODEL.REF.CHIP.ANGLE  F32      90.0
+PSASTRO.MODEL.ROT.PARITY      S32      -1
Index: trunk/ippconfig/megacam/dvo.config
===================================================================
--- trunk/ippconfig/megacam/dvo.config	(revision 39907)
+++ trunk/ippconfig/megacam/dvo.config	(revision 39926)
@@ -20,6 +20,6 @@
 CCDNUM-KEYWORD		EXTNAME
 ST-KEYWORD		NONE
-OBSERVATORY-LATITUDE	NONE
-OBSERVATORY-LONGITUDE	NONE
+OBSERVATORY-LATITUDE	19.825237
+OBSERVATORY-LONGITUDE	10.3645844667
 SUBPIX_DATAFILE		NONE
 
Index: trunk/ippconfig/megacam/psastro.config
===================================================================
--- trunk/ippconfig/megacam/psastro.config	(revision 39907)
+++ trunk/ippconfig/megacam/psastro.config	(revision 39926)
@@ -137,6 +137,8 @@
 END
 
-PSASTRO.CATDIR              STR      SYNTH.GRIZY
-DVO.GETSTAR.MAX.RHO         F32      3000.0
+PSASTRO.CATDIR              STR      PS1.REF.20140713
+# PSASTRO.CATDIR              STR      SYNTH.GRIZY
+DVO.GETSTAR.MAX.RHO         F32      30000.0
+DVO.GETSTAR.OUTFORMAT       STR      PS1_DEV_0
 DVO.GETSTAR.MIN.MAG         F32      12.0
 DVO.GETSTAR.MIN.MAG.INST    F32     -15.0
Index: trunk/ippconfig/recipes/psastro.config
===================================================================
--- trunk/ippconfig/recipes/psastro.config	(revision 39907)
+++ trunk/ippconfig/recipes/psastro.config	(revision 39926)
@@ -22,4 +22,7 @@
 # extra field for ref stars:
 PSASTRO.FIELD.PADDING  F32 0.25
+
+# extra field for ref stars:
+PSASTRO.PHOTOM.WINDOW.SIGMA  F32 0.0
 
 # pmAstromGridMatch:
@@ -233,4 +236,6 @@
 
 PSASTRO.MODEL.REF.CHIP        STR      NONE
+PSASTRO.MODEL.REF.CHIP.ANGLE  F32      0.0
+PSASTRO.MODEL.ROT.PARITY      S32      +1
 PSASTRO.MODEL.FIT.BORESITE    BOOL     FALSE
 PSASTRO.MODEL.SET.BORESITE    BOOL     FALSE
Index: trunk/ippconfig/recipes/psphot.config
===================================================================
--- trunk/ippconfig/recipes/psphot.config	(revision 39907)
+++ trunk/ippconfig/recipes/psphot.config	(revision 39926)
@@ -64,6 +64,6 @@
 FOOTPRINT_GROW_RADIUS               S32   3       	  # How much to grow bright footprints
 FOOTPRINT_GROW_RADIUS_2             S32   5       	  # How much to grow faint footprints
-FOOTPRINT_CULL_NSIGMA_DELTA         F32   4       	  # Cull peaks that aren't nsigma above coll to neighbour
-FOOTPRINT_CULL_NSIGMA_MIN           F32   1       	  # Minimum height of colls in units of skyStdev
+FOOTPRINT_CULL_NSIGMA_DELTA         F32   4       	  # Cull peaks that aren't nsigma above col to neighbour
+FOOTPRINT_CULL_NSIGMA_MIN           F32   1       	  # Minimum height of cols in units of skyStdev
 FOOTPRINT_CULL_NSIGMA_PAD           F32   0.01       	  # Fractional Padding for stdev
 FOOTPRINT_USE_UNSUBTRACTED          BOOL  TRUE            # find footprints without sources subtracted
Index: trunk/ppMerge/src/ppMergeLoop.c
===================================================================
--- trunk/ppMerge/src/ppMergeLoop.c	(revision 39907)
+++ trunk/ppMerge/src/ppMergeLoop.c	(revision 39926)
@@ -398,5 +398,5 @@
 
             psFree(fileGroups);
-            psFree(zeros);
+	    //            psFree(zeros);
 
             // XXX eventually need to keep both the shutter and the pattern, as we do with dark
Index: trunk/psLib/src/astro/psCoord.c
===================================================================
--- trunk/psLib/src/astro/psCoord.c	(revision 39907)
+++ trunk/psLib/src/astro/psCoord.c	(revision 39926)
@@ -234,4 +234,7 @@
     const psPlane* coords)
 {
+  if (!transform) {
+    fprintf (stderr, "problem\n");
+  }
     PS_ASSERT_PTR_NON_NULL(transform, NULL);
     PS_ASSERT_PTR_NON_NULL(transform->x, NULL);
@@ -305,5 +308,7 @@
 void projectionFree(psProjection *p)
 {
-    // There are no dynamically allocated items
+  if (!p) return;
+  if (!p->radial) return;
+  psFree (p->radial);
 }
 
@@ -321,4 +326,5 @@
     p->Ys = Ys;
     p->type = type;
+    p->radial = NULL;
 
     psMemSetDeallocator(p, (psFreeFunc) projectionFree);
@@ -368,4 +374,5 @@
       case PS_PROJ_ZEA:
       case PS_PROJ_ZPL:
+      case PS_PROJ_ZPN:
         class = PS_PROJECTION_CLASS_ZENITHAL;
         break;
@@ -442,4 +449,35 @@
 	    out->y = -zeta * cosPhiCT;
 	    break;
+
+	  case PS_PROJ_ZPN: {
+	    // the forward projection is:
+	    // theta = atan2(stht, ctht)
+	    // gamma = (pi/2 - theta) : theta in radians
+	    // Ro = sum (P_i gamma^i)
+	    // R  = (180/pi) Ro
+	    
+	    // Ro = (pi/180)(90 - theta)
+	    // R = (180/pi)sum (P_i R^i)
+	    
+	    // is ZPN defined for Npolyterms = 0 or 1?
+
+	    double cosTheta = hypot(sinPhiCT, cosPhiCT);
+	    double theta = atan2 (sinTheta, cosTheta);
+	    
+	    double gamma = M_PI_2 - theta;
+	    
+	    // i = 0 .. N - 1 (1 <= Npolyterms <= 21)
+	    double Ro = 0.0;
+	    for (int i = projection->radial->n - 1; i > 0; i--) {
+	      double Pi = projection->radial->data.F64[i];
+	      Ro = (Ro + Pi)*gamma;
+	    }
+	    Ro += projection->radial->data.F64[0];
+	    
+	    out->x = (cosTheta == 0.0) ? 0.0 : +Ro * sinPhiCT / cosTheta ;
+	    out->y = (cosTheta == 0.0) ? 0.0 : -Ro * cosPhiCT / cosTheta ;
+	    break;
+	  }
+
 	  default:
 	    psAbort("invalid projection");
@@ -525,4 +563,5 @@
       case PS_PROJ_ZEA:
       case PS_PROJ_ZPL:
+      case PS_PROJ_ZPN:
         class = PS_PROJECTION_CLASS_ZENITHAL;
         break;
@@ -574,9 +613,10 @@
 	  case PS_PROJ_SIN:
             // Orhtographic deprojection
+            cosTheta = R;
             sinTheta = sqrt (1 - R*R);
-            cosTheta = R;
             break;
 	  case PS_PROJ_STG:
-            psAbort("STG not defined");
+	    sinTheta = (4 - R) / (4 + R);
+	    cosTheta = sqrt (1 - sinTheta*sinTheta);
             break;
 	  case PS_PROJ_ZEA:
@@ -587,4 +627,48 @@
             cosTheta = sqrt (1 - PS_SQR(sinTheta));
             break;
+
+      case PS_PROJ_ZPN:
+
+	// the forward projection is:
+	// theta = atan2(stht, ctht)
+	// gamma = (pi/2 - theta) : theta in radians
+	// Ro = sum (P_i gamma^i)
+	// R  = (180/pi) Ro
+
+	// given R, we need to find theta:
+	// Ro = R * (pi / 180) = sum (P_i gamma^i)
+	// solve sum (P_i gamma^i) - Ro = 0 using Newton-Raphson
+
+	// use Ro to get a guess for gamma and iterate
+
+	{
+	  // find the roots of f(gamma) - R = 0
+	  // starting guess for gamma is (R - P0) / P1
+	  double gamma = (R - projection->radial->data.F64[0]) / projection->radial->data.F64[1];
+	  
+	  for (int iter = 0; iter < 5; iter++) {
+	    
+	    double Rc = 0.0; // this will hold the ander 
+	    double dR = 0.0;
+	    for (int i = projection->radial->n - 1; i > 1; i--) {
+	      double Pi = projection->radial->data.F64[i];
+	      Rc = (Rc + Pi)*gamma;
+	      dR = (dR + i*Pi)*gamma;
+	    }
+	    double P0 = projection->radial->data.F64[0];
+	    double P1 = projection->radial->data.F64[1];
+	    Rc = (Rc + P1)*gamma + P0;
+	    dR = (dR + P1);
+
+	    double gamma_new = gamma - (Rc - R) / dR;
+	    gamma = gamma_new;
+	  }
+	  
+	  double theta = M_PI_2 - gamma ;
+	  cosTheta = cos (theta);
+	  sinTheta = sin (theta);
+	  break;
+	}
+	
 	  default:
             psAbort("invalid projection");
@@ -949,4 +1033,7 @@
         myPT = psPlaneTransformAlloc(order, order);
     } else {
+      // the user has supplied a model with a specific order : fit that order
+      myPT = psMemIncrRefCounter(out); // we need to return something which can be freed
+# if (0)
         if ((out->x->nX == order) && (out->x->nY == order) &&
 	    (out->y->nX == order) && (out->y->nX == order)) {
@@ -956,4 +1043,5 @@
             myPT = psPlaneTransformAlloc(order, order);
         }
+# endif
     }
 
@@ -1183,43 +1271,23 @@
 
     switch (type) {
-      case PS_PROJ_LIN:
-        psStringAppend (&name, "%s-LIN", prefix);
-        return name;
-      case PS_PROJ_PLY:
-        psStringAppend (&name, "%s-PLY", prefix);
-        return name;
-      case PS_PROJ_WRP:
-        psStringAppend (&name, "%s-WRP", prefix);
-        return name;
-      case PS_PROJ_TAN:
-        psStringAppend (&name, "%s-TAN", prefix);
-        return name;
-      case PS_PROJ_TNX:
-        psStringAppend (&name, "%s-TNX", prefix);
-        return name;
-      case PS_PROJ_DIS:
-        psStringAppend (&name, "%s-DIS", prefix);
-        return name;
-      case PS_PROJ_SIN:
-        psStringAppend (&name, "%s-SIN", prefix);
-        return name;
-      case PS_PROJ_STG:
-        psStringAppend (&name, "%s-STG", prefix);
-        return name;
-      case PS_PROJ_AIT:
-        psStringAppend (&name, "%s-AIT", prefix);
-        return name;
-      case PS_PROJ_PAR:
-        psStringAppend (&name, "%s-PAR", prefix);
-        return name;
-      case PS_PROJ_GLS:
-        psStringAppend (&name, "%s-GLS", prefix);
-        return name;
-      case PS_PROJ_CAR:
-        psStringAppend (&name, "%s-CAR", prefix);
-        return name;
-      case PS_PROJ_MER:
-        psStringAppend (&name, "%s-MER", prefix);
-        return name;
+      case PS_PROJ_LIN: psStringAppend (&name, "%s-LIN", prefix); return name;
+      case PS_PROJ_PLY: psStringAppend (&name, "%s-PLY", prefix); return name;
+      case PS_PROJ_WRP: psStringAppend (&name, "%s-WRP", prefix); return name;
+      case PS_PROJ_TAN: psStringAppend (&name, "%s-TAN", prefix); return name;
+
+      case PS_PROJ_DIS: psStringAppend (&name, "%s-DIS", prefix); return name;
+      case PS_PROJ_SIN: psStringAppend (&name, "%s-SIN", prefix); return name;
+      case PS_PROJ_STG: psStringAppend (&name, "%s-STG", prefix); return name;
+      case PS_PROJ_TNX: psStringAppend (&name, "%s-TNX", prefix); return name;
+
+      case PS_PROJ_ZEA: psStringAppend (&name, "%s-ZEA", prefix); return name;
+      case PS_PROJ_ZPL: psStringAppend (&name, "%s-ZPL", prefix); return name;
+      case PS_PROJ_ZPN: psStringAppend (&name, "%s-ZPN", prefix); return name;
+      case PS_PROJ_AIT: psStringAppend (&name, "%s-AIT", prefix); return name;
+
+      case PS_PROJ_PAR: psStringAppend (&name, "%s-PAR", prefix); return name;
+      case PS_PROJ_GLS: psStringAppend (&name, "%s-GLS", prefix); return name;
+      case PS_PROJ_CAR: psStringAppend (&name, "%s-CAR", prefix); return name;
+      case PS_PROJ_MER: psStringAppend (&name, "%s-MER", prefix); return name;
 
       default:
@@ -1238,8 +1306,11 @@
     if (!strcmp (&name[4], "-WRP")) return PS_PROJ_WRP;
     if (!strcmp (&name[4], "-TAN")) return PS_PROJ_TAN;
-    if (!strcmp (&name[4], "-TNX")) return PS_PROJ_TNX;
     if (!strcmp (&name[4], "-DIS")) return PS_PROJ_DIS;
     if (!strcmp (&name[4], "-SIN")) return PS_PROJ_SIN;
     if (!strcmp (&name[4], "-STG")) return PS_PROJ_STG;
+    if (!strcmp (&name[4], "-TNX")) return PS_PROJ_TNX;
+    if (!strcmp (&name[4], "-ZEA")) return PS_PROJ_ZEA;
+    if (!strcmp (&name[4], "-ZPL")) return PS_PROJ_ZPL;
+    if (!strcmp (&name[4], "-ZPN")) return PS_PROJ_ZPN;
     if (!strcmp (&name[4], "-AIT")) return PS_PROJ_AIT;
     if (!strcmp (&name[4], "-PAR")) return PS_PROJ_PAR;
Index: trunk/psLib/src/astro/psCoord.h
===================================================================
--- trunk/psLib/src/astro/psCoord.h	(revision 39907)
+++ trunk/psLib/src/astro/psCoord.h	(revision 39926)
@@ -130,4 +130,5 @@
     PS_PROJ_ZEA,                        ///< Sine projection
     PS_PROJ_ZPL,                        ///< Sine projection
+    PS_PROJ_ZPN,                        ///< Sine projection
     PS_PROJ_AIT,                        ///< Aitoff projection
     PS_PROJ_PAR,                        ///< Par projection
@@ -150,6 +151,6 @@
     double Ys;                         ///< plate-scale in Y direction
     psProjectionType type;             ///< Projection type
-}
-psProjection;
+    psVector *radial;	       ///< radial distortion terms 
+} psProjection;
 
 /** Allocates a psPlane
Index: trunk/psLib/src/fits/psFitsScale.c
===================================================================
--- trunk/psLib/src/fits/psFitsScale.c	(revision 39907)
+++ trunk/psLib/src/fits/psFitsScale.c	(revision 39926)
@@ -189,15 +189,30 @@
                 // Desperate retry
                 mean = psStatsGetValue(stats, DESPERATE_MEAN_STAT);
-                stdev = psStatsGetValue(stats, DESPERATE_STDEV_STAT);
+		if ((STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+		  stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ);
+		}
+		else { 
+		  stdev = psStatsGetValue(stats, DESPERATE_STDEV_STAT);
+		}
             }
         } else {
             // Retry with all available pixels
             mean = psStatsGetValue(stats, MEAN_STAT);
-            stdev = psStatsGetValue(stats, STDEV_STAT);
+	    if ((STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+	      stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ);
+	    }
+	    else {
+	      stdev = psStatsGetValue(stats, STDEV_STAT);
+	    }
         }
     } else {
         // First attempt
         mean = psStatsGetValue(stats, MEAN_STAT);
-        stdev = psStatsGetValue(stats, STDEV_STAT);
+	if ((STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+	  stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ);
+	}
+	else {
+	  stdev = psStatsGetValue(stats, STDEV_STAT);
+	}
     }
     psFree(rng);
@@ -554,15 +569,31 @@
                 // Desperate retry
                 mean = psStatsGetValue(stats, DESPERATE_MEAN_STAT);
-                stdev = psStatsGetValue(stats, DESPERATE_STDEV_STAT);
-            }
+		if ((DESPERATE_STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(DESPERATE_STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+		  stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ); // Calculate a "sigma" based on the interquartile distance.
+		}
+		else {
+		  
+		  stdev = psStatsGetValue(stats, DESPERATE_STDEV_STAT);
+		}
+	    }	
         } else {
             // Retry with all available pixels
             mean = psStatsGetValue(stats, MEAN_STAT);
-            stdev = psStatsGetValue(stats, STDEV_STAT);
+	    if ((STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+	      stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ); // Calculate a "sigma" based on the interquartile distance.
+	    }
+	    else {
+	      stdev = psStatsGetValue(stats, STDEV_STAT);
+	    }
         }
     } else {
         // First attempt
         mean = psStatsGetValue(stats, MEAN_STAT);
-        stdev = psStatsGetValue(stats, STDEV_STAT);
+	if ((STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+	  stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ); // Calculate a "sigma" based on the interquartile distance.
+	}
+	else { 
+	  stdev = psStatsGetValue(stats, STDEV_STAT);
+	}
     }
     psFree(rng);
@@ -723,15 +754,30 @@
                 // Desperate retry
                 mean = psStatsGetValue(stats, DESPERATE_MEAN_STAT);
-                stdev = psStatsGetValue(stats, DESPERATE_STDEV_STAT);
+		if ((DESPERATE_STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(DESPERATE_STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+		  stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ); // Calculate a "sigma" based on the interquartile distance.
+		}
+		else { 
+		  stdev = psStatsGetValue(stats, DESPERATE_STDEV_STAT);
+		}
             }
         } else {
             // Retry with all available pixels
             mean = psStatsGetValue(stats, MEAN_STAT);
-            stdev = psStatsGetValue(stats, STDEV_STAT);
+	    if ((STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+	      stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ); // Calculate a "sigma" based on the interquartile distance.
+	    }
+	    else {
+	      stdev = psStatsGetValue(stats, STDEV_STAT);
+	    }
         }
     } else {
         // First attempt
         mean = psStatsGetValue(stats, MEAN_STAT);
-        stdev = psStatsGetValue(stats, STDEV_STAT);
+	if ((STDEV_STAT == PS_STAT_SAMPLE_QUARTILE)||(STDEV_STAT == PS_STAT_ROBUST_QUARTILE)) {
+	  stdev = 0.7415 * (stats->sampleUQ - stats->sampleLQ); // Calculate a "sigma" based on the interquartile distance.
+	}
+	else {
+	  stdev = psStatsGetValue(stats, STDEV_STAT);
+	}
     }
     psFree(rng);
Index: trunk/psLib/src/types/psMetadata.c
===================================================================
--- trunk/psLib/src/types/psMetadata.c	(revision 39907)
+++ trunk/psLib/src/types/psMetadata.c	(revision 39926)
@@ -1390,5 +1390,5 @@
             break;
         case PS_DATA_F64:
-            fprintf(fd, "%f\n", item->data.F64);
+            fprintf(fd, "%g\n", item->data.F64);
             break;
         case PS_DATA_METADATA:
Index: trunk/psModules/src/astrom/pmAstrometryDistortion.c
===================================================================
--- trunk/psModules/src/astrom/pmAstrometryDistortion.c	(revision 39907)
+++ trunk/psModules/src/astrom/pmAstrometryDistortion.c	(revision 39926)
@@ -335,5 +335,7 @@
 
     psFree (fpa->fromTPA);
-    fpa->fromTPA = psPlaneTransformInvert(NULL, fpa->toTPA, *region, 50);
+    psPlaneTransform *myPT = psPlaneTransformAlloc(fpa->toTPA->x->nX+4, fpa->toTPA->x->nY+4);
+    fpa->fromTPA = psPlaneTransformInvert(myPT, fpa->toTPA, *region, 50);
+    psFree (myPT);
     psFree (region);
 
Index: trunk/psModules/src/astrom/pmAstrometryModel.c
===================================================================
--- trunk/psModules/src/astrom/pmAstrometryModel.c	(revision 39907)
+++ trunk/psModules/src/astrom/pmAstrometryModel.c	(revision 39926)
@@ -320,4 +320,6 @@
     // the PosZero is the offset between the reported and actual POSANGLE values
     float PosZero = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.POS_ZERO");  /// XXX be consistent with degrees v radians
+    // Indicate which direction the position angle goes
+    int rotParity = psMetadataLookupS32 (&status, file->fpa->concepts, "FPA.ROT_PARITY");
     char *refChip = psMetadataLookupStr (&status, file->fpa->concepts, "FPA.REF.CHIP");
 
@@ -349,4 +351,5 @@
 
     psMetadataAddF32(row,    PS_LIST_TAIL, "POS_ZERO", PS_META_REPLACE, "POSANGLE offset (degrees)", PosZero);
+    psMetadataAddS32(row,    PS_LIST_TAIL, "ROT_PARITY", PS_META_REPLACE, "rotator parity", rotParity);
     psMetadataAddStr(row,    PS_LIST_TAIL, "REF_CHIP", PS_META_REPLACE, "reference chip for model", refChip);
 
@@ -624,4 +627,5 @@
     TRANSFER (file->fpa->concepts, row, "BORE_P0");
     TRANSFER (file->fpa->concepts, row, "POS_ZERO");
+    TRANSFER (file->fpa->concepts, row, "ROT_PARITY");
     TRANSFER (file->fpa->concepts, row, "REF_CHIP");
 
@@ -687,8 +691,10 @@
     char *refChip  = psMetadataLookupStr(&status, file->fpa->concepts, "REF_CHIP"); REQUIRE (status, "missing REF_CHIP");
 
+    int rotatorParity = psMetadataLookupS32(&status, file->fpa->concepts, "ROT_PARITY"); REQUIRE (status, "missing ROT_PARITY");
+    
     // XXX we've swapped the sign and parity of POS (add to model)
     // apply true posangle = -(POS - POS_ZERO)
     psLogMsg ("psModules.astrom", 4, "Position Angle: %f, Model Position Angle Zero Point: %f\n", POS, PosZero);
-    psPlaneTransform *fromTPA = psPlaneTransformRotate (NULL, file->fpa->fromTPA, (PosZero - POS));
+    psPlaneTransform *fromTPA = psPlaneTransformRotate (NULL, file->fpa->fromTPA, rotatorParity * (PosZero - POS));
     psFree (file->fpa->fromTPA);
     file->fpa->fromTPA = fromTPA;
Index: trunk/psModules/src/astrom/pmAstrometryObjects.c
===================================================================
--- trunk/psModules/src/astrom/pmAstrometryObjects.c	(revision 39907)
+++ trunk/psModules/src/astrom/pmAstrometryObjects.c	(revision 39926)
@@ -225,5 +225,6 @@
     psArray *ref,
     psArray *match,
-    psStats *stats)
+    psStats *stats,
+    const psMetadata *config)
 {
     PS_ASSERT_PTR_NON_NULL(map, NULL);
@@ -232,4 +233,11 @@
     PS_ASSERT_PTR_NON_NULL(match, NULL);
     PS_ASSERT_PTR_NON_NULL(stats, NULL);
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    // sigma of gaussian window to down-weight photometric outliers (ignored if NAN or 0.0)
+    bool status;
+    double photomWindowSigma  = psMetadataLookupF32 (&status, config, "PSASTRO.PHOTOM.WINDOW.SIGMA");
+    bool   photomWindowApply  = !(isnan(photomWindowSigma) || (fabs(photomWindowSigma) < 0.01));
+    double photomWindowFactor = photomWindowApply ? -0.5/PS_SQR(photomWindowSigma) : 0.0;
 
     // reassign values for clip fit
@@ -252,5 +260,6 @@
         y->data.F32[i] = refStar->FP->y;
 
-        wt->data.F32[i] = 1.0;
+	// wt is used as an error (sqrt(variance)) in the fit. the 1.01 prevents the weight from going to 0.0 for perfect matches
+        wt->data.F32[i] = 1.01 - exp(photomWindowFactor*PS_SQR(refStar->magCal - rawStar->magCal)); 
     }
 
@@ -657,4 +666,5 @@
     obj->Color= 0;
     obj->dMag = 0;
+    obj->magCal = 0;
 
     return (obj);
@@ -685,4 +695,5 @@
     obj->Color =  old->Color;
     obj->dMag  =  old->dMag;
+    obj->magCal =  old->magCal;
 
     return(obj);
@@ -774,6 +785,11 @@
     double gridOffset = psMetadataLookupF32 (&status, config, "PSASTRO.GRID.OFFSET");
 
-    // sampling scale of the grid
-    double gridScale  = psMetadataLookupF32 (&status, config, "PSASTRO.GRID.SCALE");
+     // sampling scale of the grid
+     double gridScale  = psMetadataLookupF32 (&status, config, "PSASTRO.GRID.SCALE");
+
+    // sigma of gaussian window to down-weight photometric outliers (ignored if NAN or 0.0)
+    double photomWindowSigma  = psMetadataLookupF32 (&status, config, "PSASTRO.PHOTOM.WINDOW.SIGMA");
+    bool   photomWindowApply  = !(isnan(photomWindowSigma) || (fabs(photomWindowSigma) < 0.01));
+    double photomWindowFactor = photomWindowApply ? -0.5/PS_SQR(photomWindowSigma) : 0.0;
 
     // set the static scaling factors
@@ -816,9 +832,12 @@
             }
 
+	    // XXX should I make the scale factor in front a recipe value?
+	    int Npts = 10 * exp(photomWindowFactor*PS_SQR(ob1->magCal - ob2->magCal)); 
+
             // accumulate bin stats
-            NP[iY][iX] ++;
-            DX[iY][iX] += dX;
-            DY[iY][iX] += dY;
-            D2[iY][iX] += PS_SQR(dX) + PS_SQR(dY);
+            NP[iY][iX] += Npts;
+            DX[iY][iX] += dX*Npts;
+            DY[iY][iX] += dY*Npts;
+            D2[iY][iX] += PS_SQR(dX*Npts) + PS_SQR(dY*Npts);
         }
     }
@@ -1053,4 +1072,9 @@
     double tweakNsigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.TWEAK.NSIGMA");
 
+    // sigma of gaussian window to down-weight photometric outliers (ignored if NAN or 0.0)
+    double photomWindowSigma  = psMetadataLookupF32 (&status, recipe, "PSASTRO.PHOTOM.WINDOW.SIGMA");
+    bool   photomWindowApply  = !(isnan(photomWindowSigma) || (fabs(photomWindowSigma) < 0.01));
+    double photomWindowFactor = photomWindowApply ? -0.5/PS_SQR(photomWindowSigma) : 0.0;
+
     nBin = 2*tweakRange / tweakScale;
     psVector *xHist = psVectorAlloc (nBin, PS_TYPE_F32);
@@ -1079,6 +1103,9 @@
                 continue;
 
-            xHist->data.F32[xBin] += 1.0;
-            yHist->data.F32[yBin] += 1.0;
+	    // XXX should I make the scale factor in front a recipe value?
+	    int Npts = 10 * exp(photomWindowFactor*PS_SQR(ob1->magCal - ob2->magCal));  // sigma = 0.22 mag
+
+            xHist->data.F32[xBin] += Npts;
+            yHist->data.F32[yBin] += Npts;
         }
     }
Index: trunk/psModules/src/astrom/pmAstrometryObjects.h
===================================================================
--- trunk/psModules/src/astrom/pmAstrometryObjects.h	(revision 39907)
+++ trunk/psModules/src/astrom/pmAstrometryObjects.h	(revision 39926)
@@ -43,4 +43,5 @@
     float dMag;				///< error on object magnitude
     float SBinst;			///< surface brightness, used for Koppenhoefer correction
+    float magCal;		        ///< object calibrated magnitude in extracted filter
 }
 pmAstromObj;
@@ -347,5 +348,6 @@
     psArray *ref,
     psArray *match,
-    psStats *stats
+    psStats *stats,
+    const psMetadata *config
 );
 
Index: trunk/psModules/src/astrom/pmAstrometryWCS.c
===================================================================
--- trunk/psModules/src/astrom/pmAstrometryWCS.c	(revision 39907)
+++ trunk/psModules/src/astrom/pmAstrometryWCS.c	(revision 39926)
@@ -43,5 +43,5 @@
     pmAstromWCS *wcs = pmAstromWCSfromHeader (header);
     if (!wcs) {
-        return false;
+	return false;
     }
 
@@ -70,5 +70,5 @@
     pmAstromWCS *wcs = pmAstromWCSfromHeader (header);
     if (!wcs) {
-        return false;
+	return false;
     }
 
@@ -86,6 +86,6 @@
     pmAstromWCS *wcs = pmAstromWCSfromHeader (header);
     if (!wcs) {
-        psError(PS_ERR_UNKNOWN, false, "failure to determine WCS terms from header");
-        return false;
+	psError(PS_ERR_UNKNOWN, false, "failure to determine WCS terms from header");
+	return false;
     }
 
@@ -96,17 +96,17 @@
 
     if (!status1 || !status2) {
-        Nx = psMetadataLookupS32 (&status1, header, "IMNAXIS1");
-        Ny = psMetadataLookupS32 (&status2, header, "IMNAXIS2");
+	Nx = psMetadataLookupS32 (&status1, header, "IMNAXIS1");
+	Ny = psMetadataLookupS32 (&status2, header, "IMNAXIS2");
     }
 
     if (!status1 || !status2) {
-        Nx = psMetadataLookupS32 (&status1, header, "ZNAXIS1");
-        Ny = psMetadataLookupS32 (&status2, header, "ZNAXIS2");
+	Nx = psMetadataLookupS32 (&status1, header, "ZNAXIS1");
+	Ny = psMetadataLookupS32 (&status2, header, "ZNAXIS2");
     }
 
     if (!status1 || !status2) {
-        psFree (wcs);
-        psError(PS_ERR_UNKNOWN, false, "missing required FPA size in header");
-        return false;
+	psFree (wcs);
+	psError(PS_ERR_UNKNOWN, false, "missing required FPA size in header");
+	return false;
     }
 
@@ -123,6 +123,6 @@
     pmAstromWCS *wcs = pmAstromWCSBilevelChipFromFPA (chip, tol);
     if (!wcs) {
-        psError(PS_ERR_UNKNOWN, false, "failure to determine WCS terms from fpa");
-        return false;
+	psError(PS_ERR_UNKNOWN, false, "failure to determine WCS terms from fpa");
+	return false;
     }
 
@@ -139,6 +139,6 @@
     pmAstromWCS *wcs = pmAstromWCSBilevelMosaicFromFPA (fpa, tol);
     if (!wcs) {
-        psError(PS_ERR_UNKNOWN, false, "failure to determine WCS terms from fpa");
-        return false;
+	psError(PS_ERR_UNKNOWN, false, "failure to determine WCS terms from fpa");
+	return false;
     }
 
@@ -163,9 +163,9 @@
 
     if (chip == NULL)
-        return false;
+	return false;
     if (sky == NULL)
-        return false;
+	return false;
     if (wcs == NULL)
-        return false;
+	return false;
 
     psPlane *Chip = psPlaneAlloc();
@@ -188,9 +188,9 @@
 
     if (chip == NULL)
-        return false;
+	return false;
     if (sky == NULL)
-        return false;
+	return false;
     if (wcs == NULL)
-        return false;
+	return false;
 
     psError(PS_ERR_UNKNOWN, true, "not yet implemented: needs to invert the transformation");
@@ -223,6 +223,6 @@
     char *ctype = psMetadataLookupPtr (&status, header, "CTYPE2");
     if (!status) {
-        psLogMsg ("psastro", 5, "warning: no WCS metadata in header\n");
-        return NULL;
+	psLogMsg ("psastro", 5, "warning: no WCS metadata in header\n");
+	return NULL;
     }
 
@@ -232,6 +232,6 @@
     type = psProjectTypeFromString (ctype);
     if (type == PS_PROJ_NTYPE) {
-        psLogMsg ("psastro", 2, "warning: unknown projection type %s\n", ctype);
-        return NULL;
+	psLogMsg ("psastro", 2, "warning: unknown projection type %s\n", ctype);
+	return NULL;
     }
 
@@ -243,25 +243,25 @@
 
     if (cdKeys && pcKeys) {
-        // XXX make this an option
-        psLogMsg ("psastro", 5, "warning: both CDi_j and PC00i00j defined in headers, using PC00i00j terms\n");
+	// XXX make this an option
+	psLogMsg ("psastro", 5, "warning: both CDi_j and PC00i00j defined in headers, using PC00i00j terms\n");
     }
     if (!cdKeys && !pcKeys) {
-        psError(PS_ERR_UNKNOWN, true, "missing both CDi_j and PC00i00j WCS terms");
-        // XXX we could default here to RA, DEC, ROTANGLE
-        return NULL;
+	psError(PS_ERR_UNKNOWN, true, "missing both CDi_j and PC00i00j WCS terms");
+	// XXX we could default here to RA, DEC, ROTANGLE
+	return NULL;
     }
     if (isPoly) {
-        if (!pcKeys) {
-            psError(PS_ERR_UNKNOWN, true, "polynomial terms defined, but missing PC00i00j WCS terms");
-            return NULL;
-        }
-        if (fitOrder == 0)
-            fitOrder = 1;
-        if ((fitOrder > 3) || (fitOrder < 1)) {
-            psError(PS_ERR_UNKNOWN, true, "NPLYTERM value undefined: %d", fitOrder);
-            return NULL;
-        }
+	if (!pcKeys) {
+	    psError(PS_ERR_UNKNOWN, true, "polynomial terms defined, but missing PC00i00j WCS terms");
+	    return NULL;
+	}
+	if (fitOrder == 0)
+	    fitOrder = 1;
+	if ((fitOrder > 3) || (fitOrder < 1)) {
+	    psError(PS_ERR_UNKNOWN, true, "NPLYTERM value undefined: %d", fitOrder);
+	    return NULL;
+	}
     } else {
-        fitOrder = 1;
+	fitOrder = 1;
     }
 
@@ -277,4 +277,29 @@
     wcs->crpix2 = psMetadataLookupF64 (&status, header, "CRPIX2");
     wcs->toSky = psProjectionAlloc (wcs->crval1*PM_RAD_DEG, wcs->crval2*PM_RAD_DEG, PM_RAD_DEG, PM_RAD_DEG, type);
+
+    // XXX if type == ZPN, look for PV2_%d elements:
+    if (type == PS_PROJ_ZPN) {
+	psVector *maxRadial = psVectorAlloc (21, PS_TYPE_F64);
+	for (int i = 0; i <= 20; i++) {
+	    char name[64];
+	    snprintf (name, 64, "PV2_%d", i);
+
+	    maxRadial->data.F64[i] = 0.0;
+	    double value = psMetadataLookupF64 (&status, header, name);
+
+	    if (status) {
+		maxRadial->data.F64[i] = value;
+		maxRadial->n = i;
+	    }
+
+	    // PV2_1 is implicit if not present
+	    if ((i == 1) && !status) {
+		maxRadial->data.F64[i] = 1.0;
+		continue;
+	    }
+	}
+	maxRadial->n ++;
+	wcs->toSky->radial = maxRadial;
+    }
 
     // These aren't needed but having them empty is disconcerting
@@ -289,59 +314,59 @@
     // test the CDELTi varient
     if (pcKeys) {
-        wcs->wcsCDkeys = 0;
-        wcs->cdelt1 = psMetadataLookupF64 (&status, header, "CDELT1");
-        wcs->cdelt2 = psMetadataLookupF64 (&status, header, "CDELT2");
-
-        // test the CROTAi varient:
-        // XXX double check lambda..
-        double rotate = psMetadataLookupF64 (&status, header, "CROTA2");
-        if (status) {
-            wcs->trans->x->coeff[1][0] = +wcs->cdelt1 * cos(rotate*PM_RAD_DEG); // == PC1_1
-            wcs->trans->x->coeff[0][1] = -wcs->cdelt2 * sin(rotate*PM_RAD_DEG); // == PC1_2
-            wcs->trans->y->coeff[1][0] = +wcs->cdelt1 * sin(rotate*PM_RAD_DEG); // == PC2_1
-            wcs->trans->y->coeff[0][1] = +wcs->cdelt2 * cos(rotate*PM_RAD_DEG); // == PC2_2
-            return wcs;
-        }
-
-        // FITS WCS PCi,j has units of unity
-        // wcs->trans has units of degrees/pixel
-        wcs->trans->x->coeff[1][0] = wcs->cdelt1 * psMetadataLookupF64 (&status, header, "PC001001"); // == PC1_1
-        wcs->trans->x->coeff[0][1] = wcs->cdelt2 * psMetadataLookupF64 (&status, header, "PC001002"); // == PC1_2
-        wcs->trans->y->coeff[1][0] = wcs->cdelt1 * psMetadataLookupF64 (&status, header, "PC002001"); // == PC2_1
-        wcs->trans->y->coeff[0][1] = wcs->cdelt2 * psMetadataLookupF64 (&status, header, "PC002002"); // == PC2_2
-
-        if (isPoly) {
-            // Elixir-style polynomial terms
-            // XXX currently, Elixir/DVO cannot accept mixed orders
-            for (int i = 0; i <= fitOrder; i++) {
-                for (int j = 0; j <= fitOrder; j++) {
-                    if (i + j < 2)
-                        continue;
-                    if (i + j > fitOrder) {
-                        wcs->trans->x->coeffMask[i][j] = PS_POLY_MASK_SET;
-                        wcs->trans->y->coeffMask[i][j] = PS_POLY_MASK_SET;
-                        continue;
-                    }
-                    sprintf (name, "PCA1X%1dY%1d", i, j);
-                    wcs->trans->x->coeff[i][j] = pow(wcs->cdelt1, i) * pow(wcs->cdelt2, j) * psMetadataLookupF64 (&status, header, name);
-                    sprintf (name, "PCA2X%1dY%1d", i, j);
-                    wcs->trans->y->coeff[i][j] = pow(wcs->cdelt1, i) * pow(wcs->cdelt2, j) * psMetadataLookupF64 (&status, header, name);
-                }
-            }
-        }
-        return wcs;
+	wcs->wcsCDkeys = 0;
+	wcs->cdelt1 = psMetadataLookupF64 (&status, header, "CDELT1");
+	wcs->cdelt2 = psMetadataLookupF64 (&status, header, "CDELT2");
+
+	// test the CROTAi varient:
+	// XXX double check lambda..
+	double rotate = psMetadataLookupF64 (&status, header, "CROTA2");
+	if (status) {
+	    wcs->trans->x->coeff[1][0] = +wcs->cdelt1 * cos(rotate*PM_RAD_DEG); // == PC1_1
+	    wcs->trans->x->coeff[0][1] = -wcs->cdelt2 * sin(rotate*PM_RAD_DEG); // == PC1_2
+	    wcs->trans->y->coeff[1][0] = +wcs->cdelt1 * sin(rotate*PM_RAD_DEG); // == PC2_1
+	    wcs->trans->y->coeff[0][1] = +wcs->cdelt2 * cos(rotate*PM_RAD_DEG); // == PC2_2
+	    return wcs;
+	}
+
+	// FITS WCS PCi,j has units of unity
+	// wcs->trans has units of degrees/pixel
+	wcs->trans->x->coeff[1][0] = wcs->cdelt1 * psMetadataLookupF64 (&status, header, "PC001001"); // == PC1_1
+	wcs->trans->x->coeff[0][1] = wcs->cdelt2 * psMetadataLookupF64 (&status, header, "PC001002"); // == PC1_2
+	wcs->trans->y->coeff[1][0] = wcs->cdelt1 * psMetadataLookupF64 (&status, header, "PC002001"); // == PC2_1
+	wcs->trans->y->coeff[0][1] = wcs->cdelt2 * psMetadataLookupF64 (&status, header, "PC002002"); // == PC2_2
+
+	if (isPoly) {
+	    // Elixir-style polynomial terms
+	    // XXX currently, Elixir/DVO cannot accept mixed orders
+	    for (int i = 0; i <= fitOrder; i++) {
+		for (int j = 0; j <= fitOrder; j++) {
+		    if (i + j < 2)
+			continue;
+		    if (i + j > fitOrder) {
+			wcs->trans->x->coeffMask[i][j] = PS_POLY_MASK_SET;
+			wcs->trans->y->coeffMask[i][j] = PS_POLY_MASK_SET;
+			continue;
+		    }
+		    sprintf (name, "PCA1X%1dY%1d", i, j);
+		    wcs->trans->x->coeff[i][j] = pow(wcs->cdelt1, i) * pow(wcs->cdelt2, j) * psMetadataLookupF64 (&status, header, name);
+		    sprintf (name, "PCA2X%1dY%1d", i, j);
+		    wcs->trans->y->coeff[i][j] = pow(wcs->cdelt1, i) * pow(wcs->cdelt2, j) * psMetadataLookupF64 (&status, header, name);
+		}
+	    }
+	}
+	return wcs;
     }
 
     // test the CDi_j varient
     if (cdKeys) {
-        wcs->wcsCDkeys = 1;
-
-        wcs->trans->x->coeff[1][0] = psMetadataLookupF64 (&status, header, "CD1_1"); // == PC1_1
-        wcs->trans->x->coeff[0][1] = psMetadataLookupF64 (&status, header, "CD1_2"); // == PC1_2
-        wcs->trans->y->coeff[1][0] = psMetadataLookupF64 (&status, header, "CD2_1"); // == PC2_1
-        wcs->trans->y->coeff[0][1] = psMetadataLookupF64 (&status, header, "CD2_2"); // == PC2_2
-        wcs->cdelt1 = hypot (wcs->trans->x->coeff[1][0], wcs->trans->x->coeff[0][1]);
-        wcs->cdelt2 = hypot (wcs->trans->y->coeff[1][0], wcs->trans->y->coeff[0][1]);
-        return wcs;
+	wcs->wcsCDkeys = 1;
+
+	wcs->trans->x->coeff[1][0] = psMetadataLookupF64 (&status, header, "CD1_1"); // == PC1_1
+	wcs->trans->x->coeff[0][1] = psMetadataLookupF64 (&status, header, "CD1_2"); // == PC1_2
+	wcs->trans->y->coeff[1][0] = psMetadataLookupF64 (&status, header, "CD2_1"); // == PC2_1
+	wcs->trans->y->coeff[0][1] = psMetadataLookupF64 (&status, header, "CD2_2"); // == PC2_2
+	wcs->cdelt1 = hypot (wcs->trans->x->coeff[1][0], wcs->trans->x->coeff[0][1]);
+	wcs->cdelt2 = hypot (wcs->trans->y->coeff[1][0], wcs->trans->y->coeff[0][1]);
+	return wcs;
     }
     psLogMsg ("psastro", 2, "warning: missing rotation matrix?\n");
@@ -376,84 +401,93 @@
     psMetadataAddF64 (header, PS_LIST_TAIL, "CRPIX2", PS_META_REPLACE, "", wcs->crpix2);
 
+    if (wcs->toSky->type == PS_PROJ_ZPN) {
+	psAssert (wcs->toSky->radial, "missing radial vector");
+	for (int i = 0; i < wcs->toSky->radial->n; i++) {
+	    if (wcs->toSky->radial->data.F64[i] == 0.0) continue;
+	    snprintf (name, 16, "PV2_%d", i);
+	    psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->toSky->radial->data.F64[i]);
+	}
+    }
+
     // XXX make it optional to write out CDi_j terms, or other versions
     // apply CDELT1,2 (degrees / pixel) to yield PCi,j terms of order unity
     if (!wcs->wcsCDkeys) {
 
-      double cdelt1 = wcs->cdelt1;
-      double cdelt2 = wcs->cdelt2;
-      psMetadataAddF64 (header, PS_LIST_TAIL, "CDELT1", PS_META_REPLACE, "", cdelt1);
-      psMetadataAddF64 (header, PS_LIST_TAIL, "CDELT2", PS_META_REPLACE, "", cdelt2);
-
-      // test the PC00i00j varient:
-      psMetadataAddF64 (header, PS_LIST_TAIL, "PC001001", PS_META_REPLACE, "", wcs->trans->x->coeff[1][0] / cdelt1); // == PC1_1
-      psMetadataAddF64 (header, PS_LIST_TAIL, "PC001002", PS_META_REPLACE, "", wcs->trans->x->coeff[0][1] / cdelt2); // == PC1_2
-      psMetadataAddF64 (header, PS_LIST_TAIL, "PC002001", PS_META_REPLACE, "", wcs->trans->y->coeff[1][0] / cdelt1); // == PC2_1
-      psMetadataAddF64 (header, PS_LIST_TAIL, "PC002002", PS_META_REPLACE, "", wcs->trans->y->coeff[0][1] / cdelt2); // == PC2_2
-
-      // Elixir-style polynomial terms
-      // XXX currently, Elixir/DVO cannot accept mixed orders
-      // XXX need to respect the masks
-      // XXX is wcs->cdelt1,2 always consistent?
-      int fitOrder = wcs->trans->x->nX;
-      if (fitOrder > 1) {
-        for (int i = 0; i <= fitOrder; i++) {
-          for (int j = 0; j <= fitOrder; j++) {
-            if (i + j < 2)
-              continue;
-            if (i + j > fitOrder)
-              continue;
-            sprintf (name, "PCA1X%1dY%1d", i, j);
-            psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->trans->x->coeff[i][j] / pow(cdelt1, i) / pow(cdelt2, j));
-            sprintf (name, "PCA2X%1dY%1d", i, j);
-            psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->trans->y->coeff[i][j] / pow(cdelt1, i) / pow(cdelt2, j));
-          }
-        }
-        psMetadataAddS32 (header, PS_LIST_TAIL, "NPLYTERM", PS_META_REPLACE, "", fitOrder);
-      }
-
-      // remove any existing 'CDi_j style' wcs keywords
-      if (psMetadataLookup(header, "CD1_1")) {
-        psMetadataRemoveKey(header, "CD1_1");
-        psMetadataRemoveKey(header, "CD1_2");
-        psMetadataRemoveKey(header, "CD2_1");
-        psMetadataRemoveKey(header, "CD2_2");
-      }
-
-      // Remove 'CDi_jX' WCS keywords
-      psString cd11 = psStringCopy("CD1_1 ");
-      psString cd12 = psStringCopy("CD1_2 ");
-      psString cd21 = psStringCopy("CD2_1 ");
-      psString cd22 = psStringCopy("CD2_2 ");
-      for (char extra = 'A'; extra <= 'Z'; extra++) {
-          cd11[strlen(cd11)-1] = extra;
-          if (psMetadataLookup(header, cd11)) {
-              cd12[strlen(cd12)-1] = extra;
-              cd21[strlen(cd21)-1] = extra;
-              cd22[strlen(cd22)-1] = extra;
-              psMetadataRemoveKey(header, cd11);
-              psMetadataRemoveKey(header, cd12);
-              psMetadataRemoveKey(header, cd21);
-              psMetadataRemoveKey(header, cd22);
-          }
-      }
-      psFree(cd11);
-      psFree(cd12);
-      psFree(cd21);
-      psFree(cd22);
+	double cdelt1 = wcs->cdelt1;
+	double cdelt2 = wcs->cdelt2;
+	psMetadataAddF64 (header, PS_LIST_TAIL, "CDELT1", PS_META_REPLACE, "", cdelt1);
+	psMetadataAddF64 (header, PS_LIST_TAIL, "CDELT2", PS_META_REPLACE, "", cdelt2);
+
+	// test the PC00i00j varient:
+	psMetadataAddF64 (header, PS_LIST_TAIL, "PC001001", PS_META_REPLACE, "", wcs->trans->x->coeff[1][0] / cdelt1); // == PC1_1
+	psMetadataAddF64 (header, PS_LIST_TAIL, "PC001002", PS_META_REPLACE, "", wcs->trans->x->coeff[0][1] / cdelt2); // == PC1_2
+	psMetadataAddF64 (header, PS_LIST_TAIL, "PC002001", PS_META_REPLACE, "", wcs->trans->y->coeff[1][0] / cdelt1); // == PC2_1
+	psMetadataAddF64 (header, PS_LIST_TAIL, "PC002002", PS_META_REPLACE, "", wcs->trans->y->coeff[0][1] / cdelt2); // == PC2_2
+
+	// Elixir-style polynomial terms
+	// XXX currently, Elixir/DVO cannot accept mixed orders
+	// XXX need to respect the masks
+	// XXX is wcs->cdelt1,2 always consistent?
+	int fitOrder = wcs->trans->x->nX;
+	if (fitOrder > 1) {
+	    for (int i = 0; i <= fitOrder; i++) {
+		for (int j = 0; j <= fitOrder; j++) {
+		    if (i + j < 2)
+			continue;
+		    if (i + j > fitOrder)
+			continue;
+		    sprintf (name, "PCA1X%1dY%1d", i, j);
+		    psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->trans->x->coeff[i][j] / pow(cdelt1, i) / pow(cdelt2, j));
+		    sprintf (name, "PCA2X%1dY%1d", i, j);
+		    psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->trans->y->coeff[i][j] / pow(cdelt1, i) / pow(cdelt2, j));
+		}
+	    }
+	    psMetadataAddS32 (header, PS_LIST_TAIL, "NPLYTERM", PS_META_REPLACE, "", fitOrder);
+	}
+
+	// remove any existing 'CDi_j style' wcs keywords
+	if (psMetadataLookup(header, "CD1_1")) {
+	    psMetadataRemoveKey(header, "CD1_1");
+	    psMetadataRemoveKey(header, "CD1_2");
+	    psMetadataRemoveKey(header, "CD2_1");
+	    psMetadataRemoveKey(header, "CD2_2");
+	}
+
+	// Remove 'CDi_jX' WCS keywords
+	psString cd11 = psStringCopy("CD1_1 ");
+	psString cd12 = psStringCopy("CD1_2 ");
+	psString cd21 = psStringCopy("CD2_1 ");
+	psString cd22 = psStringCopy("CD2_2 ");
+	for (char extra = 'A'; extra <= 'Z'; extra++) {
+	    cd11[strlen(cd11)-1] = extra;
+	    if (psMetadataLookup(header, cd11)) {
+		cd12[strlen(cd12)-1] = extra;
+		cd21[strlen(cd21)-1] = extra;
+		cd22[strlen(cd22)-1] = extra;
+		psMetadataRemoveKey(header, cd11);
+		psMetadataRemoveKey(header, cd12);
+		psMetadataRemoveKey(header, cd21);
+		psMetadataRemoveKey(header, cd22);
+	    }
+	}
+	psFree(cd11);
+	psFree(cd12);
+	psFree(cd21);
+	psFree(cd22);
 
 
     } else {
 
-      psMetadataAddF64 (header, PS_LIST_TAIL, "CD1_1", PS_META_REPLACE, "", wcs->trans->x->coeff[1][0]);
-      psMetadataAddF64 (header, PS_LIST_TAIL, "CD1_2", PS_META_REPLACE, "", wcs->trans->x->coeff[0][1]);
-      psMetadataAddF64 (header, PS_LIST_TAIL, "CD2_1", PS_META_REPLACE, "", wcs->trans->y->coeff[1][0]);
-      psMetadataAddF64 (header, PS_LIST_TAIL, "CD2_2", PS_META_REPLACE, "", wcs->trans->y->coeff[0][1]);
-
-      if (psMetadataLookup(header, "PC001001")) {
-        psMetadataRemoveKey(header, "PC001001");
-        psMetadataRemoveKey(header, "PC001002");
-        psMetadataRemoveKey(header, "PC002001");
-        psMetadataRemoveKey(header, "PC002002");
-      }
+	psMetadataAddF64 (header, PS_LIST_TAIL, "CD1_1", PS_META_REPLACE, "", wcs->trans->x->coeff[1][0]);
+	psMetadataAddF64 (header, PS_LIST_TAIL, "CD1_2", PS_META_REPLACE, "", wcs->trans->x->coeff[0][1]);
+	psMetadataAddF64 (header, PS_LIST_TAIL, "CD2_1", PS_META_REPLACE, "", wcs->trans->y->coeff[1][0]);
+	psMetadataAddF64 (header, PS_LIST_TAIL, "CD2_2", PS_META_REPLACE, "", wcs->trans->y->coeff[0][1]);
+
+	if (psMetadataLookup(header, "PC001001")) {
+	    psMetadataRemoveKey(header, "PC001001");
+	    psMetadataRemoveKey(header, "PC001002");
+	    psMetadataRemoveKey(header, "PC002001");
+	    psMetadataRemoveKey(header, "PC002002");
+	}
     }
 
@@ -473,8 +507,8 @@
     // cdelt1,2 has units of degree/pixel
     for (int i = 0; i <= toFPA->x->nX; i++) {
-        for (int j = 0; j <= toFPA->x->nX; j++) {
-            toFPA->x->coeff[i][j] *= pixelScale/wcs->cdelt1;
-            toFPA->y->coeff[i][j] *= pixelScale/wcs->cdelt2;
-        }
+	for (int j = 0; j <= toFPA->x->nX; j++) {
+	    toFPA->x->coeff[i][j] *= pixelScale/wcs->cdelt1;
+	    toFPA->y->coeff[i][j] *= pixelScale/wcs->cdelt2;
+	}
     }
 
@@ -485,80 +519,81 @@
     // projection from TPA (linear microns) to SKY (radians)
     psProjection *toSky = psProjectionAlloc (wcs->toSky->R, wcs->toSky->D, PM_RAD_DEG*pdelt1, PM_RAD_DEG*pdelt2, wcs->toSky->type);
+    toSky->radial = psMemIncrRefCounter (wcs->toSky->radial);
 
     if (fpa->toSky == NULL) {
 	psFree(fpa->toTPA);
 	psFree(fpa->fromTPA);
-        fpa->toTPA = psPlaneTransformIdentity (1);
-        fpa->fromTPA = psPlaneTransformIdentity (1);
-        fpa->toSky = toSky;
+	fpa->toTPA = psPlaneTransformIdentity (1);
+	fpa->fromTPA = psPlaneTransformIdentity (1);
+	fpa->toSky = toSky;
     } else {
 
-        // this section allows the loaded chip to be included in an fpa structure in which
-        // other chips have already been loaded (ie, the fpa->toTPA, fpa->toSky components have
-        // already been defined).  we have to adjust to match the existing transformation.
-
-        if (fpa->toTPA == NULL)
-            psAbort("projection defined, tangent-plane not defined");
-        if (fpa->fromTPA == NULL)
-            psAbort("projection defined, tangent-plane not defined");
-
-        // convert from pixels on this chip to pixels on reference chip
-        // rX has units of refpixels / pixel
-        double rX = toSky->Xs / fpa->toSky->Xs;
-        double rY = toSky->Ys / fpa->toSky->Ys;
-
-        for (int i = 0; i <= toFPA->x->nX; i++) {
-            for (int j = 0; j <= toFPA->x->nY; j++) {
-                toFPA->x->coeff[i][j] *= rX;
-                toFPA->y->coeff[i][j] *= rY;
-            }
-        }
-
-        // apply the exiting fromTPA transformation to make the new toFPA consistent with the toTPA layter
-        // XXX this only works if toTPA is at most a linear transformation
-        psPlaneTransform *toFPAnew = psPlaneTransformAlloc(toFPA->x->nX, toFPA->x->nY);
-        for (int i = 0; i <= toFPA->x->nX; i++) {
-          for (int j = 0; j <= toFPA->x->nY; j++) {
-            double f1 = toFPA->x->coeffMask[i][j] ? 0.0 : fpa->fromTPA->x->coeff[1][0]*toFPA->x->coeff[i][j];
-            double f2 = toFPA->y->coeffMask[i][j] ? 0.0 : fpa->fromTPA->x->coeff[0][1]*toFPA->y->coeff[i][j];
-            toFPAnew->x->coeff[i][j] = f1 + f2;
-
-            double g1 = toFPA->x->coeffMask[i][j] ? 0.0 : fpa->fromTPA->y->coeff[1][0]*toFPA->x->coeff[i][j];
-            double g2 = toFPA->y->coeffMask[i][j] ? 0.0 : fpa->fromTPA->y->coeff[0][1]*toFPA->y->coeff[i][j];
-            toFPAnew->y->coeff[i][j] = g1 + g2;
-          }
-        }
-        toFPAnew->x->coeff[0][0] += fpa->fromTPA->x->coeff[0][0];
-        toFPAnew->y->coeff[0][0] += fpa->fromTPA->y->coeff[0][0];
-
-        psFree (toFPA);
-        toFPA = toFPAnew;
-
-        // adjust reference pixel for new toSky reference coordinate
-        // find the FPA coordinate of 0,0 for this chip.
-        psPlane *fpOld = psPlaneAlloc();
-        psPlane *fpNew = psPlaneAlloc();
-        psPlane *tp = psPlaneAlloc();
-        psSphere *sky = psSphereAlloc();
-
-        sky->r = toSky->R;
-        sky->d = toSky->D;
-        psProject (tp, sky, fpa->toSky); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
-        psPlaneTransformApply (fpOld, fpa->fromTPA, tp);
-
-        sky->r = fpa->toSky->R;
-        sky->d = fpa->toSky->D;
-        psProject (tp, sky, fpa->toSky); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
-        psPlaneTransformApply (fpNew, fpa->fromTPA, tp);
-
-        toFPA->x->coeff[0][0] -= fpNew->x - fpOld->x;
-        toFPA->y->coeff[0][0] -= fpNew->y - fpOld->y;
-
-        psFree (sky);
-        psFree (tp);
-        psFree (fpOld);
-        psFree (fpNew);
-
-        psFree (toSky);
+	// this section allows the loaded chip to be included in an fpa structure in which
+	// other chips have already been loaded (ie, the fpa->toTPA, fpa->toSky components have
+	// already been defined).  we have to adjust to match the existing transformation.
+
+	if (fpa->toTPA == NULL)
+	    psAbort("projection defined, tangent-plane not defined");
+	if (fpa->fromTPA == NULL)
+	    psAbort("projection defined, tangent-plane not defined");
+
+	// convert from pixels on this chip to pixels on reference chip
+	// rX has units of refpixels / pixel
+	double rX = toSky->Xs / fpa->toSky->Xs;
+	double rY = toSky->Ys / fpa->toSky->Ys;
+
+	for (int i = 0; i <= toFPA->x->nX; i++) {
+	    for (int j = 0; j <= toFPA->x->nY; j++) {
+		toFPA->x->coeff[i][j] *= rX;
+		toFPA->y->coeff[i][j] *= rY;
+	    }
+	}
+
+	// apply the exiting fromTPA transformation to make the new toFPA consistent with the toTPA layter
+	// XXX this only works if toTPA is at most a linear transformation
+	psPlaneTransform *toFPAnew = psPlaneTransformAlloc(toFPA->x->nX, toFPA->x->nY);
+	for (int i = 0; i <= toFPA->x->nX; i++) {
+	    for (int j = 0; j <= toFPA->x->nY; j++) {
+		double f1 = toFPA->x->coeffMask[i][j] ? 0.0 : fpa->fromTPA->x->coeff[1][0]*toFPA->x->coeff[i][j];
+		double f2 = toFPA->y->coeffMask[i][j] ? 0.0 : fpa->fromTPA->x->coeff[0][1]*toFPA->y->coeff[i][j];
+		toFPAnew->x->coeff[i][j] = f1 + f2;
+
+		double g1 = toFPA->x->coeffMask[i][j] ? 0.0 : fpa->fromTPA->y->coeff[1][0]*toFPA->x->coeff[i][j];
+		double g2 = toFPA->y->coeffMask[i][j] ? 0.0 : fpa->fromTPA->y->coeff[0][1]*toFPA->y->coeff[i][j];
+		toFPAnew->y->coeff[i][j] = g1 + g2;
+	    }
+	}
+	toFPAnew->x->coeff[0][0] += fpa->fromTPA->x->coeff[0][0];
+	toFPAnew->y->coeff[0][0] += fpa->fromTPA->y->coeff[0][0];
+
+	psFree (toFPA);
+	toFPA = toFPAnew;
+
+	// adjust reference pixel for new toSky reference coordinate
+	// find the FPA coordinate of 0,0 for this chip.
+	psPlane *fpOld = psPlaneAlloc();
+	psPlane *fpNew = psPlaneAlloc();
+	psPlane *tp = psPlaneAlloc();
+	psSphere *sky = psSphereAlloc();
+
+	sky->r = toSky->R;
+	sky->d = toSky->D;
+	psProject (tp, sky, fpa->toSky); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
+	psPlaneTransformApply (fpOld, fpa->fromTPA, tp);
+
+	sky->r = fpa->toSky->R;
+	sky->d = fpa->toSky->D;
+	psProject (tp, sky, fpa->toSky); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
+	psPlaneTransformApply (fpNew, fpa->fromTPA, tp);
+
+	toFPA->x->coeff[0][0] -= fpNew->x - fpOld->x;
+	toFPA->y->coeff[0][0] -= fpNew->y - fpOld->y;
+
+	psFree (sky);
+	psFree (tp);
+	psFree (fpOld);
+	psFree (fpNew);
+
+	psFree (toSky);
     }
 
@@ -578,26 +613,26 @@
     // XXX if the inversion fails, we probably do not have a valid transform anyway
     if (!chip->fromFPA) {
-      psWarning ("failed to find a valid transformation");
-      psFree (chip->toFPA);
-      return false;
+	psWarning ("failed to find a valid transformation");
+	psFree (chip->toFPA);
+	return false;
     }
 
     // this can take a very long time...
     while (fpa->toSky->R < 0)
-        fpa->toSky->R += 2.0*M_PI;
+	fpa->toSky->R += 2.0*M_PI;
     while (fpa->toSky->R > 2.0*M_PI)
-        fpa->toSky->R -= 2.0*M_PI;
+	fpa->toSky->R -= 2.0*M_PI;
 
     fpa->wcsCDkeys = wcs->wcsCDkeys;
 
     psTrace ("psastro", 5, "toFPA: %f %f  (%f,%f),(%f,%f)\n",
-             chip->toFPA->x->coeff[0][0], chip->toFPA->y->coeff[0][0],
-             chip->toFPA->x->coeff[1][0], chip->toFPA->x->coeff[0][1],
-             chip->toFPA->y->coeff[1][0], chip->toFPA->y->coeff[0][1]);
+	     chip->toFPA->x->coeff[0][0], chip->toFPA->y->coeff[0][0],
+	     chip->toFPA->x->coeff[1][0], chip->toFPA->x->coeff[0][1],
+	     chip->toFPA->y->coeff[1][0], chip->toFPA->y->coeff[0][1]);
 
     psTrace ("psastro", 5, "frFPA: %f %f  (%f,%f),(%f,%f)\n",
-             chip->fromFPA->x->coeff[0][0], chip->fromFPA->y->coeff[0][0],
-             chip->fromFPA->x->coeff[1][0], chip->fromFPA->x->coeff[0][1],
-             chip->fromFPA->y->coeff[1][0], chip->fromFPA->y->coeff[0][1]);
+	     chip->fromFPA->x->coeff[0][0], chip->fromFPA->y->coeff[0][0],
+	     chip->fromFPA->x->coeff[1][0], chip->fromFPA->x->coeff[0][1],
+	     chip->fromFPA->y->coeff[1][0], chip->fromFPA->y->coeff[0][1]);
 
     return true;
@@ -613,7 +648,14 @@
      */
 
-    // create transformation with 0,0 reference pixel and units of microns/pixel
     psFree (chip->toFPA);
-    chip->toFPA = psPlaneTransformSetCenter (NULL, wcs->trans, -wcs->crpix1, -wcs->crpix2);
+    chip->toFPA = psPlaneTransformAlloc(wcs->trans->x->nX, wcs->trans->x->nY);
+
+    // copy the toFPA x,y, transformations to the wcs version
+    chip->toFPA->x = psPolynomial2DCopy (chip->toFPA->x, wcs->trans->x);
+    chip->toFPA->y = psPolynomial2DCopy (chip->toFPA->y, wcs->trans->y);
+
+    // these need to be set based on crval1,2
+    chip->toFPA->x->coeff[0][0] = wcs->crval1;
+    chip->toFPA->y->coeff[0][0] = wcs->crval2;
 
     // determine the inverse transformation: we need the chip pixels covered by this transform
@@ -633,4 +675,5 @@
     // cdelt1,2 has units of degrees/micron
     fpa->toSky = psProjectionAlloc (wcs->toSky->R, wcs->toSky->D, wcs->cdelt1*PM_RAD_DEG, wcs->cdelt2*PM_RAD_DEG, wcs->toSky->type);
+    fpa->toSky->radial = psMemIncrRefCounter (wcs->toSky->radial);
 
     // create transformation with 0,0 reference pixel
@@ -639,8 +682,8 @@
     // convert fpa->toTPA to units of unity (microns/micron)
     for (int i = 0; i <= fpa->toTPA->x->nX; i++) {
-        for (int j = 0; j <= fpa->toTPA->x->nY; j++) {
-            fpa->toTPA->x->coeff[i][j] /= wcs->cdelt1;
-            fpa->toTPA->y->coeff[i][j] /= wcs->cdelt2;
-        }
+	for (int j = 0; j <= fpa->toTPA->x->nY; j++) {
+	    fpa->toTPA->x->coeff[i][j] /= wcs->cdelt1;
+	    fpa->toTPA->y->coeff[i][j] /= wcs->cdelt2;
+	}
     }
 
@@ -648,5 +691,7 @@
     // the region defines the FPA pixels covered by the tranformation
     psFree (fpa->fromTPA);
-    fpa->fromTPA = psPlaneTransformInvert(NULL, fpa->toTPA, region, 50);
+    psPlaneTransform *myPT = psPlaneTransformAlloc(fpa->toTPA->x->nX+4, fpa->toTPA->x->nY+4);
+    fpa->fromTPA = psPlaneTransformInvert(myPT, fpa->toTPA, region, 50);
+    psFree (myPT);
     return true;
 }
@@ -684,13 +729,13 @@
 
     for (int i = 0; i <= toTPA->x->nX; i++) {
-        for (int j = 0; j <= toTPA->x->nY; j++) {
-            double f1 = chip->toFPA->x->coeffMask[i][j] ? 0.0 : fpa->toTPA->x->coeff[1][0]*chip->toFPA->x->coeff[i][j];
-            double f2 = chip->toFPA->y->coeffMask[i][j] ? 0.0 : fpa->toTPA->x->coeff[0][1]*chip->toFPA->y->coeff[i][j];
-            toTPA->x->coeff[i][j] = f1 + f2;
-
-            double g1 = chip->toFPA->x->coeffMask[i][j] ? 0.0 : fpa->toTPA->y->coeff[1][0]*chip->toFPA->x->coeff[i][j];
-            double g2 = chip->toFPA->y->coeffMask[i][j] ? 0.0 : fpa->toTPA->y->coeff[0][1]*chip->toFPA->y->coeff[i][j];
-            toTPA->y->coeff[i][j] = g1 + g2;
-        }
+	for (int j = 0; j <= toTPA->x->nY; j++) {
+	    double f1 = chip->toFPA->x->coeffMask[i][j] ? 0.0 : fpa->toTPA->x->coeff[1][0]*chip->toFPA->x->coeff[i][j];
+	    double f2 = chip->toFPA->y->coeffMask[i][j] ? 0.0 : fpa->toTPA->x->coeff[0][1]*chip->toFPA->y->coeff[i][j];
+	    toTPA->x->coeff[i][j] = f1 + f2;
+
+	    double g1 = chip->toFPA->x->coeffMask[i][j] ? 0.0 : fpa->toTPA->y->coeff[1][0]*chip->toFPA->x->coeff[i][j];
+	    double g2 = chip->toFPA->y->coeffMask[i][j] ? 0.0 : fpa->toTPA->y->coeff[0][1]*chip->toFPA->y->coeff[i][j];
+	    toTPA->y->coeff[i][j] = g1 + g2;
+	}
     }
     toTPA->x->coeff[0][0] += fpa->toTPA->x->coeff[0][0];
@@ -701,4 +746,6 @@
     // convert projection from FPA to SKY into wcs projection (degrees to radians)
     wcs->toSky = psProjectionAlloc (fpa->toSky->R, fpa->toSky->D, PM_RAD_DEG, PM_RAD_DEG, fpa->toSky->type);
+    wcs->toSky->radial = psMemIncrRefCounter (fpa->toSky->radial);
+
     wcs->crval1 = fpa->toSky->R*PS_DEG_RAD;
     wcs->crval2 = fpa->toSky->D*PS_DEG_RAD;
@@ -714,9 +761,9 @@
     psPlane *center = psPlaneTransformGetCenter (tpa1, tol);
     if (!center) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to solve for TPA center.");
-        psFree (toTPA);
-        psFree (tpa1);
-        psFree (wcs);
-        return NULL;
+	psError(PS_ERR_UNKNOWN, false, "Unable to solve for TPA center.");
+	psFree (toTPA);
+	psFree (tpa1);
+	psFree (wcs);
+	return NULL;
     }
 
@@ -751,8 +798,8 @@
     // convert wcs->trans to a matrix with units of degrees/pixel
     for (int i = 0; i <= wcs->trans->x->nX; i++) {
-        for (int j = 0; j <= wcs->trans->x->nY; j++) {
-            wcs->trans->x->coeff[i][j] *= pdelt1;
-            wcs->trans->y->coeff[i][j] *= pdelt2;
-        }
+	for (int j = 0; j <= wcs->trans->x->nY; j++) {
+	    wcs->trans->x->coeff[i][j] *= pdelt1;
+	    wcs->trans->y->coeff[i][j] *= pdelt2;
+	}
     }
 
@@ -773,5 +820,9 @@
 */
 
-// convert the chip-level toFPA to a wcs polynomial transformation
+// convert the chip-level toFPA to a wcs polynomial transformation.  the pmAstromWCS
+// structure represents a single layer transformation (e.g., RA-TAN, RA-WRP).  Here we are
+// converting the chip-level to a WRP projection in the structure.  Later, this will be
+// converted to the WCS keywords
+
 pmAstromWCS *pmAstromWCSBilevelChipFromFPA (const pmChip *chip, double tol)
 {
@@ -784,27 +835,27 @@
     pmAstromWCS *wcs = pmAstromWCSAlloc(chip->toFPA->x->nX, chip->toFPA->x->nY);
 
+    // copy the toFPA x,y, transformations to the wcs version
+    wcs->trans->x = psPolynomial2DCopy (wcs->trans->x, chip->toFPA->x);
+    wcs->trans->y = psPolynomial2DCopy (wcs->trans->y, chip->toFPA->y);
+
     // Chip to FPA transformation is a Cartesian 'projection'
     // reference pixel for FPA is 0.0, 0.0
     wcs->toSky = psProjectionAlloc (0.0, 0.0, 1.0, 1.0, PS_PROJ_WRP);
-    wcs->crval1 = 0.0;
-    wcs->crval2 = 0.0;
-
-    // given transformation, solve for coordinates which yields output coordinates of 0,0
-    psPlane *center = psPlaneTransformGetCenter (chip->toFPA, tol);
-    if (!center) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to solve for TPA center.");
-        psFree (wcs);
-        return NULL;
-    }
-
-    // adjust wcs transform to use center as reference coordinate
-    // resulting transformation has units of microns/pixel
-    psPlaneTransformSetCenter (wcs->trans, chip->toFPA, center->x, center->y);
-
-    // calculated center is crpix1,2
-    wcs->crpix1 = center->x;
-    wcs->crpix2 = center->y;
-    psFree (center);
-
+
+    // reference pixel (CRPIX1,2) is (0.0, 0.0):
+    wcs->crpix1 = 0.0;
+    wcs->crpix2 = 0.0;
+
+    // we need to set CRVAL1,2 for the 0,0 pixel:
+    wcs->crval1 = psPolynomial2DEval (chip->toFPA->x, 0.0, 0.0);
+    wcs->crval2 = psPolynomial2DEval (chip->toFPA->y, 0.0, 0.0);
+
+    wcs->toSky->R = wcs->crval1*PM_RAD_DEG;
+    wcs->toSky->D = wcs->crval2*PM_RAD_DEG;
+
+    // these need to be set to 0.0 since they have been moved to crpix1,crpix2
+    wcs->trans->x->coeff[0][0] = 0.0;
+    wcs->trans->y->coeff[0][0] = 0.0;
+    
     // output coordinates are in microns : CDELT1,2 has units of microns/pixel
     wcs->cdelt1 = hypot (wcs->trans->x->coeff[1][0], wcs->trans->x->coeff[0][1]);
@@ -834,7 +885,7 @@
     psPlane *center = psPlaneTransformGetCenter (fpa->toTPA, tol);
     if (!center) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to solve for TPA center.");
-        psFree (wcs);
-        return NULL;
+	psError(PS_ERR_UNKNOWN, false, "Unable to solve for TPA center.");
+	psFree (wcs);
+	return NULL;
     }
 
@@ -854,8 +905,8 @@
     // convert wcs->trans to units of degree/micron
     for (int i = 0; i <= wcs->trans->x->nX; i++) {
-        for (int j = 0; j <= wcs->trans->x->nY; j++) {
-            wcs->trans->x->coeff[i][j] *= pdelt1;
-            wcs->trans->y->coeff[i][j] *= pdelt2;
-        }
+	for (int j = 0; j <= wcs->trans->x->nY; j++) {
+	    wcs->trans->x->coeff[i][j] *= pdelt1;
+	    wcs->trans->y->coeff[i][j] *= pdelt2;
+	}
     }
 
@@ -880,16 +931,16 @@
     int k=0;
     for (int j=0; j<nSamples; j++) {
-        double y = bounds->y0 + (j * deltaY / nSamples);
-        for (int i=0; i<nSamples; i++) {
-            psPlane *s = psPlaneAlloc();
-            s->x = bounds->x0 + (i * deltaX / nSamples);
-            s->y = y;
-            psArraySet(src, k, s);
-            psPlane *d = psPlaneTransformApply(NULL, trans, s);
-            psArraySet(dst, k, d);
-            psFree(s);  // drop our refs to s and d
-            psFree(d);
-            ++k;
-        }
+	double y = bounds->y0 + (j * deltaY / nSamples);
+	for (int i=0; i<nSamples; i++) {
+	    psPlane *s = psPlaneAlloc();
+	    s->x = bounds->x0 + (i * deltaX / nSamples);
+	    s->y = y;
+	    psArraySet(src, k, s);
+	    psPlane *d = psPlaneTransformApply(NULL, trans, s);
+	    psArraySet(dst, k, d);
+	    psFree(s);  // drop our refs to s and d
+	    psFree(d);
+	    ++k;
+	}
     }
 
@@ -897,6 +948,6 @@
 
     if (!psPlaneTransformFit(newTrans, src, dst, 0, 0)) {
-        psError(PS_ERR_UNKNOWN, false, "linear fit to transform failed");
-        return NULL;
+	psError(PS_ERR_UNKNOWN, false, "linear fit to transform failed");
+	return NULL;
     }
 
@@ -907,14 +958,14 @@
     printf("   i     chip_x  tpa_x     tpa_x_fit     dx         chip_y    tpa_y     tpa_y_fit     dy     dx > 0.5 || dy > 0.5\n");
     for (int i=0; i<psArrayLength(dst); i++) {
-        psPlane *d = (psPlane *) psArrayGet(dst, i);
-        psPlane *s = (psPlane *) psArrayGet(src, i);
-
-        new = psPlaneTransformApply(new, newTrans, s);
-
-        double xerr = new->x - d->x;
-        double yerr = new->y - d->y;
-        bool bigerr = (fabs(xerr) > .5) || (fabs(yerr) > .5);
-        printf("%4d %9.2f %9.2f %9.2f %9.4f     %9.2f %9.2f %9.2f %9.4f   %s\n"
-        , i, s->x, new->x, d->x, xerr, s->y, new->y, d->y, yerr, bigerr ? "BIGERR" : "");
+	psPlane *d = (psPlane *) psArrayGet(dst, i);
+	psPlane *s = (psPlane *) psArrayGet(src, i);
+
+	new = psPlaneTransformApply(new, newTrans, s);
+
+	double xerr = new->x - d->x;
+	double yerr = new->y - d->y;
+	bool bigerr = (fabs(xerr) > .5) || (fabs(yerr) > .5);
+	printf("%4d %9.2f %9.2f %9.2f %9.4f     %9.2f %9.2f %9.2f %9.4f   %s\n"
+	       , i, s->x, new->x, d->x, xerr, s->y, new->y, d->y, yerr, bigerr ? "BIGERR" : "");
     }
     psFree(new);
@@ -934,11 +985,11 @@
 
     if (outFPA == NULL) {
-        outFPA = inFPA;
+	outFPA = inFPA;
     }
     if (outChip == NULL) {
-        outChip = inChip;
+	outChip = inChip;
     }
     if (outputBounds == NULL) {
-        outputBounds = pmChipPixels(outChip);
+	outputBounds = pmChipPixels(outChip);
     }
 
@@ -946,6 +997,6 @@
     psPlaneTransform *chipToTPA = psPlaneTransformCombine(NULL, inChip->toFPA, inFPA->toTPA, *outputBounds, 50);
     if (!chipToTPA) {
-        psError(PS_ERR_UNKNOWN, false, "failed to create chipToTPA");
-        return false;
+	psError(PS_ERR_UNKNOWN, false, "failed to create chipToTPA");
+	return false;
     }
 
@@ -954,6 +1005,6 @@
     psFree(chipToTPA);
     if (!chipToFPA) {
-        psError(PS_ERR_UNKNOWN, false, "linear fit of chip to TPA transform failed");
-        return false;
+	psError(PS_ERR_UNKNOWN, false, "linear fit of chip to TPA transform failed");
+	return false;
     }
 
@@ -961,15 +1012,15 @@
     psPlaneTransform *outToFPA;
     if (offset_x != 0. && offset_y != 0.) {
-        outToFPA = psPlaneTransformSetCenter(NULL, chipToFPA, offset_x, offset_y);
-        psFree(chipToFPA);
+	outToFPA = psPlaneTransformSetCenter(NULL, chipToFPA, offset_x, offset_y);
+	psFree(chipToFPA);
     } else {
-        outToFPA = chipToFPA;
+	outToFPA = chipToFPA;
     }
 
     psPlaneTransform *outFromFPA = psPlaneTransformInvert(NULL, outToFPA, *outputBounds, 50);
     if (!outFromFPA) {
-        psFree(outToFPA);
-        psError(PS_ERR_UNKNOWN, false, "inversion of fit of output chip toFPA failed");
-        return false;
+	psFree(outToFPA);
+	psError(PS_ERR_UNKNOWN, false, "inversion of fit of output chip toFPA failed");
+	return false;
     }
 
@@ -1023,30 +1074,30 @@
 
     for (int j = 0; j < nSamples; j++) {
-        double y = bounds->y0 + (j * deltaY / nSamples);
-        for (int i =  0; i < nSamples; i++) {
-
-            psSphere srcSky;
-            psPlane *srcChip = psPlaneAlloc();
-            psPlane *dstTP = psPlaneAlloc();
-
-            srcChip->x = bounds->x0 + (i * deltaX / nSamples);
-            srcChip->y = y;
-
-            psPlaneTransformApply (&srcFP, inChip->toFPA, srcChip);
-            psPlaneTransformApply (&srcTP, inFPA->toTPA, &srcFP);
-            psDeproject (&srcSky, &srcTP, inFPA->toSky);
-
-            // fprintf (stderr, "%f %f | %f %f | %f %f | %f %f\n", srcChip->x, srcChip->y, srcFP.x, srcFP.y, srcTP.x, srcTP.y, srcSky.r*PS_DEG_RAD, srcSky.d*PS_DEG_RAD);
-
-            psProject (dstTP, &srcSky, outFPA->toSky);
-
-            srcChip->x -= bounds->x0;
-            srcChip->y -= bounds->y0;
-            psArrayAdd (src, 100, srcChip);
-            psArrayAdd (dst, 100, dstTP);
-
-            psFree(srcChip);  // drop our refs to s and d
-            psFree(dstTP);
-        }
+	double y = bounds->y0 + (j * deltaY / nSamples);
+	for (int i =  0; i < nSamples; i++) {
+
+	    psSphere srcSky;
+	    psPlane *srcChip = psPlaneAlloc();
+	    psPlane *dstTP = psPlaneAlloc();
+
+	    srcChip->x = bounds->x0 + (i * deltaX / nSamples);
+	    srcChip->y = y;
+
+	    psPlaneTransformApply (&srcFP, inChip->toFPA, srcChip);
+	    psPlaneTransformApply (&srcTP, inFPA->toTPA, &srcFP);
+	    psDeproject (&srcSky, &srcTP, inFPA->toSky);
+
+	    // fprintf (stderr, "%f %f | %f %f | %f %f | %f %f\n", srcChip->x, srcChip->y, srcFP.x, srcFP.y, srcTP.x, srcTP.y, srcSky.r*PS_DEG_RAD, srcSky.d*PS_DEG_RAD);
+
+	    psProject (dstTP, &srcSky, outFPA->toSky);
+
+	    srcChip->x -= bounds->x0;
+	    srcChip->y -= bounds->y0;
+	    psArrayAdd (src, 100, srcChip);
+	    psArrayAdd (dst, 100, dstTP);
+
+	    psFree(srcChip);  // drop our refs to s and d
+	    psFree(dstTP);
+	}
     }
 
@@ -1056,8 +1107,8 @@
 
     if (!psPlaneTransformFit(newToFPA, src, dst, 0, 0)) {
-        psError(PS_ERR_UNKNOWN, false, "linear fit to transform failed");
-        psFree(src);
-        psFree(dst);
-        return NULL;
+	psError(PS_ERR_UNKNOWN, false, "linear fit to transform failed");
+	psFree(src);
+	psFree(dst);
+	return NULL;
     }
 
@@ -1065,15 +1116,15 @@
     for (int i = 0; i < src->n; i++) {
 
-        psSphere srcSky, dstSky;
-        psPlane *srcChip = src->data[i];
-        psPlane *dstTP   = dst->data[i];
-
-        psPlaneTransformApply (&srcFP, newToFPA, srcChip);
-        psDeproject (&srcSky, &srcFP, outFPA->toSky);
-        psDeproject (&dstSky, dstTP, outFPA->toSky);
-
-        double dX = (srcSky.r*PS_DEG_RAD - dstSky.r*PS_DEG_RAD)*3600.0;
-        double dY = (srcSky.d*PS_DEG_RAD - dstSky.d*PS_DEG_RAD)*3600.0;
-        fprintf (stderr, "%f %f | %f %f | %f %f | %f %f | %f %f | %f %f\n", dX, dY, srcChip->x, srcChip->y, srcFP.x, srcFP.y, dstTP->x, dstTP->y, srcSky.r*PS_DEG_RAD, srcSky.d*PS_DEG_RAD, dstSky.r*PS_DEG_RAD, dstSky.d*PS_DEG_RAD);
+	psSphere srcSky, dstSky;
+	psPlane *srcChip = src->data[i];
+	psPlane *dstTP   = dst->data[i];
+
+	psPlaneTransformApply (&srcFP, newToFPA, srcChip);
+	psDeproject (&srcSky, &srcFP, outFPA->toSky);
+	psDeproject (&dstSky, dstTP, outFPA->toSky);
+
+	double dX = (srcSky.r*PS_DEG_RAD - dstSky.r*PS_DEG_RAD)*3600.0;
+	double dY = (srcSky.d*PS_DEG_RAD - dstSky.d*PS_DEG_RAD)*3600.0;
+	fprintf (stderr, "%f %f | %f %f | %f %f | %f %f | %f %f | %f %f\n", dX, dY, srcChip->x, srcChip->y, srcFP.x, srcFP.y, dstTP->x, dstTP->y, srcSky.r*PS_DEG_RAD, srcSky.d*PS_DEG_RAD, dstSky.r*PS_DEG_RAD, dstSky.d*PS_DEG_RAD);
 
     }
@@ -1086,7 +1137,7 @@
     psPlaneTransform *newFromFPA = psPlaneTransformInvert(NULL, newToFPA, *bounds, 1);
     if (!newFromFPA) {
-        psFree(newToFPA);
-        psError(PS_ERR_UNKNOWN, false, "inversion of fit of output chip toFPA failed");
-        return false;
+	psFree(newToFPA);
+	psError(PS_ERR_UNKNOWN, false, "inversion of fit of output chip toFPA failed");
+	return false;
     }
 
@@ -1111,5 +1162,5 @@
 
     if (!wcs)
-        return;
+	return;
     psFree (wcs->trans);
     psFree (wcs->toSky);
@@ -1133,16 +1184,16 @@
 /*****
 
-For mosaic astrometry, we need to have a starting set of projection terms in which the
-chip-to-FPA terms result in a fixed physical unit on the focal plane (eg, pixels or
-microns).  This set of projections, coupled with an identity toTPA (ie, no distortion) will
-result in substantial errors between the observed and predicted star positions on the focal
-plane: this is the measurement of the optical distortion in the camera.  At the same time,
-we need to carry around the transformations which allow us to make an accurate calculation
-of the position of the stars based on the input (per-chip) astrometry.  These
-transformations will allow us to match the raw and ref stars robustly.  To convert the
-per-chip astrometry (which may have been calculated with a different plate scale for each
-chip) to a collection of astrometry terms for chips in a single mosaic, we need to adjust
-the chip-to-FPA scaling (eg, pc11) to match the variations in the effective plate scale for
-each chip (eg, cdelt1).  Thus, we need to carry around both the
+      For mosaic astrometry, we need to have a starting set of projection terms in which the
+      chip-to-FPA terms result in a fixed physical unit on the focal plane (eg, pixels or
+      microns).  This set of projections, coupled with an identity toTPA (ie, no distortion) will
+      result in substantial errors between the observed and predicted star positions on the focal
+      plane: this is the measurement of the optical distortion in the camera.  At the same time,
+      we need to carry around the transformations which allow us to make an accurate calculation
+      of the position of the stars based on the input (per-chip) astrometry.  These
+      transformations will allow us to match the raw and ref stars robustly.  To convert the
+      per-chip astrometry (which may have been calculated with a different plate scale for each
+      chip) to a collection of astrometry terms for chips in a single mosaic, we need to adjust
+      the chip-to-FPA scaling (eg, pc11) to match the variations in the effective plate scale for
+      each chip (eg, cdelt1).  Thus, we need to carry around both the
 
 *****/
Index: trunk/psModules/src/detrend/pmFringeStats.c
===================================================================
--- trunk/psModules/src/detrend/pmFringeStats.c	(revision 39907)
+++ trunk/psModules/src/detrend/pmFringeStats.c	(revision 39926)
@@ -336,6 +336,12 @@
         dfPt[i] = 1.0 / medianSd->sampleStdev;
 
-        psTrace("psModules.detrend", 7, "[%d:%d,%d:%d]: %f %f : %s\n", (int)region.x0, (int)region.x1,
-                (int)region.y0, (int)region.y1, fPt[i], dfPt[i], readout->parent->hdu->extname);
+	if (readout->parent->hdu) {
+	  psTrace("psModules.detrend", 7, "[%d:%d,%d:%d]: %f %f : %s\n", (int)region.x0, (int)region.x1,
+		  (int)region.y0, (int)region.y1, fPt[i], dfPt[i], readout->parent->hdu->extname);
+	}
+	else {
+	  psTrace("psModules.detrend", 7, "[%d:%d,%d:%d]: %f %f : THIS_IS_A_SPOOKY_GHOST_CELL\n", (int)region.x0, (int)region.x1,
+		  (int)region.y0, (int)region.y1, fPt[i], dfPt[i]);
+	}
     }
     psFree(sky);
Index: trunk/psModules/src/objects/pmPCM_MinimizeChisq.c
===================================================================
--- trunk/psModules/src/objects/pmPCM_MinimizeChisq.c	(revision 39907)
+++ trunk/psModules/src/objects/pmPCM_MinimizeChisq.c	(revision 39926)
@@ -480,5 +480,5 @@
 # if (TESTCOPY)
     psImageCopy (pcm->modelConvFlux, pcm->modelFlux, pcm->modelFlux->type.type);
-# else
+# else // TESTCOPY
     if (pcm->use1Dgauss) {
 
@@ -496,5 +496,5 @@
 	psImageConvolveKernel (pcm->modelConvFlux, pcm->modelFlux, NULL, 0, pcm->psfFFT);
     }
-# endif
+# endif // TESTCOPY
 
     for (int n = 0; n < pcm->dmodelsFlux->n; n++) {
@@ -505,5 +505,5 @@
 # if (TESTCOPY)
 	psImageCopy (dmodelConv, dmodel, dmodel->type.type);
-# else
+# else // TESTCOPY
 	if (pcm->use1Dgauss) {
 	    if (USE_1D_CACHE) {
@@ -520,7 +520,7 @@
 	    psImageConvolveKernel (dmodelConv, dmodel, NULL, 0, pcm->psfFFT);
 	}
-# endif
-    }
-# else
+# endif // TESTCOPY
+    }
+# else // PRE_CONVOLVE
     // convolve model image and derivative images with psf via FFT
     psImageConvolveFFT (pcm->modelConvFlux, pcm->modelFlux, NULL, 0, pcm->psf);
@@ -547,5 +547,5 @@
     }
 # endif // PRE-CONVOLVE
-# else
+# else // USE_FFT
     // convolve model image and derivative images with psf direct
     psImageConvolveDirect (pcm->modelConvFlux, pcm->modelFlux, pcm->psf);
Index: trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c
===================================================================
--- trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c	(revision 39907)
+++ trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c	(revision 39926)
@@ -119,4 +119,6 @@
                         psMetadataAdd (row, PS_LIST_TAIL, "RA_REF",     PS_DATA_F64, "right ascension (deg, J2000)", PM_DEG_RAD*ref->sky->r);
                         psMetadataAdd (row, PS_LIST_TAIL, "DEC_REF",    PS_DATA_F64, "declination (deg, J2000)",     PM_DEG_RAD*ref->sky->d);
+                        psMetadataAdd (row, PS_LIST_TAIL, "RA_RAW",     PS_DATA_F64, "right ascension (deg, J2000)", PM_DEG_RAD*raw->sky->r);
+                        psMetadataAdd (row, PS_LIST_TAIL, "DEC_RAW",    PS_DATA_F64, "declination (deg, J2000)",     PM_DEG_RAD*raw->sky->d);
                         psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP_REF", PS_DATA_F32, "x fitted coord on chip",       ref->chip->x);
                         psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP_REF", PS_DATA_F32, "y fitted coord on chip",       ref->chip->y);
Index: trunk/psastro/src/psastro.h
===================================================================
--- trunk/psastro/src/psastro.h	(revision 39907)
+++ trunk/psastro/src/psastro.h	(revision 39926)
@@ -70,5 +70,5 @@
 bool              psastroCorrectKH (pmConfig *config, pmFPAview *view, pmReadout *readout, psMetadata *recipe, psArray *inStars);
 
-psArray          *pmSourceToAstromObj (psArray *sources);
+psArray          *pmSourceToAstromObj (psArray *sources, float MagOffset);
 bool              psastroAstromGuess (int *nStars, pmConfig *config);
 bool              psastroAstromGuessCheck (pmConfig *config);
Index: trunk/psastro/src/psastroAstromGuess.c
===================================================================
--- trunk/psastro/src/psastroAstromGuess.c	(revision 39907)
+++ trunk/psastro/src/psastroAstromGuess.c	(revision 39926)
@@ -75,5 +75,6 @@
     pmFPA *fpa = input->fpa;
 
-    if (DEBUG) psastroDumpCorners ("corners.up.guess1.dat", "corners.dn.guess1.dat", fpa);
+    // this call only works if we have loaded a model : seg fault if not
+    if (DEBUG && useModel) psastroDumpCorners ("corners.up.guess1.dat", "corners.dn.guess1.dat", fpa);
 
     // load mosaic-level astrometry?
@@ -91,4 +92,10 @@
             if (!psastroAstromGuessSetChip (fpa, chip, view, pixelScale, bilevelAstrometry)) continue;
         }
+
+	if (!chip->toFPA || !chip->fromFPA) {
+	  char *name = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
+	  fprintf (stderr, "no astrom model for %s, skipping\n", name);
+	  continue;
+	}
 
         if (newFPA) {
@@ -312,4 +319,10 @@
     while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) {
         if (!chip->process || !chip->file_exists || !chip->data_exists) { continue; }
+
+	if (!chip->toFPA || !chip->fromFPA) {
+	  char *name = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
+	  fprintf (stderr, "no astrom model for %s, skipping\n", name);
+	  continue;
+	}
 
         // XXX we are currently inconsistent with marking the good vs the bad data
Index: trunk/psastro/src/psastroChipAstrom.c
===================================================================
--- trunk/psastro/src/psastroChipAstrom.c	(revision 39907)
+++ trunk/psastro/src/psastroChipAstrom.c	(revision 39926)
@@ -85,9 +85,9 @@
 		  for (int nn = 0; nn < refstars->n; nn++) {
 		    pmAstromObj *ref = refstars->data[nn];
-		    fprintf (outfile, "%lf %lf  %lf %lf  %lf %lf  %lf %lf\n", 
+		    fprintf (outfile, "%lf %lf  %lf %lf  %lf %lf  %lf %lf : %f %f\n", 
 			     ref->sky->r*PS_DEG_RAD, ref->sky->d*PS_DEG_RAD,
 			     ref->TP->x, ref->TP->y, 
 			     ref->FP->x, ref->FP->y, 
-			     ref->chip->x, ref->chip->y);
+			     ref->chip->x, ref->chip->y, ref->Mag, ref->magCal);
 		  }
 		  fclose (outfile);
@@ -101,9 +101,9 @@
 		  for (int nn = 0; nn < gridrawstars->n; nn++) {
 		    pmAstromObj *ref = gridrawstars->data[nn];
-		    fprintf (outfile, "%lf %lf  %lf %lf  %lf %lf  %lf %lf\n", 
+		    fprintf (outfile, "%lf %lf  %lf %lf  %lf %lf  %lf %lf : %f %f\n", 
 			     ref->sky->r*PS_DEG_RAD, ref->sky->d*PS_DEG_RAD,
 			     ref->TP->x, ref->TP->y, 
 			     ref->FP->x, ref->FP->y, 
-			     ref->chip->x, ref->chip->y);
+			     ref->chip->x, ref->chip->y, ref->Mag, ref->magCal);
 		  }
 		  fclose (outfile);
Index: trunk/psastro/src/psastroConvert.c
===================================================================
--- trunk/psastro/src/psastroConvert.c	(revision 39907)
+++ trunk/psastro/src/psastroConvert.c	(revision 39926)
@@ -51,4 +51,29 @@
     bool status;
 
+    // XXX I want to make this optional
+    float MagOffset = 0.0;
+    if (1) {
+      // select the input data sources
+      pmFPAfile *input = psMetadataLookupPtr (NULL, config->files, "PSASTRO.INPUT");
+      if (!input) {
+	psError(PSASTRO_ERR_CONFIG, true, "failed to find PSASTRO.INPUT\n");
+	return false;
+      }
+      pmFPA *fpa = input->fpa;
+
+      float zeropt, exptime;
+
+      // really error-out here?  or just skip?
+      if (!psastroZeroPointFromRecipe (&zeropt, &exptime, NULL, fpa, recipe)) {
+        psLogMsg ("psastro", PS_LOG_INFO, "failed to load zeropt data from recipe");
+	zeropt = 0.0;
+	exptime = 1.0;
+      }
+
+      // recipe values are given in instrumental magnitudes
+      // use the zero point and exposure time to convert to apparent mags: M_ap = M_inst + C_0 + 2.5*log(exptime)
+      MagOffset = zeropt + 2.5*log10(exptime);
+    }
+
     // PSPHOT.SOURCES carries the pmSource objects (from psphot analysis or loaded externally)
     pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
@@ -59,5 +84,5 @@
 
     // convert the pmSource objects into pmAstromObj objects (drop !STAR and SATSTAR?)
-    psArray *inStars = pmSourceToAstromObj (sources);
+    psArray *inStars = pmSourceToAstromObj (sources, MagOffset);
 
     // apply Koppenhoefer correction if needed
@@ -175,5 +200,5 @@
 
 // select a magnitude range?
-psArray *pmSourceToAstromObj (psArray *sources) {
+psArray *pmSourceToAstromObj (psArray *sources, float MagOffset) {
 
     psArray *objects = psArrayAllocEmpty (sources->n);
@@ -211,4 +236,5 @@
         obj->dMag = source->psfMagErr;
         obj->SBinst = source->psfMag + 5.0*log10(axes.major);
+        obj->magCal = obj->Mag + MagOffset;
 
         // XXX do we have the information giving the readout and cell offset?
Index: trunk/psastro/src/psastroDemoDump.c
===================================================================
--- trunk/psastro/src/psastroDemoDump.c	(revision 39907)
+++ trunk/psastro/src/psastroDemoDump.c	(revision 39926)
@@ -234,4 +234,10 @@
         if (!chip->process || !chip->file_exists || !chip->data_exists) { continue; }
 
+	if (!chip->toFPA || !chip->fromFPA) {
+	  char *name = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
+	  fprintf (stderr, "no astrom model for %s, skipping\n", name);
+	  continue;
+	}
+
 	// XXX write out the four corners for a test
 	psRegion *region = pmChipPixels (chip);
Index: trunk/psastro/src/psastroFixChips.c
===================================================================
--- trunk/psastro/src/psastroFixChips.c	(revision 39907)
+++ trunk/psastro/src/psastroFixChips.c	(revision 39926)
@@ -306,4 +306,5 @@
         psRegion *region = pmChipPixels (obsChip);
         obsChip->toFPA   = toFPA;
+	// NOTE: when we call psPlaneTransformInvert here, we do not increase the order as in other places
         obsChip->fromFPA = psPlaneTransformInvert(NULL, obsChip->toFPA, *region, 50);
         psFree (region);
Index: trunk/psastro/src/psastroLoadRefstars.c
===================================================================
--- trunk/psastro/src/psastroLoadRefstars.c	(revision 39907)
+++ trunk/psastro/src/psastroLoadRefstars.c	(revision 39926)
@@ -265,4 +265,5 @@
             ref->Color    = 0.0;
         }
+	ref->magCal   = ref->Mag;
 
         // XXX VERY temporary hack to avoid M31 bulge
@@ -306,4 +307,5 @@
             ref->Color = 0.0;
         }
+	ref->magCal   = ref->Mag;
 
         // XXX VERY temporary hack to avoid M31 bulge
Index: trunk/psastro/src/psastroModelAdjust.c
===================================================================
--- trunk/psastro/src/psastroModelAdjust.c	(revision 39907)
+++ trunk/psastro/src/psastroModelAdjust.c	(revision 39926)
@@ -28,4 +28,6 @@
     }
 
+
+    
     // if we have not measured the boresite position, no adjustment is needed
     bool fitBoresite = psMetadataLookupBool (&status, recipe, "PSASTRO.MODEL.FIT.BORESITE");
@@ -52,5 +54,14 @@
 	return false; 
     } 
-
+    float refChipAngleNominal = PS_RAD_DEG*psMetadataLookupF32 (&status, recipe, "PSASTRO.MODEL.REF.CHIP.ANGLE");
+    if (!refChipName) {
+	psError(PS_ERR_IO, true, "reference chip is missing from recipe"); 
+	return false; 
+    } 
+
+    int rotatorParity = psMetadataLookupS32(&status, recipe, "PSASTRO.MODEL.ROT.PARITY");
+    if (!status) psAbort ("Can't find recipe option PSASTRO.MODEL.ROT.PARITY");
+    psMetadataAddS32 (output->fpa->concepts, PS_LIST_TAIL, "FPA.ROT_PARITY", PS_META_REPLACE, "rotator parity parameter", rotatorParity);
+    
     // get reference chip from name
     pmChip *refChip = pmConceptsChipFromName (output->fpa, refChipName);
@@ -81,11 +92,18 @@
 	psFree (PT);
     }
-
+    
     // rotate the chip-to-FPA transforms to have 0.0 posangle for refChip; 
     // compensate by rotating fpa to TPA transform
 
     // get the current posangle of the ref chip
-    float chipAngle = atan2 (refChip->toFPA->y->coeff[1][0], refChip->toFPA->x->coeff[1][0]);
-    fprintf (stderr, "chipAngle: %f\n", chipAngle*PS_DEG_RAD);
+    // this should have a negative sign : chipAngle = -atan2 (dM/dy, dM/dx)
+    float chipAngle = -atan2 (refChip->toFPA->y->coeff[1][0], refChip->toFPA->x->coeff[1][0]);
+
+    // chipAngle should be refChipAngleNominal @ POSANGLE = 0.0
+    float posAngleOffset = rotatorParity * (chipAngle - refChipAngleNominal);
+
+    fprintf (stderr, "chipAngle is: %f, at PA = 0.0, it should be %f, rotating model by %f (parity %d)\n", 
+	     chipAngle*PS_DEG_RAD, refChipAngleNominal*PS_DEG_RAD, posAngleOffset*PS_DEG_RAD, rotatorParity);
+
     // psMetadataAddF32 (output->fpa->concepts, PS_LIST_TAIL, "FPA.POSANGLE", PS_META_REPLACE, "boresite parameter", posangle);
 
@@ -99,9 +117,11 @@
 	psRegion *region = pmChipPixels (chip);
 
-	psPlaneTransform *toFPA = psPlaneTransformRotate (NULL, chip->toFPA, chipAngle);
+	// this should ALSO have a negative sign: this rotates by +posAngleOffset
+	psPlaneTransform *toFPA = psPlaneTransformRotate (NULL, chip->toFPA, posAngleOffset);
 	psFree (chip->toFPA);
 	chip->toFPA = toFPA;
 
 	// invert the new fromFPA transform to get the new toFPA transform
+	// NOTE: when we call psPlaneTransformInvert here, we do not increase the order as in other places
 	psPlaneTransform *fromFPA = psPlaneTransformInvert(NULL, chip->toFPA, *region, 50);
 	psFree (chip->fromFPA);
@@ -125,4 +145,5 @@
 
     psFree (output->fpa->fromTPA);
+    // NOTE: when we call psPlaneTransformInvert here, we do not increase the order as in other places
     output->fpa->fromTPA = psPlaneTransformInvert(NULL, output->fpa->toTPA, *fpaRegion, 50);
 
@@ -131,4 +152,5 @@
 
     psMetadata *header = output->fpa->hdu->header;
+    
     pmAstromWriteBilevelMosaic (header, output->fpa, NONLIN_TOL);
 
@@ -172,4 +194,5 @@
 	// invert the new fromFPA transform to get the new toFPA transform
 	// the region used here is the region covered by the chip in the FPA
+	// NOTE: when we call psPlaneTransformInvert here, we do not increase the order as in other places
 	psPlaneTransform *fromFPA = psPlaneTransformInvert(NULL, chip->toFPA, *region, 50); 
 	psFree (chip->fromFPA);
Index: trunk/psastro/src/psastroMosaicAstrom.c
===================================================================
--- trunk/psastro/src/psastroMosaicAstrom.c	(revision 39907)
+++ trunk/psastro/src/psastroMosaicAstrom.c	(revision 39926)
@@ -15,4 +15,5 @@
 
 bool psastroMosaicFit (pmFPA *fpa, psMetadata *recipe, const char *rootname, int pass);
+bool psastroProjectionRefit (pmFPA *fpa, psMetadata *recipe);
 
 // XXX require this fpa to have multiple chip extensions and a PHU?
@@ -43,27 +44,36 @@
     if (!status) psAbort ("missing config value");
 
+    // if projection is not TAN, fit the measured projection here and combine toTPA/fromTPA functions
+    bool fitMosaicDistortion = true;
+    if ((fpa->toSky->type != PS_PROJ_TAN) && (fpa->toSky->type != PS_PROJ_DIS)) {
+      if (!psastroProjectionRefit (fpa, recipe)) psAbort ("failed to refit distortion");
+      fitMosaicDistortion = false;
+    }
+
     // this should be in a loop with nIter =
-    for (int iter = 0; iter < nIter; iter++) {
+    for (int iter = 0; fitMosaicDistortion && (iter < nIter); iter++) {
         if (!psastroMosaicFit (fpa, recipe, outroot, iter)) return false;
     }
 
-    // now fit the chips under the common distortion with higher-order terms
-    // first, re-perform the match with a slightly tighter circle
-    if (!psastroMosaicSetMatch (fpa, recipe, nIter)) {
-        psError(PSASTRO_ERR_UNKNOWN, false, "failed to match raw and ref stars for mosaic (4th pass)");
-        return false;
-    }
-    if (!psastroMosaicChipAstrom (fpa, recipe, nIter)) {
-        psError(PSASTRO_ERR_UNKNOWN, false, "failed to measure chip astrometry in mosaic mode (4th pass)");
-        return false;
-    }
-
-    if (psTraceGetLevel("psastro.dump") > 0) {
+    for (int iter = 0; (iter < nIter); iter++) {
+      // now fit the chips under the common distortion with higher-order terms
+      // first, re-perform the match with a slightly tighter circle
+      if (!psastroMosaicSetMatch (fpa, recipe, iter)) {
+        psError(PSASTRO_ERR_UNKNOWN, false, "failed to match raw and ref stars for mosaic (4th pass %d)", iter);
+        return false;
+      }
+      if (!psastroMosaicChipAstrom (fpa, recipe, iter)) {
+        psError(PSASTRO_ERR_UNKNOWN, false, "failed to measure chip astrometry in mosaic mode (pass %d)", iter);
+        return false;
+      }
+      
+      if (psTraceGetLevel("psastro.dump") > 0) {
         // the last filename (see filenames in psastroMosaicFit)
         char filename[256];
         snprintf (filename, 256, "%s.%d.dat", outroot, 2*nIter + 2);
         psastroDumpMatches (fpa, filename);
-    }
-
+      }
+    }
+    
     // save WCS and analysis metadata in update header.
     // (pull or create local view to entry on readout->analysis)
@@ -154,2 +164,143 @@
     return true;
 }
+
+// we have a fpa->toSky projection which is NOT of type TAN along with a toTPA which is
+// the Identity transform.  we want to convert this to TAN projection plus a non-identity
+// transformation to take the non-TAN components.
+
+// we are going to generate a set of FP->(x,y) using the current projection + fromTPA
+// transformations along with a set of TP->(x,y) values using the desired TAN projection,
+// then we will fit TP vs FP
+
+bool psastroProjectionRefit (pmFPA *fpa, psMetadata *recipe) {
+
+  bool status;
+
+    // allocate mosaic-level polynomial transformation and set masks needed by DVO
+    int order = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.ORDER");
+    if (!status) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to find mosaic distortion fit order\n");
+        return false;
+    }
+
+    pmChip *chip = NULL;
+    pmCell *cell = NULL;
+    pmReadout *readout = NULL;
+    pmFPAview *view = pmFPAviewAlloc (0);
+
+    psVector *L = psVectorAllocEmpty (1000, PS_TYPE_F32);
+    psVector *M = psVectorAllocEmpty (1000, PS_TYPE_F32);
+
+    psVector *P = psVectorAllocEmpty (1000, PS_TYPE_F32);
+    psVector *Q = psVectorAllocEmpty (1000, PS_TYPE_F32);
+
+    psProjection *toSkyTan = psProjectionAlloc (fpa->toSky->R, fpa->toSky->D, fpa->toSky->Xs, fpa->toSky->Ys, PS_PROJ_TAN);
+
+    float xMin = NAN;
+    float xMax = NAN;
+    float yMin = NAN;
+    float yMax = NAN;
+
+    bool firstObject = true;
+
+    // this loop selects the matched stars for all chips
+    while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) {
+        psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process || !chip->file_exists) continue;
+	
+	while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
+            psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+            if (!cell->process || !cell->file_exists) continue;
+
+	    // process each of the readouts
+	    // XXX there can only be one readout per chip, right?
+	    while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
+		if (! readout->data_exists) continue;
+
+		// select the raw objects for this readout
+		psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS.SUBSET");
+		if (refstars == NULL) continue;
+		psTrace ("psastro", 4, "Trying %ld refstars\n", refstars->n);
+
+		psArray *matches = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.MATCH");
+		if (matches == NULL) continue;
+
+		// we are looking over the matched refstars only to be sure we are
+		// covering the valid space of the projection + transformation, and not
+		// beyond
+
+		for (int i = 0; i < matches->n; i++) {
+		    pmAstromMatch *match = matches->data[i];
+		    pmAstromObj *ref = refstars->data[match->ref];
+
+		    psPlane fpOld, tpNew, tpOld;
+
+		    psProject (&tpOld, ref->sky, fpa->toSky); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
+		    psPlaneTransformApply (&fpOld, fpa->fromTPA, &tpOld);
+
+		    psProject (&tpNew, ref->sky, toSkyTan); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
+
+		    psVectorAppend (L, fpOld.x);
+		    psVectorAppend (M, fpOld.y);
+
+		    psVectorAppend (P, tpNew.x);
+		    psVectorAppend (Q, tpNew.y);
+
+		    if (firstObject) {
+		      xMin = xMax = fpOld.x;
+		      yMin = yMax = fpOld.y;
+		      firstObject = false;
+		    }
+
+		    xMin = PS_MIN (xMin, fpOld.x);
+		    xMax = PS_MAX (xMax, fpOld.x);
+		    yMin = PS_MIN (yMin, fpOld.y);
+		    yMax = PS_MAX (yMax, fpOld.y);
+		}
+	    }
+	}
+    }
+
+    // the original transforms are (1, 1), but we will need higher order to fit the distortions
+    psFree (fpa->toTPA);
+
+    // the original transforms are (1, 1), but we will need higher order to fit the distortions
+    fpa->toTPA = psPlaneTransformAlloc (order, order);
+    for (int i = 0; i <= fpa->toTPA->x->nX; i++) {
+        for (int j = 0; j <= fpa->toTPA->x->nY; j++) {
+            if (i + j > order) {
+		fpa->toTPA->x->coeffMask[i][j] = PS_POLY_MASK_SET;
+		fpa->toTPA->y->coeffMask[i][j] = PS_POLY_MASK_SET;
+            }
+        }
+    }
+
+    psVectorFitPolynomial2D (fpa->toTPA->x, NULL, 0, P, NULL, L, M);
+    psVectorFitPolynomial2D (fpa->toTPA->y, NULL, 0, Q, NULL, L, M);
+    
+    psRegion fitRegion = psRegionSet (xMin, xMax, yMin, yMax);
+
+    // psPlaneTransformInvert will generate a new fromTPA with order to match toTPA
+    psFree (fpa->fromTPA);
+    psPlaneTransform *myPT = psPlaneTransformAlloc(fpa->toTPA->x->nX+4, fpa->toTPA->x->nY+4);
+    fpa->fromTPA = psPlaneTransformInvert (myPT, fpa->toTPA, fitRegion, 100);
+    psFree (myPT);
+
+    psFree (fpa->toSky);
+    fpa->toSky = toSkyTan;
+
+    psFree (L);
+    psFree (M);
+    psFree (P);
+    psFree (Q);
+
+    psFree (view);
+
+    if (!psastroMosaicSetAstrom (fpa)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to apply mosaic distortion terms\n");
+        return false;
+    }
+
+    return true;
+}
+
Index: trunk/psastro/src/psastroMosaicCorrectDistortion.c
===================================================================
--- trunk/psastro/src/psastroMosaicCorrectDistortion.c	(revision 39907)
+++ trunk/psastro/src/psastroMosaicCorrectDistortion.c	(revision 39926)
@@ -62,5 +62,7 @@
 
     psFree (fpa->fromTPA);
-    fpa->fromTPA = psPlaneTransformInvert(NULL, fpa->toTPA, *region, 50);
+    psPlaneTransform *myPT = psPlaneTransformAlloc(fpa->toTPA->x->nX+4, fpa->toTPA->x->nY+4);
+    fpa->fromTPA = psPlaneTransformInvert(myPT, fpa->toTPA, *region, 50);
+    psFree (myPT);
     psFree (region);
 
Index: trunk/psastro/src/psastroMosaicGradients.c
===================================================================
--- trunk/psastro/src/psastroMosaicGradients.c	(revision 39907)
+++ trunk/psastro/src/psastroMosaicGradients.c	(revision 39926)
@@ -79,5 +79,5 @@
     int order = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.ORDER");
     if (!status) {
-	psError(PSASTRO_ERR_UNKNOWN, false, "failed to find single-chip fit order\n");
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to find mosaic distortion fit order\n");
 	psFree (gradients);
 	psFree (view);
Index: trunk/psastro/src/psastroMosaicOneChip.c
===================================================================
--- trunk/psastro/src/psastroMosaicOneChip.c	(revision 39907)
+++ trunk/psastro/src/psastroMosaicOneChip.c	(revision 39926)
@@ -100,19 +100,19 @@
     }
 
-    // XXX allow statitic to be set by the user
+    // XXX allow statistic to be set by the user
     // only clip if we are fitting the chip parameters.
     psStats *fitStats = NULL;
-//    if (order == 0) {
-//      fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
-//      fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NSIGMA");
-//      fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER");
-//    } else {
-        fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
-        fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NSIGMA");
-        fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER");
-//    }
+    if (FALSE && (order == 0)) {
+      fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
+      fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NSIGMA");
+      fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER");
+    } else {
+      fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
+      fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NSIGMA");
+      fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER");
+    }
 
     // need to pass in an update header, sent in from above
-    pmAstromFitResults *results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats);
+    pmAstromFitResults *results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats, recipe);
     if (!results) {
         psError(PSASTRO_ERR_DATA, false, "failed to perform the matched fit\n");
Index: trunk/psastro/src/psastroOneChipFit.c
===================================================================
--- trunk/psastro/src/psastroOneChipFit.c	(revision 39907)
+++ trunk/psastro/src/psastroOneChipFit.c	(revision 39926)
@@ -124,5 +124,5 @@
 
         // improved fit for astrometric terms
-        results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats);
+        results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats, recipe);
         if (!results) {
             psLogMsg ("psastro", 3, "failed to perform the matched fit\n");
Index: trunk/psphot/src/psphotSourceStats.c
===================================================================
--- trunk/psphot/src/psphotSourceStats.c	(revision 39907)
+++ trunk/psphot/src/psphotSourceStats.c	(revision 39926)
@@ -560,4 +560,18 @@
         }
 
+	if (psTraceGetLevel("psphot.moments.save")) {
+	  char name[64];
+	  sprintf (name, "moments.v%d.dat", i);
+	  FILE *fout = fopen (name, "w");
+	  for (int j = 0; j < sources->n; j++) {
+            pmSource *source = sources->data[j];
+            psAssert (source->moments, "force moments to exist");
+            source->moments->nPixels = 0;
+            status = pmSourceMoments (source, 20, sigma[i], 0.0, 0.0, maskVal);
+	    fprintf (fout, "%f %f | %f %f %f | %f\n", source->moments->Mx, source->moments->My, source->moments->Mxx, source->moments->Mxy, source->moments->Myy, source->moments->Sum);
+	  }
+	  fclose (fout);
+	}
+
         // choose a grid scale that is a fixed fraction of the psf sigma^2
         float PSF_CLUMP_GRID_SCALE = 0.1*PS_SQR(sigma[i]);
