<& /htmlheader, title => "TJD $tjd $model" &>
<& modelheader &>

<!--
<% Dumper(\@norep_chunks_processed) %>
<% Dumper(\%pairs_ingested) %>
-->

<table width="90%">
<tr><td valign="top">

<div class="L24bold"><% $tjd_str %></div>
<div class="L14">
	<% qq{$utdate_str<br><a href="http://ipp0022.ifa.hawaii.edu/ps1sc/denneau/$ocnum/hammer.html">OC $ocnum</a>} %>
</div>
<p height="20px">

<b>All Chunks By Observation Time</b><br>
<table border=1 cellspacing=0 cellpadding=2 width="100%">
	<tr>
		<th class="darkheader">Chunk Name</th>
		<th class="darkheader">Obs Time (UT)</th>
		<th class="darkheader">Last Processing Status</th>
		<th class="darkheader">Num Exposures</th>
	</tr>

% foreach my $k (@chunks_ingested) {
% my ($start_time_str) = mopslib_mjd2utctimestr($k->{start_mjd}, '=');     # use = as delimiter bewteen date and time
% $start_time_str =~ s/^.*=//;
% $start_time_str = $1 if $start_time_str =~ /^(\d\d:\d\d)/;
% $start_time_str .= ' UT';
	<tr>
		<td><% $k->{cn} %></td>
		<td align="center"><% $start_time_str %></td>
		<td align="center"><% $statmap{$k->{status}} || 'UNKNOWN' %></td>
		<td align="center"><% $k->{ct} %></td>
	</tr>
% }
</table>
<p>
<b>By Run ID</b><br>
%   my $rk;
%   foreach $rk (sort {$b <=> $a} keys %runs_all) {
    <table border="1" cellspacing="0" cellpadding="2" width="100%">
        <col width="30%"/>
        <col width="10%"/>
        <col width="20%"/>
        <col width="10%"/>

% if ($have_runs) {
        <tr>
            <th class="darkheader" colspan="4" scope="col"><% $rk ? (sprintf "<b>Run %d updated %s</b>", $rk, $runs_all{$rk}[0]{updated}): '' %></th>
        </tr>
% }
   	    <tr>
		    <th class="darkheader" scope="col">Chunk Name</th>
    		<th class="darkheader" scope="col">Type</th>
    		<th class="darkheader" scope="col">Status</th>
	    	<th class="darkheader" scope="col">Footprints</th>
        </tr>
%       if (exists $runs_quad{$rk}) {	
%           for (my $i = 0; $i < @{$runs_quad{$rk}}; $i++) {	
%               my ($qv) = $quadchunkmap{$runs_quad{$rk}[$i]{name}};
%           	my $ch = $qv->{name}; my $qct = $qv->{nfoot};
%           	my $urlenc = $qv->{sel}; $urlenc = uri_escape($urlenc);
        <tr>
            <td>
  	            <% qq{<a target="_blank" href="/czar/$model/tracklets.html?sort=d&limit=100&nn=$nn&minv=0.1&sm=$urlenc&run_id=$rk">$ch</a>} %> 
      	    </td>
  	        <td align="center"> QUAD </td>
  	        <td align="center">
	            <% $statmap{$runs_quad{$rk}[$i]{status}} || 'UNKNOWN' %>
    	    </td>
	        <td align="center">
	            <% $qct %>
    	    </td>
    	</tr>
%	        }
%       }
%       if (exists $runs_md{$rk}) {	
%           for (my $i = 0; $i < @{$runs_md{$rk}}; $i++) {	
%               my ($mv) = $quadchunkmap{$runs_md{$rk}[$i]{name}};
%           	my $ch = $mv->{name}; my $mct = $mv->{nfoot};
%           	my $urlenc = $mv->{sel}; $urlenc = uri_escape($urlenc);
        <tr>
            <td>
  	            <% qq{<a target="_blank" href="/czar/$model/tracklets.html?sort=d&limit=100&nn=$nn&minv=0.1&sm=$urlenc&run_id=$rk">$ch</a>} %>  
      	    </td>
  	        <td align="center"> MD </td>
  	        <td align="center">
	            <% $statmap{$runs_md{$rk}[$i]{status}} || 'UNKNOWN' %>
    	    </td>
	        <td align="center">
	            <% $mct %>
    	    </td>
    	</tr>
%	        }
%       }
%       if (exists $runs_pair{$rk}) {	
%           for (my $i = 0; $i < @{$runs_pair{$rk}}; $i++) {	
%               my ($pv) = $pairchunkmap{$runs_pair{$rk}[$i]{name}};
%           	my $ch = $pv->{name}; my $pct = $pv->{nfoot};
%           	my $urlenc = $pv->{sel}; $urlenc = uri_escape($urlenc);
%     	        my $pminv = $guru ? .15 : .3;
        <tr>
            <td>
% if (!$runs_pair{$rk}[$i]{needguru} || $guru) {
  	            <% qq{<a target="_blank" href="/czar/$model/pairs.html?minv=$pminv&nn=$nn&sm=$urlenc&run_id=$rk">$ch</a>} %> 
% } else {
  	            <% qq{$ch} %> 
% }
      	    </td>
            <td align="center"> PAIR </td>
  	        <td align="center">
	            <% $statmap{$runs_pair{$rk}[$i]{status}} || 'UNKNOWN' %>
    	    </td>
	        <td align="center">
	            <% $pct %>
    	    </td>
    	</tr>
%	        }
%       }    
    </table>
    <p>
%   }
<ul>
    <li><a target="_blank" href="/czar/<% $model %>/tracklets.html?sort=d&limit=100&nn=<% $nn %>&minv=0.0&maxv=0.1">Slow Movers</a> (experts only)<br/></li>
	<li>Comets <a target="_blank" href="mbos.html?nn=<% $nn %>">MBOs</a> | Unknown (<a target="_blank" href="comets.html?nn=<% $nn %>&show=diff">Diff</a> | <a target="_blank" href="comets.html?nn=<% $nn %>&show=chip">Chip</a>) | <a target="_blank" href="subcomets.html?nn=<% $nn %>&show=diff">Submitted</a></li>
	<li>Derived Objects (<a target="_blank" href="dobjs.html?sort=d&limit=100&nn=<% $nn %>"><% $tjd %> only</a>, <a target="_blank" href="dobjs.html?sort=d&limit=100&ocnum=<% $ocnum %>">OC <% $ocnum %></a>)</li>
	<li><a target="_blank" href="/czar/<% $model %>/known.html?nostamp=1&limit=500&nn=<% $nn %>">Known Pairs</a></li>
	<li><a target="_blank" href="/submitted_neos.html?tjd=<% $tjd %>">Submitted NEOs</a></li>
</ul>

<h3>Efficiency</h3>
<ul>
<li><a target="_blank" href="/model/<% $model %>/efft.html?nn=<% $nn %>">Tracklets</a></li>
<li><a target="_blank" href="/model/<% $model %>/effl.html?ocnum=<% $ocnum %>">Derived objects and PANDAs</a></li>
<li><a target="_blank" href="/model/<% $model %>/deteff?nn=<% $nn %>">Known object efficiency</a></li>
</ul>

<h3>Custom</h3>
<ul>
<li><a target="_blank" href="/model/<% $model %>/custom_themis.html?nn=<% $nn %>">Themis Family</a></li>
<li><a target="_blank" href="/model/<% $model %>/custom_extremelightcurve.html?nn=<% $nn %>">Extreme Lightcurve</a></li>
</ul>

<div>
<a href="/model/<% $model %>/fields.html?nn=<% $nn %>">Night <% $tjd %> field list</a><br>
<a href="/model/<% $model %>/nightlyindex.html">Old index page</a><br>
</div>

</td>

<td align="right" valign="top">
    <canvas id="map" width="700" height="467" style="border: 1px solid #333333; background-color: #000000;">
    <p>Your lame browser doesn't support canvas.</p>
    </canvas>
    <div style="align: right"><a href="?tjd=<% $tjd %>&proj=h">Hammer</a> | <a href="?tjd=<% $tjd %>&proj=s">Spherical</a></div>

<!-- night nav below plot -->
    <table width="700"><tr>
    <td valign="top" width="20px">

% if (defined($prev_tjd)) {
<a href="<% qq{?tjd=$prev_tjd&proj=$proj} %>"><img src="/images/left.png"></a>
</td>
<td align="left" valign="top">
<a href="<% qq{?tjd=$prev_tjd&proj=$proj} %>"><% $prev_tjd_str %></a><br><% "$prev_utdate_str<br>OC $prev_oc" %>
% }
    </td>

    <td align="right" valign="top">
% if (defined($next_tjd)) {
<a href="<% qq{?tjd=$next_tjd&proj=$proj} %>"><% $next_tjd_str %></a><br><% "$next_utdate_str<br>OC $next_oc" %>
    </td>
    <td valign="top" width="20px">
<a href="<% qq{?tjd=$next_tjd&proj=$proj} %>"><img src="/images/right.png"></a>
% } 
    </td>
    </tr></table>

</tr></table>

% if ($proj eq 's') {
<script type="text/javascript" src="/hammer/s3d.js"></script>
<& fieldmapsph.js, tjd => $tjd, show_plan => 's23456' &>
% } else {
<script type="text/javascript" src="/hammer/hammer.js"></script>
<& fieldmap.js, tjd => $tjd, show_plan => 's23456' &>
% }

<& /htmlfooter &>

<%args>
$today => undef
$nn => undef
$tjd => undef
$utdate => undef
$proj => 'h'
$guru => undef
</%args>

<%init>
use Data::Dumper;
use POSIX qw(strftime);
use Astro::Time;
use URI::Escape;
use PS::MOPS::Lib;
use PS::MOPS::DC::Field;

my %statmap = (
    I => 'INGESTED',
    N => 'READY',
    D => 'SYNTH',
    T => 'TRACKLET',
    U => 'POSTTRACKLET',
    A => 'ATTRIB',
    K => 'LINKING',
    L => 'COMPLETED',
    X => 'SKIP',
);

my $inst = $m->notes('INST');
my $mc = $inst->getConfig();
my $gmt_offset_hours = $mc->{site}->{gmt_offset_hours} || die "can't get gmt_offset_hours";
my $model = $m->notes('MODEL');
my $dbh = $inst->dbh;

# Today's info.
my ($year, $mon, $day);
my $today_nn;
my $today_tjd;
my @schmoo = gmtime;
$year = $schmoo[5] + 1900;
$mon = $schmoo[4] + 1;
$day = $schmoo[3];
$today_tjd = int(cal2mjd($day, $mon, $year, 0)) - 50000;
$today_nn = $today_tjd - 1 + 50000;
my $today_tjd_str = sprintf "TJD %d", $today_nn + 1 - 50000;
my $today_utdate_str = make_nice_date_str($tjd + 50000);
#$today_utdate_str =~ s/T.*//; # trim everything after date
my $today_oc = mopslib_mjd2ocnum($today_nn);

# User info.
if ($tjd) {
    $nn = $tjd - 1 + 50000;
}
elsif ($utdate) {
    if ($utdate =~ /today/) {
        $nn = $today_nn;
    }
    elsif ($utdate =~ /^(\d\d\d\d)[\/.-]?(\d\d)[\/.-]?(\d\d)$/) {
        ($year, $mon, $day) = ($1, $2, $3);
        $nn = int(cal2mjd($day, $mon, $year, 0)) - 1;
    }
}
else {
    # nothing specified, use latest.
    ($nn) = $dbh->selectrow_array('select nn from fields order by nn desc limit 1');
    $nn = $today_nn unless $nn; # no fields, oh well
}

$tjd = $nn - 50000 + 1;
my $tjd_str = sprintf "TJD %d", $nn + 1 - 50000;
my $utdate_str = make_nice_date_str($tjd + 50000);
#$utdate_str =~ s/T.*//; # trim everything after date
#$utdate_str .= ' UT';
my $ocnum = mopslib_mjd2ocnum($nn);

my $off;
my $next_tjd;
my $next_nn;
my $next_tjd_str;
my $next_utdate_str;
my $next_oc;

my $prev_tjd;
my $prev_nn;
my $prev_tjd_str;
my $prev_utdate_str;
my $prev_oc;

$off = get_nearest_nn_offset($dbh, $nn, 1);
if ($off) {
    $next_tjd = $tjd + $off;
    $next_nn = $nn + $off;
    $next_tjd_str = sprintf "TJD %d", $next_tjd;
    $next_utdate_str = make_nice_date_str($next_tjd + 50000);
#    $next_utdate_str =~ s/T.*//; # trim everything after date
#    $next_utdate_str .= ' UT';
    $next_oc = mopslib_mjd2ocnum($next_tjd + 50000);
}

$off = get_nearest_nn_offset($dbh, $nn, -1);
if ($off) {
    $prev_tjd = $tjd + $off;
    $prev_nn = $nn + $off;
    $prev_tjd_str = sprintf "TJD %d", $prev_tjd;
    $prev_utdate_str = make_nice_date_str($prev_tjd + 50000);
#    $prev_utdate_str =~ s/T.*//; # trim everything after date
#    $prev_utdate_str .= ' UT';
    $prev_oc = mopslib_mjd2ocnum($prev_tjd + 50000);
}


my $sth;
#
# Figure out what we've ingested.
#
$sth = $dbh->prepare(<<"SQL") or die $dbh->errstr;
select survey_mode, status, min(time_start) start_mjd, count(*) ct
from fields 
where nn=?
group by survey_mode, status
order by epoch_mjd
SQL
$sth->execute($nn) or die $sth->errstr;
my @chunks_ingested;
while (my $href = $sth->fetchrow_hashref) {
   push @chunks_ingested, { cn => $href->{survey_mode}, status => $href->{status}, start_mjd => $href->{start_mjd}, ct => $href->{ct} };
}
$sth->finish;


# See if we actually have a runs table.  Old MOPS DBs don't.
my $have_runs = $dbh->selectrow_array(<<"SQL", undef, $model, 'runs');
SELECT COUNT(*) 
FROM information_schema.tables  
WHERE table_schema = ? 
AND table_name = ?
SQL

if ($have_runs) {
    # Require non-empty runs table.
    ($have_runs) = $dbh->selectrow_array("select count(*) from runs r join fields f using(field_id) where f.nn=?", undef, $nn);
}



#CREATE TEMPORARY TABLE norep_chunks_processed
#(run_id BIGINT,
# survey_mode VARCHAR(120),
# type VARCHAR(120),
# status CHAR,
# footprints INT,
# updated TIMESTAMP)


# Gather information about all chunks.
my @norep_chunks_processed;     # proxy for former temp table


if ($have_runs) {
    $sth = $dbh->prepare(<<"SQL") or die $dbh->errstr;
SELECT temp.run_id run_id, temp.quad_name survey_mode, status, type, count(*) footprints, max(run_date) updated
FROM (
    SELECT run_id, group_concat(distinct survey_mode order by survey_mode separator ' ') quad_name,
    r.run_date run_date, r.status, IF(survey_mode LIKE 'MD%', 'MD', 'Quad') type 
  FROM fields LEFT JOIN runs r 
  USING (field_id) 
  WHERE nn=? 
  GROUP BY run_id, IF(parent_id is null, field_id, parent_id) 
  HAVING count(*) >= 3) AS temp 
GROUP BY run_id, quad_name
SQL
}
else {
    $sth = $dbh->prepare(<<"SQL") or die $dbh->errstr;
SELECT temp.run_id run_id, temp.quad_name survey_mode, status, type, count(*) footprints, max(run_date) updated
FROM (
    SELECT 1 run_id, group_concat(distinct survey_mode order by survey_mode separator ' ') quad_name,
    current_timestamp() run_date, f.status, IF(survey_mode LIKE 'MD%', 'MD', 'Quad') type 
  FROM fields f
  WHERE nn=? 
  GROUP BY IF(parent_id is null, field_id, parent_id) 
  HAVING count(*) >= 3
) AS temp 
GROUP BY quad_name
SQL
}

$sth->execute($nn) or die $sth->errstr; 
while (my $href = $sth->fetchrow_hashref) {
    push @norep_chunks_processed, $href;
}
$sth->finish;



# Get chunk+run info.
if ($have_runs) {
    $sth = $dbh->prepare(<<"SQL") or die $dbh->errstr;
SELECT temp.run_id run_id, temp.quad_name survey_mode, status, type, count(*) footprints, max(run_date) updated
FROM (
	SELECT run_id, group_concat(distinct survey_mode order by survey_mode separator ' ') quad_name,
    r.run_date run_date, r.status, 'Pair' type 
  FROM fields LEFT JOIN runs r 
  USING (field_id) 
  WHERE nn=? 
  GROUP BY run_id, IF(parent_id is null, field_id, parent_id) 
  HAVING count(*) = 2) AS temp 
GROUP BY run_id, quad_name
SQL
}
else {
    $sth = $dbh->prepare(<<"SQL") or die $dbh->errstr;
SELECT temp.run_id run_id, temp.quad_name survey_mode, status, type, count(*) footprints, max(run_date) updated
FROM (
	SELECT 1 run_id, group_concat(distinct survey_mode order by survey_mode separator ' ') quad_name,
    current_timestamp() run_date, f.status, 'Pair' type 
  FROM fields f
  WHERE nn=? 
  GROUP BY IF(parent_id is null, field_id, parent_id) 
  HAVING count(*) = 2) AS temp 
GROUP BY quad_name
SQL
}
$sth->execute($nn) or die $sth->errstr; 
while (my $href = $sth->fetchrow_hashref) {
    push @norep_chunks_processed, $href;
}
$sth->finish;

#
# This section creates a hash keyed on run_id, for each run_id there is a single array 
# which contains one or more hash elements. Each hash element consists of two keys :
#   name which contains the name of the chunk
#   status which contains the status the chunk was processued up to during the run
#
my (%runs_pair, %runs_quad, %runs_md, %runs_all, @sorted);
@sorted = sort { $a->{run_id} <=> $b->{run_id} } @norep_chunks_processed;
while (my $href = shift @sorted) {
	my %run_data = ( name => $href->{survey_mode}, status => $href->{status}, updated => $href->{updated});
	if ($href->{type} eq "Quad") {
 		push @{$runs_quad{$href->{run_id}}}, { %run_data };
        push @{$runs_all{$href->{run_id}}}, { %run_data };
    } 
 	elsif ($href->{type} eq "MD") {
		push @{$runs_md{$href->{run_id}}}, { %run_data };
        push @{$runs_all{$href->{run_id}}}, { %run_data };
    } 
 	elsif ($href->{survey_mode} !~ /(z|y)$/) {
 		push @{$runs_pair{$href->{run_id}}}, { %run_data };
        push @{$runs_all{$href->{run_id}}}, { %run_data };
    }
    else {
        # Guru chunks, especially difficult to czar.
 		push @{$runs_pair{$href->{run_id}}}, { %run_data, needguru => 1 };
        push @{$runs_all{$href->{run_id}}}, { %run_data, needguru => 1 };
    }
}

#
# Figure out what quads we have.
#
my %quads_ingested;
my $have_mds;
my $have_quads;
@sorted = grep { $_->{type} =~ /MD|Quad/ } @norep_chunks_processed;
while (my $href = shift @sorted) {
    if ($href->{survey_mode} =~ /^MD/) {
        $have_mds = 1;
    }
    else {
        $have_quads = 1;
    }
    $quads_ingested{$href->{survey_mode}} = $href->{footprints};
}

#
# This section creates a map of queried quad names to a substring
# select for czaring.  In other words, the GROUP_CONCAT() of all
# survey_modes in a quad may include several survey_modes; this
# maps the GROUP_CONCAT() result to a single, shorter string
# used to select tracklets for czaring, e.g.
# 140.3PI.00.ANE1.Q1.g+140.3PI.00.ANE1 => 140.3PI.00.ANE1.Q
#
my %quadchunkmap;
my $sm;
foreach my $ch (keys %quads_ingested) {
    if ($ch =~ /^MD/) {
        $sm = $ch;
    }
    elsif ($ch =~ /CNP/) {
        $sm = 'CNP';
    }
    elsif ($ch =~ /3PI/) {
    	# Break the multicolor quad into its two components which are seperated by a comma. 
    	$ch =~ m/\,(.*)/;
        my $visit = $1;

        my @components = split /\./, $visit;
        if ($ch =~ /^\d+\.3PI\.\d\d\.([\w\+-]+)/) {
            $sm = $1;
        }
        else {
            $sm = join('.', @components[0..$#components - 2]);
        }
    }
    elsif ($ch =~ /SS/ ) {
#    	$ch =~ m/\,(.*)/;
#        my $visit = $1;
        my @components = split /\./, $ch;
        $sm = join('.', @components[0..$#components - 2]);
    }
    $quadchunkmap{$ch} = { name => $ch, sel => $sm, nfoot => $quads_ingested{$ch} };
}

#
# Figure out what pairs we have.
#
my %pairs_ingested;
my $have_pairs;
@sorted = grep { $_->{type} eq 'Pair' } @norep_chunks_processed;
while (my $href = shift @sorted) {
    $have_pairs = 1;
    $pairs_ingested{$href->{survey_mode}} = $href->{footprints};
}

#
# This section creates a map of queried pair names to a substring
# select for czaring.  In other words, the GROUP_CONCAT() of all
# survey_modes in a quad may include several survey_modes; this
# maps the GROUP_CONCAT() result to a single, shorter string
# used to select tracklets for czaring, e.g.
# 140.3PI.00.ANE1.Q1.g+140.3PI.00.ANE1 => 140.3PI.00.ANE1.Q
#
my %pairchunkmap;
foreach my $ch (keys %pairs_ingested) {
#    next if $ch =~ /MD/ or (!$guru and $ch =~ /(z|y)$/);
    $sm = $ch;
    $pairchunkmap{$ch} = { name => $ch, sel => $sm, nfoot => $pairs_ingested{$ch} };
}

sub get_nearest_nn_offset {
    # return the offset to the TJD in the direction specified (forward or backward) from the
    # specified TJD.  Dir should simply be 1 or -1.  Return none if there is no data in that direction.
    my ($dbh, $nn, $dir) = @_;
    my $foo;
    my $off;
    if ($dir > 0) {
        $foo = $dbh->selectcol_arrayref(<<"SQL") or die $dbh->errstr;
select nn from fields where nn > $nn order by nn limit 1
SQL
    }
    else {
        $foo = $dbh->selectcol_arrayref(<<"SQL") or die $dbh->errstr;
select nn from fields where nn < $nn order by nn desc limit 1
SQL
    }

    if ($foo && $foo->[0]) {
        $off = $foo->[0] - $nn;     # offset from current night
    }
    return $off;
}

sub make_nice_date_str {
    my ($mjd) = @_;
    my $unixtime = ($mjd - 40587) * 86400;  # seconds since Unix epoch (40587 => Unix epoch Jan 1 1970)
    return uc strftime("%a %d %b %Y UT", gmtime($unixtime));
}
</%init>
