#!/usr/bin/perl #Attached is a more useful version of the same script which #works the same way. I have put in two setting: 1) the minimum #number of valid pairs before a W-S will be generated as #output [default: 5], and 2) the baseline photometric sigma #[default: 0.010]. I think you'll find almost all the stars #with a W-S statistic greater than 1 will now be variables! #Cheers, #Doug #============================================================== # Douglas L Welch | Office/voicemail (905) 525-9140 x23186 # Physics & Astronomy | FAX (905) 546-1252 # McMaster University | # Hamilton, Ontario | # Canada L8S 4M1 | E-mail welch@physics.mcmaster.ca #============================================================== #-------------------------------------------- # TASS Welch-Stetson routine by D.L. Welch, May 2002 # Based on Welch, D.L & Stetson, P.B. 1993, AJ, 105, 1813-1821 # # - requires at least 5 pairs now (min_valid) #-------------------------------------------- # Format of input file is: # 0 == seq_num # 1 == num_obs (number of VI pairs) # 2 == avg_ra # 3 == avg_dec # 4 == jd # 5 == "V" # 6 == vmag # 7 == vsig # 8 == vflag # 9 == "I" # 10 == imag # 11 == isig # 12 == iflag #-------------------------------------------- # Output columns: # 1 == seq_num # 2 == num_obs (number of VI pairs) # removed: 3 == nok (number of pairs with neither sigma equal to zero) # 3 == avg_ra # 4 == avg_dec # 5 == v_avg # 6 == vsig_avg # 7 == i_avg # 8 == isig_avg # 9 == total number of nights # 10 == Largest nightly outlier (expressed in standard deviations from the nightly mean) # 11 == Number of outliers # 12 == Welch-Stetson statistic # 13 == Mean of nightly W-S # 14 == number of nights used for short period variability indicators # 15 == V short period variability indicator = 1 - mean square successive difference/2/variance # 16 == I short period variability indicator # 17 == number of pairs used for the above two indicators # 18 == Difference between maximum and minimum nightly average in V, divided by largest nightly standard deviation in V (of the minimum or maximum night) # 19 == Difference between maximum and minimum nightly average in I, divided by largest nightly standard deviation in I (of the minimum or maximum night) # 20 == number of nights used for long period variability indicators # # Remarks: # output parameters 12, 17 and 18 should be large for short period variables (variation during a night) # output parameters 14 and 15 should be large for long period variables (i.e. large differences between nightly means) #-------------------------------------------- # Settings: # min_valid == minimum number of valid pairs for generating # the Welch-Stetson statistic # min_valid_night_long == minimum number of valid pairs for a night for taking part # in the long term (internight) variability indicators # min_valid_night_short == minimum number of valid pairs for a night for generating # short term (intranight) variability indicators # It is assumed that $min_valid_night_long <= $min_valid_night_short # base_sigma == photometric error to be added in quadrature # to input errors # max_outlier == maximum number of standard deviations an observation # may differ from the mean, for it to be taken into account for the mean W-S, or nightly averages #-------------------------------------------- # # Only data with both V and I flags = 0 and Vsig and Isig > 0 are taken into account # #-------------------------------------------- $line_num = 0; $star_num = 0; $ltvok_num = 0; $min_valid = 30; $min_valid_night_long = 5; $min_valid_night_short = 20; $base_sigma = 0.01; $max_outlier = 3.0; $Nbad = 0; if ($bad) { # A file with a list of bad nights is given (lines with two entries: fromJD toJD) ((open BAD, $bad) || (die "Bad file $bad does not exist.")); while () { ($badfrom[++$Nbad], $badto[$Nbad]) = (split(' '))[0..1]; } } sub badnight($) { my $jd = shift; for my $i (1..$Nbad) { if (($jd >= $badfrom[$i]) && ($jd <= $badto[$i])) { return 1; } } return 0; } sub Sort # Quicksort # Arguments: # - Array on which to sort ($SortKey) # - First index in array # - Last index in array # - @SortArray: List of other arrays to be sorted (should not include $SortKey) { my ($SortKey, $l, $r, @SortArray) = @_; my $i = $l; my $j = $r; my $mid = $$SortKey[int(($l + $r)/2)]; my $array; do { while ($$SortKey[$i] < $mid) { $i++; } while ($mid < $$SortKey[$j]) { $j--; } if ($i <= $j) { for $array ($SortKey, @SortArray) { my $tmp = $$array[$i]; $$array[$i] = $$array[$j]; $$array[$j] = $tmp; } $i++; $j--; } } until $i > $j; if ($l < $j) { Sort($SortKey, $l, $j, @SortArray); } if ($i < $r) { Sort($SortKey, $i, $r, @SortArray); } } sub treat_night ($$) { my ($from, $to) = @_; if ($to - $from + 1 >= $min_valid_night_long) { # Make averages for the night $v_num_sum = 0.0; $v_den_sum = 0.0; $v_sqr_sum = 0.0; $i_num_sum = 0.0; $i_den_sum = 0.0; $i_sqr_sum = 0.0; $nok = 0; for my $i ($from..$to) { $vwgt = 1./($v_sig[$i]**2+$base_sigma**2); $v_num_sum += $v_obs[$i]*$vwgt; $v_den_sum += $vwgt; $iwgt = 1./($i_sig[$i]**2+$base_sigma**2); $i_num_sum += $i_obs[$i]*$iwgt; $i_den_sum += $iwgt; $nok++; } $v_avg = $v_num_sum/$v_den_sum; $i_avg = $i_num_sum/$i_den_sum; $ws = 0.0; # Calculate standard deviations for my $i ($from..$to) { $vwgt = 1./($v_sig[$i]**2+$base_sigma**2); $v_sqr_sum += $vwgt * ($v_obs[$i] - $v_avg)**2; $iwgt = 1./($i_sig[$i]**2+$base_sigma**2); $i_sqr_sum += $iwgt * ($i_obs[$i] - $i_avg)**2; } $v_stdev = sqrt($v_sqr_sum/$v_den_sum); $i_stdev = sqrt($i_sqr_sum/$i_den_sum); # Remove outliers for my $i ($from..$to) { # Largest deviation ? $v_dev = abs($v_obs[$i]-$v_avg)/$v_stdev; if ($v_dev > $max_dev) { $max_dev = $v_dev; } $i_dev = abs($i_obs[$i]-$i_avg)/$i_stdev; if ($i_dev > $max_dev) { $max_dev = $i_dev; } if ($v_dev > $max_outlier || $i_dev > $max_outlier) { $outlier[$i] = 1; $outliers++; $vwgt = 1./($v_sig[$i]**2+$base_sigma**2); $v_num_sum -= $v_obs[$i]*$vwgt; $v_den_sum -= $vwgt; $v_sqr_sum -= $vwgt * ($v_obs[$i] - $v_avg)**2; $iwgt = 1./($i_sig[$i]**2+$base_sigma**2); $i_num_sum -= $i_obs[$i]*$iwgt; $i_den_sum -= $iwgt; $i_sqr_sum += $iwgt * ($i_obs[$i] - $i_avg)**2; $nok--; } } if ($nok >= $min_valid_night_long) { # Recalculate averages $v_avg = $v_num_sum/$v_den_sum; $i_avg = $i_num_sum/$i_den_sum; $v_stdev = sqrt($v_sqr_sum/$v_den_sum); $i_stdev = sqrt($i_sqr_sum/$i_den_sum); if ($nights_ok_long) { if ($v_avg < $v_max) { $v_max = $v_avg; } if ($v_avg > $v_min) { $v_min = $v_avg; } if ($i_avg < $i_max) { $i_max = $i_avg; } if ($i_avg > $i_min) { $i_min = $i_avg; } if ((($v_max == $v_avg) || ($v_min == $v_avg)) && ($v_stdev > $v_max_stdev)) { $v_max_stdev = $v_stdev; } if ((($v_max == $v_avg) || ($v_min == $v_avg)) && ($i_stdev > $i_max_stdev)) { $i_max_stdev = $i_stdev; } } else { $v_max = $v_avg; $v_min = $v_avg; $v_max_stdev = $v_stdev; $i_max = $i_avg; $i_min = $i_avg; $i_max_stdev = $i_stdev; } $nights_ok_long++; if ($nok >= $min_valid_night_short) { # Other short period variability indicators # Calculate sum of (squared difference between subsequent observations/variance) $vvi_night = 0; $ivi_night = 0; for my $i0 ($from..$to-1) { if (!$outlier[$i0]) { # Get the next measurement $i1 = $i0 + 1; while (($i1 <= $to) && $outlier[$i1]) { $i1++; } if ($i1 > $to) { last; } # No further measurements $vvi_night += ($v_obs[$i1] - $v_obs[$i0])**2; $ivi_night += ($i_obs[$i1] - $i_obs[$i0])**2; $pairs++; } } $vvi += $v_den_sum * $vvi_night/$v_sqr_sum; $ivi += $i_den_sum * $ivi_night/$i_sqr_sum; # Form residuals and W-S index for my $i ($from..$to) { if (!$outlier[$i]) { $v_sigma = sqrt($v_sig[$i]**2 + $base_sigma**2); $i_sigma = sqrt($i_sig[$i]**2 + $base_sigma**2); $del_v = ($v_obs[$i]-$v_avg)/$v_sigma; $del_i = ($i_obs[$i]-$i_avg)/$i_sigma; $ws = $ws + $del_v*$del_i; } } # Normalize W-S index $ws2 += $ws/sqrt($nok*($nok-1.0)); $nights_ok_short++; } } } } my $tassid = 0; # Current TASS star ID sub treatstar() { if (!$num_obs) { $ltvok_num++; return; } # Calculate WS index per night # Sort on JD Sort (\@jd_obs, 0, $num_obs-1, \@v_obs, \@v_sig, \@i_obs, \@i_sig); $jd = 0; $first_j = 0; $ws2 = 0.0; $nights = 0; $nights_ok_long = 0; $nights_ok_short = 0; $max_dev = 0.0; $vvi = 0.0; $ivi = 0.0; $pairs = 0; $outliers = 0; for $j (0..$num_obs-1) { if ($jd_obs[$j] > $jd + 0.7) { # New night starts if ($jd) { # Treat the previous night treat_night($first_j, $j-1); } $nights++; $jd = $jd_obs[$j]; $first_j = $j; } } # Treat last night treat_night($first_j, $num_obs-1); # Make the normal W-S index # Create averages $v_num_sum = 0.0; $v_den_sum = 0.0; $i_num_sum = 0.0; $i_den_sum = 0.0; $ws_obs = 0; for $i (0..$num_obs-1) { if (!$outlier[$i]) { $vwgt = 1./($v_sig[$i]**2+$base_sigma**2); $v_num_sum += $v_obs[$i]*$vwgt; $v_den_sum += $vwgt; $iwgt = 1./($i_sig[$i]**2+$base_sigma**2); $i_num_sum += $i_obs[$i]*$iwgt; $i_den_sum += $iwgt; $ws_obs++; } } $v_avg = $v_num_sum/$v_den_sum; $i_avg = $i_num_sum/$i_den_sum; # Form residuals and W-S index $ws = 0.0; $vsig_sum = 0.0; $isig_sum = 0.0; for $i (0..$num_obs-1) { if (!$outlier[$i]) { $v_sigma = sqrt($v_sig[$i]**2 + $base_sigma**2); $i_sigma = sqrt($i_sig[$i]**2 + $base_sigma**2); $del_v = ($v_obs[$i]-$v_avg)/$v_sigma; $del_i = ($i_obs[$i]-$i_avg)/$i_sigma; $ws = $ws + $del_v*$del_i; $vsig_sum += $v_sig[$i]; $isig_sum += $i_sig[$i]; } } if (($nights_ok_long > 1) || ($ws_obs >= $min_valid) || ($nights_ok_short)) { printf("%5d %3d %8.4f %8.4f %5.2f %4.2f %5.2f %4.2f %2d", $tassid, $num_obs, $sum_ra/$num_lines, $sum_dec/$num_lines, $v_avg, $vsig_sum/$num_obs, $i_avg, $isig_sum/$num_obs, $nights); if ($max_dev) { printf(" %4.1f %3d", $max_dev, $outliers); } else { printf(" %4s %3s", "-", "-"); } if ($ws_obs >= $min_valid) { # Normalize W-S index $ws = $ws/sqrt($ws_obs*($ws_obs-1.0)); printf(" %6.2f", $ws); } else { printf(" %6s", "-"); $ltvok_num++; } if ($nights_ok_short) { printf(" %6.2f %2d", $ws2/$nights_ok_short, $nights_ok_short); } else { printf(" %6s %2d", "-", 0); } if ($pairs) { # printf(" %4.2f %4.2f %3d", sqrt($pairs/$vvi), sqrt($pairs/$ivi), $pairs); printf(" %5.2f %5.2f %3d", 1 - $vvi/$pairs/2, 1 - $ivi/$pairs/2, $pairs); } else { printf(" %5s %5s %3s", "-", "-", "-"); } if ($nights_ok_long > 1) { printf(" %4.1f %4.1f %2d", ($v_min - $v_max)/$v_max_stdev, ($i_min - $i_max)/$i_max_stdev, $nights_ok_long); } else { printf(" %4s %4s %2d", "-", "-", $nights_ok_long); } print "\n"; } undef @jd_obs; undef @outlier; undef @v_obs; undef @v_sig; undef @i_obs; undef @i_sig; } # Read line from STDIN while (<>) { chop; ($seq_num, $ra, $dec, $jd, $vmag, $vsig, $vflag, $imag, $isig, $iflag) = (split(' ',$_))[0, 2..4, 6..8, 10..12]; if ($seq_num != $tassid) { # Do the calculations for the previous star if ($tassid) { treatstar; } # New star $tassid = $seq_num; $star_num++; $sum_ra = $ra; $sum_dec = $dec; $num_obs = 0; $num_lines = 1; } else { # Still the same star $sum_ra += $ra; $sum_dec += $dec; $num_lines += 1; } $line_num++; if (!$vflag && !$iflag && $vsig && $isig && !badnight($jd)) { $jd_obs[++$#jd_obs] = $jd; $v_obs[++$#v_obs] = $vmag; $v_sig[++$#v_sig] = $vsig; $i_obs[++$#i_obs] = $imag; $i_sig[++$#i_sig] = $isig; $num_obs++; } } # Do the calculations for the final star if ($tassid) { treatstar; } printf(STDERR "Total number of lines processed: %6d\n", $line_num); printf(STDERR "Total number of stars processed: %6d\n\n", $star_num); printf(STDERR "Number of objects with less than %d valid pairs : %6d\n", $min_valid, $ltvok_num);