#!/usr/local/bin/perl -w # # ============================================================================ # SL - 10/98 # athena2eic.pl - converts athena files (WHOI ship files) to electronic # index cards (EIC). Ported from athena2dsl.pl # # Usage: athena2eic.pl <-i infile> [-o outfile] [-e e_fields] [-O type] # te_fields format: attr1=value1&att2=value2...\n"; # # Description: Reads through input dir and converts files with specified # pattern to eic type files. # # Assumptions: Athena data files consist of the following: # Header # Blank line # Data Description # Blank line # data # # JSECONDS,CDATE,CTIME will be in data # Note: Currently use CDATA,CTIME (could use JSECONDS in future) # There's no data before JSECONDS,CDATE,CTIME # Assume ID's are as defined in the next few lines $JSECONDS_ID = "001"; $CDATE_ID = "002"; $CTIME_ID = "003"; # Time is monotonically increasing # Data within records are *NOT* space delimited - will replace # spaces with commas. (comma separated records are OK, # but may need to be handled specially for plots - subfields) # Data within records are *NOT* ; delimited - as above, # will replace with commas. # Modification date of each of the files is consistant with the # range of timestamps in each of the files. This information # is used to generate links for mostrecent.dsl and # mostrecent.index.dsl # # History: # # Who Date Description # --- -------- ------------------------------------------------- # SL 05/27/97 Create # ARM 05/29/97 Add code to convert only if infile modtime > outfile # modtime. # ARM 05/29/97 Add code to create links to most recent files in outdir. # SL 06/01/97 Convert lat/long of *specific* id's to format GMT can read. # These are stored as additional subfields w/in ID. Currently # convert 080 - GPSPC_TP, 045 GPS_TP. # SL 10/05/98 Ported to convert to EIC & simplified somewhat - only # does one file at a time. Version 1.0 # SL 12/18/98 Fixed lat/lon conversion bug # ============================================================================ # # Example Athena Datafile; # #R/V ATLANTIS DATA LOG - 1 minute log file #Primary Data File (ASCII) #04/01/97 04:43:27 #Julian Seconds = 13079162607 #ATHENA V5.1 # #001| JSECONDS Date & time (Julian seconds) #002| CDATE Computer date #003| CTIME Computer time #011| GYRO Ship's heading (Gyro syncro) #024| SSCND Sea surface conductivity (mmho/cm) #025| SSTMP Sea surface temperature (C) #080| GPSPC_TP GPS P-Code time & position #082| GPSPC_CG GPS P-Code course over ground #083| GPSPC_SG GPS P-Code speed over ground # #001| 13079162620 #002| 04/01/97 #003| 04:43:40 #011| 170.2,T #024| +00.5055 #025| +23.2636 #080| 044334.716,2825.3768,N,07632.0692,W,3 #082| 162.9,T #083| 010.1,N # # EIC Format (ASCII attribute-value pairs, deliminated) # Standard EIC fields begin with EIC. # sample Format: # EIC.id=867253174.53880&EIC.ver=v1&EIC.mod=Wed Jun 25 15:39:34 UTC 1997& # EIC.title=Title&EIC.auth=&EIC.poc=&EIC.desc=&EIC.key=&EIC.cat=& # EIC.subj=&EIC.time=1964/06/26 00:00:00& # EIC.lat=41.51&EIC.lon=-70.66&EIC.msl=-851.0&EIC.info=url&EIC.data=url& # EIC.image=&EIC.icon=&EIC.cmts=& ... User fields &EIC.end=867253174.53880 # ########################################################################## require "getopts.pl"; require "ctime.pl"; require "flush.pl"; $VERSION = "v1.0"; print "\n$0 - $VERSION\n"; &Getopts('i:o:p:t:O:e:'); #Parse args and set defaults if not specified if ($opt_i ne "") {$infile = $opt_i;} else {$infile = "";} if ($opt_o ne "") {$outfile = $opt_o;} else {$outfile = "$infile.eic";} if ($opt_e ne "") {$e_fields = $opt_e;} else {$e_fields = "";} if ($opt_O ne "") {$output_type = $opt_O;} else {$output_type = "ascii";} if ($output_type eq "html") {print "Content-type: text/html\n\n"; print "\n"; print ""; print "
";
	 }

# Quick sanity check
if ($infile eq "")
    {print "Usage: $0 <-i infile> [-o outfile] [-e e_fields] [-O type]\n";
     print "\te_fields format: attr1=value1&att2=value2...\n";
     exit;
     }

if (!open(IN,"$infile"))
    {print "Unable to open infile - $infile \n";
     exit;
     }
if (!open(OUT,">$outfile"))
    {print "Unable to open outfile - $outfile \n";
     exit;
     }

###TEMP write index file [index info is included in card as well]
#print "Generating index file: $outfile.index ... ";
#open(OUT_IND,">$outfile.index");

# read header and then index info (use blank line as sentinel)
# Do header first
while ($line = )
       {#print OUT_IND "# $line";
        chomp($line);
        $line =~ s/\cM//g; #elim ctrl_m embedded in header
        push(@header_list,$line);
	if ($line =~ /(\d*)\/(\d*)\/(\d*)(\s*)(\d*)\:(\d*)\:(\d*)/)
	  {$line =~ tr/ / /s;
	   ($date,$time) = split(/ /,$line);
	   ($mm,$dd,$yy) = split("/",$date);
	   #make year 4-digit - quick hack works since current date
	   #note: will fail in year 2098!
	   if (length($yy) == 2 && $yy >= 98) {$yy += 1900;}
					 else {$yy += 2000;}
           $timestamp = "$yy/$mm/$dd $time";
	   }
        last if (length($line) < 3); #assume blank line
        }

#Index info here - keep track of first ID after CTIME as well as last id
undef %id_name;
$first_id = "";
while ($line = )
       {$line =~ s/\r\n$/\n/; chop($line);
        last if (length($line) < 3);
        ($id,$desc) = split(/\| /,$line);
	($name) = split(" ",$desc);
	$id_name{$id} = "$name";
	$id_desc{$id} = "$desc";
	push(@id_list,$id);
	next if ($id le $CTIME_ID);
        if ($first_id eq "") {$first_id = $id;}
#       print OUT_IND "$id - $desc\n";
       }

close($OUT_IND);
$last_id = $id; #keep track of last id type

#Generate one EIC for index info 
$Card_Id = time;
$random = int(rand(100) * 1000.0);
$C_ID = "$Card_Id.$random";
$C_Ver = 1.0;
$curr_time = &ctime(time); chop($curr_time);
$C_Mod = $curr_time;
$C_Title = "Athena Index";
$C_Cat = "athena_index";
$C_time = $timestamp;
print OUT "EIC.id=$C_ID&EIC.ver=$C_Ver&EIC.mod=$C_Mod&";
print OUT "EIC.title=$C_Title&";
print OUT "EIC.time=$C_time&EIC.cat=$C_Cat&";
flush(OUT);
$hcnt=0;
foreach $hdr (@header_list)
  {$hcnt++;
   print OUT "hdr_$hcnt=$hdr&";
   }
foreach $id (@id_list)
   {print OUT "id-$id=$id_desc{$id}&";
    }
print OUT "EIC.end=$C_ID\n";


# convert to EIC format - add id, ver, mod, title, auth, poc, desc
# key, cat, subj, reformat date, add time, and reformat lat/long
print "\nGenerating card file: $outfile...";
print "\n    First_id is $first_id, last id is $last_id\n";

#parse records & generate cards...
$cnt = 0;
while ($line = )
 	{$line =~ s/\r\n$/\n/; chop($line);
	 ($id,$data) = split(/\| /,$line);
         # parse out date/time- currently use CDATE/CTIME
	 # Could use JSECONDS in the future...
	 if ($id eq "$JSECONDS_ID") 
	    {$jseconds = "$data";
             #convert jsec to date & time...
	     }
	 if ($id eq "$CDATE_ID") 
	    {($mm,$dd,$yy) = split("/",$data);
	     #make year 4-digit - quick hack works since current date
	     #note: will fail in year 2098!
	     if (length($yy) == 2 && $yy >= 98) {$yy += 1900;}
					   else {$yy += 2000;}
             $date = "$yy/$mm/$dd";
	     }
	 if ($id eq "$CTIME_ID") {$time = $data;}
         next if ($id lt $first_id);
         if ($id eq $first_id)
	    {# Generate standard eic fields for new record
	     $Card_Id = time;
	     $random = int(rand(100) * 1000.0);
	     $C_ID = "$Card_Id.$random";
	     $C_Ver = 1.0;
             $curr_time = &ctime(time);
             chop($curr_time);
	     $C_Mod = $curr_time;
	     $C_Title = "Athena Data";
	     $C_Cat = "athena_data";
	     print OUT "EIC.id=$C_ID&EIC.ver=$C_Ver&EIC.mod=$C_Mod&";
	     print OUT "EIC.title=$C_Title&";
	     print OUT "EIC.time=$date $time&EIC.cat=$C_Cat&";
	     }
	 #If no data, or slash, or "bad val"[TBD], set to null
         if (length($data) == 0 || $data eq "-") {$data = "NULL"};
	
	 #Get rid of any & for EIC format - in future escape & w/ \nnn
	 $data =~ s/&/ /g;
	  
	 #=====================================================================
	 #### Hacked to get lat/long of specific id's to EIC.lat,EIC.lon
	 #### Previously used ID numbers (080,045,...), as these are not 
	 #### consistent between datasets now use names (eg; GPS_GGA)
	 #### Names may not be consistent as well. Give-up  could use
	 #### either. For clarity, names are preferred and thus used.
	 ####  Note: 080/045 have same format, same with 011/014
	 ####
	 $name = $id_name{$id};
	 $recognized_names = "|GPSPC_TP|GPS_GGA|GPS_GTA|GPS_TT|";
	 if ($data ne "NULL" && $recognized_names =~ /\|$name\|/ )
	   {if ($name eq "GSPC_TP")
	      {#String: time,ddmm.mmmm,N|S,dddmm.mmmm,E|W,N
	       #044334.716,2825.3768,N,07632.0692,W,3
		($dummy,$lat,$latdir,$lon,$londir) = split(",",$data);
		}
	    elsif ($name eq "GPS_GGA" || $name eq "GPS_GTA" || 
                   $name eq "GPS_TT")
	      {#String: label,time,ddmm.mmmm,N|S,dddmm.mmmm,E|W,N
	       #eg: $GPGGA,024949.083,1415.4427,S,11328.0826,W,3...
		($dummy,$dummy2,$lat,$latdir,$lon,$londir) = split(",",$data);
		}
	    $lat_deg = int($lat/100.0);
	    $lat_min = $lat - $lat_deg * 100.0;
	    $c_lat   = $lat_deg + $lat_min/60.0;
	    $lon_deg = int($lon/100.0);
	    $lon_min = $lon - $lon_deg * 100.0;
	    $c_lon   = $lon_deg + $lon_min/60.0;
	    if ($latdir eq "S") {$lat *= -1.0;}
	    if ($londir eq "W") {$lon *= -1.0;}
	    print OUT "EIC.lat=$c_lat&EIC.lon=$c_lon&EIC.elev=0&";
	    }
	 print OUT "$id_name{$id}=$data&";
 	 if ($id eq $last_id) 
	    {if ($e_fields ne "") {print OUT "$e_fields&";}
	     print OUT "EIC.end=$C_ID\n";
	     $cnt++;
	     }
         }
 print "\n--- Done: $cnt EICs generated ---\n";
 

if ($output_type eq "html")
	{print "
"; print ""; } exit;