include include include include # Output formats. define FORMATS "|multispec|onedspec|" # Operations. define OPS "|abs|copy|dex|exp|flam|fnu|inv|ln|log|lum|mag|sqrt\ |replace|+|-|*|/|^|" define ABS 1 define COPY 2 define DEX 3 define EXP 4 define FLAM 5 define FNU 6 define INV 7 define LN 8 define LOG 9 define LUM 10 define MAG 11 define SQRT 12 define REP 13 define ADD 14 define SUB 15 define MUL 16 define DIV 17 define POW 18 # T_SARITH -- Arithmetic operations (including copying) on spectra. procedure t_sarith() int inlist1 # List of input spectra int op # Operation int inlist2 # List of input spectra or operands int outlist # List of output spectra double w1 # Starting wavelength double w2 # Ending wavelength bool rebin # Rebin wavelength region? int format # Output format pointer aps # Aperture/col/line list pointer bands # Band list pointer beams # Beam list bool complement # Complement aperture/beam selection int apmod # Aperture modulus (used with subapertures) int offset # Add this offset to apertures on output bool reverse # Reverse order of operands bool ignoreaps # Ignore apertures? bool clobber # Clobber existing images? bool merge # Merge with existing images? bool renumber # Renumber apertures? bool verbose # Verbose? real errval # Error value int list1, list2 pointer sp, input1, opstr, input2, output, ptr double clgetd() int imtopenp(), imtopen(), imtlen(), imtgetim() int clgwrd(), clgeti() bool clgetb() pointer rng_open() common /sarith/ errval begin call smark (sp) call salloc (input1, SZ_LINE, TY_CHAR) call salloc (opstr, SZ_LINE, TY_CHAR) call salloc (input2, SZ_LINE, TY_CHAR) call salloc (output, SZ_LINE, TY_CHAR) # Get parameters. inlist1 = imtopenp ("input1") op = clgwrd ("op", Memc[opstr], SZ_LINE, OPS) if (op > SQRT) inlist2 = imtopenp ("input2") else inlist2 = imtopen ("") outlist = imtopenp ("output") w1 = clgetd ("w1") w2 = clgetd ("w2") if (IS_INDEFD(w1) && IS_INDEFD(w2)) rebin = false else rebin = clgetb ("rebin") format = clgwrd ("format", Memc[input1], SZ_LINE, FORMATS) call clgstr ("apertures", Memc[input1], SZ_LINE) call clgstr ("bands", Memc[input2], SZ_LINE) call clgstr ("beams", Memc[output], SZ_LINE) apmod = clgeti ("apmodulus") offset = clgeti ("offset") reverse = clgetb ("reverse") ignoreaps = clgetb ("ignoreaps") clobber = clgetb ("clobber") merge = clgetb ("merge") renumber = clgetb ("renumber") verbose = clgetb ("verbose") errval = clgetd ("errval") if (op == 0) call error (1, "Unknown operation") # Decode range strings and set complement if needed ptr = input1 complement = false if (Memc[ptr] == '!') { complement = true ptr = ptr + 1 } iferr (aps = rng_open (Memc[ptr], INDEF, INDEF, INDEF)) call error (0, "Bad aperture/column/line list") ptr = input2 if (Memc[ptr] == '!') { complement = true ptr = ptr + 1 } iferr (bands = rng_open (Memc[ptr], INDEF, INDEF, INDEF)) call error (0, "Bad band list") ptr = output if (Memc[ptr] == '!') { complement = true ptr = ptr + 1 } iferr (beams = rng_open (Memc[ptr], INDEF, INDEF, INDEF)) call error (0, "Bad beam list") # Check lists. if (imtlen (outlist) > 1 && imtlen (outlist) != imtlen (inlist1)) call error (1, "Input and output image lists don't make sense") if (op > SQRT && imtlen (inlist2) > 1 && imtlen (inlist2) != imtlen (inlist1)) call error (1, "Input operand lists don't make sense") # Do the operations. while (imtgetim (inlist1, Memc[input1], SZ_LINE) != EOF) { if (imtgetim (inlist2, Memc[output], SZ_LINE) == EOF) call strcpy (Memc[input2], Memc[output], SZ_LINE) call strcpy (Memc[output], Memc[input2], SZ_LINE) if (imtlen (outlist) > 1) { list1 = imtopen (Memc[input1]) list2 = imtopen (Memc[input2]) } else { list1 = inlist1 list2 = inlist2 } switch (format) { case 1: if (imtgetim (outlist, Memc[output], SZ_LINE) == EOF) call strcpy (Memc[input1], Memc[output], SZ_LINE) call imgimage (Memc[output], Memc[output], SZ_LINE) call sa_ms (list1, list2, Memc[output], op, Memc[opstr], w1, w2, rebin, aps, bands, beams, complement, apmod, offset, reverse, ignoreaps, clobber, merge, renumber, verbose) case 2: call sa_getim (outlist, Memc[input1], Memc[output], SZ_LINE) call imgimage (Memc[output], Memc[output], SZ_LINE) call sa_1d (list1, list2, Memc[output], op, Memc[opstr], w1, w2, rebin, aps, bands, beams, complement, apmod, offset, reverse, ignoreaps, clobber, renumber, verbose) } if (list1 != inlist1) { call imtclose (list1) call imtclose (list2) } } call rng_close (aps) call rng_close (bands) call rng_close (beams) call imtclose (inlist1) call imtclose (inlist2) call imtclose (outlist) call sfree (sp) end # SA_MS -- Operate on input list to multispec output procedure sa_ms (list1, list2, output, op, opstr, w1, w2, rebin, aps, bands, beams, complement, apmod, offset, reverse, ignoreaps, clobber, merge, renumber, verbose) int list1 # Input image list int list2 # Input image list char output[ARB] # Output image int op # Operation char opstr[ARB] # Operation string double w1 # Starting wavelength double w2 # Ending wavelength bool rebin # Rebin wavelength region? pointer aps # Apertures/columns/lines pointer bands # Bands pointer beams # Beams bool complement # Complement aperture/beam selection int apmod # Aperture modulus int offset # Offset to add to output aperture numbers bool reverse # Reverse order of operands bool ignoreaps # Ignore apertures? bool clobber # Clobber existing image? bool merge # Merge with existing image? bool renumber # Renumber apertures? bool verbose # Verbose output? bool select, same real aplow[2], aphigh[2] double l1, dl, a, b, w, wb, dw, z, p1, p2, p3 int i, j, k, l, nin int ap, beam, dtype, nw, err int ninaps, noutaps, naps, npts, nbands, mwoutdim int last, op1, axis[3] pointer ptr, in1, in2, out, outtmp, mwtmp, mwin1, mwin2, mwout pointer sh1, sh2, shout, const, coeff, inaps, outaps pointer sp, str, str1, key, input1, input2, temp, ltm1, ltv1, ltm2, ltv2 double shdr_lw() int imaccess(), ctod() int imtlen(), imtgetim(), imgnfn() bool strne(), rng_elementi(), fp_equald() pointer immap() , imgl3r(), impl3r(), imofnlu() pointer smw_openim(), mw_open() errchk immap, smw_openim, mw_open, imunmap, imgstr, imdelete errchk imgl3r, impl3r errchk shdr_open, sa_sextract data axis/1,2,3/ begin call smark (sp) call salloc (str, SZ_LINE, TY_CHAR) call salloc (str1, SZ_LINE, TY_CHAR) call salloc (key, SZ_LINE, TY_CHAR) call salloc (input1, SZ_FNAME, TY_CHAR) call salloc (input2, SZ_FNAME, TY_CHAR) call salloc (temp, SZ_FNAME, TY_CHAR) call salloc (ltm1, 3*3, TY_DOUBLE) call salloc (ltv1, 3, TY_DOUBLE) call salloc (ltm2, 3*3, TY_DOUBLE) call salloc (ltv2, 3, TY_DOUBLE) call malloc (coeff, 1, TY_CHAR) const = NULL # Initialize. Memc[input2] = EOS in1 = NULL; in2 = NULL; out = NULL; outtmp=NULL; mwtmp = NULL mwin1 = NULL; mwin2 = NULL; mwout = NULL sh1 = NULL; sh2 = NULL; shout = NULL ninaps = 0; noutaps = 0; nbands = 0 l1 = 1.; dl = 1. err = NO iferr { # Check for existing output image and abort if clobber is not set. if (imaccess (output, READ_ONLY) == YES) { if (!clobber) { call sprintf (Memc[str], SZ_LINE, "Output spectrum %s already exists") call pargstr (output) call error (1, Memc[str]) } else if (merge) { # Open the output and check the type. ptr = immap (output, READ_ONLY, 0); out = ptr ptr = smw_openim (out); mwout = ptr if (SMW_FORMAT(mwout) == SMW_ND) { call sprintf (Memc[str], SZ_LINE, "%s - Wrong format") call pargstr (output) call error (1, Memc[str]) } # Determine existing apertures and renumber them if needed noutaps = SMW_NSPEC(mwout) nbands = SMW_NBANDS(mwout) call salloc (outaps, noutaps, TY_INT) do i = 1, noutaps { call shdr_open (out, mwout, i, 1, INDEFI, SHHDR, sh2) if (renumber) Memi[outaps+i-1] = i + offset else Memi[outaps+i-1] = AP(sh2) } } call mktemp ("temp", Memc[temp], SZ_FNAME) } else call strcpy (output, Memc[temp], SZ_FNAME) # Open input list. Determine the number of final output apertures # and maximum length in order to set the output dimensions. Check # also that there is data to copy. call imtrew (list1) nin = imtlen (list1) npts = 0 naps = noutaps while (imtgetim (list1, Memc[input1], SZ_FNAME) != EOF) { iferr { in1 = NULL mwin1 = NULL ptr = immap (Memc[input1], READ_ONLY, 0); in1 = ptr ptr = smw_openim (in1); mwin1 = ptr j = 1 if (SMW_FORMAT(mwin1) != SMW_ND) { j = 0 do i = 1, SMW_NBANDS(mwin1) { select = rng_elementi (bands, i) if (!select) next j = j + 1 } if (j == 0) call error (1, "No bands selected in image") } nbands = max (j, nbands) do i = 1, SMW_NSPEC(mwin1) { call shdr_open (in1, mwin1, i, 1, INDEFI, SHHDR, sh1) ap = AP(sh1) if (SMW_FORMAT(mwin1) == SMW_ND) { call smw_mw (mwin1, i, 1, ptr, j, k) select = rng_elementi (aps, j) && rng_elementi (bands, k) } else { j = ap if (apmod > 1) j = mod (j, apmod) select = rng_elementi (aps, j) } select = select && rng_elementi (beams, BEAM(sh1)) if ((complement && select) || (!complement && !select)) next if (renumber) ap = naps + 1 ap = ap + offset for (j=0; j 1) { call shdr_close (sh1) call smw_close (mwin1) if (in1 != NULL) call imunmap (in1) } } # Check the selected apertures. if (ninaps == 0) call error (1, "No spectra selected") for (i=0; i 1) IM_NDIM(outtmp) = 3 else if (naps > 1) IM_NDIM(outtmp) = 2 else IM_NDIM(outtmp) = 1 l1 = 1. dl = 1. i = SMW_PDIM(MW(sh2)) j = SMW_PAXIS(MW(sh2),1) mwoutdim = IM_NDIM(outtmp) mwtmp = mw_open (NULL, mwoutdim) call mw_newsystem (mwtmp, "equispec", mwoutdim) call mw_swattrs (SMW_MW(mwout,0), 0, "sformat", "equispec") call mw_swtype (mwtmp, axis, mwoutdim, "linear", "") if (LABEL(sh2) != EOS) call mw_swattrs (mwtmp, 1, "label", LABEL(sh2)) if (UNITS(sh2) != EOS) call mw_swattrs (mwtmp, 1, "units", UNITS(sh2)) ifnoerr (call mw_gwattrs (SMW_MW(MW(sh2),0), SMW_PAXIS(MW(sh2),1), "units_display", Memc[str], SZ_LINE)) call mw_swattrs (mwtmp, 1, "units_display", Memc[str]) call mw_gltermd (SMW_MW(mwout,0), Memd[ltm1], Memd[ltv1], i) call mw_gltermd (mwtmp, Memd[ltm2], Memd[ltv2], mwoutdim) Memd[ltm2] = dl * Memd[ltm1+(i+1)*(j-1)] Memd[ltv2] = (Memd[ltv1+(j-1)] - l1) / dl + 1 call mw_sltermd (mwtmp, Memd[ltm2], Memd[ltv2], mwoutdim) call smw_open (mwtmp, NULL, outtmp) do i = 1, noutaps { call smw_gwattrs (mwout, i, 1, ap, beam, dtype, w, dw, nw, z, aplow, aphigh, coeff) call smw_swattrs (mwtmp, i, 1, Memi[outaps+i-1], beam, dtype, w, dw, nw, z, aplow, aphigh, Memc[coeff]) } do j = 1, IM_LEN(out,3) { do i = 1, IM_LEN(out,2) { ptr = impl3r (outtmp, i, j) call aclrr (Memr[ptr], IM_LEN(outtmp,1)) call amovr (Memr[imgl3r(out,i,j)], Memr[ptr], IM_LEN(out,1)) if (verbose) { call shdr_open (out, mwout, i, j, INDEFI, SHHDR, sh2) call shdr_open (outtmp, mwtmp, i, j, INDEFI, SHHDR, shout) if (AP(sh2) != AP(shout)) call sa_verbose (sh2, NULL, shout, output, COPY, "copy", const, reverse) } } } do j = 1, IM_LEN(out,3) do i = IM_LEN(out,2)+1, IM_LEN(outtmp,2) { ptr = impl3r (outtmp, i, j) call aclrr (Memr[ptr], IM_LEN(outtmp,1)) } do j = IM_LEN(out,3)+1, nbands do i = 1, IM_LEN(outtmp,2) { ptr = impl3r (outtmp, i, j) call aclrr (Memr[ptr], IM_LEN(outtmp,1)) } call shdr_close (shout) call shdr_close (sh2) call smw_close (mwout) mwout = mwtmp mwtmp = NULL call imunmap (out) out = outtmp outtmp = NULL } else { if (nin > 1) { ptr = immap (Memc[input2], READ_ONLY, 0); in1 = ptr ptr = smw_openim (in1); mwin1 = ptr call shdr_open (in1, mwin1, i, 1, INDEFI, SHDATA, sh1) } ptr = immap (Memc[temp], NEW_COPY, in1); out = ptr if (IM_PIXTYPE(out) != TY_DOUBLE) IM_PIXTYPE(out) = TY_REAL ifnoerr (call imgstr (out, "MSTITLE", Memc[str], SZ_LINE)) { call strcpy (Memc[str], IM_TITLE(out), SZ_IMTITLE) call imdelf (out, "MSTITLE") } # Set header IM_LEN(out,1) = npts IM_LEN(out,2) = naps IM_LEN(out,3) = nbands if (nbands > 1) IM_NDIM(out) = 3 else if (naps > 1) IM_NDIM(out) = 2 else IM_NDIM(out) = 1 mwoutdim = IM_NDIM(out) j = imofnlu (out, "DISPAXIS,APID*,BANDID*") while (imgnfn (j, Memc[key], SZ_LINE) != EOF) call imdelf (out, Memc[key]) call imcfnl (j) i = SMW_PDIM(MW(sh1)) j = SMW_PAXIS(MW(sh1),1) ptr = mw_open (NULL, mwoutdim); mwout = ptr call mw_newsystem (mwout, "equispec", mwoutdim) call mw_swattrs (mwout, 0, "sformat", "equispec") call mw_swtype (mwout, axis, mwoutdim, "linear", "") if (LABEL(sh1) != EOS) call mw_swattrs (mwout, 1, "label", LABEL(sh1)) if (UNITS(sh1) != EOS) call mw_swattrs (mwout, 1, "units", UNITS(sh1)) ifnoerr (call mw_gwattrs (SMW_MW(MW(sh1),0), SMW_PAXIS(MW(sh1),1), "units_display", Memc[str], SZ_LINE)) call mw_swattrs (mwout, 1, "units_display", Memc[str]) call mw_gltermd (SMW_MW(mwin1,0), Memd[ltm1], Memd[ltv1], i) call mw_gltermd (mwout, Memd[ltm2], Memd[ltv2], mwoutdim) Memd[ltv2] = (Memd[ltv1+(j-1)] - l1) / dl + 1 Memd[ltm2] = dl * Memd[ltm1+(i+1)*(j-1)] call mw_sltermd (mwout, Memd[ltm2], Memd[ltv2], mwoutdim) call smw_open (mwout, NULL, out) if (nin > 1) { call shdr_close (sh1) call smw_close (mwin1) call imunmap (in1) } } # Now do the actual copy last = noutaps call imtrew (list1) call imtrew (list2) while (imtgetim (list1, Memc[input1], SZ_FNAME) != EOF) { i = imtgetim (list2, Memc[input2], SZ_FNAME) iferr { if (nin > 1) { in1 = NULL mwin1 = NULL ptr = immap (Memc[input1], READ_ONLY, 0); in1 = ptr ptr = smw_openim (in1); mwin1 = ptr call shdr_open (in1, mwin1, 1, 1, INDEFI, SHHDR, sh1) } # Check dispersion function compatibility # Nonlinear functions can't be copied to different physical # coordinate system though the linear dispersion can be # adjusted. call mw_gltermd (SMW_MW(mwout,0), Memd[ltm2], Memd[ltv2], mwoutdim) a = Memd[ltv2] b = Memd[ltm2] if (DC(sh1) == DCFUNC && !rebin) { i = SMW_PDIM(mwin1) j = SMW_PAXIS(mwin1,1) call mw_gltermd (SMW_MW(mwin1,0), Memd[ltm1], Memd[ltv1], i) Memd[ltv1] = (Memd[ltv1+(j-1)] - l1) / dl + 1 Memd[ltm1] = dl * Memd[ltm1+(i+1)*(j-1)] if (!fp_equald (a, Memd[ltv1]) || !fp_equald (b, Memd[ltm1])) { call error (1, "Physical basis for nonlinear dispersion functions don't match") } } # Check for second operand if (op > SQRT) { ifnoerr (ptr = immap (Memc[input2], READ_ONLY, 0)) { in2 = ptr sh2 = NULL mwin2 = NULL ptr = smw_openim (in2); mwin2 = ptr call shdr_open (in2, mwin2, 1, 1, INDEFI, SHHDR, sh2) } else { const = NULL i = 1 if (ctod (Memc[input2], i, w) <= 0) call error (1, "Error in second operand") call malloc (const, IM_LEN(out,1), TY_REAL) call amovkr (real (w), Memr[const], IM_LEN(out,1)) } } do i = 1, SMW_NSPEC(mwin1) { call shdr_open (in1, mwin1, i, 1, INDEFI, SHHDR, sh1) ap = AP(sh1) if (SMW_FORMAT(mwin1) == SMW_ND) { call smw_mw (mwin1, i, 1, ptr, j, k) select = rng_elementi (aps, j) && rng_elementi (bands, k) } else { j = ap if (apmod > 1) j = mod (j, apmod) select = rng_elementi (aps, j) } select = select && rng_elementi (beams, BEAM(sh1)) if ((complement && select) || (!complement && !select)) next if (renumber) ap = last + 1 ap = ap + offset for (j=0; j SQRT) { ifnoerr (ptr = immap (Memc[input2], READ_ONLY, 0)) { in2 = ptr sh2 = NULL mwin2 = NULL ptr = smw_openim (in2); mwin2 = ptr call shdr_open (in2, mwin2,1,1,INDEFI,SHHDR,sh2) } else { const = NULL i = 1 if (ctod (Memc[input2], i, w) <= 0) call error (1, "Error in second operand") call malloc (const, IM_LEN(in1,1), TY_REAL) call amovkr (real (w), Memr[const], IM_LEN(in1,1)) } } do band = 1, SMW_NBANDS(mwin1) { if (SMW_FORMAT(mwin1) != SMW_ND) { select = rng_elementi (bands, band) if (!select) next } do i = 1, SMW_NSPEC(mwin1) { call shdr_open (in1, mwin1, i, band, INDEFI, SHHDR, sh1) # Check aperture and beam numbers. ap = AP(sh1) if (SMW_FORMAT(mwin1) == SMW_ND) { call smw_mw (mwin1, i, band, ptr, j, k) select = rng_elementi (aps,j) && rng_elementi (bands,k) } else { j = ap if (apmod > 1) j = mod (j, apmod) select = rng_elementi (aps, j) } select = select && rng_elementi (beams, BEAM(sh1)) if ((complement && select) || (!complement && !select)) next if (renumber) { naps = naps + 1 ap = naps } ap = ap + offset iferr { out = NULL mwout = NULL err = NO # Open output spectrum call strcpy (output, Memc[str], SZ_LINE) j = patmake (".[0-9][0-9][0-9][0-9]$", Memc[key], SZ_LINE) j = patmatch (Memc[str], Memc[key]) if (j > 0) Memc[str+j-6] = EOS if (SMW_FORMAT(mwin1) != SMW_ND) { call sprintf (Memc[output1], SZ_FNAME, "%s.%d%03d") call pargstr (Memc[str]) call pargi (PINDEX(sh1,2)-1) call pargi (ap) } else { call sprintf (Memc[output1], SZ_FNAME, "%s.%04d") call pargstr (Memc[str]) call pargi (ap) } if (imaccess (Memc[output1], READ_ONLY) == YES) { if (clobber) call mktemp ("temp", Memc[temp], SZ_FNAME) else { call sprintf (Memc[str], SZ_LINE, "Output spectrum %s already exists") call pargstr (output) call error (1, Memc[str]) } } else call strcpy (Memc[output1], Memc[temp], SZ_FNAME) # Get data call shdr_open (in1, mwin1, i, band, INDEFI, SHDATA, sh1) # Set header ptr = immap (Memc[temp], NEW_COPY, in1); out = ptr if (IM_PIXTYPE(out) != TY_DOUBLE) IM_PIXTYPE(out) = TY_REAL IM_NDIM(out) = 1 if (!streq (TITLE(sh1), IM_TITLE(out))) { call imastr (out, "MSTITLE", IM_TITLE(out)) call strcpy (TITLE(sh1), IM_TITLE(out), SZ_IMTITLE) } j = imofnlu (out, "DISPAXIS,APID*,BANDID*") while (imgnfn (j, Memc[key], SZ_LINE) != EOF) call imdelf (out, Memc[key]) call imcfnl (j) if (Memc[SID(sh1,1)] != EOS) call imastr (out, "BANDID1", Memc[SID(sh1,1)]) # Set WCS j = SMW_PDIM(MW(sh1)) k = SMW_PAXIS(MW(sh1),1) ptr = mw_open (NULL, 1); mwout = ptr call mw_newsystem (mwout, "equispec", 1) call mw_swattrs (mwout, 0, "sformat", "equispec") call mw_swtype (mwout, 1, 1, "linear", "") if (LABEL(sh1) != EOS) call mw_swattrs (mwout, 1, "label", LABEL(sh1)) if (UNITS(sh1) != EOS) call mw_swattrs (mwout, 1, "units", UNITS(sh1)) ifnoerr (call mw_gwattrs (SMW_MW(MW(sh1),0), SMW_PAXIS(MW(sh1),1), "units_display", Memc[str], SZ_LINE)) call mw_swattrs (mwout, 1, "units_display", Memc[str]) call mw_gltermd (SMW_MW(mwin1,0), Memd[ltm1], Memd[ltv1], j) call mw_gltermd (mwout, Memd[ltm2], Memd[ltv2], 1) Memd[ltv2] = Memd[ltv1+(k-1)] Memd[ltm2] = Memd[ltm1+(j+1)*(k-1)] call sa_sextract (sh1, w1, w2, rebin, dtype, w, dw, nw) IM_LEN(out,1) = nw + NP1(sh1) - 1 Memd[ltv2] = (Memd[ltv1] - w) / dw + 1 Memd[ltm2] = dw * Memd[ltm1] call mw_sltermd (mwout, Memd[ltm2], Memd[ltv2], 1) call smw_open (mwout, NULL, out) # Copy and adjust dispersion info call smw_gwattrs (mwin1, i, band, AP(sh1), beam, j, w, dw, nw, z, aplow, aphigh, coeff) w = shdr_lw (sh1, 1D0) wb = shdr_lw (sh1, double(SN(sh1))) if (rebin) Memc[coeff] = EOS p1 = (NP1(sh1) - Memd[ltv2]) / Memd[ltm2] p2 = (NP2(sh1) - Memd[ltv2]) / Memd[ltm2] p3 = (IM_LEN(out,1) - Memd[ltv2]) / Memd[ltm2] nw = nint (min (max (p1, p3), max (p1, p2))) + NP1(sh1) - 1 w = w * (1 + z) wb = wb * (1 + z) if (dtype == DCLOG) { w = log10 (w) wb = log10 (wb) if (p1 != p2) dw = (wb - w) / (p2 - p1) w = w - (p1 - 1) * dw wb = w + (nw - 1) * dw w = 10.**w wb = 10.**wb dw = (wb - w) / (nw - 1) } else { if (p1 != p2) dw = (wb - w) / (p2 - p1) w = w - (p1 - 1) * dw wb = w + (nw - 1) * dw } call smw_swattrs (mwout, 1, 1, ap, beam, dtype, w, dw, nw, z, aplow, aphigh, Memc[coeff]) # Copy data op1 = op if (sh2 != NULL) { if (ignoreaps) call shdr_open (in2, mwin2, i, band, INDEFI, SHDATA, sh2) else { call shdr_open (in2, mwin2, i, band, AP(sh1), SHDATA, sh2) if (AP(sh2) != AP(sh1)) op1 = COPY } } # For now just copy noise band. if (STYPE(sh1,1) == SHSIG) op1 = COPY call sa_arith (op1, sh1, sh2, const, reverse, Memr[SY(sh1)], Memr[impl1r(out)+NP1(sh1)-1], SN(sh1)) if (verbose) { call shdr_open (out, mwout, 1, 1, INDEFI, SHHDR, shout) call sa_verbose (sh1, sh2, shout, Memc[output1], op1, opstr, const, reverse) } } then { err = YES call erract (EA_WARN) } call shdr_close (shout) if (mwout != NULL) { if (err == NO) call smw_saveim (mwout, out) call smw_close (mwout) } if (out != NULL) { call imunmap (out) if (!streq (Memc[output1], Memc[temp])) { if (err == NO) { call imgimage (Memc[input1], Memc[str], SZ_LINE) if (streq (Memc[output1], Memc[str])) call imunmap (in1) call imgimage (Memc[input2], Memc[str], SZ_LINE) if (streq (Memc[output1], Memc[str])) call imunmap (in2) call imdelete (Memc[output1]) call imrename (Memc[temp], Memc[output1]) } else call imdelete (Memc[temp]) } else if (err == YES) call imdelete (Memc[output1]) } } } } then call erract (EA_WARN) call shdr_close (sh2) call shdr_close (sh1) call smw_close (mwin1) call smw_close (mwin2) if (in2 != NULL) call imunmap (in2) if (in1 != NULL) call imunmap (in1) } call mfree (coeff, TY_CHAR) call sfree (sp) end # SA_ARITH -- Do arithmetic operation procedure sa_arith (op, sh, sh2, const, reverse, in, out, n) int op # Operation pointer sh # Input SHDR pointer pointer sh2 # Second operand spectrum (NULL if none) pointer const # Second operand constant (NULL if none) bool reverse # Reverse order of operands real in[n] # Input data real out[n] # Output data int n # Number of data points int i pointer buf real sa_errfcn() extern sa_errfcn() begin if (op > SQRT) { if (sh2 != NULL) { call shdr_rebin (sh2, sh) buf = SY(sh2) } else buf = const } switch (op) { case ABS: call aabsr (in, out, n) case COPY: call amovr (in, out, n) case DEX: do i = 1, n out[i] = 10. ** in[i] case EXP: do i = 1, n out[i] = exp (in[i]) case FLAM: buf = SX(sh) do i = 1, n { out[i] = in[i] / (Memr[buf] ** 2 / 2.997925e18) buf = buf + 1 } case FNU: buf = SX(sh) do i = 1, n { out[i] = in[i] * (Memr[buf] ** 2 / 2.997925e18) buf = buf + 1 } case INV: call arczr (1., in, out, n, sa_errfcn) case LN: call allnr (in, out, n, sa_errfcn) case LOG: call alogr (in, out, n, sa_errfcn) case LUM: do i = 1, n out[i] = 10. ** (-0.4 * in[i]) case MAG: do i = 1, n { if (in[i] <= 0.) out[i] = sa_errfcn (0.) else out[i] = -2.5 * log10 (in[i]) } case SQRT: call asqrr (in, out, n, sa_errfcn) case REP: call amovr (Memr[buf], out, n) case ADD: call aaddr (in, Memr[buf], out, n) case SUB: if (reverse) call asubr (Memr[buf], in, out, n) else call asubr (in, Memr[buf], out, n) case MUL: call amulr (in, Memr[buf], out, n) case DIV: if (reverse) call advzr (Memr[buf], in, out, n, sa_errfcn) else call advzr (in, Memr[buf], out, n, sa_errfcn) case POW: if (reverse) { do i = 1, n out[i] = Memr[buf+i-1] ** in[i] } else { do i = 1, n out[i] = in[i] ** Memr[buf+i-1] } } end # SA_ERRFCN -- SARITH Error Function real procedure sa_errfcn (x) real x, errval common /sarith/ errval begin return (errval) end # SA_VERBOSE -- Print verbose output. procedure sa_verbose1 (input1, input2, output, ap1, ap2, apout, op, opstr, const, reverse) char input1[ARB], input2[ARB] # Input spectra char output[ARB] # Output spectrum int ap1, ap2 # Input apertures int apout # Output apertures int op # Opcode char opstr[ARB] # Operation string pointer const # Pointer to constant if used bool reverse # Reverse operands? begin if (op <= SQRT) { if (op == COPY) { call printf ("%s[%d] --> %s") call pargstr (input1) call pargi (ap1) call pargstr (output) call pargi (apout) } else { call printf ("%s[%d] -- %s --> %s") call pargstr (input1) call pargi (ap1) call pargstr (opstr) call pargstr (output) call pargi (apout) } } else if (const == NULL) { call printf ("%s[%d] %s %s[%d] --> %s") if (reverse) { call pargstr (input2) call pargi (ap2) call pargstr (opstr) call pargstr (input1) call pargi (ap1) } else { call pargstr (input1) call pargi (ap1) call pargstr (opstr) call pargstr (input2) call pargi (ap2) } call pargstr (output) call pargi (apout) } else { if (reverse) { call printf ("%g %s %s[%d] --> %s") call pargr (Memr[const]) call pargstr (opstr) call pargstr (input1) call pargi (ap1) } else { call printf ("%s[%d] %s %g --> %s") call pargstr (input1) call pargi (ap1) call pargstr (opstr) call pargr (Memr[const]) } } call pargstr (output) if (!IS_INDEFI(apout)) { call printf ("[%d]") call pargi (apout) } call printf ("\n") call flush (STDOUT) end # SA_VERBOSE -- Print verbose output. procedure sa_verbose (sh1, sh2, shout, output, op, opstr, const, reverse) pointer sh1, sh2 # Input spectra pointer shout # Output spectrum char output[ARB] # Output image name int op # Opcode char opstr[ARB] # Operation string pointer const # Pointer to constant if used bool reverse # Reverse operands? begin if (op <= SQRT) { if (op == COPY) { call printf ("%s%s(%d) --> %s%s(%d)") call pargstr (IMNAME(sh1)) call pargstr (IMSEC(sh1)) call pargi (AP(sh1)) } else { call printf ("%s%s(%d) -- %s --> %s%s(%d)") call pargstr (IMNAME(sh1)) call pargstr (IMSEC(sh1)) call pargi (AP(sh1)) call pargstr (opstr) } } else if (const == NULL) { call printf ("%s%s(%d) %s %s%s(%d) --> %s%s(%d)") if (reverse) { call pargstr (IMNAME(sh2)) call pargstr (IMSEC(sh2)) call pargi (AP(sh2)) call pargstr (opstr) call pargstr (IMNAME(sh1)) call pargstr (IMSEC(sh1)) call pargi (AP(sh1)) } else { call pargstr (IMNAME(sh1)) call pargstr (IMSEC(sh1)) call pargi (AP(sh1)) call pargstr (opstr) call pargstr (IMNAME(sh2)) call pargstr (IMSEC(sh2)) call pargi (AP(sh2)) } } else { if (reverse) { call printf ("%g %s %s%s(%d) --> %s%s(%d)") call pargr (Memr[const]) call pargstr (opstr) call pargstr (IMNAME(sh1)) call pargstr (IMSEC(sh1)) call pargi (AP(sh1)) } else { call printf ("%s%s(%d) %s %g --> %s%s(%d)") call pargstr (IMNAME(sh1)) call pargstr (IMSEC(sh1)) call pargi (AP(sh1)) call pargstr (opstr) call pargr (Memr[const]) } } call pargstr (output) call pargstr (IMSEC(shout)) call pargi (AP(shout)) call printf ("\n") call flush (STDOUT) end # SA_GETIM -- Get image from a list with the image kernal extension removed. procedure sa_getim (list, defname, image, maxchar) int list # Image list char defname[ARB] # Default image name char image[maxchar] # Image name int maxchar # Image name maximum character length int i, stat, imtgetim(), strmatch() pointer sp, str, section begin call smark (sp) call salloc (str, maxchar, TY_CHAR) call salloc (section, SZ_FNAME, TY_CHAR) stat = imtgetim (list, Memc[str], maxchar) if (stat == EOF) call strcpy (defname, Memc[str], maxchar) call imgsection (Memc[str], Memc[section], SZ_FNAME) call imgimage (Memc[str], image, maxchar) i = strmatch (image, ".??h$") if (i > 0) image[i-4] = EOS call strcat (Memc[section], image, maxchar) call sfree (sp) end # SA_SEXTRACT -- Extract a specific wavelength region procedure sa_sextract (sh, w1, w2, rebin, dtype, l1, dl, n) pointer sh #U SHDR structure double w1 #I Starting wavelength double w2 #I Ending wavelength bool rebin #I Rebin wavelength region? int dtype #O Dispersion type double l1 #O Starting logical pixel double dl #O Logical pixel increment int n #O Number of logical pixels int i1, i2 double a, b bool fp_equald() double shdr_lw(), shdr_wl() errchk shdr_wl, shdr_linear, shdr_extract begin if (IS_INDEFD(w1) && IS_INDEFD(w2)) { l1 = 1. dl = 1. n = SN(sh) dtype = DC(sh) return } a = w1 b = w2 if (IS_INDEFD(a)) a = shdr_lw (sh, 1.0D0) if (IS_INDEFD(b)) b = shdr_lw (sh, double (SN(sh))) l1 = shdr_wl (sh, a) dl = shdr_wl (sh, b) if (fp_equald(l1,dl) || max(l1,dl) < 1. || min (l1,dl) > SN(sh)) call error (1, "No pixels to extract") l1 = max (1D0, min (double (SN(sh)), l1)) dl = max (1D0, min (double (SN(sh)), dl)) i1 = nint (l1) i2 = nint (dl) n = abs (i2 - i1) + 1 if (!rebin) { l1 = i1 dl = i2 } if (n == 1) dl = 1 else dl = (dl - l1) / (n - 1) if (SY(sh) != NULL) call shdr_extract (sh, real(a), real(b), rebin) dtype = DC(sh) end