#!/bin/perl
#
#  This script gets TLM data generates Genesis EDR file. Run without 
#  command line arguments to see usage.
#
$scriptname = "make_gns_edrs.pl";
$version    = "3.0.4 -- August 8, 2001 -- BVS/NAIF";

#
#  Version 3.0.4 -- August 8, 2001 -- BVS/NAIF
#
#     Corrected products type tokens -- replaced 'ql' with 'q' and 
#     'f' with 'r' -- in the file to match SIS.
#
#  Version 3.0.3 -- July 27, 2001 -- BVS/NAIF
#
#     Reset MSOPCK's ANGULAR_RATE_PRESENT keyword to be 
#     'MAKE UP/NO AVERAGING' for correct angular rate simulation.
#
#  Version 3.0.2 -- November 11, 2000 -- BVS/NAIF
#
#     Added channels B-2819, B-2820, B-2821, B-2822 to ``sci'' EDR.
#     Updated non-channelized APID list for GEM and GIM to include 
#     raw count apids -- 41 (GEM raw) & 42 (GIM raw).
#
#  Version 3.0.1 -- October 8, 2000 -- BVS/NAIF
#
#     Fixed success message for CK runs to contain CK file name.
#
#  Version 3.0.0 -- September 22, 2000 -- BVS/NAIF
#
#     Updated to produce ``trs'' (thruster firing information from 
#     small forces APID) EDRs and CKs from SPIN_TRACK quaternion 
#     packets. Updated to generate ``sci'' and ``can'' EDRs instead of 
#     former ``sci'' EDRs. List of channels in EDRs corresponds to 
#     EDR SIS 1.005.
#
#  Version 2.1.0 -- August 31, 2000 -- BVS/NAIF
#
#     Updated to eliminate initial sTot query (used to obtain raw 
#     packet, .pkt file) and to use msop_query with input from TDS 
#     instead.
#
#  Version 2.0.0 -- August 24, 2000 -- BVS/NAIF
#
#     Replaced cht ECSV-based EDR with eps, fsw, prp, sci and trm EDRs
#     with the list of channels for each of these EDRs corresponding to 
#     EDR SIS 1.004.
#
#  Version 1.1.0 -- August 17, 2000 -- BVS/NAIF
#
#     Added WIND/MEC F1D packet (APID 26) to the list of MEC APIDs 
#     to get from TDS.
#
#  Version 1.0.0 -- July 25, 2000 -- BVS/NAIF
#
#     Initial release -- combined make_gns_edr.pl and make_gns_ecsv.pl
#

#
#  Misc. setups.
#
#$ecdr2ecsv   = "/sfoc/mcdm/ecdr2ecsv";
#
$gns_edr     = "/sdma/naif/ops/projects/GNS/edr/bin/gns_edr";
$stot        = "/sfoc/bin/stot";
$msop_query  = "/u1/local/bin/msop_query";
$ecdr2ecsv   = "/sdma/naif/ops/projects/GNS/edr/bin/ecdr2ecsv";
$packetdecom = "/sdma/naif/ops/projects/GNS/sff/bin/packet_decom_gns";
$smf2ecsv    = "/sdma/naif/ops/projects/GNS/edr/bin/smf2ecsv.pl";
$msopck      = "/sdma/naif/ops/bin/msopck";
$gzip        = "/usr/local/bin/gzip";

$dmd_ccl     = "/sdma/naif/ops/projects/GNS/dmd/genesis_ccl.bin";
$dmd_p2c     = "/sdma/naif/ops/projects/GNS/dmd/genesis_ccl.dep";
$dmd_tdl     = "/sdma/naif/ops/projects/GNS/dmd/genesis_tdl.bin";
$dmd_cold    = "/sdma/naif/ops/projects/GNS/dmd/genesis_cpt.bin";

$lskfile     = "/sdma/naif/ops/projects/GNS/lsk/gns.tls";
$sclkfile    = "/sdma/naif/ops/projects/GNS/sclk/gns.tsc";

#
#  Check file locations.
#
if ( ! -x $gns_edr ) {
   die "ERROR: $scriptname: '$gns_edr' doesn't exist or not executable.\n";  
}
if ( ! -x $stot ) {
   die "ERROR: $scriptname: '$stot' doesn't exist or not executable.\n";  
}
if ( ! -x $msop_query ) {
   die "ERROR: $scriptname: '$msop_query' doesn't exist or not executable.\n";  
}
if ( ! -x $ecdr2ecsv ) {
   die "ERROR: $scriptname: '$ecdr2ecsv' doesn't exist or not executable.\n";  
}
if ( ! -x $packetdecom ) {
   die "ERROR: $scriptname: '$packetdecom' doesn't exist or not executable.\n";  
}
if ( ! -x $smf2ecsv ) {
   die "ERROR: $scriptname: '$smf2ecsv' doesn't exist or not executable.\n";  
}
if ( ! -x $msopck ) {
   die "ERROR: $scriptname: '$msopck' doesn't exist or not executable.\n";  
}
if ( ! -x $gzip ) {
   die "ERROR: $scriptname: '$gzip' doesn't exist or not executable.\n";  
}
if ( ! -e $dmd_ccl ) {
   die "ERROR: $scriptname: '$dmd_ccl' doesn't exist.\n";  
}
if ( ! -e $dmd_p2c ) {
   die "ERROR: $scriptname: '$dmd_p2c' doesn't exist.\n";  
}
if ( ! -e $dmd_tdl ) {
   die "ERROR: $scriptname: '$dmd_tdl' doesn't exist.\n";  
}
if ( ! -e $dmd_cold ) {
   die "ERROR: $scriptname: '$dmd_cold' doesn't exist.\n";  
}
if ( ! -e $lskfile ) {
   die "ERROR: $scriptname: '$lskfile' doesn't exist.\n";  
}
if ( ! -e $sclkfile ) {
   die "ERROR: $scriptname: '$sclkfile' doesn't exist.\n";  
}

#
#  If we have incorrect number of command line arguments, 
#  display usage.
#
if ( @ARGV != 6 ){
   print <<"EndOfUsageText";
   
$scriptname -- Ver. $version

Usage:

   > $scriptname <type> <tds> <inst> <timetype> <begtime> <endtime>
   
where:

   type ....... one of: test|ql|nearfinal|final
   tds ........ one of: stl|hrd|swt|master|cdr
   inst ....... one of: gim|gem|con|mec|can|eps|fsw|prp|sci|trm|trs|ck 
   timetype ... one of: ert|scet
   begtime .... begin time (SCET or ERT; use YYYY-MM-DDTHR:MN:SC.### format)
   endtime .... end time (SCET or ERT; use YYYY-MM-DDTHR:MN:SC.### format)
      
EndOfUsageText

   exit(1);

}

#
#  Process command line arguments. First, set product type.
#
if      ( $ARGV[0] =~ /^test$/i   ) { 
   $edrtype = "t";  
} elsif ( $ARGV[0] =~ /^ql$/i     ) { 
   $edrtype = "q"; 
} elsif ( $ARGV[0] =~ /^nearfinal$/i     ) { 
   $edrtype = "n"; 
} elsif ( $ARGV[0] =~ /^final$/i  ) { 
   $edrtype = "r";  
} else  {
   die "ERROR: $scriptname: cannot recognize first argument '$ARGV[0]'.\n";  
} 

#
#  Set TDS server name and ID.
#
if      ( $ARGV[1] =~ /^stl$/i    ) { 
   $tdsname = "GNS_STL_QueryServer";
   $tdsid   = "l";
} elsif ( $ARGV[1] =~ /^hrd$/i    ) { 
   $tdsname = "GNS_HRD_QueryServer";
   $tdsid   = "h";
} elsif ( $ARGV[1] =~ /^swt$/i    ) { 
   $tdsname = "GNS_SWT_QueryServer";
   $tdsid   = "s";
} elsif ( $ARGV[1] =~ /^master$/i ) { 
   $tdsname = "Gns_MASTER_QueryServer";
   $tdsid   = "m";
} elsif ( $ARGV[1] =~ /^cdr$/i    ) { 
   $tdsname = "Gns_CDR_QueryServer";
   $tdsid   = "c";
} else {
   die "ERROR: $scriptname: cannot recognize second argument '$ARGV[1]'.\n"; 
}

#
#  For quick-look and final EDRs we will not include TDS is into the file 
#  name.
#
if ( $edrtype eq "q" || $edrtype eq "n" || $edrtype eq "r" ) {
   $tdsid = "";
}

#
#  Set instrument name/subsustem and list of channels for it.
#
if      ( $ARGV[2] =~ /^gem$/i    ) {
   $edrformat  = "hdf";
   $inst       = "gem";
   $apids      = "apid_31 apid_32 apid_33 apid_41";
} elsif ( $ARGV[2] =~ /^gim$/i    ) { 
   $edrformat  = "hdf";
   $inst       = "gim";
   $apids      = "apid_28 apid_29 apid_30 apid_34 apid_42";
} elsif ( $ARGV[2] =~ /^con$/i    ) { 
   $edrformat  = "hdf";
   $inst       = "con";
   $apids      = "apid_25";
} elsif ( $ARGV[2] =~ /^mec$/i    ) { 
   $edrformat  = "hdf";
   $inst       = "mec";
   $apids      = "apid_24 apid_26";
} elsif ( $ARGV[2] =~ /^ck$/i    ) { 
   $edrformat  = "ck";
   $inst       = "gnssc";
   $apids      = "apid_27";
} elsif ( $ARGV[2] =~ /^trs$/i    ) { 
   $edrformat  = "smf";
   $inst       = "trs";
   $apids      = "apid_38";
} elsif ( $ARGV[2] =~ /^eps$/i    ) { 
   $edrformat  = "ecsv";
   $inst       = "eps";
   $apids      = "all_ch_apids";
   $channels   = <<"EndOfepsChannels";
E-0019 DN \%d
E-0000 DN \%d
E-0004 DN \%d
E-0029 DN \%d
B-2405 DN \%d
B-2406 DN \%d
B-2407 DN \%d
B-2411 DN \%d
B-2423 DN \%d
B-2425 DN \%d
B-2426 DN \%d
B-2431 DN \%d
EndOfepsChannels
} elsif ( $ARGV[2] =~ /^fsw$/i    ) { 
   $edrformat  = "ecsv";
   $inst       = "fsw";
   $apids      = "all_ch_apids";
   $channels   = <<"EndOffswChannels";
B-0189 DN \%d
B-0190 DN \%d
B-2289 DN \%d
B-2290 DN \%d
F-3269 DN \%d
F-1049 DN \%d
F-1050 DN \%d
F-1516 DN \%d
O-1727 DN \%d
O-1728 DN \%d
O-1729 DN \%d
O-1730 DN \%d
O-1731 DN \%d
O-1732 DN \%d
O-1724 DN \%d
O-1725 DN \%d
O-1726 DN \%d
O-1736 DN \%d
O-1737 DN \%d
O-1738 DN \%d
O-1739 DN \%d
O-1740 DN \%d
O-1741 DN \%d
O-1733 DN \%d
O-1734 DN \%d
O-1735 DN \%d
O-2860 DN \%d
O-2910 DN \%d
O-2925 DN \%d
O-2928 DN \%d
O-2929 DN \%d
O-2942 DN \%d
O-2828 DN \%d
O-2836 DN \%d
O-2840 DN \%d
O-1745 DN \%d
O-1746 DN \%d
O-1747 DN \%d
O-1748 DN \%d
O-1749 DN \%d
O-1750 DN \%d
O-1742 DN \%d
O-1743 DN \%d
O-1744 DN \%d
O-2060 DN \%d
O-2284 DN \%d
O-2291 DN \%d
O-2292 DN \%d
O-2295 DN \%d
O-2296 DN \%d
O-2304 DN \%d
O-2308 DN \%d
O-2311 DN \%d
O-2934 DN \%d
O-2935 DN \%d
O-2940 DN \%d
O-2943 DN \%d
O-2946 DN \%d
O-2950 DN \%d
O-2953 DN \%d
O-2958 DN \%d
O-2987 DN \%d
EndOffswChannels
} elsif ( $ARGV[2] =~ /^prp$/i    ) { 
   $edrformat  = "ecsv";
   $inst       = "prp";
   $apids      = "all_ch_apids";
   $channels   = <<"EndOfprpChannels";
P-0016 DN \%d
P-0014 DN \%d
P-0021 DN \%d
P-0018 DN \%d
P-0025 DN \%d
P-0002 DN \%d
P-0004 DN \%d
P-0718 DN \%d
EndOfprpChannels
} elsif ( $ARGV[2] =~ /^can$/i    ) { 
   $edrformat  = "ecsv";
   $inst       = "can";
   $apids      = "all_ch_apids";
   $channels   = <<"EndOfcanChannels";
I-0111 DN \%d
B-1357 DN \%d
I-0197 DN \%d
I-0198 DN \%d
I-0199 DN \%d
I-0200 DN \%d
I-0201 DN \%d
I-0202 DN \%d
I-0203 DN \%d
I-0204 DN \%d
I-0205 DN \%d
I-0136 DN \%d
I-0137 DN \%d
I-0138 DN \%d
I-0116 DN \%d
B-1358 DN \%d
I-0206 DN \%d
I-0207 DN \%d
I-0208 DN \%d
I-0209 DN \%d
I-0210 DN \%d
I-0211 DN \%d
I-0212 DN \%d
I-0213 DN \%d
I-0214 DN \%d
I-0139 DN \%d
I-0159 DN \%d
I-0161 DN \%d
I-0117 DN \%d
B-1359 DN \%d
I-0215 DN \%d
I-0216 DN \%d
I-0217 DN \%d
I-0218 DN \%d
I-0219 DN \%d
I-0220 DN \%d
I-0221 DN \%d
I-0222 DN \%d
I-0223 DN \%d
I-0191 DN \%d
I-0192 DN \%d
I-0193 DN \%d
I-0118 DN \%d
B-1360 DN \%d
I-0224 DN \%d
I-0225 DN \%d
I-0226 DN \%d
I-0227 DN \%d
I-0228 DN \%d
I-0229 DN \%d
I-0230 DN \%d
I-0231 DN \%d
I-0232 DN \%d
I-0194 DN \%d
I-0195 DN \%d
I-0196 DN \%d
B-1454 DN \%d
I-0245 DN \%d
I-0246 DN \%d
I-0247 DN \%d
B-1455 DN \%d
I-0110 DN \%d
I-0106 DN \%d
I-0119 DN \%d
B-1344 DN \%d
I-0248 DN \%d
I-0249 DN \%d
I-0250 DN \%d
B-1456 DN \%d
I-0233 DN \%d
I-0234 DN \%d
I-0235 DN \%d
B-1363 DN \%d
I-0236 DN \%d
I-0237 DN \%d
I-0238 DN \%d
B-1362 DN \%d
B-1361 DN \%d
I-0121 DN \%d
I-0120 DN \%d
I-0124 DN \%d
I-0125 DN \%d
I-0126 DN \%d
I-0127 DN \%d
I-0128 DN \%d
I-0129 DN \%d
I-0123 DN \%d
I-0122 DN \%d
I-0130 DN \%d
I-0131 DN \%d
I-0132 DN \%d
I-0133 DN \%d
I-0134 DN \%d
I-0135 DN \%d
I-0108 DN \%d
I-0107 DN \%d
B-1343 DN \%d
I-0239 DN \%d
I-0240 DN \%d
I-0241 DN \%d
B-1452 DN \%d
B-1364 DN \%d
I-0242 DN \%d
I-0243 DN \%d
I-0244 DN \%d
B-1453 DN \%d
B-1345 DN \%d
B-1346 DN \%d
B-1347 DN \%d
B-1348 DN \%d
B-1349 DN \%d
B-1350 DN \%d
B-1351 DN \%d
B-1352 DN \%d
B-1353 DN \%d
B-1354 DN \%d
B-1355 DN \%d
B-1356 DN \%d
EndOfcanChannels
} elsif ( $ARGV[2] =~ /^sci$/i    ) { 
   $edrformat  = "ecsv";
   $inst       = "sci";
   $apids      = "all_ch_apids";
   $channels   = <<"EndOfsciChannels";
I-0190 DN \%d
I-0101 DN \%d
I-0102 DN \%d
I-0104 DN \%d
I-0105 DN \%d
I-3371 DN \%d
I-0945 DN \%d
I-0949 DN \%d
I-0958 DN \%d
I-0961 DN \%d
I-0465 DN \%d
I-3299 DN \%d
I-3302 DN \%d
I-3303 DN \%d
I-3344 DN \%d
I-3345 DN \%d
I-3365 DN \%d
I-1372 DN \%d
I-1521 DN \%d
I-3298 DN \%d
I-0744 DN \%d
I-3551 DN \%d
I-0269 DN \%d
I-0270 DN \%d
I-0271 DN \%d
I-0458 DN \%d
B-1329 DN \%d
B-1330 DN \%d
B-1331 DN \%d
B-1332 DN \%d
B-1333 DN \%d
B-1334 DN \%d
I-0962 DN \%d
B-1336 DN \%d
B-1337 DN \%d
B-1338 DN \%d
B-1339 DN \%d
B-1340 DN \%d
B-1341 DN \%d
I-0969 DN \%d
I-0109 DN \%d
I-0147 DN \%d
I-0146 DN \%d
I-1328 DN \%d
I-0189 DN \%d
I-0150 DN \%d
I-0149 DN \%d
I-0151 DN \%d
I-1322 DN \%d
I-1324 DN \%d
I-1332 DN \%d
I-0153 DN \%d
I-0152 DN \%d
I-0148 DN \%d
I-0141 DN \%d
I-0140 DN \%d
I-0252 DN \%d
I-0185 DN \%d
I-0251 DN \%d
I-0093 DN \%d
I-0094 DN \%d
I-0095 DN \%d
I-0253 DN \%d
I-0142 DN \%d
I-0144 DN \%d
I-0143 DN \%d
I-0255 DN \%d
I-0187 DN \%d
I-0254 DN \%d
I-0097 DN \%d
I-0098 DN \%d
I-0099 DN \%d
I-0256 DN \%d
I-0145 DN \%d
I-0721 DN \%d
I-0725 DN \%d
I-0726 DN \%d
I-0257 DN \%d
B-2819 DN \%d
B-2820 DN \%d
B-2821 DN \%d
B-2822 DN \%d
EndOfsciChannels
} elsif ( $ARGV[2] =~ /^trm$/i    ) { 
   $edrformat  = "ecsv";
   $inst       = "trm";
   $apids      = "all_ch_apids";
   $channels   = <<"EndOftrmChannels";
T-0315 DN \%d
T-0313 DN \%d
T-0314 DN \%d
T-0309 DN \%d
T-0311 DN \%d
T-0307 DN \%d
T-0299 DN \%d
T-0301 DN \%d
T-0303 DN \%d
T-0305 DN \%d
T-0237 DN \%d
T-0485 DN \%d
EndOftrmChannels
} else {
   die "ERROR: $scriptname: cannot recognize third argument '$ARGV[2]'.\n";  
} 

#
#  Set interval specification and ordering time types.
#
if      ( $ARGV[3] =~ /^ert/i     ) { 
   $timetype  = "ERT";
   $timeorder = "ERT";
   $timeid    = "e";
} elsif ( $ARGV[3] =~ /^scet/i    ) { 
   $timetype  = "SCET";
   $timeorder = "SCLK";
   $timeid    = "s";
} else {
   die "ERROR: $scriptname: cannot recognize fourth argument '$ARGV[3]'.\n";  
}

#
#  For quick-look and final EDRs we will not include time ID is into the file 
#  name.
#
if ( $edrtype eq "q" || $edrtype eq "n" || $edrtype eq "r" ) {
   if ( $timeid eq "e" ) {
      die "ERROR: $scriptname: quick-look, near-final and final EDRs cannot ".
          "be generated using ERT time bracketing/sorting.\n";  
   }
   $timeid = "";
}

#
#  Set begin time. It must be in YYYY-MM-DDTHR:MN:SC.### format.
#
if ( $ARGV[4] =~ /^\d{4,4}-\d{2,2}-\d{2,2}T\d{2,2}:\d{2,2}:\d{2,2}\.\d{3,3}$/){

   #
   #  For near-final and final EDRs we also require begin time HRMNSC be 
   #  00:00:00.000. This requirement is dictated by the final EDR file naming 
   #  schema.
   #
   if ( ( $edrtype eq "n" || $edrtype eq "r" ) && 
        ! ( $ARGV[4] =~ /^.*00\:00\:00\.000$/) ) {
      die "ERROR: $scriptname: begin time for near-final and final EDRs ".
          "must be 00:00:00.000.\n";  
   }
   
   $begtime = $ARGV[4];
   $begtime =~ s/-/\//g;
   $begtime =~ s/T/-/g;

} else {
   die "ERROR: $scriptname: begin time '$ARGV[4]' has invalid format.\n";  
}

#
#  Set end time. It must be in YYYY-MM-DDTHR:MN:SC.### format.
#
if ( $ARGV[5] =~ /^\d{4,4}-\d{2,2}-\d{2,2}T\d{2,2}:\d{2,2}:\d{2,2}\.\d{3,3}$/){

   #
   #  For near-final and final EDRs we also require end time HRMNSC be 
   #  23:59:59.999. This requirement is dictated by final EDR file naming 
   #  schema.
   #
   if ( ( $edrtype eq "n" || $edrtype eq "r" ) && 
        ! ( $ARGV[5] =~ /^.*23\:59\:59\.999$/) ) {
      die "ERROR: $scriptname: end time for near-final and final EDRs ".
          "must be 23:59:59.999.\n";  
   }
   
   $endtime = $ARGV[5];
   $endtime =~ s/-/\//g;
   $endtime =~ s/T/-/;

} else {
   die "ERROR: $scriptname: end time '$ARGV[5]' has invalid format.\n";  
}

#
#  Create file base name.
#
$bt = $begtime;
$bt =~ tr/\ \-\/\://d;
$et = $endtime;
$et =~ tr/\ \-\/\://d;
if ( $edrtype eq "n" || $edrtype eq "r" ) {
   $fnbase = sprintf( "%s_%s%s%s_%s_%s_v1", $inst, $edrtype, $tdsid, $timeid,
                      substr( $bt, 2, 6 ), 
                      substr( $et, 2, 6 ) );
} else {
   $fnbase = sprintf( "%s_%s%s%s_%s_%s_v1", $inst, $edrtype, $tdsid, $timeid,
                      substr( $bt, 2, 10 ), 
                      substr( $et, 2, 10 ) );
}

#
#  While base name for HDF and ECSV file is constructed the same way, the 
#  set of files to be produced is different.
#
if      ( $edrformat eq "ecsv" ) {

   $pvlfile  = $fnbase.".pvl";
   $pktfile  = $fnbase.".pkt";
   $qpffile  = $fnbase.".qpf";
   $ecdrfile = $fnbase.".ecdr";
   $ecsvfile = $fnbase.".ecsv";
   $gzpdfile = $ecsvfile.".gz";

   #
   #  Check whether files already exist -- we don't want to overwrite them.
   #
   if ( -e $pvlfile ) {
      die "ERROR: $scriptname: pvl file '$pvlfile' already exists.\n";
   }
   if ( -e $pktfile ) {
      die "ERROR: $scriptname: packet file '$pktfile' already exists.\n";
   }
   if ( -e $qpffile ) {
      die "ERROR: $scriptname: qpf file '$qpffile' already exists.\n";
   }
   if ( -e $ecdrfile ) {
      die "ERROR: $scriptname: ecdr file '$ecdrfile' already exists.\n";
   }
   if ( -e $ecsvfile ) {
      die "ERROR: $scriptname: ecsv file '$ecsvfile' already exists.\n";
   }
   if ( -e $ecsvfile ) {
      die "ERROR: $scriptname: gzipped ecsv file '$gzpdfile' already ".
          "exists.\n";
   }

} elsif ( $edrformat eq "smf" ) {

   $pvlfile  = $fnbase.".pvl";
   $pktfile  = $fnbase.".pkt";
   $dpktfile = $fnbase.".dpkt";
   $ecsvfile = $fnbase.".ecsv";
   $gzpdfile = $ecsvfile.".gz";

   #
   #  Check whether files already exist -- we don't want to overwrite them.
   #
   if ( -e $pvlfile ) {
      die "ERROR: $scriptname: pvl file '$pvlfile' already exists.\n";
   }
   if ( -e $pktfile ) {
      die "ERROR: $scriptname: packet file '$pktfile' already exists.\n";
   }
   if ( -e $dpktfile ) {
      die "ERROR: $scriptname: decom'd packet file '$dpktfile' already exists.\n";
   }
   if ( -e $ecsvfile ) {
      die "ERROR: $scriptname: ecsv file '$ecsvfile' already exists.\n";
   }
   if ( -e $ecsvfile ) {
      die "ERROR: $scriptname: gzipped ecsv file '$gzpdfile' already ".
          "exists.\n";
   }

} elsif ( $edrformat eq "hdf" ) {

   $pvlfile  = $fnbase.".pvl";
   $pktfile  = $fnbase.".pkt";
   $hdffile  = $fnbase.".hdf";
   $logfile  = $fnbase.".gns_edr.log";
   
   #
   #  Check whether files already exist -- we don't want to overwrite them.
   #
   if ( -e $pvlfile ) {
      die "ERROR: $scriptname: pvl file '$pvlfile' already exists.\n";
   }
   if ( -e $pktfile ) {
      die "ERROR: $scriptname: packet file '$pktfile' already exists.\n";
   }
   if ( -e $hdffile ) {
      die "ERROR: $scriptname: HDF file '$hdffile' already exists.\n";
   }
   if ( -e $logfile ) {
      die "ERROR: $scriptname: gns_edr log file '$logfile' already exists.\n";
   }
   
} elsif ( $edrformat eq "ck" ) {

   $pvlfile  = $fnbase.".pvl";
   $pktfile  = $fnbase.".pkt";
   $hdffile  = $fnbase.".quats";
   $logfile  = $fnbase.".gns_edr.log";
   $msopfile = $fnbase.".msopck.setup";
   $cmtfile  = $fnbase.".cmt";
   $ckfile   = $fnbase.".bc";
   
   #
   #  Check whether files already exist -- we don't want to overwrite them.
   #
   if ( -e $pvlfile ) {
      die "ERROR: $scriptname: pvl file '$pvlfile' already exists.\n";
   }
   if ( -e $pktfile ) {
      die "ERROR: $scriptname: packet file '$pktfile' already exists.\n";
   }
   if ( -e $hdffile ) {
      die "ERROR: $scriptname: quaternion file '$hdffile' already exists.\n";
   }
   if ( -e $logfile ) {
      die "ERROR: $scriptname: gns_edr log file '$logfile' already exists.\n";
   }
   if ( -e $msopfile ) {
      die "ERROR: $scriptname: MSOPCK setup file '$msopfile' already exists.\n";
   }
   if ( -e $cmtfile ) {
      die "ERROR: $scriptname: comment file '$cmtfile' already exists.\n";
   }
   if ( -e $ckfile ) {
      die "ERROR: $scriptname: comment file '$ckfile' already exists.\n";
   }
   
} else {
   die "ERROR: $scriptname: internal bug -- \$edrformat value '$edrformat' ".
       "is not allowed.\n";
}

#
#  If EDR format is HDF, we need to get raw packets using stot.
#
if ( $edrformat eq "hdf" || $edrformat eq "smf" || $edrformat eq "ck"  ) {

   #
   #  Generate PVL.
   #
   open( PVL, ">$pvlfile" ) || 
      die "ERROR: $scriptname: cannot open '$pvlfile' for write.\n";

print PVL <<"EndOfTemplateText";
   OBJECT = TDS_Query;
   DESCRIPTION = 'Request for GNS Science Data';
   REQUESTER_NAME = 'Boris Semenov, GNS/DMA';
   MISSION_NAME = GNS;
   SPACECRAFT_NAME = Gns;
   DATA_FROM = { NERT } ;
   TIME_RANGE = { $begtime .. $endtime } $timetype;
   TIME_ORDER = $timeorder;
   GROUP = FRAME;
      DATA_TYPE = '$apids';
      DSS_ID = ALL;
      TELEMETRY_MODE = MERGED;
   END_GROUP = FRAME;
   END_OBJECT = TDS_Query;
EndOfTemplateText

   close( PVL ) || die "ERROR: $scriptname: cannot close '$pvlfile'.\n";
   
   #
   # Run stot to create raw packet file.
   #
   $result = `$stot $tdsname $pvlfile $pktfile -f 2>&1`;
   $status = ( $? >> 8 );
   
   if ( $status ) {
      die "ERROR: $scriptname: $stot failed. Messages ".
          "were:\n$result.\n";  
   }
   if ( ! ( -e $pktfile ) ) {
      die "ERROR: $scriptname: raw packet file $pktfile has not been ".
          "created. $stot messages were:\n$result.\n";  
   }
   if ( -z $pktfile ) {
      die "ERROR: $scriptname: raw packet file $pktfile has zero ".
          "size. $stot messages were:\n$result.\n";  
   }
}

#
#  We have got raw packets in a .pkt file for HDF production (as of 
#  script version 2.1.0 we don't need to do it for ECSV EDRs). Now, 
#  depending on whether we need to generate HDF or ECSV EDR, we run 
#  different tools.
#
if      ( $edrformat eq "ecsv" ) {

   #
   #  Generate QPF for msop_query.
   #
   open( QPF, ">$qpffile" ) || 
      die "ERROR: $scriptname: cannot open '$qpffile' for write.\n";
   
   print QPF <<"EndOfTemplateText";
start_time      $begtime
stop_time       $endtime
sample_mode     ON_SAMPLE
time_type       $timetype
time_order      $timeorder
ecdr_time       SCLK
wse_filter      "anomaly_flags=D0 and pkt_fill_flag=D0"
dmd_ccl         $dmd_ccl
dmd_p2c         $dmd_p2c 
dmd_tdl         $dmd_tdl
dmd_cold        $dmd_cold
SPACECRAFT_NAME Gns
MISSION_NAME    GNS
channel_clear
save_ecdr       $ecdrfile
$channels
EndOfTemplateText
   
   close( QPF ) || die "ERROR: $scriptname: cannot close '$qpffile'.\n";
   
   #
   #  Run msop_query to create ecdr file.
   #
   $result = `$msop_query -r $qpffile -q $tdsname > /dev/null 2>&1`;
   $status = ( $? >> 8 );
   
   if ( $status ) {
      die "ERROR: $scriptname: $msop_query failed. See '$qpffile.log' ".
            "for details.\n";
   }
   
   #
   #  If ecdr packet file has non-zero size, generate ECSV from the data in it.
   #
   if ( ( -e $ecdrfile ) && ! ( -z $ecdrfile ) ) {
   
      #
      #  Run ecdr2ecsv.
      #
      $result = `$ecdr2ecsv -f kctde -d GNS_ECSV_EDR -p DMA/JPL -g $ecdrfile $ecsvfile 2>&1`;
      $status = ( $? >> 8 );
   
      if ( $status ) {
         
         #
         #  ecdr2ecsv failed. Pull out error messages and die.
         #
         die "ERROR: $scriptname: $ecdr2ecsv failed. Messages ".
             "were:\n\n$result\n";
               
      } else {
   
         #
         #  ecdr2ecsv succeeded. Run gzip to make compress ecsv file.
         #
         $result = `$gzip $ecsvfile 2>&1`;
         
         if ( ( ! $status ) && ( -e $gzpdfile ) ) {
         
            #
            #  Report success.
            #
            print "$gzpdfile -- compressed CHTLM EDR ".
                  "file -- was created successfully.\n";
                  
         } else {
            
            die "ERROR: $scriptname: $gzip failed. Messages were:".
                "\n\n$result\n";
               
         }
   
      }
      
   } else {
      die "ERROR: $scriptname: ecdr file '$ecdrfile' has zero size. ".
            "See '$qpffile.log' for details.\n"; 
   }

} elsif ( $edrformat eq "smf" ) {

   #
   #  Run packet_decom to decomutate obtained small_forces packets.
   #
   $result = `$packetdecom  $pktfile > $dpktfile 2>&1`;
   
   #
   #  Unfortunately, packet_decom doesn't behave properly and doesn't 
   #  return status correctly. So, thus check is blocked for now. 
   # 
   #$status = ( $? >> 8 );
   #
   #if ( $status ) {
   #  die "ERROR: $scriptname: $packetdecom failed. See '$dpktfile' ".
   #      "for details.\n";
   #}
   
   #
   #  If decom'd packet file has non-zero size, generate ECSV from the 
   #  data in it.
   #
   if ( ( -e $dpktfile ) && ! ( -z $dpktfile ) ) {
   
      #
      #  Run smf2ecsv script to do conversion.
      #
      $result = `$smf2ecsv $dpktfile $ecsvfile > $ecsvfile.log 2>&1`;
      $status = ( $? >> 8 );
   
      if ( $status ) {
         
         #
         #  smf2ecsv failed. Pull out error messages and die.
         #
         die "ERROR: $scriptname: $smf2ecsv failed. See $ecsvfile.log ".
             "file for error messages.\n";
               
      } else {
   
         #
         #  smf2ecsv succeeded. Run gzip to make compress ecsv file.
         #
         $result = `$gzip $ecsvfile 2>&1`;
         
         if ( ( ! $status ) && ( -e $gzpdfile ) ) {
         
            #
            #  Report success.
            #
            print "$gzpdfile -- compressed CHTLM EDR ".
                  "file -- was created successfully.\n";
                  
         } else {
            
            die "ERROR: $scriptname: $gzip failed. Messages were:".
                "\n\n$result\n";
               
         }
   
      }
      
   } else {
      die "ERROR: $scriptname: decom'd packet file '$dpktfile' doesn't ".
          "exist or has zero size."; 
   }

} elsif ( $edrformat eq "hdf" ) {

   #
   #  Run gns_edr.
   #
   $result = `$gns_edr -inst $inst -tlm $pktfile -edr $hdffile >$logfile 2>&1`;
   $status = ( $? >> 8 );

   if ( $status ) {
      
      #
      #  gns_edr failed. Pull out error messages and die.
      #
      $result = `grep -i error $logfile`;
      die "ERROR: $scriptname: $gns_edr failed. Messages were:\n\n".
          "$result\n".
          "See '$logfile' for complete log.\n";
          
   } else {

      #
      #  gns_edr succeeded. Report success and any warning that 
      #  were issued.
      #
      print "$hdffile -- HDF EDR ".
            "file -- was created successfully.\n";
      
      $result = `grep -i warning $logfile`;
      if ( $result ) {
         print "\nWarning messages were:\n\n$result\n";
      }

   }

} elsif ( $edrformat eq "ck" ) {

   #
   #  Run gns_edr to dump quaternions
   #
   $result = `$gns_edr -inst acs -tlm $pktfile -edr $hdffile >$logfile 2>&1`;
   $status = ( $? >> 8 );

   if ( $status ) {
      
      #
      #  gns_edr failed. Pull out error messages and die.
      #
      $result = `grep -i error $logfile`;
      die "ERROR: $scriptname: $gns_edr failed. Messages were:\n\n".
          "$result\n".
          "See '$logfile' for complete log.\n";

   } elsif ( ! ( -e $hdffile ) || -z $hdffile ) {

      #
      #  gns_edr didn't fail but produced zero-size or no output file.
      #  Report error and die.
      #
      die "ERROR: $scriptname: $gns_edr didn't fail but produced ".
          "zero-size or no output file. See '$logfile' for details ".
          "of the run.\n";

   } else {

      #
      #  gns_edr succeeded. Generate MSOPCK setup and CK comments files
      #  and run MSOPCK to create CK using dumped SPIN_TRACK quaternions
      #
      #  First, generate MSOPCK setup file.
      #
      open( MSOPCKSETUP, ">$msopfile" ) || 
         die "ERROR: $scriptname: cannot open '$msopfile' for write.\n";
   
      print MSOPCKSETUP <<"EndOfMSOPCKText";
\\begindata

PRODUCER_ID             = 'GNS_DMA/JPL'

LSK_FILE_NAME           = '$lskfile'
SCLK_FILE_NAME          = '$sclkfile'
INTERNAL_FILE_NAME      = 'GNS SC Orientation CK File by NAIF/JPL'
COMMENTS_FILE_NAME      = '$cmtfile'

CK_TYPE                 = 3
CK_SEGMENT_ID           = 'GNS STRK_QUAT(APID27)-based ATTITUDE'
INSTRUMENT_ID           = -47000
REFERENCE_FRAME_NAME    = 'J2000'
ANGULAR_RATE_PRESENT    = 'MAKE UP/NO AVERAGING'

INPUT_DATA_TYPE         = 'MSOP QUATERNIONS' 
INPUT_TIME_TYPE         = 'SCLK'

MAXIMUM_VALID_INTERVAL  = 18.0
QUATERNION_NORM_ERROR   = 1.0E-3

\\begintext
EndOfMSOPCKText
   
      close( MSOPCKSETUP ) || die "ERROR: $scriptname: cannot close '$msopfile'.\n";

      #
      #  Then, generate CK comments file.
      #
      open( COMMENTS, ">$cmtfile" ) || 
         die "ERROR: $scriptname: cannot open '$cmtfile' for write.\n";
   
      print COMMENTS <<"EndOfCOMMENTSText";

Genesis Spacecraft Orientation CK File, STRK_QUAT packet (APID 27) based
===========================================================================
  
 
Orientation Data in the File
--------------------------------------------------------
 
     This file contains orientation and angular velocity data for the
     Genesis spacecraft frame, 'GNS_SC_BUS', relative to the J2000, 'J2000', 
     inertial frame. The NAIF ID code for the 'GNS_SC_BUS' frame is -47000.
 
 
Status
--------------------------------------------------------
 
     This file is a regular operational reconstructed C-Kernel file 
     created by GNS DMA using spacecraft orientation data downlinked in 
     the STRK_QUAT (APID 27) non-channelized telemetry packets.

     This file can be used for spacecraft operations and science data 
     processing support by the project science and engineering teams.
 
 
Pedigree
--------------------------------------------------------
 
     This file was generated by an automated process which extracts
     from GNS Telemetry Data System (TDS) STRK_QUAT telemetry packets 
     containing spacecraft orientation quaternions computed on-board, 
     decomutates packets using GNS EDR generator program and writes 
     decomutated quaternions to a CK file using MSOPCK program. 

     This file doesn't contains actual angular rate data because such 
     data is not available in the STRK_QUAT telemetry packets. Instead, 
     the angular rates stored in the file are "manufactured" by MSOPCK 
     program using an assumption that the spacecraft was rotating at a 
     constant rate between each two orientations specified by neighbor 
     quaternions. 
 
 
Approximate Time Coverage
--------------------------------------------------------
 
     This file is a type 3 CK file (segment) which provides linear
     interpolation between orientation data points extracted from
     telemetry. Such interpolation is not applied to the whole coverage of
     the file (segment) but only inside intervals where enough orientation
     telemetry data was available and orientation data points were close to
     each other in time for such interpolation to make sense.
 
     A table containing the complete list of valid interpolation intervals
     in the file is provided at the end of these comments.
 
     The start time and stop time of the total coverage for every segment
     in the file are given in the header of the intervals table for that
     segment.
 
 
Usage Note
--------------------------------------------------------
 
     In order to use this file a GNS SCLK file, containing coefficients
     mapping GNS on-board time to ET, and standard LSK file, providing UTC
     to ET mapping, must be loaded into a user's program.
 
 
Contacts
--------------------------------------------------------
 
     If you have any question regarding this data contact NAIF at JPL:
 
        Boris V. Semenov
        (818)-354-8136
        boris.semenov\@jpl.nasa.gov

EndOfCOMMENTSText
   
      close( COMMENTS ) || die "ERROR: $scriptname: cannot close '$cmtfile'.\n";

      #
      #  And finally run MSOPCK.
      #
      $result = `$msopck $msopfile $hdffile $ckfile 2>&1`;
      $status = ( $? >> 8 );

      if ( $status ) {
      
         #
         #  MSOPCK failed. Report error messages and die.
         #
         die "ERROR: $scriptname: $msopck failed. Messages were:\n\n".
             "$result\n";

      } else {

         #
         #  MSOPCK succeeded. Report about it.
         #
         print "$ckfile -- CK ".
               "file -- was created successfully.\n";
       
      }

   }

} else {
   die "ERROR: $scriptname: internal bug -- \$edrformat value '$edrformat' ".
       "is not allowed.\n";
}

#
#  All done.
#
exit;
