# Norman Kuring 13-Aug-2010 Original development
# Norman Kuring 8-Oct-2010 Break down alarms to the orbit/file
# level.
# Norman Kuring 9-Mar-2011 Sort orbits by both start and end times
# in cases of two identical start times.
# Norman Kuring 29-Mar-2011 Allow for the generation of a color-
# coded menu even when the user-selected
# start and end time do not match those
# of any orbit file.
# Norman Kuring 19-Apr-2011 Changed the name of the metadata files.
# Norman Kuring 21-Apr-2011 Allow comments in parameter index files.
# Norman Kuring 5-May-2011 Make this script work for both Aquarius
# and Service Platform telemetry.
# Norman Kuring 13-May-2011 Allow for reading of service platform
# telemetry from both the stand-alone
# and L1A-derived files.
# Norman Kuring 17-May-2011 When I started representing parameters
# with hexadecimal instead of decimal
# indices in a bid to shorten URL's, I
# inadvertantly messed up array indexing
# in other portions of my code. This is
# now fixed, and the proper alarm colors
# are once more on display.
# Norman Kuring 14-Sep-2011 Introduce additional sub-menus via
# a separate metadata file.
$ENV{PATH} = '';
use strict;
use vars qw(%in);
use Time::Local;
use lib '/web/aquarius/scripts';
use ReadTelemMeta qw(
get_max_alarms_range
get_max_alarms
get_param_specs
get_menu_hierarchy
readmeta
read_units
remove_menu_singlets
sort_menu_leaves
);
use Utility qw(
read_dir
monthbounds
send_header
);
my $thisScript = '/cgi/' . (split /\//,$0)[-1];
# Get the CGI parameters that specify what
# to display and how to display it.
require '/web/aquarius/cgi/cgi-lib.pl';
&ReadParse;
# Does the telemetry come from standalone HKT files
# or from the L1A files.
$in{fr} = $in{fr} eq 'hkt' ? 'hkt' : 'l1a';
my $telemtyp = $in{ty} eq 'sp' ? 'sp' : 'aq';
# Get parameter grouping information if any is available.
my %hierarchy = get_menu_hierarchy;
# Get parameter information as a hash of arrays.
# [ 0 , 1 , 2 , 3, 4, 5, 6, 7 ]
# $pindex{PARAM_ID}[GROUP_ID,GROUP_COLUMN,UNITS,RL,YL,YH,RH,DESCRIPTION]
my %pindex = get_param_specs($telemtyp);
my @params = sort keys %pindex;
# Make a hash that make_ul() can use to shorten parameter names.
my $i=-1;
my %params = map {$i++; ($_,sprintf("%lx",$i))} @params;
# Group the parameters by group_id
my %groups;
foreach my $p (@params){
push @{ $groups{ $pindex{$p}[0] } }, hex($params{$p});
}
my @groups = sort keys %groups;
my $alarmdir = '/web/aquarius/metadata/alarms';
my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my %month;
for(my $i=0; $i<@month; $i++){
$month{$month[$i]} = $i;
}
my ($selyear) = $in{yr} =~ /^(\d{4})$/;
my ($selmon) = $in{mo} =~ /^([A-Z][a-z]{2})$/;
my ($selday) = $in{dy} =~ /^(\d{1,2})$/;
my (@selorb) = $in{or} =~ /^(\d+)@(\d+)$/;
my (%alarms,%monalarms);
my @years =
map /^Q(\d{4})\.$telemtyp\.bin$/,
read_dir($alarmdir,'^Q\d{4}\.' . $telemtyp . '\.bin$');
my $missing = chr(0);
my $nominal = chr(1);
my $warning = chr(2);
my $error = chr(3);
my %alarm = ($missing,'-',$nominal,'G',$warning,'Y',$error,'R');
my %aclass= ($missing,'al0',$nominal,'alG',$warning,'alY',$error,'alR');
# Build the year tables.
my $ytables = '';
my $monthhdrs = '
' . join(" | \n", @month) . ' | ';
my %dalarms;
foreach my $y (@years){
my @args = ($telemtyp,$y);
if($selyear and $selmon and $selyear == $y){
push @args,$month{$selmon};
}
my $malarms;
($malarms,$dalarms{$y}) = get_max_alarms(@args);
my $cols = qq(\n\n\n\n);
$ytables .= join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$y
Group |
$monthhdrs
--
foreach my $g (@groups){
$ytables .=
join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$g |
--
for(my $m=0; $m<12; $m++){
my $hl = $y eq $selyear && $month[$m] eq $selmon ? ' highlight' : '';
my $max = $missing;
foreach my $p (@{ $groups{$g} }){
$max = $malarms->[$p][$m] if $malarms->[$p][$m] gt $max;
}
my $q = join '&',
"fr=$in{fr}",
"ty=$telemtyp",
"yr=$y",
"mo=$month[$m]";
$ytables .=
join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$alarm{$max}
|
--
}
$ytables .= "
\n";
}
$ytables .= "\n
\n";
}
# Build the month table if a month was selected.
my $mtable = '';
if($selyear and $selmon){
my @d = monthbounds($selyear,$month{$selmon});
my $ndays = $d[1] - $d[0] + 1;
my $dayhdr = '';
for(my $d=1; $d<=$ndays; $d++){
$dayhdr .= qq($d | \n);
}
$mtable .= join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$selmon $selyear
Group |
$dayhdr
--
foreach my $g (@groups){
$mtable .=
join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$g |
--
for(my $d=1; $d<=$ndays; $d++){
my $hl = $d eq $selday ? ' highlight' : '';
my $max = $missing;
foreach my $p (@{ $groups{$g} }){
$max = $dalarms{$selyear}[$p][$d-1]
if $dalarms{$selyear}[$p][$d-1] gt $max;
}
my $q = join '&',
"fr=$in{fr}",
"ty=$telemtyp",
"yr=$selyear",
"mo=$selmon",
"dy=$d";
$mtable .=
join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$alarm{$max}
|
--
}
$mtable .= "
\n";
}
$mtable .= "\n
\n
\n";
}
# Build the orbit table if a day was selected.
my @chosenalarms;
my $otable='';
if($selyear and $selmon and $selday){
my $day = timegm(0,0,0,$selday,$month{$selmon},$selyear-1900)/86400;
my @stet = orbits_stet($day,$in{fr});
my %max;
my $orbhdr = '';
foreach my $t (@stet){
my $shms = sprintf "%02d
%02d
%02d",(gmtime $t->[0])[2,1,0];
my $ehms = sprintf "%02d
%02d
%02d",(gmtime $t->[1])[2,1,0];
$orbhdr .= qq($shms - $ehms | \n);
my @max = get_max_alarms_range($telemtyp,@$t);
if(@selorb and $selorb[0] == $t->[0] and $selorb[1] == $t->[1]){
# Save these alarms to build the menu with.
@chosenalarms = @max;
}
foreach my $g (@groups){
foreach my $p (@{ $groups{$g} }){
if($max[$p] gt $max{$g}{"@$t"}){
$max{$g}{"@$t"} = $max[$p];
}
}
}
}
$otable .= join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$selday $selmon $selyear
Group |
$orbhdr
--
foreach my $g (@groups){
$otable .=
join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$g |
--
foreach my $t (@stet){
my $key = "@$t";
my $hl = $t->[0] == $selorb[0] && $t->[1] == $selorb[1] ?
' highlight' : '';
my $q = join '&',
"fr=$in{fr}",
"ty=$telemtyp",
"yr=$selyear",
"mo=$selmon",
"dy=$selday",
"or=$t->[0]",
"or=$t->[1]";
$otable .=
join "\n", map {join ' ',split ' '} split /^/m ,<<" --" . "\n";
$alarm{$max{$g}{$key}}
|
--
}
$otable .= "
\n";
}
$otable .= "\n
\n
\n";
}
my $menu = '';
if($selyear and $selmon and $selday and @selorb){
# If the user also selected an orbit...
my %units = &read_units;
# Group the parameters by group_id and by units.
my %menuA;
foreach my $p (keys %pindex){
my $units = $units{ $pindex{$p}[2] }[2] || "Dimensionless";
if($hierarchy{$p}){
# Put additional layers into the menu hierarchy
# if they have been specified in the metadata.
eval
'push @{ $menuA{ $pindex{$p}[0] }' .
"{'" . join("'}{'",@{ $hierarchy{$p} }) . "'}" .
'{ $units } }, $p';
}
else{
# Otherwise just use the top level grouping
# subdivided by the parameter units.
push @{ $menuA{ $pindex{$p}[0] }{ $units } }, $p;
}
}
# Remove all sub-menus that have just one child.
foreach my $k (keys %menuA){
$menuA{$k} = remove_menu_singlets($menuA{$k});
}
# Order the parameters in the leaf menus according to the
# metadata specification.
sort_menu_leaves(\%pindex,\%menuA);
# If the user-specified start and end times do not match start and end times
# from any telemetry filenames, I still would like to show a color-coded
# menu for the selected time range, so I must call get_max_alarms_range
# here.
@chosenalarms or @selorb
and @chosenalarms = get_max_alarms_range($telemtyp,@selorb);
$menu = (make_ul(\%menuA,$selorb[0],$selorb[1],\@chosenalarms))[1]
. "
\n";
}
# Send the HTML to the client.
&send_header;
print <<"--";
Aquarius Telemetry Alarms (time line)
$menu
$otable
$mtable
$ytables