diff --git a/starcheck/calc_ccd_temps.py b/starcheck/calc_ccd_temps.py index 661bdaac..6fb24f9b 100755 --- a/starcheck/calc_ccd_temps.py +++ b/starcheck/calc_ccd_temps.py @@ -613,7 +613,7 @@ def globfile(pathglob): try: json_obstemps = get_ccd_temps(**vars(opt)) write_obstemps(opt.output_temps, json_obstemps) - except Exception, msg: + except Exception as msg: if opt.traceback: raise else: diff --git a/starcheck/pcad_att_check.py b/starcheck/pcad_att_check.py index 48d5f313..bc906640 100755 --- a/starcheck/pcad_att_check.py +++ b/starcheck/pcad_att_check.py @@ -1,9 +1,11 @@ # Licensed under a 3-clause BSD style license - see LICENSE.rst import re -import hopper +from astropy.table import Table +import Quaternion + from parse_cm import read_backstop, read_maneuver_summary, read_or_list from Chandra.Time import DateTime -from astropy.table import Table +import hopper def check_characteristics_date(ofls_characteristics_file, ref_date=None): @@ -67,13 +69,17 @@ def make_pcad_attitude_check_report(backstop_file, or_list_file=None, mm_file=No lines = [] # output report lines mm = read_maneuver_summary(mm_file) - q = [mm[0][key] for key in ['q1_0', 'q2_0', 'q3_0', 'q4_0']] + q = Quaternion.normalize([mm[0][key] for key in ['q1_0', 'q2_0', 'q3_0', 'q4_0']]) bs = read_backstop(backstop_file) simfa_time, simfa = recent_sim_history(DateTime(bs[0]['date']).secs, simfocus_file) simpos_time, simpos = recent_sim_history(DateTime(bs[0]['date']).secs, simtrans_file) - initial_state = {'q_att': q, + + initial_state = {'q1': q[0], + 'q2': q[1], + 'q3': q[2], + 'q4': q[3], 'simpos': simpos, 'simfa_pos': simfa} @@ -115,22 +121,18 @@ def make_pcad_attitude_check_report(backstop_file, or_list_file=None, mm_file=No # gives the history of updates as a dict with a `value` and `date` key. sc = hopper.run_cmds(backstop_file, or_list, ofls_characteristics_file, initial_state=initial_state) - # Iterate through obsids in order - obsids = [obj['value'] for obj in sc.obsids] - for obsid in obsids: - if obsid not in sc.checks: - continue - - checks = sc.checks[obsid] - for check in checks: - if check['name'] == 'CheckObsreqTargetFromPcad': - ok = check['ok'] + # Iterate through checks by obsid to print status + checks = sc.get_checks_by_obsid() + for obsid in sc.obsids: + for check in checks[obsid]: + if check.name == 'attitude_consistent_with_obsreq': + ok = check.success all_ok &= ok - if check.get('skip'): - message = 'SKIPPED: {}'.format(check['message']) + if check.not_applicable: + message = 'SKIPPED: {}'.format(":".join(check.infos)) else: - message = 'OK' if ok else check['message'] - line = '{:5d}: {}'.format(obsid, message) + message = 'OK' if ok else "ERROR: {}".format(":".join(check.errors)) + line = '{:5d}: {}'.format(obsid, message) lines.append(line) if out is not None: diff --git a/starcheck/src/lib/PoorTextFormat.pm b/starcheck/src/lib/PoorTextFormat.pm new file mode 100644 index 00000000..d69eeadf --- /dev/null +++ b/starcheck/src/lib/PoorTextFormat.pm @@ -0,0 +1,178 @@ +package PoorTextFormat; + +##*************************************************************************** +# +# History: +# 9-May-00 Fixed bug with linked target in 'text' +# Apr-00 Created (TLA) +# +##*************************************************************************** + +# + +use English; + +$cmd{latex} = { + list_preamble => '\begin{itemize}', + list_start => '\item', + list_end => '', + list_postamble=> '\end{itemize}', +}; + +$cmd{text} = { + line_start => '', + line_end => '', + list_start => '', + list_end => '', + item_start => ' * ', + item_end => '', + fixed_start => '', + fixed_end => '', + red_start => '', + red_end => '', + green_start => '', + green_end => '', + yellow_start => '', + yellow_end => '', + link_target_middle => '', + link_target_end => '', + page_break => "====================================================================================\n", +}; + +$preamble{text} = ''; +$postamble{text} = ''; + +$cmd{html} = { + line_start => '', + line_end => '', + list_start => '', + item_start => '
  • ', + item_end => '
  • ', + fixed_start => '
    ',
    +    fixed_end     => '
    ', + red_start => '', + red_end => '', + blue_start => '', + blue_end => '', + green_start => '', + green_end => '', + yellow_start => '', + yellow_end => '', + image_start => '
    ', + page_break => '

    ', + target_start => '', + link_target_start => '', + link_target_end => '', + html_start => qq{ }, + html_end => qq{ }, +}; + +$preamble{html} = <<'END_HTML_PREAMBLE' + + + + + + + +END_HTML_PREAMBLE + ; + +$postamble{html} = <<'END_HTML_POSTAMBLE' + + +END_HTML_POSTAMBLE + ; + +1; + +##************************************************************************ +sub new { +##************************************************************************ + my $classname = shift; + my $self = {}; + bless ($self); + + return $self; +} + +##************************************************************************ +sub ptf2any { +##************************************************************************ + $self = shift; + $fmt = shift; # Output format + @ptf = split "\n", shift; # Input ptf text to translate + + return unless (exists $cmd{$fmt}); + + $line_start = $cmd{$fmt}->{line_start}; + $line_end = $cmd{$fmt}->{line_end}; + + my $out = $preamble{$fmt}; + + foreach (@ptf) { + chomp; + if (/\\(\S+{[^}]*})/ || /\\(\S+) ?/) { # There is a PTF command + $ptf_cmd = $1; + my $postmatch = $POSTMATCH; +# print STDERR "PTF_CMD = $ptf_cmd\n"; +# print STDERR "postmatch0 = :$POSTMATCH:\n"; + $out .= $PREMATCH; + $out .= $cmd{$fmt}->{$ptf_cmd} if (exists $cmd{$fmt}->{$ptf_cmd}); + + # Command specific special processing + if ($ptf_cmd eq 'list_start') { + $line_start = $cmd{$fmt}->{item_start}; + } + if ($ptf_cmd eq 'list_start') { + $line_end = $cmd{$fmt}->{item_end}; + } + if ($ptf_cmd eq 'list_end') { + $line_start = $cmd{$fmt}->{line_start}; + } + if ($ptf_cmd eq 'list_end') { + $line_end = $cmd{$fmt}->{line_end}; + } + if ($ptf_cmd eq 'image') { + if ($cmd{$fmt}->{image_start}) { + $out .= $cmd{$fmt}->{image_start} . $POSTMATCH . $cmd{$fmt}->{image_end} . "\n"; + } + next; # Rest of line is ignored + } + if ($ptf_cmd eq 'html') { + if ($cmd{$fmt}->{html_start}) { + $out .= $cmd{$fmt}->{html_start} . $POSTMATCH . $cmd{$fmt}->{html_end} . "\n"; + } + next; + } + + if ($ptf_cmd =~ /^target\{([^}]*)\}/) { + if ($cmd{$fmt}->{target_start}) { + $out .= $cmd{$fmt}->{target_start} . $1 . $cmd{$fmt}->{target_end}; + } + } + + if ($ptf_cmd =~ /^link_target\{[^}]*\}/) { + if (exists $cmd{$fmt}->{link_target_end}) { + my ($target, $text) = ($ptf_cmd =~ /\{([^,]+),([^,]+)\}/); + $out .= $cmd{$fmt}->{link_target_start} . $target + if ($cmd{$fmt}->{link_target_start}); + $out .= $cmd{$fmt}->{link_target_middle} + . $text + . $cmd{$fmt}->{link_target_end}; + } + } + + $_ = $postmatch; + redo; # if (/\S/ || $PREMATCH); # Redo only if there is non-trivial stuff left over + } else { + $out .= "$line_start$_$line_end\n"; + } + } + + $out .= $postamble{$fmt}; +} diff --git a/starcheck/src/lib/Ska/Starcheck/Dark_Cal_Checker.pm b/starcheck/src/lib/Ska/Starcheck/Dark_Cal_Checker.pm index a7261a77..2ab70a33 100644 --- a/starcheck/src/lib/Ska/Starcheck/Dark_Cal_Checker.pm +++ b/starcheck/src/lib/Ska/Starcheck/Dark_Cal_Checker.pm @@ -8,7 +8,7 @@ use Carp; use IO::All; use Ska::Convert qw(date2time time2date); use Quat; -use Config::General; +use Config::General qw( ParseConfig ); use Math::Trig; use Data::Dumper; diff --git a/starcheck/src/lib/Ska/Starcheck/FigureOfMerit.pm b/starcheck/src/lib/Ska/Starcheck/FigureOfMerit.pm index b8b4f543..e79d1f1d 100644 --- a/starcheck/src/lib/Ska/Starcheck/FigureOfMerit.pm +++ b/starcheck/src/lib/Ska/Starcheck/FigureOfMerit.pm @@ -28,8 +28,11 @@ use Inline Python => q{ from chandra_aca.star_probs import acq_success_prob, prob_n_acq, mag_for_p_acq +def _mag_for_p_acq(p_acq, date, t_ccd): + return mag_for_p_acq(p_acq, date.decode(), t_ccd) + def _acq_success_prob(date, t_ccd, mag, color, spoiler, halfwidth): - out = acq_success_prob(date, float(t_ccd), float(mag), float(color), spoiler, int(halfwidth)) + out = acq_success_prob(date.decode(), float(t_ccd), float(mag), float(color), spoiler, int(halfwidth)) return out.tolist() def _prob_n_acq(acq_probs): @@ -89,7 +92,7 @@ sub set_dynamic_mag_limits{ my $t_ccd = $self->{ccd_temp}; # Dynamic mag limits based on 75% and 50% chance of successful star acq # Maximum limits of 10.3 and 10.6 - $self->{mag_faint_yellow} = min(10.3, mag_for_p_acq(0.75, $date, $t_ccd)); - $self->{mag_faint_red} = min(10.6, mag_for_p_acq(0.5, $date, $t_ccd)); + $self->{mag_faint_yellow} = min(10.3, _mag_for_p_acq(0.75, $date, $t_ccd)); + $self->{mag_faint_red} = min(10.6, _mag_for_p_acq(0.5, $date, $t_ccd)); } diff --git a/starcheck/src/lib/Ska/Starcheck/Obsid.pm b/starcheck/src/lib/Ska/Starcheck/Obsid.pm index 509b646f..0b68deff 100644 --- a/starcheck/src/lib/Ska/Starcheck/Obsid.pm +++ b/starcheck/src/lib/Ska/Starcheck/Obsid.pm @@ -34,7 +34,8 @@ def _get_agasc_stars(ra, dec, roll, radius, date, agasc_file): Return as a dictionary with the agasc ids as keys and all of the values as simple Python types (int, float) """ - stars = agasc.get_agasc_cone(float(ra), float(dec), float(radius), date, agasc_file) + stars = agasc.get_agasc_cone(float(ra), float(dec), float(radius), date.decode('ascii'), + agasc_file.decode('ascii')) q_aca = Quaternion.Quat([float(ra), float(dec), float(roll)]) yags, zags = radec2yagzag(stars['RA_PMCORR'], stars['DEC_PMCORR'], q_aca) yags *= 3600 @@ -64,6 +65,40 @@ def _get_agasc_stars(ra, dec, roll, radius, date, agasc_file): return stars_dict +import numpy as np +import mica.stats.acq_stats +import mica.stats.guide_stats + +ACQS = mica.stats.acq_stats.get_stats() +GUIDES = mica.stats.guide_stats.get_stats() + + +def get_mica_stats(agasc_id, time): + + time = float(time) + + acqs = ACQS[(ACQS['agasc_id'] == int(agasc_id)) + & (ACQS['guide_tstart'] < time)] + ok = (acqs['img_func'] == 'star') & (~acqs['ion_rad']) & (~acqs['sat_pix']) + + guides = GUIDES[(GUIDES['agasc_id'] == int(agasc_id)) + & (GUIDES['kalman_tstart'] < time)] + + mags = np.concatenate( + [acqs['mag_obs'][acqs['mag_obs'] != 0], + guides['aoacmag_mean'][guides['aoacmag_mean'] != 0]]) + + avg_mag = float(np.mean(mags)) if (len(mags) > 0) else float(13.94) + stats = {'acq': len(acqs), + 'acq_noid': int(np.count_nonzero(~ok)), + 'gui' : len(guides), + 'gui_bad': int(np.count_nonzero(guides['f_track'] < .95)), + 'gui_fail': int(np.count_nonzero(guides['f_track'] < .01)), + 'gui_obc_bad': int(np.count_nonzero(guides['f_obc_bad'] > .05)), + 'avg_mag': avg_mag} + return stats + + }; @@ -76,11 +111,8 @@ use English; use IO::All; use Ska::Convert qw(date2time); -use Ska::Starcheck::FigureOfMerit qw( make_figure_of_merit set_dynamic_mag_limits ); use RDB; - -use SQL::Abstract; -use Ska::DatabaseUtil qw( sql_fetchall_array_of_hashref ); +use Ska::Starcheck::FigureOfMerit qw( make_figure_of_merit set_dynamic_mag_limits ); use Carp; # Constants @@ -111,7 +143,6 @@ my %bad_acqs; my %bad_gui; my %bad_id; my %config; -my $db_handle; 1; @@ -138,14 +169,6 @@ sub new { $self->{config} = \%config; return $self; } - -################################################################################## -sub set_db_handle { -################################################################################## - my $handle = shift; - $db_handle = $handle; -} - ################################################################################## sub setcolors { @@ -1950,10 +1973,9 @@ sub print_report { $acq_prob = sprintf("Prob Acq Success %5.3f", $prob); } - # Make the id a URL if there is star history or if star history could - # not be checked (no db_handle) + # Make the id a URL if there is star history my $star_link; - if ((not defined $db_handle) or (($db_stats->{acq} or $db_stats->{gui}))){ + if ($db_stats->{acq} or $db_stats->{gui}){ $star_link = sprintf("HREF=\"%s%s\"",$acq_stat_lookup, $c->{"GS_ID${i}"}); } else{ @@ -2144,11 +2166,6 @@ sub print_report { $self->{STARCHECK} ); $o .= sprintf("NEXT ", $self->{next}->{obsid}); } - else{ - $o .= sprintf("", - $self->{STARCHECK} ); - $o .= sprintf("NEXT ", $self->{next}->{obsid}); - } $o .= " "; } @@ -2358,107 +2375,9 @@ sub star_dbhist { my $star_id = shift; my $obs_tstart = shift; - my $obs_tstart_minus_day = $obs_tstart - 86400; - return undef if (not defined $db_handle); - - my %stats = ( - 'agasc_id' => $star_id, - 'acq' => 0, - 'acq_noid' => 0, - 'gui' => 0, - 'gui_bad' => 0, - 'gui_fail' => 0, - 'gui_obc_bad' => 0, - 'avg_mag' => 13.9375, - ); - - - - eval{ - # acq_stats_data - my $sql = SQL::Abstract->new(); - my %acq_where = ( 'agasc_id' => $star_id, - 'type' => { '!=' => 'FID'}, - 'tstart' => { '<' => $obs_tstart_minus_day } - ); - - my ($acq_all_stmt, @acq_all_bind ) = $sql->select('acq_stats_data', - '*', - \%acq_where ); - - my @acq_all = sql_fetchall_array_of_hashref( $db_handle, $acq_all_stmt, @acq_all_bind ); - my @mags; - - if (scalar(@acq_all)){ - my $noid = 0; - for my $attempt (@acq_all){ - if ($attempt->{'obc_id'} =~ 'NOID'){ - $noid++; - } - else{ - push @mags, $attempt->{'mag_obs'}; - } - } - $stats{'acq'} = scalar(@acq_all); - $stats{'acq_noid'} = $noid; - } - - # guide_stats_view - $sql = SQL::Abstract->new(); - my %gui_where = ( 'id' => $star_id, - 'type' => { '!=' => 'FID' }, - 'kalman_tstart' => { '<' => $obs_tstart_minus_day }); - - my ($gui_all_stmt, @gui_all_bind ) = $sql->select('guide_stats_view', - '*', - \%gui_where ); - - my @gui_all = sql_fetchall_array_of_hashref( $db_handle, $gui_all_stmt, @gui_all_bind ); - - - if (scalar(@gui_all)){ - my $bad = 0; - my $fail = 0; - my $obc_bad = 0; - for my $attempt (@gui_all){ - if ($attempt->{'percent_not_tracking'} >= 5){ - $bad++; - } - if ($attempt->{'percent_not_tracking'} == 100){ - $fail++; - } - else{ - if ((defined $attempt->{'mag_obs_mean'}) and ($attempt->{'mag_obs_mean'} < 13.9 )){ - push @mags, $attempt->{'mag_obs_mean'}; - } - } - if ($attempt->{'percent_obc_bad_status'} >= 5){ - $obc_bad++; - } - } - $stats{'gui'} = scalar(@gui_all); - $stats{'gui_bad'} = $bad; - $stats{'gui_fail'} = $fail; - $stats{'gui_obc_bad'} = $obc_bad; - } - - my $mag_sum = 0; - if (scalar(@mags)){ - map { $mag_sum += $_ } @mags; - $stats{'avg_mag'} = $mag_sum / scalar(@mags); - } - }; - if ($@){ - # if we get db errors, just print and move on - print STDERR $@; - - } - - return \%stats; - - + return get_mica_stats($star_id, $obs_tstart_minus_day); } ############################################################################################# diff --git a/starcheck/src/starcheck.pl b/starcheck/src/starcheck.pl index 62af1ceb..182fe11f 100755 --- a/starcheck/src/starcheck.pl +++ b/starcheck/src/starcheck.pl @@ -48,14 +48,19 @@ use Inline Python => q{ import os +import re +import ast from chandra_aca.star_probs import set_acq_model_ms_filter import starcheck from starcheck.pcad_att_check import make_pcad_attitude_check_report, check_characteristics_date from starcheck.calc_ccd_temps import get_ccd_temps from starcheck.version import version +def debyte_dict(d): + return ast.literal_eval(re.sub(r"b'", "'", repr(d))) + def ccd_temp_wrapper(kwargs): - return get_ccd_temps(**kwargs) + return get_ccd_temps(**debyte_dict(kwargs)) def plot_cat_wrapper(kwargs): try: @@ -63,7 +68,7 @@ except ImportError as err: # write errors to starcheck's global warnings and STDERR perl.warning("Error with Inline::Python imports {}\n".format(err)) - return make_plots_for_obsid(**kwargs) + return make_plots_for_obsid(**debyte_dict(kwargs)) def starcheck_version(): return version @@ -72,6 +77,9 @@ sc_data = os.path.join(os.path.dirname(starcheck.__file__), 'data') return sc_data if os.path.exists(sc_data) else "" +def _make_pcad_attitude_check_report(kwargs): + return make_pcad_attitude_check_report(**debyte_dict(kwargs)) + }; @@ -139,7 +147,6 @@ # Set up for global warnings my @global_warn; - # asterisk only include to make globs work correctly my $backstop = get_file("$par{dir}/${sosa_dir_slash}*.backstop", 'backstop', 'required'); my $guide_summ = get_file("$par{dir}/mps/mg*.sum", 'guide summary'); @@ -267,20 +274,6 @@ } -# See if we have database access -my $db_handle; -eval{ - eval 'use Ska::DatabaseUtil'; - $db_handle = Ska::DatabaseUtil::sql_connect( 'sybase-aca-aca_read' ); - -}; -if (($@) or (not defined $db_handle)){ - warning("Unable to connect to Sybase server; links generated for all AGASC ids by default \n"); -} -else{ - Ska::Starcheck::Obsid::set_db_handle($db_handle); - } - # Dark Cal Checker Section use Ska::Starcheck::Dark_Cal_Checker; my $dark_cal_checker; @@ -699,9 +692,10 @@ sub json_obsids{ } else{ my $att_report = "${STARCHECK}/pcad_att_check.txt"; - my $att_ok = make_pcad_attitude_check_report( - $backstop, $or_file, $mm_file, $simtrans_file, $simfocus_file, - $char_file, $att_report, $aimpoint_file); + my $att_ok = _make_pcad_attitude_check_report({ + backstop_file=> $backstop, or_list_file=>$or_file, mm_file=> $mm_file, + simtrans_file=>$simtrans_file, simfocus_file=>$simfocus_file, + ofls_characteristics_file=>$char_file, out=>$att_report, dynamic_offsets_file=>$aimpoint_file}); if ($att_ok){ $out .= "[OK] Coordinates as expected.\n"; }