include include include include include # Profile types. define PTYPES "|gaussian|lorentzian|voigt|" define GAUSS 1 # Gaussian profile define LORENTZ 2 # Lorentzian profile define VOIGT 3 # Voigt profile # Type of constraints. define FITTYPES "|fixed|single|all|" define FIXED 1 # Fixed parameter define SINGLE 2 # Fit a single value for all lines define INDEP 3 # Fit independent values for all lines # Elements of fit array. define BKG 1 # Background define POS 2 # Position define INT 3 # Intensity define GAU 4 # Gaussian FWHM define LOR 5 # Lorentzian FWHM # Output image options. define OPTIONS "|difference|fit|" define DIFF 1 define FIT 2 # Monte-Carlo errors define MC_N 50 # Monte-Carlo samples (overridden by users) define MC_P 10 # Percent done interval (percent) define MC_SIG 68 # Sigma sample point (percent) define NSUB 3 # Number of pixel subsamples # T_FITPROFS -- Fit image profiles. procedure t_fitprofs() int inlist # List of input spectra pointer aps # Aperture list pointer bands # Band list int ptype # Profile type pointer pg, xg, yg, sg, lg # Fitting region and initial components real gfwhm # Default gfwhm real lfwhm # Default lfwhm int fit[5] # Fit flags: background, position, gfwhm, lfwhm int nerrsample # Number of error samples to use real sigma0 # Constant noise real invgain # Inverse gain pointer components # List of components bool verbose # Verbose? int log # Log file int plot # Plot file int outlist # List of output spectra int option # Output image option bool clobber # Clobber existing images? bool merge # Merge with existing images? real x, y, g, l bool complement int i, p, ng, nalloc pointer sp, input, output, ptr real clgetr() bool clgetb() int clgeti(), clgwrd(), clscan() int imtopenp(), imtgetim(), imtlen() int open(), fscan(), nscan(), strdic(), nowhite() pointer rng_open() errchk open begin call smark (sp) call salloc (input, SZ_FNAME, TY_CHAR) call salloc (output, SZ_FNAME, TY_CHAR) # Get parameters. inlist = imtopenp ("input") outlist = imtopenp ("output") if (imtlen (outlist) > 1 && imtlen (outlist) != imtlen (inlist)) call error (1, "Input and output image lists do not make sense") verbose = clgetb ("verbose") call clgstr ("logfile", Memc[output], SZ_FNAME) if (nowhite (Memc[output], Memc[output], SZ_FNAME) == 0) log = NULL else log = open (Memc[output], APPEND, TEXT_FILE) call clgstr ("plotfile", Memc[output], SZ_FNAME) if (nowhite (Memc[output], Memc[output], SZ_FNAME) == 0) plot = NULL else plot = open (Memc[output], APPEND, BINARY_FILE) ptype = clgwrd ("profile", Memc[output], SZ_FNAME, PTYPES) gfwhm = clgetr ("gfwhm") lfwhm = clgetr ("lfwhm") if (clgetb ("fitbackground")) fit[BKG] = SINGLE else fit[BKG] = FIXED fit[POS] = clgwrd ("fitpositions", Memc[output], SZ_FNAME, FITTYPES) fit[INT] = INDEP fit[GAU] = clgwrd ("fitgfwhm", Memc[output], SZ_FNAME, FITTYPES) fit[LOR] = clgwrd ("fitlfwhm", Memc[output], SZ_FNAME, FITTYPES) option = clgwrd ("option", Memc[output], SZ_FNAME, OPTIONS) clobber = clgetb ("clobber") merge = clgetb ("merge") nerrsample = clgeti ("nerrsample") sigma0 = clgetr ("sigma0") invgain = clgetr ("invgain") if (IS_INDEF(sigma0) || IS_INDEF(invgain) || sigma0<0. || invgain<0.) { sigma0 = INDEF invgain = INDEF } # Get the initial positions/peak/ptype/gfwhm/lfwhm. call clgstr ("positions", Memc[input], SZ_FNAME) if (nowhite (Memc[input], Memc[input], SZ_FNAME) == 0) { call sfree (sp) call error (1, "A 'positions' file must be specified") } i = open (Memc[input], READ_ONLY, TEXT_FILE) ng = 0 while (fscan (i) != EOF) { call gargr (x) call gargr (y) call gargwrd (Memc[output], SZ_FNAME) call gargr (g) call gargr (l) p = strdic (Memc[output], Memc[output], SZ_FNAME, PTYPES) if (p == 0) p = ptype switch (nscan()) { case 0: next case 1: y = INDEF p = ptype g = gfwhm l = lfwhm case 2: p = ptype g = gfwhm l = lfwhm case 3: g = gfwhm l = lfwhm case 4: switch (p) { case GAUSS: l = lfwhm case LORENTZ: l = g g = gfwhm case VOIGT: l = lfwhm } } if (ng == 0) { nalloc = 10 call malloc (pg, nalloc, TY_INT) call malloc (xg, nalloc, TY_REAL) call malloc (yg, nalloc, TY_REAL) call malloc (sg, nalloc, TY_REAL) call malloc (lg, nalloc, TY_REAL) } else if (ng == nalloc) { nalloc = nalloc + 10 call realloc (pg, nalloc, TY_INT) call realloc (xg, nalloc, TY_REAL) call realloc (yg, nalloc, TY_REAL) call realloc (sg, nalloc, TY_REAL) call realloc (lg, nalloc, TY_REAL) } switch (p) { case GAUSS: Memi[pg+ng] = p Memr[xg+ng] = x Memr[yg+ng] = y Memr[sg+ng] = g Memr[lg+ng] = 0. case LORENTZ: Memi[pg+ng] = p Memr[xg+ng] = x Memr[yg+ng] = y Memr[sg+ng] = 0. Memr[lg+ng] = g case VOIGT: Memi[pg+ng] = p Memr[xg+ng] = x Memr[yg+ng] = y Memr[sg+ng] = g Memr[lg+ng] = l } ng = ng + 1 } call close (i) if (ng == 0) call error (1, "No profiles defined") call realloc (xg, ng+2, TY_REAL) call realloc (yg, ng+2, TY_REAL) call realloc (sg, ng+2, TY_REAL) call realloc (lg, ng+2, TY_REAL) # Get fitting region and add to end of xg array. i = clscan ("region") call gargr (Memr[xg+ng]) call gargr (Memr[xg+ng+1]) if (i == EOF || nscan() < 1) # Decode range strings and set complement if needed. complement = false call clgstr ("lines", Memc[input], SZ_FNAME) ptr = input if (Memc[ptr] == '!') { complement = true ptr = ptr + 1 } iferr (aps = rng_open (Memc[ptr], INDEF, INDEF, INDEF)) call error (1, "Bad lines/column/aperture list") call clgstr ("bands", Memc[input], SZ_FNAME) ptr = input if (Memc[ptr] == '!') { complement = true ptr = ptr + 1 } iferr (bands = rng_open (Memc[ptr], INDEF, INDEF, INDEF)) call error (1, "Bad band list") # Decode components. call clgstr ("components", Memc[input], SZ_FNAME) iferr (components = rng_open (Memc[input], INDEF, INDEF, INDEF)) call error (1, "Bad component list") while (imtgetim (inlist, Memc[input], SZ_FNAME) != EOF) { if (imtgetim (outlist, Memc[output], SZ_FNAME) == EOF) Memc[output] = EOS call fp_ms (Memc[input], aps, bands, complement, Memi[pg], Memr[xg], Memr[yg], Memr[sg], Memr[lg], ng, fit, nerrsample, sigma0, invgain, components, verbose, log, plot, Memc[output], option, clobber, merge) } if (log != NULL) call close (log) if (plot != NULL) call close (plot) call rng_close (aps) call rng_close (bands) call rng_close (components) call imtclose (inlist) call imtclose (outlist) call mfree (pg, TY_INT) call mfree (xg, TY_REAL) call mfree (yg, TY_REAL) call mfree (sg, TY_REAL) call mfree (lg, TY_REAL) call sfree (sp) end # FP_MS -- Handle I/O and call fitting procedure. procedure fp_ms (input, aps, bands, complement, pg, xg, yg, sg, lg, ng, fit, nerrsample, sigma0, invgain, components, verbose, log, plot, output, option, clobber, merge) char input[ARB] # Input image pointer aps # Apertures pointer bands # Bands bool complement # Complement aperture selection int pg[ng] # Profile type real xg[ng] # Positions real yg[ng] # Peaks real sg[ng] # Gaussian FWHM real lg[ng] # Lorentzian FWHM int ng # Number of profiles int fit[5] # Fit flags int nerrsample # Number of error samples real sigma0 # Constant noise real invgain # Inverse gain pointer components # Output Component list bool verbose # Verbose output? int log # Log file descriptor int plot # Plot file descriptor char output[ARB] # Output image int option # Output image option bool clobber # Clobber existing image? bool merge # Merge with existing image? real aplow[2], aphigh[2] double a, b, w1, wb, dw, z, p1, p2, p3 bool select int i, j, k, l, ap, beam, dtype, nw, ninaps, noutaps, nbands, naps, last int mwoutdim, axis[3] pointer ptr, in, out, tmp, mwin, mwout, sh, shout pointer sp, str, key, temp, ltm1, ltv1, ltm2, ltv2, coeff, outaps pointer model double shdr_lw() int imaccess(), imgnfn() bool streq(), strne(), rng_elementi(), fp_equald() pointer smw_openim(), mw_open() pointer immap(), imgl3r(), impl3r(), imofnlu() errchk immap, smw_openim, mw_open, shdr_open, imunmap, imgstr, imgl3r, impl3r errchk imdelete data axis/1,2,3/ begin call smark (sp) call salloc (str, SZ_LINE, TY_CHAR) call salloc (key, SZ_LINE, 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) coeff = NULL # Initialize. in = NULL; out = NULL; tmp = NULL mwin = NULL; mwout = NULL sh = NULL; shout = NULL ninaps = 0; noutaps = 0; nbands = 0 iferr { # Check for existing output image and abort if clobber is not set. if (output[1] != EOS && 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) { # Merging when the input and output are the same is a nop. if (streq (input, output)) { call sfree (sp) return } # 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. 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, sh) Memi[outaps+i-1] = AP(sh) } } call mktemp ("temp", Memc[temp], SZ_FNAME) } else call strcpy (output, Memc[temp], SZ_FNAME) # Open the input and determine the number of final output # apertures in order to set the output dimensions. ptr = immap (input, READ_ONLY, 0); in = ptr ptr = smw_openim (in); mwin = ptr naps = noutaps j = 1 if (SMW_FORMAT(mwin) != SMW_ND) { j = 0 do i = 1, SMW_NBANDS(mwin) { 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(mwin) { call shdr_open (in, mwin, i, 1, INDEFI, SHHDR, sh) ap = AP(sh) if (SMW_FORMAT(mwin) == SMW_ND) { call smw_mw (mwin, i, 1, ptr, j, k) select = rng_elementi (aps, j) && rng_elementi (bands, k) } else select = rng_elementi (aps, ap) if ((complement && select) || (!complement && !select)) next for (j=0; j 1) IM_NDIM(tmp) = 3 else if (naps > 1) IM_NDIM(tmp) = 2 else IM_NDIM(tmp) = 1 do j = 1, IM_LEN(out,3) do i = 1, IM_LEN(out,2) { ptr = impl3r (tmp, i, j) call aclrr (Memr[ptr], IM_LEN(tmp,1)) call amovr (Memr[imgl3r(out,i,j)], Memr[ptr], IM_LEN(out,1)) } do j = 1, IM_LEN(out,3) do i = IM_LEN(out,2)+1, IM_LEN(tmp,2) { ptr = impl3r (tmp, i, j) call aclrr (Memr[ptr], IM_LEN(tmp,1)) } do j = IM_LEN(out,3)+1, nbands do i = 1, IM_LEN(tmp,2) { ptr = impl3r (tmp, i, j) call aclrr (Memr[ptr], IM_LEN(tmp,1)) } call imunmap (out) out = tmp tmp = NULL } else if (Memc[temp] != EOS) { ptr = immap (Memc[temp], NEW_COPY, in); out = ptr if (IM_PIXTYPE(out) != TY_DOUBLE) IM_PIXTYPE(out) = TY_REAL # Set header IM_LEN(out,1) = SMW_LLEN(mwin,1) 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(mwin) j = SMW_PAXIS(mwin,1) ptr = mw_open (NULL, mwoutdim); mwout = ptr call mw_newsystem (mwout, "equispec", mwoutdim) call mw_swtype (mwout, axis, mwoutdim, "linear", "") if (LABEL(sh) != EOS) call mw_swattrs (mwout, 1, "label", LABEL(sh)) if (UNITS(sh) != EOS) call mw_swattrs (mwout, 1, "units", UNITS(sh)) call mw_gltermd (SMW_MW(mwin,0), Memd[ltm1], Memd[ltv1], i) call mw_gltermd (mwout, Memd[ltm2], Memd[ltv2], mwoutdim) Memd[ltv2] = Memd[ltv1+(j-1)] Memd[ltm2] = Memd[ltm1+(i+1)*(j-1)] call mw_sltermd (mwout, Memd[ltm2], Memd[ltv2], mwoutdim) call smw_open (mwout, NULL, out) } if (out != NULL) { # Check dispersion function compatibility # Nonlinear functions can be copied to different physical # coordinate system though the linear dispersion can be # modified. call mw_gltermd (SMW_MW(mwout,0), Memd[ltm2], Memd[ltv2], mwoutdim) a = Memd[ltv2] b = Memd[ltm2] if (DC(sh) == DCFUNC) { i = SMW_PDIM(mwin) j = SMW_PAXIS(mwin,1) call mw_gltermd (SMW_MW(mwin,0), Memd[ltm1], Memd[ltv1], i) Memd[ltv1] = Memd[ltv1+(j-1)] Memd[ltm1] = 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") } } } # Now do the actual fitting call salloc (model, SMW_LLEN(mwin,1), TY_REAL) last = noutaps do i = 1, SMW_NSPEC(mwin) { call shdr_open (in, mwin, i, 1, INDEFI, SHHDR, sh) # Check apertures. ap = AP(sh) if (SMW_FORMAT(mwin) == SMW_ND) { call smw_mw (mwin, i, 1, ptr, j, k) select = rng_elementi (aps, j) && rng_elementi (bands, k) } else select = rng_elementi (aps, ap) if ((complement && select) || (!complement && !select)) next call fp_title (sh, Memc[str], verbose, log) call shdr_open (in, mwin, i, 1, INDEFI, SHDATA, sh) if (SN(sh) < SMW_LLEN(mwin,1)) call aclrr (Memr[model], SMW_LLEN(mwin,1)) iferr (call fp_fit (sh, Memr[SX(sh)], Memr[SY(sh)], SN(sh), pg, xg, yg, sg, lg, ng, fit, nerrsample, sigma0, invgain, components, verbose, log, plot, Memc[str], Memr[model])) { call erract (EA_WARN) } if (out != NULL) { for (j=0; j %s%s(%s)\n") call pargstr (IMNAME(sh)) call pargstr (IMSEC(sh)) call pargi (AP(sh)) call pargstr (IMNAME(shout)) call pargstr (IMSEC(shout)) call pargi (AP(shout)) call flush (STDOUT) } } } call smw_close (MW(sh)) if (out != NULL) { call smw_saveim (mwout, out) if (shout != NULL) call smw_close (MW(shout)) call imunmap (out) if (strne (Memc[temp], output)) { call imdelete (output) call imrename (Memc[temp], output) } } call imunmap (in) } then { if (shout != NULL) call smw_close (MW(shout)) else if (mwout != NULL) call smw_close (mwout) if (sh != NULL) call smw_close (MW(sh)) else if (mwin != NULL) call smw_close (mwin) if (tmp != NULL) call imunmap (tmp) if (out != NULL) call imunmap (out) if (in != NULL) call imunmap (in) call erract (EA_WARN) } call shdr_close (shout) call shdr_close (sh) call mfree (coeff, TY_CHAR) call sfree (sp) end define SQ2PI 2.5066283 # FP_FIT -- Fit profile functions procedure fp_fit (sh, x, y, n, ptypes, pos, peaks, gfwhms, lfwhms, ng, fit, nerrsample, sigma0, invgain, components, verbose, log, plot, title, mod) pointer sh # Spectrum data structure real x[n] # Coordinates real y[n] # Data int n # Number of data points int ptypes[ARB] # Profile types real pos[ARB] # Fitting region and initial positions real peaks[ARB] # Peak values real gfwhms[ARB] # Background levels and initial gfwhm real lfwhms[ARB] # Initial lfwhm int ng # Number of gaussian components int fit[5] # Fit flags int nerrsample # Number of error samples real sigma0 # Constant noise real invgain # Inverse gain pointer components # Component list bool verbose # Output to STDOUT? int log # Log file descriptor int plot # Plot file descriptor char title[ARB] # Plot title real mod[n] # Model int i, j, k, i1, i2, nfit, nsub, mc_n, mc_p, mc_sig long seed real xc, x1, x2, dx, y1, dy, z1, dz, w, z, scale, sscale real peak, flux, cont, gfwhm, lfwhm, eqw, chisq real flux1, cont1, eqw1, wyc1, slope1, v, u bool doerr pointer sp, str, xd, yd, sd, xg, yg, sg, lg, pg, yd1, xg1, yg1, sg1, lg1 pointer ym, conte, xge, yge, sge, lge, fluxe, eqwe pointer gp, gopen() bool rng_elementi() real model(), gasdev(), asumr() double shdr_lw(), shdr_wl errchk fp_background, dofit, dorefit begin # Determine fitting region. x1 = pos[ng+1] x2 = pos[ng+2] i1 = nint (shdr_wl (sh, double(x1))) i2 = nint (shdr_wl (sh, double(x2))) i = min (n, max (i1, i2)) i1 = max (1, min (i1, i2)) i2 = i nfit = i2 - i1 + 1 if (nfit < 3) { call aclrr (mod, n) call error (1, "Too few data points in fitting region") } x1 = shdr_lw (sh, double(i1)) x2 = shdr_lw (sh, double(i2)) # Allocate memory. call smark (sp) call salloc (str, SZ_LINE, TY_CHAR) call salloc (xd, nfit, TY_REAL) call salloc (yd, nfit, TY_REAL) call salloc (sd, nfit, TY_REAL) call salloc (xg, ng, TY_REAL) call salloc (yg, ng, TY_REAL) call salloc (sg, ng, TY_REAL) call salloc (lg, ng, TY_REAL) call salloc (pg, ng, TY_INT) # Subtract the continuum and scale the data. call fp_background (sh, x, y, n, x1, x2, y1, dy) scale = 0. doerr = !IS_INDEF(sigma0) do i = i1, i2 { Memr[xd+i-i1] = x[i] Memr[yd+i-i1] = y[i] - (y1 + dy * (x[i]-x1)) if (y[i] <= 0.) doerr = false scale = max (scale, abs (Memr[yd+i-i1])) } if (doerr) { do i = i1, i2 Memr[sd+i-i1] = sqrt (sigma0 ** 2 + invgain * y[i]) sscale = asumr (Memr[sd], nfit) / nfit } else { call amovkr (1., Memr[sd], nfit) sscale = 1. } call adivkr (Memr[yd], scale, Memr[yd], nfit) call adivkr (Memr[sd], sscale, Memr[sd], nfit) y1 = y1 / scale dy = dy / scale # Setup initial estimates. do i = 1, ng { Memr[xg+i-1] = pos[i] Memr[sg+i-1] = gfwhms[i] Memr[lg+i-1] = lfwhms[i] Memi[pg+i-1] = ptypes[i] if (IS_INDEF(peaks[i])) { j = max (1, min (nfit, nint (shdr_wl(sh,double(pos[i])))-i1+1)) Memr[yg+i-1] = Memr[yd+j-1] } else Memr[yg+i-1] = peaks[i] / scale } z1 = 0. dz = 0. dx = (x[n] - x[1]) / (n - 1) nsub = NSUB call dofit (fit, Memr[xd], Memr[yd], Memr[sd], nfit, dx, nsub, z1, dz, Memr[xg], Memr[yg], Memr[sg], Memr[lg], Memi[pg], ng, chisq) # Compute Monte-Carlo errors. mc_n = nerrsample mc_p = nint (mc_n * MC_P / 100.) mc_sig = nint (mc_n * MC_SIG / 100.) if (doerr && mc_sig > 9) { call salloc (yd1, nfit, TY_REAL) call salloc (ym, nfit, TY_REAL) call salloc (xg1, ng, TY_REAL) call salloc (yg1, ng, TY_REAL) call salloc (sg1, ng, TY_REAL) call salloc (lg1, ng, TY_REAL) call salloc (conte, mc_n*ng, TY_REAL) call salloc (xge, mc_n*ng, TY_REAL) call salloc (yge, mc_n*ng, TY_REAL) call salloc (sge, mc_n*ng, TY_REAL) call salloc (lge, mc_n*ng, TY_REAL) call salloc (fluxe, mc_n*ng, TY_REAL) call salloc (eqwe, mc_n*ng, TY_REAL) do i = 1, nfit { w = Memr[xd+i-1] Memr[ym+i-1] = model (w, dx, nsub, Memr[xg], Memr[yg], Memr[sg], Memr[lg], Memi[pg], ng) } seed = 1 do i = 0, mc_n-1 { do j = 1, nfit Memr[yd1+j-1] = Memr[ym+j-1] + sscale / scale * Memr[sd+j-1] * gasdev (seed) wyc1 = z1 slope1 = dz call amovr (Memr[xg], Memr[xg1], ng) call amovr (Memr[yg], Memr[yg1], ng) call amovr (Memr[sg], Memr[sg1], ng) call amovr (Memr[lg], Memr[lg1], ng) call dorefit (fit, Memr[xd], Memr[yd1], Memr[sd], nfit, dx, nsub, wyc1, slope1, Memr[xg1], Memr[yg1], Memr[sg1], Memr[lg1], Memi[pg], ng, chisq) do j = 0, ng-1 { cont = y1 + z1 + (dy + dz) * Memr[xg+j] - dy * x1 cont1 = y1 + wyc1 + (dy + slope1) * Memr[xg+j] - dy * x1 switch (Memi[pg+j]) { case GAUSS: flux = 1.064467 * Memr[yg+j] * Memr[sg+j] flux1 = 1.064467 * Memr[yg1+j] * Memr[sg1+j] case LORENTZ: flux = 1.570795 * Memr[yg+j] * Memr[lg+j] flux1 = 1.570795 * Memr[yg1+j] * Memr[lg1+j] case VOIGT: call voigt (0., 0.832555*Memr[lg+j]/Memr[sg+j], v, u) flux = 1.064467 * Memr[yg+j] * Memr[sg+j] / v call voigt (0., 0.832555*Memr[lg1+j]/Memr[sg1+j], v, u) flux1 = 1.064467 * Memr[yg1+j] * Memr[sg1+j] / v } if (cont > 0. && cont1 > 0.) { eqw = -flux / cont eqw1 = -flux1 / cont1 } else { eqw = 0. eqw1 = 0. } Memr[conte+j*mc_n+i] = abs (cont1 - cont) Memr[xge+j*mc_n+i] = abs (Memr[xg1+j] - Memr[xg+j]) Memr[yge+j*mc_n+i] = abs (Memr[yg1+j] - Memr[yg+j]) Memr[sge+j*mc_n+i] = abs (Memr[sg1+j] - Memr[sg+j]) Memr[lge+j*mc_n+i] = abs (Memr[lg1+j] - Memr[lg+j]) Memr[fluxe+j*mc_n+i] = abs (flux1 - flux) Memr[eqwe+j*mc_n+i] = abs (eqw1 - eqw) } } do j = 0, ng-1 { call asrtr (Memr[conte+j*mc_n], Memr[conte+j*mc_n], mc_n) call asrtr (Memr[xge+j*mc_n], Memr[xge+j*mc_n], mc_n) call asrtr (Memr[yge+j*mc_n], Memr[yge+j*mc_n], mc_n) call asrtr (Memr[sge+j*mc_n], Memr[sge+j*mc_n], mc_n) call asrtr (Memr[lge+j*mc_n], Memr[lge+j*mc_n], mc_n) call asrtr (Memr[fluxe+j*mc_n], Memr[fluxe+j*mc_n], mc_n) call asrtr (Memr[eqwe+j*mc_n], Memr[eqwe+j*mc_n], mc_n) } call amulkr (Memr[conte], scale, Memr[conte], mc_n*ng) call amulkr (Memr[yge], scale, Memr[yge], mc_n*ng) call amulkr (Memr[fluxe], scale, Memr[fluxe], mc_n*ng) } call amulkr (Memr[yg], scale, Memr[yg], ng) y1 = (y1 + z1 + dz * x1) * scale dy = (dy + dz) * scale # Log computed values call sprintf (Memc[str], SZ_LINE, "# Nfit=%d, background=%b, positions=%s, gfwhm=%s, lfwhm=%s\n") call pargi (ng) call pargb (fit[BKG] == SINGLE) if (fit[POS] == FIXED) call pargstr ("fixed") else if (fit[POS] == SINGLE) call pargstr ("single") else call pargstr ("all") if (fit[GAU] == FIXED) call pargstr ("fixed") else if (fit[GAU] == SINGLE) call pargstr ("single") else call pargstr ("all") if (fit[LOR] == FIXED) call pargstr ("fixed") else if (fit[LOR] == SINGLE) call pargstr ("single") else call pargstr ("all") if (log != NULL) call fprintf (log, Memc[str]) if (verbose) call printf (Memc[str]) call sprintf (Memc[str], SZ_LINE, "# %8s%10s%10s%10s%10s%10s%10s\n") call pargstr ("center") call pargstr ("cont") call pargstr ("flux") call pargstr ("eqw") call pargstr ("core") call pargstr ("gfwhm") call pargstr ("lfwhm") if (log != NULL) call fprintf (log, Memc[str]) if (verbose) call printf (Memc[str]) do i = 1, ng { if (!rng_elementi (components, i)) next xc = Memr[xg+i-1] cont = y1 + dy * (xc - x1) peak = Memr[yg+i-1] gfwhm = Memr[sg+i-1] lfwhm = Memr[lg+i-1] switch (Memi[pg+i-1]) { case 1: flux = 1.064467 * peak * gfwhm case 2: flux = 1.570795 * peak * lfwhm case 3: call voigt (0., 0.832555*lfwhm/gfwhm, v, u) flux = 1.064467 * peak * gfwhm / v } if (cont > 0.) eqw = -flux / cont else eqw = INDEF call sprintf (Memc[str], SZ_LINE, " %9.7g %9.7g %9.6g %9.4g %9.6g %9.4g %9.4g\n") call pargr (xc) call pargr (cont) call pargr (flux) call pargr (eqw) call pargr (peak) call pargr (gfwhm) call pargr (lfwhm) if (log != NULL) call fprintf (log, Memc[str]) if (verbose) call printf (Memc[str]) if (doerr && mc_sig > 9) { call sprintf (Memc[str], SZ_LINE, " (%7.7g) (%7.7g) (%7.6g) (%7.4g) (%7.6g) (%7.4g) (%7.4g)\n") call pargr (Memr[xge+(i-1)*mc_n+mc_sig]) call pargr (Memr[conte+(i-1)*mc_n+mc_sig]) call pargr (Memr[fluxe+(i-1)*mc_n+mc_sig]) call pargr (Memr[eqwe+(i-1)*mc_n+mc_sig]) call pargr (Memr[yge+(i-1)*mc_n+mc_sig]) call pargr (Memr[sge+(i-1)*mc_n+mc_sig]) call pargr (Memr[lge+(i-1)*mc_n+mc_sig]) if (log != NULL) call fprintf (log, Memc[str]) if (verbose) call printf (Memc[str]) } } # Compute model. call aclrr (mod, n) do i = 0, ng-1 { if (!rng_elementi (components, i+1)) next do j = 1, n #mod[j] = model (x[j], dx, nsub, Memr[xg+i], Memr[yg+i], # Memr[sg+i], Memr[lg+i], Memi[pg+i], ng) mod[j] = mod[j] + model (x[j], dx, nsub, Memr[xg+i], Memr[yg+i], Memr[sg+i], Memr[lg+i], Memi[pg+i], 1) } # Draw graphs if (plot != NULL) { gp = gopen ("stdvdm", NEW_FILE, plot) call gascale (gp, y[i1], nfit, 2) call asubr (y[i1], mod[i1], Memr[yd], nfit) call grscale (gp, Memr[yd], nfit, 2) do i = i1, i2 Memr[yd+i-i1] = mod[i] + y1 + dy * (x[i] - x1) call grscale (gp, Memr[yd], nfit, 2) call gswind (gp, x1, x2, INDEF, INDEF) call glabax (gp, title, "", "") call gseti (gp, G_PLTYPE, 1) call gpline (gp, Memr[xd], y[i1], nfit) call gseti (gp, G_PLTYPE, 2) call gpline (gp, Memr[xd], Memr[yd], nfit) call gline (gp, x1, y1, x2, y1+dy*(x2-x1)) call gseti (gp, G_PLTYPE, 3) call asubr (y[i1], mod[i1], Memr[yd], nfit) call gpline (gp, Memr[xd], Memr[yd], nfit) call gseti (gp, G_PLTYPE, 4) do i = 0, ng-1 { if (!rng_elementi (components, i+1)) next k = 0 do j = i1, i2 { w = x[j] z = model (w, dx, nsub, Memr[xg+i], Memr[yg+i], Memr[sg+i], Memr[lg+i], Memi[pg+i], 1) z = z + y1 + dy * (w - x1) if (k == 0) { call gamove (gp, w, z) k = 1 } else call gadraw (gp, w, z) } } call gclose (gp) } call sfree (sp) end # FP_BACKGROUND -- Iniital background. procedure fp_background (sh, x, y, n, x1, x2, y1, dy) pointer sh #I Spectrum pointer real x[n] #I Coordinate values real y[n] #I Data int n #I Number of data points real x1, x2 #I Fit endpoints real y1, dy #O Background int i, j, k, m, func real xval[2], yval[2] double z1, z2, z3 pointer sp, bkg, str int ctotok(), ctor(), ctod(), strdic(), nscan() real asumr(), amedr() double shdr_wl(), shdr_lw() define err_ 10 begin call smark (sp) call salloc (bkg, SZ_LINE, TY_CHAR) call salloc (str, SZ_LINE, TY_CHAR) xval[1] = x1 xval[2] = x2 call clgstr ("background", Memc[bkg], SZ_LINE) call sscan (Memc[bkg]) do j = 1, 2 { call gargwrd (Memc[bkg], SZ_LINE) if (nscan() != j) { i = max (1, min (n, nint (shdr_wl (sh, double(xval[j]))))) xval[j] = shdr_lw (sh, double(i)) yval[j] = y[i] next } k = 1 if (ctor (Memc[bkg], k, yval[j]) == 0) { if (ctotok (Memc[bkg], k, Memc[str], SZ_LINE) != TOK_IDENTIFIER) goto err_ func = strdic (Memc[str], Memc[str], SZ_LINE, "|avg|med|") if (func == 0) goto err_ k = k + 1 if (ctod (Memc[bkg], k, z1) == 0) goto err_ k = k + 1 if (ctod (Memc[bkg], k, z2) == 0) goto err_ k = k + 1 if (ctod (Memc[bkg], k, z3) == 0) z3 = 1 z1 = shdr_wl (sh, z1) z2 = shdr_wl (sh, z2) i = max (1, nint(min(z1,z2))) m = min (n, nint(max(z1,z2))) - i + 1 if (m < 1) goto err_ # This is included to eliminate an optimizer bug on solaris. call sprintf (Memc[bkg], SZ_LINE, "%g %g %g %d %d\n") call pargd (z1) call pargd (z2) call pargd (z3) call pargi (i) call pargi (m) switch (func) { case 1: xval[j] = z3 * asumr (x[i], m) / m yval[j] = z3 * asumr (y[i], m) / m case 2: xval[j] = z3 * asumr (x[i], m) / m yval[j] = z3 * amedr (y[i], m) } } } if (xval[1] == xval[2]) { dy = 0. y1 = (yval[1] + yval[2]) / 2. } else { dy = (yval[2] - yval[1]) / (xval[2] - xval[1]) y1 = yval[1] + dy * (x1 - xval[1]) } return err_ call sfree (sp) call error (1, "Syntax error in background specification") end include # FP_TITLE -- Set title string and print. procedure fp_title (sh, str, verbose, log) pointer sh # Spectrum header structure char str[SZ_LINE] # Title string bool verbose # Verbose? int log # Log file descriptor pointer sp, time, smw long clktime() begin # Select title format. smw = MW(sh) switch (SMW_FORMAT(smw)) { case SMW_ND: call sprintf (str, SZ_LINE, "%s%s: %s") call pargstr (IMNAME(sh)) call pargstr (IMSEC(sh)) call pargstr (TITLE(sh)) case SMW_ES, SMW_MS: call sprintf (str, SZ_LINE, "%s - Ap %d: %s") call pargstr (IMNAME(sh)) call pargi (AP(sh)) call pargstr (TITLE(sh)) } # Set time and log header. call smark (sp) call salloc (time, SZ_DATE, TY_CHAR) call cnvdate (clktime(0), Memc[time], SZ_DATE) if (log != NULL) { call fprintf (log, "# %s %s\n") call pargstr (Memc[time]) call pargstr (str) } if (verbose) { call printf ("# %s %s\n") call pargstr (Memc[time]) call pargstr (str) } call sfree (sp) end