#!/usr/bin/perl -w
# Perl script to handle HTML interface to the "signal-to-noise" program.
#    MWR 1/15/2001
# 
# Modified to add some choices for QE and sky brightness.
#    MWR 1/21/2001
#
# Modified to include list of parameters at top of output.
#    MWR 1/22/2001
#
# Added extinction into calculations.
#    MWR 3/7/2001
#        
# Fixed typo in list of zero-point photon flux for B-band
#    was      $nphot = 3.91e+06;
#    now      $nphot = 3.91e+05;
#    MWR 4/18/2002
#
# Fixed small error in "fraction_inside_slow", which was incorrectly
#    _adding_ the area of each sub-pixel unit to the sum at the end
#    of each pixel's calculation, instead of _multiplying_ the intensity
#    times this area.  Thanks to John Mahony for noticing this.
#    MWR 4/6/2003
#
# Fixed a bug in addition of light within 
#    the given aperture; wasn't handling addition of light within fractional
#    pixel apertures properly.  Thanks to David Whysong.
#    MWR 3/2/2004
#
# Modified to make the "fraction_inside_slow" function more accurate.
#      - now assumes star falls on center of one pixel (not junction of 4)
#      - now integrate explicitly over all four quadrants of the PSF,
#           instead of just doing one quadrant
#      - fix expression for x,y position of each sub-pixel location
#      - decreased "max_pix_rad" from 50->30 to speed up a bit
#    MWR 8/30/2004
#
# Modified to be specific to WIYN 0.9-m telescope and HDI camera
#    MWR 6/7/2013
#
# Added "ccd_name" variable, with choice of HDI or S2KB
#    Removed "pixsize" as passed variable; we now pick a value based on CCD.
#    Cleaned up code, putting big if-then clauses in separate functions.
#    MWR 6/11/2013
#
# Moved from the 'cgi-bin.pl' methods to 'use CGI' methods.
#    MWR 12/28/2016



use strict;
#require "./cgi-lib.pl";
use CGI;
use Math::Cephes qw(:misc);
use Math::Cephes qw(:utils);

$ENV{'PATH'} = '/bin:/usr/bin:' ;

MAIN:
{


  my (%input,   # The CGI data
      $text,    # Munged version of the text field entered by the user
      $debug,
      $a, $b, $c, $x,   # some variables we'll use
      $pi,
      $filter,
      $nmagstep,    
      $nphoton,
      $mag,
      $ccd_name,
      $tel_diam,          # in centimeters
      $fixed_qe, $var_qe, $qe,
      $pixsize,
      $readnoise,
      $fixed_sky, $var_sky, $skymag,
      $moon_phase,
      $airmass,
      $extinct_coeff,
      $exptime,
      $fwhm,
      $aper_rad,
      $dmag,
      $mag_start, $mag_end,
      $star_electrons,
      $sky_electrons,
      $sky_electrons_per_pix,
      $read_electrons,
      $npix,
      $fraction,
      $signal, 
      $noise,
      $signal_to_noise,
      $result,  # result of SQL query,
      $field);  

  # set this to 1 for lots of debugging messages
  $debug = 0;

  $pi = 3.14159;

  # Read in all the variables set by the form
  &CGI::ReadParse(\%input);


  # Check that everything has been entered
  foreach $field (qw(source user_name filter mag_start mag_end dmag 
                     readnoise moon_phase
                     airmass ccd_name
                     exptime fwhm aper_rad)) {
   &CGI::CgiDie("Error: Missing field '$field'\n") unless defined $input{$field};
  }

  print &CGI::PrintHeader;
  print &CGI::HtmlTop ("Signal-to-noise calculations for WIYN 0.9-m");

  # create local variables --- is convenient 
  $ccd_name = $input{'ccd_name'} ;
  $moon_phase = $input{'moon_phase'} ;
  $filter = $input{'filter'} ;
  $mag_start = $input{'mag_start'} ;
  $mag_end = $input{'mag_end'} ;
  $dmag = $input{'dmag'} ;
  $readnoise = $input{'readnoise'} ;
  $airmass = $input{'airmass'} ;
  $exptime = $input{'exptime'} ;
  $fwhm = $input{'fwhm'} ;
  $aper_rad = $input{'aper_rad'} ;

  # based on the user's choice of filter, we set
  #   a)  the "effective diameter" of the telescope:
  #       this is a combination of the actual collecting
  #       area of the WIYN 0.9-m telescope, accounting
  #       for its secondary obstruction, 
  #       _combined with_ the reflectivity of two mirrors.
  #       Units for effective diam are cm.
  #   b)  the QE of the detector
  #   c)  the sky brightness (mag/sq.arcsec)
  #
  # The values for a "none" filter are just guesses
  #

  $fixed_sky = get_sky($filter, $moon_phase);
  $tel_diam = get_tel_diam($filter);
  $fixed_qe = get_qe($filter, $ccd_name);
  $pixsize = get_pixsize($ccd_name);


  #
  # check for validity of values supplied by user

  if (($mag_start > $mag_end) || ($dmag <= 0.0)) {
    &CGI::CgiDie("Error: invalid magnitude start/end or delta values ") ;
  }

  $qe = $fixed_qe;
  if ($debug > 0) {
    printf "<br> qe based on fixed value is ..%s.. <br> \n", $qe;
  }
  if (($qe <= 0.0) || ($qe > 1.0)) {
    &CGI::CgiDie("Error: invalid QE, must be between 0.0 and 1.0 ") ;
  }

  if ($pixsize <= 0.0) {
    &CGI::CgiDie("Error: invalid pixel size, must be greater than 0 ") ;
  }
  if ($readnoise < 0.0) {
    &CGI::CgiDie("Error: invalid readnoise, must be >= 0 ") ;
  }

  $skymag = $fixed_sky;
  if ($debug > 0) {
    printf "<br> skymag based on fixed value is ..%s.. <br> \n", $skymag;
  }
  if (($skymag < 0.0) || ($skymag > 100.0)) {
    &CGI::CgiDie("Error: invalid skymag, must be between 0.0 and 100.0 ") ;
  }

  if ($exptime <= 0.0) {
    &CGI::CgiDie("Error: invalid exposure time, must be greater than 0 ") ;
  }
  if ($fwhm <= 0.0) {
    &CGI::CgiDie("Error: invalid FWHM, must be greater than 0 ") ;
  }
  if ($aper_rad <= 0.0) {
    &CGI::CgiDie("Error: invalid aperture radius, must be greater than 0 ") ;
  }

  # get the extinction coefficient appropriate for this filter
  $extinct_coeff = get_extinct_coeff($filter);


  if ($debug > 0) {
    print "here is a list of the variables you entered...\n";
    print "<p>\n";
    print "CCD ..$ccd_name.. <br>";
    print "filter ..$filter.. <br>";
    print "mag_start ..$mag_start.. mag_end ..$mag_end.. dmag ..$dmag..<br>";
    print "moon_phase ..$moon_phase.. <br>";
    print "tel_diam ..$tel_diam.. <br>";
    print "qe ..$qe.. <br>";
    print "pixsize ..$pixsize.. <br>";
    print "readnoise ..$readnoise.. <br>";
    print "skymag ..$skymag.. <br>";
    print "airmass ..$airmass.. <br>";
    print "extinction_coeff ..$extinct_coeff.. <br>";
    print "exptime ..$exptime.. <br>";
    print "fwhm ..$fwhm.. <br>";
    print "aper_rad ..$aper_rad.. <br>";
  }


  print "<pre>";

  # print out values we'll use in the calculations, for reference

  if (1 == 1) {
    printf "CCD:        $ccd_name \n";
    printf "Filter:     $filter \n";
    printf "Tel_diam:   $tel_diam (cm) \n";
    printf "Overall QE: $qe \n";
    printf "Pixsize:    $pixsize (arcsec/pixel) \n";
    printf "Readnoise   $readnoise (electrons) \n";
    printf "Moon Phase: $moon_phase (days past new) \n";
    printf "Sky mag:    $skymag (mag/sq.arcsec) \n";
    printf "Airmass:    $airmass \n";
    printf "Ext_coeff:  $extinct_coeff \n";
    printf "Exptime:    $exptime (sec) \n";
    printf "FWHM:       $fwhm (arcsec) \n";
    printf "Aper_rad:   $aper_rad (arcsec) \n";
    printf "\n";
  }

  # prepare to perform calculations

  # get the number of photons from a mag-zero star per sq.cm. per sec
  #    (this should be a function taking as arg the filter)
  $nphoton = mag_zeropoint($filter);
  if ($nphoton < 0) {
    printf "Error: bad magnitude zeropoint for filter %s?\n", $filter;
    print "</pre>" ;
    print &HtmlBot("HtmlBot");
    exit(0);
  }
  
  
  # how many pixels are inside the aperture?
  $npix = ($pi*$aper_rad*$aper_rad)/($pixsize*$pixsize);

  # what fraction of star's light falls within aperture?
  #   use this for quicker, less accurate result
  # $fraction = fraction_inside($fwhm, $aper_rad);
  if ($debug > 0) {
    printf "npix %7.2f  fraction %6.3f  \n", $npix, $fraction;
  }
  #
  # or use this for slower, more accurate result
  $fraction = fraction_inside_slow($fwhm, $aper_rad, $pixsize);
  if ($debug > 0) {
    printf "npix %7.2f  fraction %6.3f  \n", $npix, $fraction;
  }

  # now enter the main loop
  for ($mag = $mag_start; $mag <= $mag_end; $mag += $dmag) {

    # calculate # of electrons collected on the CCD from star, total
    $x = pow(10.0, -0.4*$mag)*$nphoton;
    $x *= $exptime;
    $x *= $pi*$tel_diam*$tel_diam*0.25;
    $x *= $qe;
    $star_electrons = $x;

    # decrease the # of electrons from star, due to extinction 
    $x = $airmass * $extinct_coeff;
    $star_electrons *= pow(10.0, -0.4*$x);

    # now calculate # of electrons collected on CCD from sky, per pixel
    $x = pow(10.0, -0.4*$skymag)*$nphoton;
    $x *= $exptime;
    $x *= $pi*$tel_diam*$tel_diam*0.25;
    $x *= $qe;
    $x *= $pixsize*$pixsize;
    $sky_electrons_per_pix = $x;

    if ($debug > 0) {
      printf "<br> mag %5.2f   star_e %10.4e  sky_e %10.4e <br>\n",
          $mag, $star_electrons, $sky_electrons_per_pix;
    }

    # this is the total number of electrons from star inside aperture
    $star_electrons *= $fraction;

    # this is the total number of electrons from sky inside aperture
    $sky_electrons = $sky_electrons_per_pix*$npix;

    # this is the total number of electrons from readout in aperture 
    $read_electrons = $readnoise*$readnoise*$npix;

    # now we can calculate signal-to-noise
    $signal = $star_electrons;
    $noise = sqrt($read_electrons + $sky_electrons + $star_electrons);
    $signal_to_noise = $signal/$noise;

    # print out the answer
    printf "mag %6.2lf:  star %12.0lf sky %10.0lf read %7.0lf -> S/N %9.2lf ",
          $mag, $star_electrons, $sky_electrons, $read_electrons, 
          $signal_to_noise;
    printf "\n";

  }

  print "</pre>" ;
  print &CGI::HtmlBot("HtmlBot");

  exit(0);
}


############################################################################
# PROCEDURE: fraction_inside
# 
# DESCRIPTION: figure out what fraction of a star's light falls within
#              the aperture.  We assume that the starlight has a circular
#              gaussian distribution with FWHM given by the first argument
#              (with units of arcsec).  We calculate the fraction of 
#              that light which falls within an aperture of radius given
#              by second argument (with units of arcsec).
#              
# RETURNS:     the fraction of light within aperture.
#
sub fraction_inside {


  my(
    $fwhm,           # FWHM of gaussian distribution of light
    $radius,         # radius of circular aperture
    $sigma,
    $z, 
    $x1, $x2,
    $large,
    $ratio
    );

  $fwhm = $_[0];
  $radius = $_[1];

  $large = 1000.0;

  # calculate how far out the "radius" is in units of "sigmas" 
  $sigma = $fwhm/2.35;
  $z = $radius/($sigma*1.414);
  
  # now, we assume that a radius of "large" is effectively infinite
  $x1 = erf($z);
  $ratio = ($x1*$x1);

  return($ratio);
}



############################################################################
# PROCEDURE: fraction_inside_slow
# 
# DESCRIPTION: figure out what fraction of a star's light falls within
#              the aperture.  We assume that the starlight has a circular
#              gaussian distribution with FWHM given by the first argument
#              (with units of arcsec).  
#               
#              This function goes to the trouble of calculating how
#              much of the light falls within fractional pixels defined
#              by the given radius of a synthetic aperture.  It is slow,
#              but more accurate than the "fraction_inside" function.
#
#              3/2/2004  Fixed a bug in addition of light within 
#                        the given aperture; wasn't handling fractional
#                        pixel apertures properly.  Thanks to David Whysong.
#                        MWR
#
#              8/30/2004 By default, the code now assumes that the star
#                        is centered on a pixel (not on the junction of 
#                        four adjacent pixels).  It now also takes into
#                        account the pixel size.
#              
# RETURNS:     the fraction of light within aperture.
#
sub fraction_inside_slow {


  my(
    $fwhm,                # arg 1: FWHM in arcsec
    $radius,              # arg 2: radius of aperture, in arcsec
    $pixsize,             # arg 3: size of a pixel, in arcsec
    $i, $j, $k, $l, 
    $max_pix_rad,
    $sigma2, 
    $x, $y, 
    $fx, $fy,
    $psf_center_x, $psf_center_y,
    $ratio,
    $bit, 
    $this_bit,
    $pix_sum,
    $all_sum,
    $rad_sum,
    $rad2, $radius2,
    $inten,
    $piece
    );

  # how many pieces do we sub-divide pixels into?
  $piece = 20;

  $fwhm = $_[0];
  $radius = $_[1];
  $pixsize = $_[2];

  # sanity check
  if ($pixsize <= 0.0) {
    printf "\nError: radius %lf must be greater than zero\n", $pixsize;
    return(0.0);
  }

  # rescale FWHM and aperture radius into pixels (instead of arcsec)
  $fwhm /= $pixsize;
  $radius /= $pixsize;

  $max_pix_rad = 30;

  # check to make sure user isn't exceeding our built-in limits
  if ($radius >= $max_pix_rad) {
    printf "\nWarning: radius exceeds limit of %d </b> \n", $max_pix_rad;
  }

  # these values control the placement of the star on the pixel grid:
  #    (0,0) to make the star centered on a junction of four pixels
  #    (0.5, 0.5) to make star centered on one pixel
  $psf_center_x = 0.5;
  $psf_center_y = 0.5;

  $sigma2 = $fwhm / 2.35;
  $sigma2 = $sigma2*$sigma2;
  $radius2 = $radius*$radius;
  $bit = 1.0/$piece;

  $rad_sum = 0.0;
  $all_sum = 0.0;

  for ($i = 0.0 - $max_pix_rad; $i < $max_pix_rad; $i++) {
    for ($j = 0.0 - $max_pix_rad; $j < $max_pix_rad; $j++) {
      

      # now, how much light falls into pixel (i, j)?
      $pix_sum = 0.0;
      for ($k = 0; $k < $piece; $k++) {

        $x = ($i - $psf_center_x) + ($k + 0.5)*$bit;
        $fx = exp(-($x*$x)/(2.0*$sigma2));

        for ($l = 0; $l < $piece; $l++) {
 
          $y = ($j - $psf_center_y) + ($l + 0.5)*$bit;
          $fy = exp(-($y*$y)/(2.0*$sigma2));
         
          $inten = $fx*$fy;
          $this_bit = $inten*$bit*$bit;
          $pix_sum += $this_bit;
        
          $rad2 = $x*$x + $y*$y;
          if ($rad2 <= $radius2) {
            $rad_sum += $this_bit;
          }
        }
      }
      $all_sum += $pix_sum;
    }
  }

  $ratio = $rad_sum / $all_sum;
  if (0) {
    printf " rad_sum %lf  all_sum %lf  -> ratio = %lf \n", 
              $rad_sum , $all_sum, $ratio;
  }

  return($ratio);

}
      

############################################################################
# PROCEDURE: mag_zeropoint
# 
# DESCRIPTION: Given a filter name, return the number of photons per
#              square centimeter per second which a star of zero'th 
#              magnitude would produce above the atmosphere.
#              We assume that the star has a spectrum like Vega's.
#              
#              The numbers are pre-calculated and we just pick the
#              appropriate one for the given filter.
#              
# RETURNS:     Number of photons per sq.cm. per sec from zero'th mag star.
# 
sub mag_zeropoint {

  my(
    $filter,
    $nphot
  );
   

  $filter = $_[0];
  $nphot = -1;

  if ($filter eq "none") { 
    $nphot = 4.32e+06;
  } 
  if ($filter eq "U") { 
    $nphot = 5.50e+05;
  } 
  if ($filter eq "B") { 
    $nphot = 3.91e+05;
  } 
  if ($filter eq "V") { 
    $nphot = 8.66e+05;
  } 
  if ($filter eq "R") { 
    $nphot = 1.10e+06;
  } 
  if ($filter eq "I") { 
    $nphot = 6.75e+05;
  } 

  if ($nphot == -1) {
    printf "Error: bad filter %s\n", $filter;
  }
  
  return($nphot);
}


############################################################################
# PROCEDURE: get_extinct_coeff
# 
# DESCRIPTION: Given a filter name, return an extinction coefficient.
#              The numbers are only approximate.
#              We use the V-band value if there's no filter.
#              
# RETURNS:     Extinction coefficient (mag/airmass)
# 
sub get_extinct_coeff {

  my(
    $filter,
    $coeff
  );
   

  $filter = $_[0];
  $coeff = -1;

  if ($filter eq "none") { 
    $coeff = 0.20;
  } 
  if ($filter eq "U") { 
    $coeff = 0.50;
  } 
  if ($filter eq "B") { 
    $coeff = 0.25;
  } 
  if ($filter eq "V") { 
    $coeff = 0.15;
  } 
  if ($filter eq "R") { 
    $coeff = 0.10;
  } 
  if ($filter eq "I") { 
    $coeff = 0.07;
  } 

  if ($coeff == -1) {
    printf "Error: bad filter %s\n", $filter;
  }
  
  return($coeff);
}




############################################################################
# PROCEDURE: get_sky
# 
# DESCRIPTION: Given a filter name and moon age in days, 
#              return the sky brightness
#              in magnitudes per square arcsec.  
#
#              We use values taken from 
#               - Neugent and Massey, PASP 122, 1246 (2010)
#               - Alastair Walker's measurements at Cerro Tololo,
#                   from KPNO newsletter, said to be similar to KPNO
#              with differences due to moon age taken from examples
#              shown at HET web site: changes are larger in blue than red.
#
#              If filter == "none", treat like V-band (for no good reason)
#              
# RETURNS:     magnitudes per square arcsecond
# 
sub get_sky {

  my(
    $filter,
    $moon_phase,
    $mag
  );
   

  $filter = $_[0];
  # 'moon_phase' is the age in days
  $moon_phase = $_[1];
  $mag = -1.0;

  if ($filter eq "none") { 
    if ($moon_phase == 0) {
      $mag = 21.7;
    }
    if ($moon_phase == 3) {
      $mag = 21.6;
    }
    if ($moon_phase == 7) {
      $mag = 21.3;
    }
    if ($moon_phase == 10) {
      $mag = 20.6;
    }
    if ($moon_phase == 14) {
      $mag = 19.9;
    }
  } 
  if ($filter eq "U") { 
    if ($moon_phase == 0) {
      $mag = 22.0;
    }
    if ($moon_phase == 3) {
      $mag = 21.7;
    }
    if ($moon_phase == 7) {
      $mag = 20.9;
    }
    if ($moon_phase == 10) {
      $mag = 20.0;
    }
    if ($moon_phase == 14) {
      $mag = 18.8;
    }
  } 
  if ($filter eq "B") { 
    if ($moon_phase == 0) {
      $mag = 22.7;
    }
    if ($moon_phase == 3) {
      $mag = 22.4;
    }
    if ($moon_phase == 7) {
      $mag = 21.6;
    }
    if ($moon_phase == 10) {
      $mag = 20.7;
    }
    if ($moon_phase == 14) {
      $mag = 19.5;
    }
  } 
  if ($filter eq "V") { 
    if ($moon_phase == 0) {
      $mag = 21.7;
    }
    if ($moon_phase == 3) {
      $mag = 21.6;
    }
    if ($moon_phase == 7) {
      $mag = 21.3;
    }
    if ($moon_phase == 10) {
      $mag = 20.6;
    }
    if ($moon_phase == 14) {
      $mag = 19.9;
    }
  } 
  if ($filter eq "R") { 
    if ($moon_phase == 0) {
      $mag = 20.9;
    }
    if ($moon_phase == 3) {
      $mag = 20.8;
    }
    if ($moon_phase == 7) {
      $mag = 20.6;
    }
    if ($moon_phase == 10) {
      $mag = 20.3;
    }
    if ($moon_phase == 14) {
      $mag = 19.9;
    }
  } 
  if ($filter eq "I") { 
    if ($moon_phase == 0) {
      $mag = 19.9;
    }
    if ($moon_phase == 3) {
      $mag = 19.9;
    }
    if ($moon_phase == 7) {
      $mag = 19.7;
    }
    if ($moon_phase == 10) {
      $mag = 19.5;
    }
    if ($moon_phase == 14) {
      $mag = 19.2;
    }
  } 

  if ($mag == -1) {
    printf "Error: bad filter %s or phase-age %s \n", $filter, $moon_phase;
  }
  
  return($mag);
}




############################################################################
# PROCEDURE: get_tel_diam
# 
# DESCRIPTION: Given a filter name, figure out the effective
#              telescope diameter (in cm).  We include these
#              effects:
#
#                  - size of primary mirror (same for all filters)
#                  - size of secondary mirror (same for all filters)
#                  - reflectivity of two mirrors (varies by filter)
# 
#              Reflectivity is assumed to be same for both mirrors,
#              and is value measured after aluminizing in 2012.
#              
# RETURNS:     effective telescope diameter (cm)
# 
sub get_tel_diam {

  my(
    $filter,
    $tel_diam
  );
   

  $filter = $_[0];
  $tel_diam = -1.0;

  if ($filter eq "none") { 
    $tel_diam = 72.0;
  } 
  if ($filter eq "U") { 
    $tel_diam = 73.4;
  } 
  if ($filter eq "B") { 
    $tel_diam = 73.4;
  } 
  if ($filter eq "V") { 
    $tel_diam = 73.4;
  } 
  if ($filter eq "R") { 
    $tel_diam = 71.6;
  } 
  if ($filter eq "I") { 
    $tel_diam = 69.3;
  } 

  if ($tel_diam == -1) {
    printf "Error: bad filter %s\n", $filter;
  }
  
  return($tel_diam);
}



############################################################################
# PROCEDURE: get_qe
# 
# DESCRIPTION: Given a filter name and a CCD name,
#              return the quantum efficiency of the detector
#              for the given filter.
# 
#              Values for HDI taken from contract with Onaka's team.
#              Values for S2KB taken from a graph on NOAO site
#                 (dated 1995!)
#
#              Values range from 0.0 (no response to light) to 1.0 
#              (perfect response to light).
#              
# RETURNS:     quantum efficiency of detector
# 
sub get_qe {

  my(
    $filter,
    $ccd_name,
    $qe
  );
   

  $filter = $_[0];
  $ccd_name = $_[1];
  $qe = -1.0;

  if ($ccd_name eq "S2KB") {

    if ($filter eq "none") { 
      $qe = 0.60;
    } 
    if ($filter eq "U") { 
      $qe = 0.50;
    } 
    if ($filter eq "B") { 
      $qe = 0.75;
    } 
    if ($filter eq "V") { 
      $qe = 0.85;
    } 
    if ($filter eq "R") { 
      $qe = 0.89;
    } 
    if ($filter eq "I") { 
      $qe = 0.66;
    } 

  }
  elsif ($ccd_name eq "HDI") {

    if ($filter eq "none") { 
      $qe = 0.70;
    } 
    if ($filter eq "U") { 
      $qe = 0.55;
    } 
    if ($filter eq "B") { 
      $qe = 0.80;
    } 
    if ($filter eq "V") { 
      $qe = 0.77;
    } 
    if ($filter eq "R") { 
      $qe = 0.73;
    } 
    if ($filter eq "I") { 
      $qe = 0.60;
    } 
  }

  if ($qe == -1) {
    printf "Error: bad filter %s and/or CCD %s \n", $filter, $ccd_name;
  }
  
  return($qe);
}



############################################################################
# PROCEDURE: get_pixsize
# 
# DESCRIPTION: Given the name of the CCD, return the pixel size (arcsec).
#              
# RETURNS:     size of pixel in arcsec
# 
sub get_pixsize {

  my(
    $ccd_name,
    $pixsize
  );
   

  $ccd_name = $_[0];
  $pixsize = -1.0;

  if ($ccd_name eq "S2KB") {
    $pixsize = 0.60;
  }
  elsif ($ccd_name eq "HDI") {
    $pixsize = 0.427;
  }

  if ($pixsize == -1) {
    printf "Error: bad CCD %s \n", $ccd_name;
  }
  
  return($pixsize);
}

