#!/usr/bin/perl # # Given a photom .cal file, this program brings all the observations # of a same physical star together in one place, and analyzes the # properties of those observations as a group. # # The user must SORT INPUT FILE BY RA in order for this program # to work properly. # # It prints out an ASCII text file with one line per observation, # grouping the lines for the same star together. # # usage: sort -n +1 M*.cal | calc_gammas_cal.pl radecfile # # where # M*.cal is a calibrated photometry file created # by the pipeline # radecfile is a file with imagename, JD, RA, Dec, # created by grab_pos.pl # $debug = 0; $radecfile = $ARGV[0]; if (-e $radecfile == 0) { printf "calc_gammas_cal.pl: radecfile ..$radecfile.. doesn't exist?\n"; exit 1; } $line_count = 0; $cur_ra = 9999.0; # degrees $cur_dec = 9999.0; # degrees $cur_jd = 9999.0; $cur_calv = 99.0; $match_radius = 5.0; # arcseconds # we accumulate values for statistical purposes in these arrays $num_obs = 0; $vmag_array[0] = 0; $vsig_array[0] = 0; $imag_array[0] = 0; $isig_array[0] = 0; $jd_array[0] = 0; # we set this flag to 1 if the next star we read is a new one $is_new_star = 0; while () { $line_count++; $line = $_; @words = split(/\s+/, $line); $star_id = $words[1]; $ra = $words[2]; $dec = $words[3]; $jd = $words[4]; $vmag = $words[6]; $vsig = $words[7]; $vflag = $words[8]; $imag = $words[10]; $isig = $words[11]; $iflag = $words[12]; if (0 == 1) { printf "%9.4f %9.4f %13.5f %6.3f %6.3f %6.3f %6.3f \n", $ra, $dec, $jd, $vmag, $vsig, $imag, $isig; } # ignore stars if flags indicate possible problems if (0 == 1) { if (($vflag != 0) || ($iflag != 0)) { next; } } # ignore stars which are outside of the specified Dec limits # (which can be used to isolate a certain portion of the field of view) if (0 == 1) { $center_dec = -0.16; $dec_width = 0.5; if (($dec > $center_dec + $dec_width) || ($dec < $center_dec - $dec_width)) { next; } } if (1 == 1) { # check -- is this a new star? if (coords_match($ra, $dec, $cur_ra, $cur_dec, $match_radius) == 0) { $is_new_star = 1; # we should perform analysis on old star's value here, if there # _is_ an old star to analyze if ($line_count > 1) { # printf "last star had %d obs \n", $num_obs; $avg_v = calc_mean($num_obs, @vmag_array); $sig_v = calc_sigma($num_obs, @vmag_array); $avg_vsig = calc_mean($num_obs, @vsig_array); $avg_i = calc_mean($num_obs, @imag_array); $sig_i = calc_sigma($num_obs, @imag_array); $avg_isig = calc_mean($num_obs, @isig_array); for ($i = 0; $i < $num_obs; $i++) { # find the central (RA, Dec) values for this V-band and I-band image ($central_rav, $central_decv, $central_rai, $central_deci) = find_central_radec($jd_array[$i], $radecfile); if ($debug > 0) { printf "central %9.4f %9.4f %9.4f %9.4f \n", $central_rav, $central_decv, $central_rai, $central_deci; } ($delta_rav, $delta_decv, $delta_rai, $delta_deci) = calc_delta_pos($cur_ra, $cur_dec, $central_rav, $central_decv, $central_rai, $central_deci); $gamma_v = $vmag_array[$i] - $avg_v; $gamma_i = $imag_array[$i] - $avg_i; printf "%-2d %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %9.4f %9.4f %9.4f %9.4f \n", $num_obs, $avg_v, $gamma_v, $avg_vsig, $sig_v, $avg_i, $gamma_i, $avg_isig, $sig_i, $delta_rav, $delta_decv, $delta_rai, $delta_deci; } } # and reset, fill zero'th elements with values for new star $num_obs = 0; $vmag_array[$num_obs] = $vmag; $vsig_array[$num_obs] = $vsig; $imag_array[$num_obs] = $imag; $isig_array[$num_obs] = $isig; $jd_array[$num_obs] = $jd; $num_obs++; $cur_ra = $ra; $cur_dec = $dec; } else { # nope, this is still same old star, just add elements to arrays $vmag_array[$num_obs] = $vmag; $vsig_array[$num_obs] = $vsig; $imag_array[$num_obs] = $imag; $isig_array[$num_obs] = $isig; $jd_array[$num_obs] = $jd; $num_obs++; } } } # we should perform analysis on the last star's value here... # we should perform analysis on old star's value here... # printf "last star had %d obs \n", $num_obs; $avg_v = calc_mean($num_obs, @vmag_array); $sig_v = calc_sigma($num_obs, @vmag_array); $avg_vsig = calc_mean($num_obs, @vsig_array); $avg_i = calc_mean($num_obs, @imag_array); $sig_i = calc_sigma($num_obs, @imag_array); $avg_isig = calc_mean($num_obs, @isig_array); for ($i = 0; $i < $num_obs; $i++) { # find the central (RA, Dec) values for the V-band and I-band images ($central_rav, $central_decv, $central_rai, $central_deci) = find_central_radec($jd_array[$i], $radecfile); if ($debug > 0) { printf "central %9.4f %9.4f %9.4f %9.4f \n", $central_rav, $central_decv, $central_rai, $central_deci; } if ($central_rav == -99) { next; } ($delta_rav, $delta_decv, $delta_rai, $delta_deci) = calc_delta_pos($cur_ra, $cur_dec, $central_rav, $central_decv, $central_rai, $central_deci); $gamma_v = $vmag_array[$i] - $avg_v; $gamma_i = $imag_array[$i] - $avg_i; printf "%-2d %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %9.4f %9.4f %9.4f %9.4f \n", $num_obs, $avg_v, $gamma_v, $sig_v, $avg_vsig, $avg_i, $gamma_i, $sig_i, $avg_isig, $delta_rav, $delta_decv, $delta_rai, $delta_deci; } exit 0; ##################################################################### # PROCEDURE: coords_match # # DESCRIPTION: given two sets of coords (both in decimal degrees), # calculate the distance between them. If the distance # is # # <= match_radius then we match: return 1 # > match_radius then no match: return 0 # # Note that the "match_radius" argument is in arcseconds, # not degrees. # # USAGE: # coords_match this_ra this_dec old_ra old_dec match_radius # sub coords_match { my($this_ra, $this_dec, $old_ra, $old_dec, $match_radius, $delta_ra, $delta_dec, $avg_dec, $factor, $DEGTORAD); $this_ra = $_[0]; $this_dec = $_[1]; $old_ra = $_[2]; $old_dec = $_[3]; $match_radius = $_[4]; # convert matching radius to degrees $match_radius /= 3600.0; $delta_ra = abs($this_ra - $old_ra); $delta_dec = abs($this_dec - $old_dec); # printf "match_radius %9.5lf delta_ra %9.5lf delta_dec %9.5lf \n", # $match_radius, $delta_ra, $delta_dec; # do a quick check first if ($delta_dec > $match_radius) { return 0; } # we need to modify the RA distance due to cos(Dec) factor. # Use the avg dec to calc this factor $avg_dec = ($this_dec + $old_dec) / 2.0; $DEGTORAD = 0.017453293; $factor = cos($avg_dec*$DEGTORAD); $delta_ra *= $factor; if ($delta_ra > $match_radius) { return 0; } # well, if we get this far, the two coords do match within # a square box of the given matching radius. # Call it a match return 1; } ######################################################################## # PROCEDURE: calc_mean # # DESCRIPTION: given the number of elements in an array, and the # array itself, calculate the mean value of the array. # # RETURNS: # the mean value # sub calc_mean { my($num, @array); my($i, $sum); my($mean); $num = $_[0]; for ($i = 0; $i < $num; $i++) { $array[$i] = $_[$i+1]; } if ($num == 0) { $mean = 0.0; return($mean); } # printf "%2d ", $num; for ($i = 0; $i < $num; $i++) { # printf "%6.3f ", $array[$i]; } $sum = 0.0; for ($i = 0; $i < $num; $i++) { $sum += $array[$i]; } $mean = $sum/$num; # printf(" %7.4f \n", $mean); return($mean); } ######################################################################## # PROCEDURE: calc_sigma # # DESCRIPTION: given the number of elements in an array, and the # array itself, calculate the standard deviation from the # mean of an array # # RETURNS: # the stdev # sub calc_sigma { my($num, @array); my($i, $sum); my($sumsq); my($mean, $stdev); $num = $_[0]; for ($i = 0; $i < $num; $i++) { $array[$i] = $_[$i+1]; } if ($num < 2) { $stdev = 0.0; return($stdev); } # printf "%2d ", $num; for ($i = 0; $i < $num; $i++) { # printf "%6.3f ", $array[$i]; } $sum = 0.0; $sumsq = 0.0; for ($i = 0; $i < $num; $i++) { $sum += $array[$i]; $sumsq += $array[$i]*$array[$i]; } $mean = $sum/$num; $stdev = sqrt(($sumsq - $num*$mean*$mean)/($num - 1)); # printf(" %7.4f \n", $stdev); return($stdev); } ######################################################################## # PROCEDURE: calc_delta_pos # # DESCRIPTION: given the (RA, Dec) of a star, and the (RA, Dec) centers # of the V-band and I-band images in which it appears, # calculate the difference between its RA and the # central RA for its images, and between its Dec and # the central Dec for its images. # # RETURNS: # We return a list with 4 values: # # this ra - central RA in V-band # this dec - central Dec in V-band # this ra - central RA in I-band # this dec - central Dec in I-band # # sub calc_delta_pos { my($ra, $dec); my($rav_center, $decv_center); my($rai_center, $deci_center); my($delta_rav, $delta_decv); my($delta_rai, $delta_deci); $ra = $_[0]; $dec = $_[1]; $rav_center = $_[2]; $decv_center = $_[3]; $rai_center = $_[4]; $deci_center = $_[5]; # calc deltas in each band $delta_rav = $ra - $rav_center; $delta_decv = $dec - $decv_center; $delta_rai = $ra - $rai_center; $delta_deci = $dec - $deci_center; return($delta_rav, $delta_decv, $delta_rai, $delta_deci); } ############################################################################# # Given a JD and a file name with JD/RA/Dec cross reference # find the central (RA, Dec) for the V-band and I-band # images taken at that time. Return those values as a 4-element list. # # If we can't find them, return values of -99 for all offsets. # sub find_central_radec { my($jd); my($file); my($rav, $decv, $rai, $deci); $jd = $_[0]; $file = $_[1]; if ($debug > 0) { printf "find_central_radec: JD %13.5f file %s \n", $jd, $file; } # initialize values to nonsense $rav = -99; $decv = -99; $rai = -99; $deci = -99; # now, look through the given file for the given JD open(JDFILE, $file) || die ("find_central_radec: can't open file $file"); while () { @words = split(/\s+/); $this_jd = $words[2]; if (abs($jd - $this_jd) < 0.0002) { if ($words[1] =~ /hira/) { $rai = $words[3]; $deci = $words[4]; } if ($words[1] =~ /hvra/) { $rav = $words[3]; $decv = $words[4]; } } } close(JDFILE); # check to make sure that we did find the given JD if (($rav == -99) || ($rai == -99)) { printf STDERR "find_central_radec: couldn't find jd $jd\n"; $rav = -99; $decv = -99; $rai = -99; $deci = -99; } @retlist = ($rav, $decv, $rai, $deci); return(@retlist); }