

include <imhdr.h>
include "rcombine.h"
# RCOMBINE -- Combine spectral groups from rapid readout mode. Propagate the
# errors and the data quality information correctly, if requested.
#
# 15-June-1993 Modified by HA Bushouse to accept any image type (not just
# .c1h) as input. Propagation of error (.c2) and data quality (.cq) images
# was also made optional instead of automatic. If the input image is NOT
# type c1, then the setting of the errors parameter is ignored (i.e. the
# .c2 files are not propagated).
#
# 05-Nov-1993 HA Bushouse: Modified rcombine.h to increase value of
# MAXRANGES from 1 to 50 to allow specification of list of random groups
# such as "1,3,6,11".
#
# 21-Nov-1994 HA Bushouse: Fixed bug in calculating "denom" when user has
# specified a value for "nbin". Also added "imflush" calls to fix buffering
# problem that was leading to incorrect values in output image.
#
# 14-Jan-1998 MD De La Pena: Removed call to iki_parse; replaced with calls
# to imgcluster and fextn in order to obtain the image extension.
#
procedure rcombine( )
pointer sp, input, output, op, groups, list, im, image, root, section, extn
pointer outroot, osection, gstr, tmp, outc1h, outc2h, outcqh, im1out
pointer im2out, imqout, inc1h, inc2h, incqh, im1in, im2in, imqin, ogstr
pointer outfile, indir, hstr
pointer imtopen(), imtgetim(), immap(), imgl1r(), impl1r()
int nbin, range[3,MAXRANGES+2], nval, ngroup, rndup, ngroup_out, icount
int igroup, ogroup, mxgrp, mode, template, remainder, istat, rtlen, ibin
int clgeti(), decode_ranges(), imaccf(), imgeti()
int get_next_number(), imtlen(), isdirectory(), fnldir()
int fnextn(), nextn
real denom
bool first, errors, dataq
bool imgetb(), streq(), clgetb()
# error function to handle sqrt of invalid argument
real errfcn() # Error function to deal with sqrt of invalid argument
extern errfcn
string nulstr ""
string history "File created from %s using operation = %s, groups = \
%s, nbin = %d."
begin
# Allocate temporary memory
call smark( sp )
call salloc( input, SZ_PATHNAME, TY_CHAR )
call salloc( output, SZ_PATHNAME, TY_CHAR )
call salloc( outfile, SZ_PATHNAME, TY_CHAR )
call salloc( indir, SZ_PATHNAME, TY_CHAR )
call salloc( op, SZ_FNAME, TY_CHAR )
call salloc( groups, SZ_FNAME, TY_CHAR )
call salloc( image, SZ_PATHNAME, TY_CHAR )
call salloc( root, SZ_FNAME, TY_CHAR )
call salloc( extn, SZ_FNAME, TY_CHAR)
call salloc( section, SZ_FNAME, TY_CHAR )
call salloc( outroot, SZ_FNAME, TY_CHAR )
call salloc( osection, SZ_FNAME, TY_CHAR )
call salloc( gstr, SZ_GSTR, TY_CHAR )
call salloc( ogstr, SZ_GSTR, TY_CHAR )
call salloc( tmp, SZ_MAX_SPEC, TY_REAL )
call salloc( inc1h, SZ_PATHNAME, TY_CHAR )
call salloc( inc2h, SZ_PATHNAME, TY_CHAR )
call salloc( incqh, SZ_PATHNAME, TY_CHAR )
call salloc( outc1h, SZ_PATHNAME, TY_CHAR )
call salloc( outc2h, SZ_PATHNAME, TY_CHAR )
call salloc( outcqh, SZ_PATHNAME, TY_CHAR )
call salloc( hstr, SZ_LINE, TY_CHAR )
# Initialize imhdr pointer to NULL
im = NULL
im1out = NULL
im2out = NULL
imqout = NULL
im1in = NULL
im2in = NULL
imqin = NULL
# Get input parameters
call clgstr( "input", Memc[input], SZ_PATHNAME )
call clgstr( "output", Memc[outfile], SZ_PATHNAME )
call clgstr( "operation", Memc[op], SZ_FNAME )
call clgstr( "groups", Memc[groups], SZ_FNAME )
ibin = clgeti( "nbin" )
dataq = clgetb( "dataqual")
# Open input template
list = imtopen( Memc[input] )
# If more than one input file was specified, check that output file is
# a directory
if ( imtlen( list ) > 1 )
if ( isdirectory( Memc[outfile], Memc[output], SZ_PATHNAME) == 0 )
call error( 1, "Output file name must be a directory if input template is used")
# Loop over file names specified in template
while( imtgetim( list, Memc[image], SZ_PATHNAME) != EOF ) {
# Parse the input image name and determine if this is a .c1 image
call imgcluster (Memc[image], Memc[root], SZ_FNAME)
nextn = fnextn (Memc[root], Memc[extn], SZ_FNAME)
if (streq (Memc[extn], "c1h")) errors = clgetb( "errors" )
else errors = false
call mkfname( Memc[image], "", "", Memc[extn], Memc[image], SZ_PATHNAME)
# Decode the range specification in the groups parameter
# decode_ranges requires max_ranges to be at least 2+number of
# clusters (groups)
if ( decode_ranges( Memc[groups], range, MAXRANGES+2, nval ) == ERR )
call error ( 1, "Invalid range of groups specified" )
# Get group information from image
im = immap( Memc[image], READ_ONLY, 0 )
if (imaccf( im, "GROUPS") == NO )
call error (1, "Image not in group format")
if (!imgetb( im, "GROUPS"))
call error (1, "Image not in group format")
if (imaccf(im, "GCOUNT") == NO )
call error (1, "Image not in group format")
ngroup = imgeti( im, "GCOUNT" )
# If nbin was set to INDEF this means combine all groups into one.
# Therefore the number of groups to bin into one output group should
# be the total number of input groups that are to be processes (nval)
# unless nval = INDEFI which happens when all groups are to be
# processed. In the latter case nbin should be set to the number of
# input groups = ngroup.
if (nval >= MAX_VAL)
nval = (ngroup - range[1,1])/range[3,1] + 1
if (IS_INDEFI (ibin))
nbin = nval
else
nbin = ibin
# Get the root and image section for current image
call imgcluster( Memc[image], Memc[root], SZ_FNAME )
call imgsection( Memc[image], Memc[section], SZ_FNAME )
# If output file name is a directory, append the input file name
# to the output, otherwise just use output file name
if ( isdirectory( Memc[outfile], Memc[output], SZ_PATHNAME) > 0 ){
rtlen = fnldir( Memc[root], Memc[indir], SZ_PATHNAME )
call strcat( Memc[root+rtlen], Memc[output], SZ_PATHNAME )
} else {
call strcpy( Memc[outfile], Memc[output], SZ_PATHNAME )
}
# If nbin does not divide evenly into nval, then we need one more
# output group than is given by nval/nbin (integer division)
rndup = 0
if ( mod( nval, nbin ) > 0 )
rndup = 1
ngroup_out = nval / nbin + rndup
# Get the output root name
call imgcluster( Memc[output], Memc[outroot], SZ_FNAME )
# Loop over input groups, count groups to get output correct.
# Set first to true so output images get opened the first time through
icount = 0
ogroup = 0
igroup = 0
first = true
repeat {
istat = get_next_number( range, igroup )
call mkgstr( igroup, 0, Memc[gstr], SZ_GSTR )
icount = icount + 1
# Open current input images unless we have exceeded the maximum
# number of groups to be processed
if ( (igroup <= ngroup) && (icount <= nval) ) {
call mkfname ( Memc[root], Memc[gstr], Memc[section], Memc[extn],
Memc[inc1h], SZ_PATHNAME )
im1in = immap( Memc[inc1h], READ_ONLY, 0 )
if (errors) {
call mkfname ( Memc[root], Memc[gstr], Memc[section], "c2h",
Memc[inc2h], SZ_PATHNAME )
im2in = immap( Memc[inc2h], READ_ONLY, 0 )
}
if (dataq) {
call mkfname ( Memc[root], Memc[gstr], Memc[section], "cqh",
Memc[incqh], SZ_PATHNAME )
imqin = immap( Memc[incqh], READ_ONLY, 0 )
}
}
# Open new output images (i.e. the next group) and zero the output
# arrays if we have processed nbin input groups, or if it is the
# first time through or if we have processed all groups.
remainder = mod(icount-1, nbin)
if ( remainder == 0 || first || (igroup > ngroup)) {
# If this is not the first pass through then we have to
# do some book keeping, and then close the output images
# before opening new ones
if (!first){
if (errors) {
call asqrr( Memr[imgl1r(im2out)], Memr[impl1r(im2out)],
IM_LEN(im2out,1), errfcn )
call imflush( im2out )
}
if ( streq("average",Memc[op] ) ){
# When averaging, divide by icount if icount groups were
# processed, else divide by the number of groups left
if ( remainder == 0 )
#denom = icount - 1 # Bug fix 21-Nov-94 H.A.B.
denom = nbin
else
denom = remainder
call adivkr( Memr[imgl1r(im1out)], denom,
Memr[impl1r(im1out)], IM_LEN(im1out,1))
call imflush( im1out )
if (errors) {
call adivkr( Memr[imgl1r(im2out)], denom,
Memr[impl1r(im2out)], IM_LEN(im2out,1))
call imflush( im2out )
}
}
call imfree( im1out )
if (errors) call imfree( im2out )
if (dataq) call imfree( imqout )
}
# If icount (current output group) is greater than
# nval then we have processed all of the groups and we
# should clean up memory and exit.
if ( icount > nval ){
call imfree( im )
break
}
first = false
# Calculate the current output group (increment ogroup if nbin
# input groups have been processed), make file names and open
# images. If the current output group = 1, then we have to create
# the file name specifying the maximum number of groups
if ( remainder == 0 )
ogroup = ogroup + 1
if ( ogroup == 1 ){
mxgrp = ngroup_out
mode = NEW_COPY
template = im
} else {
mxgrp = 0
mode = READ_WRITE
template = 0
}
call mkgstr( ogroup, mxgrp, Memc[ogstr], SZ_GSTR )
call mkfname( Memc[outroot], Memc[ogstr], Memc[osection],Memc[extn],
Memc[outc1h], SZ_PATHNAME )
im1out = immap( Memc[outc1h], mode, template )
if (errors) {
call mkfname( Memc[outroot], Memc[ogstr], Memc[osection], "c2h",
Memc[outc2h], SZ_PATHNAME )
im2out = immap( Memc[outc2h], mode, template )
}
if (dataq) {
call mkfname( Memc[outroot], Memc[ogstr], Memc[osection], "cqh",
Memc[outcqh], SZ_PATHNAME )
imqout = immap( Memc[outcqh], mode, template )
}
# The c2h and cqh files were opened as copies of the c1h file.
# This means the values of the FILETYPE keyword must be changed
# for the c2h and cqh and the BUNIT keyword for the cqh.
# Also add History lines to the c1h, c2h and cqh files.
# Only need to do all this on the first pass.
if (ogroup == 1) {
call sprintf( Memc[hstr], SZ_LINE, history )
call pargstr( Memc[input] )
call pargstr( Memc[op])
call pargstr( Memc[groups])
call pargi( nbin )
call imputh( im1out, "HISTORY", Memc[hstr])
if (errors) {
call impstr( im2out, "FILETYPE", "ERR" )
call imputh( im2out, "HISTORY", Memc[hstr])
}
if (dataq) {
call impstr( imqout, "FILETYPE", "CDQ" )
call impstr( imqout, "BUNIT", "" )
call imputh( imqout, "HISTORY", Memc[hstr])
}
}
# Zero the arrays
call aclrr( Memr[impl1r(im1out)], IM_LEN(im1out,1) )
call imflush( im1out )
if (errors) {
call aclrr( Memr[impl1r(im2out)], IM_LEN(im2out,1) )
call aclrr( Memr[tmp], IM_LEN(im2out,1) )
call imflush( im2out )
}
if (dataq) {
call aclrr( Memr[impl1r(imqout)], IM_LEN(imqout,1) )
call imflush( imqout )
}
}
call aaddr( Memr[imgl1r(im1in)], Memr[imgl1r(im1out)],
Memr[impl1r(im1out)], IM_LEN(im1in,1) )
call imflush( im1out )
if (errors) {
call amulr( Memr[imgl1r(im2in)], Memr[imgl1r(im2in)],
Memr[tmp], IM_LEN(im2in,1) )
call aaddr( Memr[tmp], Memr[imgl1r(im2out)],
Memr[impl1r(im2out)], IM_LEN(im2in,1) )
call imflush( im2out )
}
if (dataq) {
call amaxr( Memr[imgl1r(imqin)], Memr[imgl1r(imqout)],
Memr[impl1r(imqout)], IM_LEN(imqin,1) )
call imflush( imqout )
}
call imfree( im1in )
if (errors) call imfree( im2in )
if (dataq) call imfree( imqin )
}
}
call imfree( im1out )
if (errors) call imfree( im2out )
if (dataq) call imfree( imqout )
call imfree( im )
call imtclose( list )
call sfree( sp )
end
# ERRFCN -- Error function to deal with sqrt of invalid argument
real procedure errfcn( x )
real x
begin
return INDEFR
end
Source Code · Search Form · STSDAS
Maintained by the Science Software Group at STScI
This file last updated on 24 Feb 2011