c
c******************************************************************************* c$ Component_name: c PPSRESAM c$ Abstract: c This program generates an ASCII-format file containing the PPS data c calibrated and resampled onto a uniform radius grid. c$ Keywords: c PROFILE, OCCULTATIONS, PPS c FORTRAN, PUBLIC, MAIN_PROGRAM c$ Declarations: c none c$ Inputs: c (1) Name of the PDS label for the PPS data file. c (2) Name of the PDS label for the PPS geometry file. c (3) Name of the PDS label for the PPS calibration file. c (4) Radius curve segment index (if the radius curve is non-monotonic). c Segments are numbered such that segment #1 falls between the first c pair of extrema in the radius function. c (5) Lower and upper radius limits and interval (km). c (6) Point spread function type. The point spread function (PSF) of the c filtered data can be boxcar, triangle or sinc. Using a boxcar PSF, c each new sample is a uniform average of the data points centered on c the sample's midpoint and extending halfway to the nearest c neighbors. Using a triangle PSF, each sample is weighted most c heavily toward the center of the sample and extends (with linearly c decreasing weight) to each of the nearest neighbors. Using a sinc c PSF, each new sample is best construed as a local sample of a c continuous function that has been low-pass filtered, so that it c contains now power in spatial frequencies higher than the Nyquist c frequency. Note that the program runs fastest for a boxcar PSF and c perhaps 10 times slower for a sinc PSF. c (7) Output file name. c$ Outputs: c A resampled ring profile. The output file contains six columns: c (1) Radius value (km). c (2) Mean photon counts. c (3) Standard deviation in photon counts. c (4) Approximate tau. c (5) Lower limit of the 68% (+/-1 sigma) confidence interval on tau. c (6) Upper limit of the 68% (+/-1 sigma) confidence interval on tau. c$ Returns: c none c$ Detailed_description: c This program generates an ASCII-format file containing the PPS data c resampled onto a uniform radius grid. The resultant file can be c plotted or used for further analysis. This program also serves as a c sample program the Profile Toolkit. c c This program contains a few lines that are non-standard ANSI c FORTRAN-77, specifically "IMPLICIT NONE" and the "CARRIAGECONTROL" c option on OPEN. If necessary, these lines can be commented out. c However, this appears to be unnecessary on most compilers. c$ External_references: c Profile library, Object Access Library c$ Examples: c Here is a sample run of the program. It generates output file c RESAMOUT.TAB, which is included with the toolkit. c c Data file label: PPSDATA.LBL c Geometry file label: PPSGEOM.LBL c Calibration file label: PPSCALIB.LBL c 0: r = 63585.550, dr = 0.109 c 1: r = 142592.353, dr = 0.087 c Radius min, max, interval (km) = 133000,134000,2 c Filter type (boxcar,triangle,sinc): (B/T/S) = B c Output filename: RESAMOUT.TAB c c The first five lines of the output file are as follows: c 133000.00, 24.063, 1.052, 0.3891, 0.3608, 0.4191 c 133002.00, 24.601, 1.067, 0.3744, 0.3466, 0.4039 c 133004.00, 19.497, 0.958, 0.5357, 0.5010, 0.5731 c 133006.00, 21.232, 1.000, 0.4746, 0.4426, 0.5089 c 133008.00, 23.016, 1.032, 0.4189, 0.3894, 0.4503 c$ Error_handling: c The program prints an error message and aborts if anything goes wrong. c$ Limitations: c none c$ Author_and_institution: c Mark R. Showalter c PDS Ring-Moon Systems Node, NASA/Ames Research Center c$ Version_and_date: c 1.0: May 1998 c 1.1: December 1999 c 1.2: September 2002 c 1.3: September 2003 c$ Change_history: c 1.1: Revised to include commas between columns of output file. c Revised to write unweighted samples correctly in output file. c 1.2: Corrected a bug in the definition of the width of a sinc psf. c 1.3: Revised so the INCIDENCE_ANGLE comes from the geometry file, not c the calibration file. Updated comments to reflect new directory c structure. c******************************************************************************* program PPSRESAM implicit none include 'fprofile.inc' real*8 x, x1, x2, dx, xsize, y, r, r1, r2, dr, drdx, & count, covar, sigma, b, s, mu, tau, tau_lo, & tau_hi integer*4 ncolumn, nsegment, nsegments, type, fsize, & nsamples, k, flag character filename*80, char*1 integer*4 dlabel, label, column, series, curve, curve2, & star, back, newpsf, oldpsf, resampled real*8 TauFunc c Constants integer OUTUNIT/1/ real*8 SINC_HALFWIDTH/5.d0/ real*8 PI real*8 MAXTAU/99.d0/ real*8 MINTAU/-9.d0/ real*8 MAXSIGMA/99.d0/ c*********************************************************************** c Prepare to set up data series c*********************************************************************** c Prompt for label filename write(*,10) 'Data file label: ' read(*,11,end=9999) filename 10 format(1x,a,$) 11 format(a) c Open file dlabel = FPro_OpenLabel(filename) c Create column object (which we'll never use because we're unsure of c the proper buffer size) c ntable=1, ncolumn=1, nitem=0 (all), row1=1, row2=0 (all), k1=0, c buffersize=1, usedouble=FALSE series = FPro_ColumnSeries(dlabel, 1, 1, 0, 1, 0, 0, 1, .FALSE.) c Get interval and prepare to track domain overlap xsize = FPro_SeriesSampling(series, x1, x2, dx) xsize = FPro_ObjectOverlap(series, series, x1, x2) c*********************************************************************** c Set up radius function c*********************************************************************** c Prompt for label filename write(*,10) 'Geometry file label: ' read(*,11,end=9999) filename c Open file label = FPro_OpenLabel(filename) c Find column ncolumn = FPro_LabelFind(label, 1, 'RING_INTERCEPT_RADIUS') c Create column object c ntable=1, ncolumn, nitem=1, row1=1, row2=0 (all), k1=0, c buffersize=0 (all), usedouble=TRUE column = FPro_ColumnSeries(label, 1, ncolumn, 1, 1, 0, 0, 0, & .TRUE.) c Fit cubic splines curve = FPro_SplineCurve(column) c Get mu factor PI = 4.d0 * atan(1.d0) mu = cos(PI/180.d0 * & FPro_LabelFloat(label, 0, 0, 'INCIDENCE_ANGLE', & 0.d0, .TRUE.)) C Free unneeded objects call FPro_FreeObject(label) call FPro_FreeObject(column) c Update domain xsize = FPro_ObjectOverlap(curve, series, x1, x2) c*********************************************************************** c Set up stellar and background count functions c*********************************************************************** c Prompt for label filename write(*,10) 'Calibration file label: ' read(*,11,end=9999) filename c Open file label = FPro_OpenLabel(filename) c Set up linear splines for stellar signal ncolumn = FPro_LabelFind(label, 1, 'STELLAR_SIGNAL') column = FPro_ColumnSeries(label, 1, ncolumn, 1, 1, 0, 0, 0, & .TRUE.) star = FPro_LSplineFunc(column) call FPro_FreeObject(column) c Set up linear splines for background signal ncolumn = FPro_LabelFind(label, 1, 'BACKGROUND_SIGNAL') column = FPro_ColumnSeries(label, 1, ncolumn, 1, 1, 0, 0, 0, & .TRUE.) back = FPro_LSplineFunc(column) call FPro_FreeObject(column) c Close file call FPro_FreeObject(label) c Update domain xsize = FPro_ObjectOverlap(star, series, x1, x2) xsize = FPro_ObjectOverlap(back, series, x1, x2) c*********************************************************************** c Get radius limits c*********************************************************************** c Window curve curve2 = FPro_WindowFunc(curve, x1, x2) call FPro_FreeObject(curve) curve = curve2 c Summarize curve segments nsegments = FPro_CurveSegments(curve) do 200 nsegment = 0, nsegments x = FPro_CurveExtremum(curve, nsegment, r, type) y = FPro_CurveValue(curve, x, drdx) write(*,20) nsegment, r, drdx*dx 20 format(1x, i2, ': r = ', f10.3, ', dr = ', f8.3) 200 continue c Get sampling parameters if (nsegments .gt. 1) then write(*,10) 'Segment index = ' read(*,*,end=9999) nsegment else nsegment = 1 endif write(*,10) 'Radius min, max, interval (km) = ' read(*,*,end=9999) r1, r2, dr c*********************************************************************** c Set up filter c*********************************************************************** c Set up new PSF write(*,10) 'Filter type (boxcar,triangle,sinc): (B/T/S) = ' read(*,11,end=9999) char if (char .eq. 'B' .or. char .eq. 'b') then newpsf = FPro_BoxcarFunc(1.d0, 0.5d0) else if (char .eq. 'T' .or. char .eq. 't') then newpsf = FPro_TriangleFunc(1.d0, 1.d0) else if (char .eq. 'S' .or. char .eq. 's') then newpsf = FPro_SincFunc(1.d0, 1.d0, SINC_HALFWIDTH, 0.d0) else write(*,*) 'Unrecognized filter type: ' // char goto 9999 end if c Old PSF for PPS data is a boxcar of 80% width oldpsf = FPro_BoxcarFunc(1.d0, 0.4d0) c*********************************************************************** c Set up resampled data series c*********************************************************************** c Determine size of buffer fsize = FPro_ResampledSize(series, oldpsf, newpsf, curve, & nsegment, r1, r2, dr) c Now we're done with original data series call FPro_FreeObject(series) c Create new column object with correct buffer size c ntable=1, ncolumn=1, nitem=0 (all), row1=1, row2=0 (all), k1=0, c buffersize=fsize, usedouble=FALSE column = FPro_ColumnSeries(dlabel, 1, 1, 0, 1, 0, 0, fsize, & .FALSE.) c Define uniformly weighted, uncorrelated samples series = FPro_FixedStat(column, 0, 1.d0) c Set up resampled statistical series nsamples = (r2 - r1 + 1.01*dr) / dr resampled = FPro_ResampledStat(series, oldpsf, newpsf, curve, & nsegment, r1, dr, 1, nsamples) c Free unneeded objects call FPro_FreeObject(dlabel) call FPro_FreeObject(column) call FPro_FreeObject(series) call FPro_FreeObject(oldpsf) call FPro_FreeObject(newpsf) c*********************************************************************** c Open output file c*********************************************************************** write(*,10) 'Output filename: ' read(*,11,end=9999) filename open(OUTUNIT, file=filename, form='formatted', status='new' & , carriagecontrol='list' & ) c CARRIAGECONTROL is a useful qualifier supported by many c implementations of FORTRAN. Others seem to ignore it, but it may c need to be commented out in some circumstances. c*********************************************************************** c Write output file c*********************************************************************** c Loop through resampled series do 300 k = 1, nsamples r = FPro_SeriesXValue(resampled, dble(k)) x = FPro_CurveInverse(curve, nsegment, r) b = FPro_FuncValue(back, x) s = FPro_FuncValue(star, x) count = FPro_SeriesValue(resampled, k, flag) if (flag .eq. 0) then covar = FPro_StatCovar(resampled, k, k) sigma = sqrt(count * covar) tau = TauFunc(count, b, s, mu, MAXTAU) tau_lo = TauFunc(count + sigma, b, s, mu, MAXTAU) tau_hi = TauFunc(count - sigma, b, s, mu, MAXTAU) else count = 0.d0 sigma = MAXSIGMA tau = 0.d0 tau_lo = MINTAU tau_hi = MAXTAU end if write(OUTUNIT, 30) r, count, sigma, & tau, tau_lo, tau_hi 30 format(f9.2, ',', f7.3, ',', f6.3, ',', & f7.4, ',', f7.4, ',', f7.4) 300 continue close(OUTUNIT) c*********************************************************************** c Job is finished c*********************************************************************** call FPro_FreeObject(resampled) call FPro_FreeObject(curve) call FPro_FreeObject(back) call FPro_FreeObject(star) 9999 continue stop end c*********************************************************************** c This function evaluates optical depth given the count value and c calibration parameters. real*8 function TauFunc(count, b, s, mu, maxtau) real*8 count, b, s, mu, maxtau real*8 frac frac = (count - b) / s if (frac .le. 0.d0) then TauFunc = maxtau return end if TauFunc = -mu * log(frac) if (TauFunc .gt. maxtau) TauFunc = maxtau return end c******************************************************************************* c