

#@(#) t_autospec.x 2.18
include <error.h>
include "../aspect.h"
include "../as_comp.h"
include "../as_err.h"
include "../as_fit.h"
include "../as_spec.h"
include "../as_units.h"
define DEBUG false
define MAX_DOMAINS 64
#--------------------------------------------------------------------10 Mar 96--
.help t_autospec.x Jan96 source/tasks
.ih
NAME
.nf
t_autospec - Run the ASpect fitting in batch mode
get_cl_from_db - Build input component list from disk file & append to input CL
fit_report - Report fit progress to STDOUT
.fi
.ih
DESCRIPTION
Task to fit one or more model components to one or more input spectra.
Fetches task parameters, initializes data structures, etc.
.ih
ROUTINE DETAILS
.ls procedure t_autospec ()
.ls ARGUMENTS
.le
.le
.ls procedure get_cl_from_db (cl, db_table)
.ls ARGUMENTS
.ls cl (input/output: pointer)
component list
.le
.ls db_table[ARB] (input: char)
name of input DB table of components
.le
.le
.le
.ls procedure fit_report (iter, chisq, force_flush)
.ls ARGUMENTS
.ls iter (input: int)
the current iteration count
.le
.ls chisq (input: real)
the current chisq value
.le
.ls force_flush (input: bool)
force flushing the output?
.le
.le
.le
.endhelp
#-------------------------------------------------------------------------------
# T_AUTOSPEC - Test driver for spectrum & component input from disk tables,
# and fitting routines. Fetches task parameters, initializes
# data structures, etc.
#
# Revision history:
# 2-Aug-94 by RAShaw Initial implementation
# 3-Aug-94 by RAShaw Allow for multiple fit intervals
# 11-Aug-94 by RAShaw Revise calling sequence for DB_READ to take
# a pointer to component array, and to return
# the no. component objects created; also, add
# error checking.
# 12-Aug-94 by RAShaw Move "fit" related structure from "aspect.h" to
# "as_fit.h". Create new ASpect structure.
# 16-Aug-94 by RAShaw Make use of JDE's "aspect" memory structure
# 28-Aug-94 by RAShaw Make use of new database memory structure
# 30-Aug-94 by RAShaw Alter DB_READ calling sequence to include
# offset in running component number.
# 24-Oct-94 by JDE Change component list semantics & ASpect struct
# 26-Apr-95 by RAShaw Call as_clinit to fetch CL parameters; this
# used to be done in as_alloc().
# 27-Apr-95 by RAShaw Use pointer to component list instead.
# 28-Apr-95 by RAShaw Use component list managment routines.
# 24-May-95 by RAShaw Change task name.
# 5-Jun-95 by RAShaw Support dispersion/flux units for output DB.
# 23-Jun-95 by RAShaw Support input dispersion domains from a list.
# 10-Jul-95 by RAShaw Check for missing DB components; call do_fit w/
# size of component list rather than no_components
# given in last DB header.
# 14-Jul-95 by RAShaw Call do_fit w/component/spectrum list pointers.
# 27-Jul-95 by RAShaw Loop over list of fit domains.
# 11-Aug-95 by RAShaw Revise calling sequence to spmap.
# 12-Oct-95 by RAShaw Fixed mem allocation bug for domain array.
# 5-Nov-95 by RAShaw Accomodate new FIT structure.
# 7-Nov-95 by RAShaw Accomodate multiple input DB tables.
# 13-Dec-95 by RAShaw Add explicit conversion of CP units; change
# calling args of db_write to use compon. list.
# 15-Dec-95 by RAShaw Use new utility function to fetch desired
# units from the CL.
procedure t_autospec()
# Local variables:
pointer as # descriptor for ASpect memory structure
pointer db # DataBase descriptor
char dbtab[SZ_FNAME] # Name of component input table
pointer domain_arr # array of fit domain upper/lower limits
char domain_list[SZ_FNAME] # list of dispersion domains for fit
char domain_stg[SZ_LINE] # string of dispersion domains for fit
int dunit, funit # dispersion/flux unit enumerated type
double dx1, dx2 # generic
#char errmsg[SZ_LINE] # text of error messages
pointer ft # fit object
int i # loop index
#char input[SZ_FNAME] # Name of spectrum input file
pointer list # list from input filename template
int nft_reg # number of fit intervals
bool new # write new output table?
pointer o # domain object
char odbtab[SZ_FNAME] # Name of component output table
#pointer sp # single spectrum object
int status # return status
char input_list[SZ_LINE] # string of input file names
# Functions used:
pointer as_alloc() # initialize ASpect memory structure
extern chispec() # chi-square merit function
pointer db_alloc() # open DB table & initialize memory structure
int do_fit() # execute the fit, return status
int get_domains() # read dispersion domains from a string
int imtgetim() # get next image name from template
pointer imtopenp() # Open CL parameter list
int next_domain() # fetch next domain from list
pointer set_domain() # allocate domain list parameter
pointer spmap() # map a spectrum descriptor
int tbtacc() # test for existance of table
extern fit_report() # Report on progress of fitting.
errchk as_alloc, as_free, clg_units, db_alloc, db_free, db_read, db_write
errchk do_fit, set_domain, spl_add, spmap
begin
# Set output DB flux/dispersion units. If these are invalid,
# there's no point in continuing.
call clg_units (dunit, funit)
## Allocating ASpect memory structure
as = as_alloc()
call as_clinit(as)
## Fetch input spectrum file names
##list = imtopenp ("input")
call clgstr ("input", input_list, SZ_LINE)
call pr_sets (SP_INPARS(as), "flux", input_list)
SP_LIST(as) = spmap (SP_INPARS(as))
# Read input spectra from disk
# Note: the following two lines don't work, as CL list structured
# parameters are evidently not supported.
# call pr_sets (SP_INPARS(as), "flux", list)
# SP_LIST(as) = spmap (SP_INPARS(as))
#while (imtgetim (list, input, SZ_FNAME) != EOF) {
# call pr_sets (SP_INPARS(as), "flux", input)
# iferr ( sp = spmap (SP_INPARS(as)) ) {
# call sprintf (errmsg, SZ_LINE, "Unable to open spectrum: %s")
# call pargstr (input)
# call erract (EA_WARN)
# call error (FIL_ACCESS, errmsg)
# }
#
# # Merge the input spectrum list with the main list.
# do i = 1, SPL_N(sp)
# call spl_add (SP_LIST(as), SPL_A(sp,i), true)
#
# call spl_free (sp, false)
# }
# Convert the input list of spectra to internal units.
call spl_cv_units (SP_LIST(as), PHOTLAM, ANGSTROM)
# Fetch shortest/longest wavelengths.
call spl_wave_domain (SP_LIST(as), dx1, dx2)
call as_add_range (as, dx1, dx2)
# Examine spectrum objects
if (DEBUG) {
do i = 1, SPL_N(SP_LIST(as))
call sp_examine ( SPL_A(SP_LIST(as),i) )
}
## Now load components from input DB tables
# Open input DB table list and fetch components from each DB table
list = imtopenp ("db_intab")
while (imtgetim (list, dbtab, SZ_FNAME) != EOF) {
call get_cl_from_db (CMP_LIST(as), dbtab)
}
# Initialize user-function attributes from the ASpec object defaults.
# call cp_uf_init (as, CMP_LIST(as))
# Convert units of components to internal
call cpl_cv_units (CMP_LIST(as), PHOTLAM, ANGSTROM)
# Examine component objects
if (DEBUG) {
do i = 1, CPL_N(CMP_LIST(as))
call cp_examine ( CPL_A(CMP_LIST(as),i) )
}
## Enter loop to perform fits over requested domains
call calloc (domain_arr, MAX_DOMAINS*2, TY_DOUBLE)
# Fetch fit domains from the CL
call clgstr ("fit_domains", domain_list, SZ_FNAME)
o = set_domain (domain_list)
while (next_domain (o, domain_stg, SZ_LINE) != EOF) {
call printf ("Fit domain is: %s\n")
call pargstr (domain_stg)
# Construct the fit control structure
ft = AS_FIT(as)
nft_reg = get_domains (domain_stg, Memd[domain_arr], WLOW(as),
WHIGH(as), MAX_DOMAINS)
if (nft_reg <= 0)
call error (FIT_RANGE, "No valid fit domains")
# Initialize the FIT object with type, no. iterations, and
# tolerances that reside in the global ASpect Fit object.
call fit_init ( ft, SP_LIST(as), CMP_LIST(as), domain_arr,
nft_reg, FT_ALGORITHM(AS_FIT(as)), FT_ITER_LIMIT(AS_FIT(as)),
FT_DTOLER(AS_FIT(as)) )
# Execute the fit.
status = do_fit (ft, fit_report)
# Set the error calculation method and compute parameter errors.
call fit_seti (ft, FP_ERR_METHOD, CURV_MATRIX)
call do_errors (ft, chispec)
# Report error status, if any
if (status == ITER_EXCEEDED)
call printf ("WARNING: Max. iterations exceeded during fit\n")
call printf ("\n")
}
call free_domain (o)
call mfree (domain_arr, TY_DOUBLE)
## Now write components to the output DB table.
# Open output DB table
call clgstr ("db_outtab", odbtab, SZ_FNAME)
if (tbtacc (odbtab) == YES) {
new = false
db = db_alloc (odbtab, READ_WRITE)
} else {
new = true
db = db_alloc (odbtab, NEW_FILE)
call db_set_units (db, funit, dunit)
}
call db_write (db, CMP_LIST(as), new)
## Close DB table, release memory & quit
if (db != NULL)
call db_free (db)
call as_free (as)
end
#-------------------------------------------------------------------------------
# GET_CL_FROM_DB -- Build component list (DB_CL) from disk DB file and
# append to input CL.
#
# Revision history:
# 14-Dec-95 by RAShaw Initial SPP implementation
procedure get_cl_from_db (cl, db_table)
# Calling arguments:
pointer cl #I/O: component list
char db_table[ARB] #I: name of input DB table of components
# Local variables:
pointer db # input DataBase descriptor
pointer db_cl # component list read from DB
char errmsg[SZ_LINE] # text of error messages
int ncp_expected # no. components expected in DB
int ncp_db # no. components actually read from DB
# Functions used:
pointer db_alloc() # open DB table & initialize memory structure
int db_get_ncmp() # get no. components in a DB object
int db_read() # read components from DB table
errchk db_alloc, db_read
begin
db_cl = NULL
db = db_alloc (db_table, READ_WRITE)
# Ensure no. components matches that expected.
ncp_expected = db_get_ncmp (db)
if (ncp_expected <= 0) {
call sprintf (errmsg, SZ_LINE, "DataBase table %s has zero entries")
call pargstr (db_table)
call error (DB_COMPON, errmsg)
}
iferr ( ncp_db = db_read (db, db_cl, 0) ) {
call sprintf (errmsg, SZ_LINE, "Error reading DataBase table: %s")
call pargstr (db_table)
call erract (EA_WARN)
call error (DB_COMPON, errmsg)
}
if (ncp_expected != ncp_db) {
call sprintf (errmsg, SZ_LINE, "Error reading DataBase table: %s")
call pargstr (db_table)
call error (DB_COMPON, errmsg)
}
# Merge the input component list with the main list.
call cpl_append (db_cl, cl, true)
call cpl_free (db_cl, false)
if (db != NULL)
call db_free (db)
end
#-------------------------------------------------------------------------------
# FIT_REPORT -- Report fit progress to STDOUT.
procedure fit_report (iter, chisq, force_flush)
# Calling arguments:
int iter #I: The current iteration count.
real chisq #I: The current chisquare value.
bool force_flush #I: Force flushing the output?
begin
call printf (" iterations = %d chisq = %g\r")
call pargi (iter)
call pargr (chisq)
# if (force_flush)
call flush (STDOUT)
end
#-------------------------------------------------------------------------------
# End of fit_report
#-------------------------------------------------------------------------------
Source Code · Search Form · STSDAS
Maintained by the Science Software Group at STScI
This file last updated on 27 Nov 1996