#! /usr/local/bin/perl # # Read in a VIF file, find all samples, write out HTML form whose # action is to load selected records into an ODBC connected database # that resides on shore. # # I've tried to make sense out of what each function does by passing some # input and getting some output, but dealing with returning multiple # hashes passed by reference with typeglobs (See P. 117 in the Camel # book) is something I didn't want to do, so %SampHTMLRows & %SampPipes # are global lists. # # Mike McCann # (c) MBARI 11 March 1998 # # $Id: VIF2staging,v 1.15 1998/12/14 19:01:06 vicki Exp $ use POSIX; use CGI; use Carp; use File::Basename; # # Constants, sort of # $Sbase = 'http://ariel.mbari.org/~vicki/samplesDB'; # Home for samples .html $FGbase = 'http://mww.mbari.org/Ventana/stills'; # Shore-side Ventana grabs $action = 'http://dbweb1.mbari.org/samplesDB/loads/loadcoll.asp'; $ARCHIVEdir = '/hosts/barnacle/ARCHIVE'; chop($thishost = `hostname`); # # Parse the command line to get name of vif file, use it to get name # of timecode file, and later nav file. # $vif_file = parse_cmd_ln(); # # Save standard output to a log file for the record # open(STDOUT, "| tee $html_dir/$vif_file.log"); select STDOUT; $| = 1; # # Read through all of .vif file, marry tape timecode with epoch secs # in .tc file and return global lists (HTML & CSV) of sample events. # print "\nParsing VIF file $vif_file...\n\n"; parse_ANNOTATE($vif_file); # Fills in %SampHTMLRows & %SampPipes if ($count == 0) { print "No annotated samples in this VIF, exiting.\n"; exit -1; } # # Now create web form for selecting records that will be loaded into # shore-side samples database # print "\nCreating html file ...\n"; write_html($vif_file); # # Need to make symbolic link here on ariel so that images will # appear on web page # print "\nMaking symlink on ariel for images to work in samplesDB web pages ...\n"; system("remsh ariel \"cd /usr/people/vicki/Ventana/stills/$yyyy; ln -s /usr/people/vicki/$yyyyddd $ddd\""); print "\nDone creating staging database of $count samples.\n"; print "\nStarting netscape to browse URL \n\n\t$Sbase/${html_file}...\n\n"; system("netscape -geometry =1024x768 $Sbase/${html_file} &"); # ---------------------------- Subroutines --------------------------- # # Parse Command line sub parse_cmd_ln { if ($#ARGV < 0) { # Need at least 1 args die "\nUsage: $0 [html_directory]\n\n$0 extracts all the sampled-by events from the specified .vif file \nand creates a .html file in the specified html directory where the \nsamples can be printed and loaded into the samples database.\n\n"; } my $invif = basename($ARGV[0], '\.vif'); die "$invif does not exist.\n\n" unless -f $invif; die "Please supply a non-zero sized .vif file.\n\n" unless -s $invif; $html_dir = $ARGV[1] || '/hosts/ariel/usr/people/vicki/mbari_html/samplesDB'; $cur_dir = `pwd`; $whoami = `whoami`; return ($invif); } # # Parse ANNOTATE line. This function is specific to looking for # information in the VIF file that pertains to samples. It stupidly # collects information between ANNOTATE blocks and saves it for # printout before begining the next ANNOTATE block. # It returns a hash of sample events keyed by Tape timecode. sub parse_ANNOTATE { local ($invif) = @_; my $verbose = 0; my $null = ''; my ($d1, $d2); # Dummy vars for the split below. my $tcode; open(VIF, "< $invif"); open(ERR, "> $invif.err"); # Where to put clutter # # Read in Tape Timecode - Epoch seconds lookup file # read_timecodelookup($invif); # # Read in ship nav file # read_shipnavlogr("${yyyyddd}shipnavlogr.dat") || read_archivenav("${yyyyddd}") || print "Could not find nav file to read.\n"; $count = 0; $GotSample = 0; while ( ) { s/\r//g; # Remove carriage returns if vif comes from DOS s/\n//g; # Remove newlines (better than chop?) if (/^ANNOTATE/) { # Begining of block # If we have a sample then build its string if ($GotSample) { ConstructSampleString($concept,$tc,$im,$id,$in,$es,$eq,$was_eq); } undef $im; # May not have image for annotation with sample undef $id; # Clear Sample # } # # Pick off info we want # if (/^CONCEPT\s*(.+)$/) { $concept = $1; $concept =~ s/-1$//; }; if (/^PROPERTY self recorded timecode\s*(.+)$/) { $tc = $1; }; if (/^PROPERTY self still-image.* file (.+)$/) { $im = $1; $im_old = $im; }; if (/^PROPERTY self identity reference (.+)$/) { $id = $1; }; if (/^PROPERTY self interpreter user-name (.+)$/) { $in = $1; }; if (/^PROPERTY self interpreted time-unix (.+)$/) { $es = $1; }; if (/^PROPERTY self sampled-by equipment-1 (.+)$/) { $GotSample = 1; $sampleconcept = $concept; $eq = $1; $eq =~ s/-1$//; # # Special fix requested by Jenny P. to flatten all names for # a manipulator to manipulator-1 # if ($eq eq "dongo" || $eq eq "donk" || $eq eq "mongo" || $eq eq "schilling") { $was_eq = $eq; $eq = 'manipulator'; } else { $was_eq = ""; } } } # End while ( ) # Just in case the last ANNOTATE was a sample ConstructSampleString($concept,$tc,$im,$id,$in,$es,$eq,$was_eq) if ($GotSample); } # End of parse_ANNOTATE() # # Build pipe separated string to be passed to load step as hidden var sub ConstructSampleString { local($concept,$tc,$im,$id,$in,$es,$eq,$was_eq) = @_; if ($tc =~ /99:99:99:99/) { print "\n*** Can't process $concept sample with timecode of 99:99:99:99 ***\n\n"; return; } my ($hr,$mn, $se, $fr) = split(':',$tc); my $t = $hr + $mn / 60 + $se / 3600 + $fr / (3600 *30); $count++; # # Look up epoch seconds in timecode-esecs file. May not need to # do this if we have PROPERTY interpreted time-unix ($es). # Construct date_time string that SQL likes # $esecs = findUTC($t,$tc); $datetime = POSIX::strftime("%m/%d/%y %r", gmtime($esecs)); $StartDate = POSIX::strftime("%m/%d/%y", gmtime($esecs)) if $count == 1; # # Look up location for this time $esecs. # ($lat, $lon, $depth, $Lmsg) = findLocation($esecs); ##$depth = -9999.99 unless $depth =~ /\d+/; # # Check for existence of Frame Grab and whether it is from this ANNOTATION # add message to comment field # my $Imsg = ""; ##print "\nConstructSampleString(): im_old=", $im_old, "\nim=", $im, "\n"; if ($im_old && ! $im) { # No image for this ann. use previous one $Imsg = "Frame Grab not from this annotation;"; $im = $im_old; print "$im:\n$Imsg\n"; } # # Add location time mismatch warning to comment field # $cmt = "$Lmsg $Imsg"; $SampHTMLRows{$tc} = image_cell($im,$Imsg) . "\n" . time_cell($esecs) . "\n" . location_cell($depth,$lat,$lon,$warn) . "\n" . vickivims_cell($sampleconcept,$eq,$id,$was_eq) . "\n" . comment_cell($cmt); print "Done building SampHTMLRows.\n"; # # These are the actual column names of the ODBC table that we # load, they get passed to the load step in the 'action' page # @CollectionEventCols = ( "CollectionEventID", "FrameGrabImageURL", "TapeTimeCode", "EpochSeconds", "CollectionEventDTG", "Interpreter", "CollectionVIMSConcept", "Equipment", "CollectionRefName", "CollectionGroupID", "Latitude", "Longitude", "Depth" ); # # These pipe separated values must correspond exactly # to the order and values of the CollectionEventTable # in the shore-side sample DB. Comments are passed separately # in the comment_cell() # $SampPipes{$tc} = "$null|$imgsrc|$tc|$esecs|"; $SampPipes{$tc} .= "$datetime|$in|$sampleconcept|"; $SampPipes{$tc} .= "$eq|$id|$null|"; $SampPipes{$tc} .= "$lat|$lon|$depth|$null"; # Need null @ end (?) $GotSample = 0; # Reset index on new ANN $was_eq = ""; } # End sub ConstructSampleString() # # Write HTML subroutine. Creates form for loading selected samples # into database. sub write_html { local ($vfile) = @_; my ($a, $b) = split(/\./, $vfile); # Force {pv,wt} to be uppercase $vfile = (uc $a) . "." . $b; $html_file = $vfile; $html_file =~ s/\.vif/\.html/; $html_file_long = "$html_dir/$html_file"; print "write_html(): Opening $html_file_long...\n"; open(HTML, ">$html_file_long") || die "Cannot open $html_file_long: $!"; $form = new CGI; print HTML $form->start_html(-title=>"Samples to load from $vfile", -author=>'mccann@mbari.org', -BGCOLOR=>'white'); print HTML "

Shipboard Samples Staging Database "; print HTML "parsed from $vfile

\n"; print HTML $form->startform(POST,$action),"\n"; print HTML ""; print HTML "

1. Information common to all samples on this form

\n"; print HTML "\n"; print HTML "\n"; print HTML "\n"; print HTML "\n"; print HTML "\n"; print HTML "\n"; print HTML "
\n"; print HTML " Chief Scientist:\n"; print HTML $form->textfield('ChiefScientist','',15,30), "
"; print HTML "
\n"; print HTML " Ship:\n"; print HTML $form->popup_menu('Ship', ['Point Lobos','Western Flyer'], 'Point Lobos'); print HTML "
\n"; print HTML " Collector:\n"; print HTML $form->textfield('Collector','',15,30), "
"; print HTML "
\n"; print HTML " ROV:\n"; print HTML $form->popup_menu('ROV', ['Ventana','Tiburon'], 'Ventana'), "
"; print HTML "
\n"; ##print HTML "*\n"; print HTML " DiveNumber(s):\n"; print HTML $form->textfield('DiveName','',20,30); print HTML "\n"; ##print HTML "*\n"; print HTML " Waypoint(s):\n"; print HTML $form->textfield('WaypointName','',20,30); print HTML "
\n"; print HTML $form->hidden("StartDTG", $StartDate); print HTML "

2. Information about each sample

\n"; print HTML "\n"; print HTML ""; print HTML "\n"; print HTML "\n"; print HTML "\n"; # # Send DataBase Column names as hidden variable # foreach $dbcol (@CollectionEventCols) { print HTML $form->hidden("DBCOLS", $dbcol), "\n"; } # # Loop thru all samples print a table row for each. Pass PSV as hidden # variables that are keyed to the checkbox names. # foreach $sample (sort keys %SampHTMLRows) { print HTML "\n"; print HTML $SampHTMLRows{$sample}; # Rest of the row print HTML $form->hidden("SAMPLES", $SampPipes{$sample}); print HTML "\n"; } print HTML "
Check one box per sampleImageTimeLocationVicki/VIMSComments"; print HTML "
255 characters maximum\n"; print HTML "
\n

\n"; print HTML< Please mark the samples that were successfully collected, write in corrections or additions on this sheet, and give it to Jenny.

Location information is picked up from 1) nav processor log files or 2) processed shore-side ARCHIVE nav files. If the time match with the nav file is greater than 60 seconds away then a # is placed next to the values. Missing items will have a * next to them. Advanced VICKI users: you may change the equipment and add a sample number by adding properties to the concept. To recreate this page (if a new .vif file was created or new nav data are available) then re-run the script with this command as user $whoami on host $thishost:

	cd $cur_dir
	$0 $ARGV[0] $ARGV[1]
EOH print HTML $form->submit('action','Load Database'); print HTML " (Restricted to MBARI's sample coordinator)\n"; print HTML $form->endform; $now = localtime($^T); print HTML "

$Sbase/$html_file\n · " unless $ARGV[1]; print HTML "Processing log file

\n"; print HTML "
\n

\nWritten by $0: $now\n"; print HTML $form->end_html; close HTML; print "write_html(): Done writing html file.\n"; } # End of write_html() # # Construct Image cell. If on ship use saved URL, if on land, use Intranet # URL sub image_cell { local ($im, $msg) = @_; my $td; $FGbase =~ s/Ventana/Tiburon/ if $vif_file =~ /wt/i; $yr = substr($im, 0, 4); # Get JPEG image $da = substr($im, 4, 3); # that's on Intranet $jim = $im; $jim =~ s/.+\///; $jim =~ s/rgb/jpg/; $jim =~ s/:/%3a/g; $imgsrc = "${FGbase}/${yr}/${da}/${jim}"; my $pg_img = $imgsrc; $pg_img =~ s/mww/ariel/ if $vif_file =~ /pv/i; # So that ship can see it $pg_img =~ s/mww/beroe/ if $vif_file =~ /wt/i; # So that ship can see it ##MPM $pg_img = $imgsrc unless test_url($pg_img); # To handle old images that # have been removed. $pg_img = $imgsrc if $yr < 1998; # I know these have been removed. if ( $im ) { $td = "\n\n"; if ($msg) { $td .= "#
"; } $td .= ""; $td .= ""; } else { $td = "\n\n"; $td .= missing() . " No Image\n"; } return $td; } # # Construct Time cell. Tape TC, Date, Time, Epoch secs ... sub time_cell { local $esecs = $_[0]; my $td = "\n"; $td .= missing() unless $tc; $td .= "Timecode: $tc
"; $td .= missing() unless $esecs; $td .= "Local: ".POSIX::strftime("%D-%T", localtime($esecs))."
"; $td .= missing() unless $esecs; $td .= "GMT: ".POSIX::strftime("%D-%T", gmtime($esecs))."
"; $td .= missing() unless $esecs; $td .= "Epoch: $esecs
"; $td .= missing() unless $es; $td .= "Ann. time: $es "; $td .= "\n"; return $td; } # # Construct Location cell. Depth, Lat, Lon, (Easting, Northing ?) sub location_cell { local ($depth, $lat, $lon, $warn) = @_; my $td = ""; $td .= missing() unless $depth; $td .= "Depth: $depth m
"; $td .= missing() unless $lat; $td .= "Latitude: $lat
"; $td .= missing() unless $lon; $td .= "Longitude: $lon
"; $td .= "$warn" if $warn; $td .= "\n"; return $td; } # # Construct Vicki/VIMS cell. sub vickivims_cell { local ($concept, $eq, $id, $was_eq) = @_; my $td = ""; $td .= missing() unless $concept; $td .= "Concept: $concept
"; $td .= missing() unless $eq; $td .= "Equipment: $eq
"; $td .= "(was $was_eq)
" if $was_eq; $td .= missing() unless $id; $td .= "Sample#: $id
"; $td .= "\n"; return $td; } # # Construct to be filled in comment cell. sub comment_cell { local $comment = $_[0]; my $td = ""; $td .= "\n"; return $td; } # # Look up epoch seconds from .tc file sub findUTC() { my($t,$tc) = @_; my $verbose = 1; print "\nfindUTC(): \nLooking for tape timecode $tc ($t hr)\n" if $verbose; # # Do binary search on Timecode list to find record of closest time # #$tol = 1.4e-4; # Hope to find record within 1/2 second $tol = 1.7e-3; # Hope to find record within 6 seconds $Niter = 30; # Maximum number of iterations for search $a = 0; $b = $#timecode; my $i; for ($i = 0; $i < $Niter; $i++) { # See Burden & Faires $p = int($a + ($b - $a) / 2); # Bisection algorithm 2.1 print "$i: $t , $timecode[$p]\n"; if (abs($t - $timecode[$p]) < $tol) { print "Found time $timecode[$p] at index $p that matches tape timecode $t after $i iterations: "; print sprintf("%.2f",abs($timecode[$p] - $t) * 3600), " seconds difference. \n" if $verbose; last; } else { if ($t - $timecode[$p] > 0) { $a = $p; } else { $b = $p; } } } # # Linear interpolate if inside # if ( $i == $Niter && $p != 0 && $p != $#timecode ) { print "$Niter iterations reached. Linearly interpolating to get epoch seconds.\n"; print "p = $p\n"; print "Esecs: $Esecs[$p+1], $Esecs[$p]\n"; print "timecode: $timecode[$p+1], $timecode[$p]\n"; print "t = $t\n"; if ( ($timecode[$p+1] - $timecode[$p]) == 0 ) { print "Yikes! Can't interpolate. Would divide by zero.\n"; return; } return int ( ($Esecs[$p+1] - $Esecs[$p]) * ($t - $timecode[$p]) / ($timecode[$p+1] - $timecode[$p]) + $Esecs[$p] ); } # # Warning messages # print ERR "*** Warning: timecode time is ", ($timecode[$p] - $t) * 3600, " seconds away from Sample time. ***\n" if $i == $Niter; print ERR "*** Sample time of $t precedes start of ROV nav. ***\n" if $t < $timecode[0]; print ERR "*** Sample time of $t exceeds end of ROV nav. ***\n" if $t > $timecode[$#timecode]; ##print "Found epoch seconds $Esecs[$p]\n"; return $Esecs[$p]; } # End findUTC() # # Look up position from logged ship nav file. This depends on subroutine # read_shipnavlogr() being called beforehand sub findLocation() { my($t) = @_; my $verbose = 1; print "\nfindLocation(): \nLooking for epoch secs $t ...\n" if $verbose; # # Do binary search on Timecode list to find record of closest time # $tol = 6; # Hope to find record within 6 seconds $Niter = 100; # Maximum number of iterations for search $a = 0; $b = $#ROVusecs; my $i; for ($i = 0; $i < $Niter; $i++) { # See Burden & Faires $p = int($a + ($b - $a) / 2); # Bisection algorithm 2.1 ##print "findLocation(): $t - $ROVusecs[$p]\n"; if (abs($t - $ROVusecs[$p]) < $tol) { print "Found time $ROVusecs[$p] after $i iterations.\n" if $verbose; last; } else { if ($t - $ROVusecs[$p] > 0) { $a = $p; } else { $b = $p; } } } # # Warning messages, in case image times don't match with nav records # my $warning = ''; if ($i == $Niter) { print "*** Warning: Position time is ", ($ROVusecs[$p] - $t), " seconds away from Sample time. ***\n"; $warning = "Location time exceeds sample time by "; $warning .= $ROVusecs[$p] - $t." seconds;"; } print "*** Sample time of $t precedes start of ROV nav. ***\n" if $t < $ROVusecs[0]; print "*** Sample time of $t exceeds end of ROV nav. ***\n" if $t > $ROVusecs[$#ROVusecs]; print " >>> p = $p: "; print "lat, lon, depth = $ROVlat[$p], $ROVlon[$p], $ROVdepth[$p]\n"; return ($ROVlat[$p], $ROVlon[$p], $ROVdepth[$p], $warning); } # End findLocation() # # HTML for a missing field that will prevent DB loading sub missing() { return " * "; } sub read_timecodelookup() { local $invif = $_[0]; # Logic is in here to check first for videologr file, which # we started making on 1998120, then for RS20 Best file, then # lastly for the backup .tc file that lives in current dir or # on lepas. # Get year & year-day from name of .vif file $yyyyddd = substr($invif, 0, 7); $yyyy = substr($yyyyddd,0,4); $ddd = substr($yyyyddd,4,3); # Set shipname for use in directory structure $ship = 'ptlo' if $invif =~ /pv/i; $ship = 'wfly' if $invif =~ /wt/i; # # Set timecode lookup filename in order of preference # # 1. -pllogger file local on lobos # 2. -Archived pllogger file, available on shore the next day # 3. -Backup timecode logging that ran for a while on lobos # 4. -Best camera log file (ugly implementation...) $tc_file = "/users/pllogger/data/${yyyyddd}videologr.dat"; $tc_file = "/users/pllogger/data/${yyyyddd}videologr.dat.gz" unless -f $tc_file; $tc_file = "${ARCHIVEdir}/logger/$yyyy/$ship/${yyyyddd}videologr.dat.gz" unless -f $tc_file; # # We have none of the above. Look for backup log file # if ( ! -f $tc_file ) { if ($invif =~ /pv/i) { $tc_file = "${yyyyddd}PVx.tc"; $tc_file = "/hosts/lepas/frameGrabs/Ventana/stills/$yyyy/$ddd/${yyyyddd}PVx.tc" unless -f $tc_file; $tc_file = "/hosts/lepas/frameGrabs/Ventana/stills/$yyyy/$ddd/${yyyyddd}PVx.tc.gz" unless -f $tc_file; } if ($invif =~ /wt/i) { $tc_file = "${yyyyddd}WT.tc"; $tc_file = "/hosts/lepas/frameGrabs/Tiburon/stills/$yyyy/$ddd/" . $tc_file unless -f $tc_file; } } ## -Save for later- $tc_file = "/hosts/lepas/web/internal/cruises/lobos/camlog/best${yyyy}/${yyyy}-${ddd}.log"; if ( ! -f $tc_file ) { print <) { if ($tc_file =~ /\.tc/) { ($esec, $tcode) = split('\s+',$_); } elsif ($tc_file =~ /videologr\.dat/ ) { next if /^#/; ($esec, $d1, $d2, $tcode) = split(',',$_); ##print "$n: $Esecs[$n], $tcode\n"; } next if $tcode =~ /99:99:99:99/; next if $tcode =~ /NO_PROV/; next if $tcode =~ /00:00:00:00/; # Shouldn't be seeing after # tape starts! $n++; $Esecs[$n] = $esec; my ($hr,$mn, $se, $fr) = split(':',$tcode); # Timecode array in units of hours $timecode[$n] = $hr + $mn / 60 + $se / 3600 + $fr / (3600 *30); ##print "n = $n, timecode = $timecode[$n]\n"; # Test for monotony if ($timecode[$n] < $timecode_old) { print "*** Warning, tape timecode reset at index $n ***\n"; print "\t", $n - 1, ": $tcode_old\n"; print "\t", $n, ": $tcode\n"; if ($n < 5) { # Sometimes get bogey as 1st line print "Beginning of file, not yet collecting for timecode array lookup.\n\n"; $timecode_old = $timecode[$n]; $tcode_old = $tcode; $n--; next; } print "Cannot guarantee correct matching to Nav info.\n"; print "*** May need to hand process sampleDB entries ***\n\n"; $rewind_check++; } else { $rewind_check = 0; } $timecode_old = $timecode[$n]; $tcode_old = $tcode; if ($rewind_check > 10 ) { print "<< Looks like someone is rewinding the tape. <<\n"; print "<< Stopping load of timecode data. <<\n\n"; $#timecode = $#timecode - 5; # Change index $#Esecs = $#Esecs - 5; last; } } # End while () } #--------- Courtesy of Debbie & Holly via processWfNav.pl ---------- #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ # Read the realtime ship nav logger file #////////////////////////////////////////////////////////////////////////////// sub read_shipnavlogr() { local $wrkFile = $_[0]; my $inWater = 0; my $logLine = -1; my $colUsec = -1; my $colShipLat = -1; my $colShipLon = -1; my $colQual = -1; my $colMode = -1; my $colRovLat = -1; my $colRovLon = -1; my $colPres = -1; my $colHead = -1; my $colAlti = -1; my $colPitch = -1; my $colRoll = -1; my $colGyro = -1; my $n = 0; #-------------------------------------------------------------------------- # Open the intput file #-------------------------------------------------------------------------- #$wrkFile = '1998010shipnavlogr.dat.gz' unless $wrkFile; # Testing if ($thishost eq 'lobos') { $wrkFile = '/users/pllogger/data/'.$wrkFile; print "read_shipnavlogr(): hostname = $thishost, \nsetting wrkFile = $wrkFile.\n"; $np_rov = 'VENTANA'; # Nav Processor name $np_ship = 'PT_LOBOS'; # Nav Processor name } elsif ($thishost eq 'shelf') { $wrkFile = '/users/wflogger/data/'.$wrkFile; $np_rov = 'TIBURON'; # Nav Processor name $np_ship = 'WESTERN_FLYER'; # Nav Processor name } # For postprocessing on calypso elsif ($thishost eq 'calypso') { # Use archivenav, signal that by returning with 0 return 0; } else { $wrkFile = '/users/pllogger/data/'.$wrkFile; print "read_shipnavlogr(): hostname = $thishost, assuming testing:\n"; print "\tsetting wrkFile = $wrkFile.\n"; print "\tsetting np_rov = VENTANA.\n"; print "\tsetting np_ship = PT_LOBOS.\n"; $np_rov = 'VENTANA'; # Nav Processor name- Testing $np_ship = 'PT_LOBOS'; # Nav Processor name- Testing } # # Check if uncompressed file exists, if not then look for gzipped one # if (-f $wrkFile) { print "read_shipnavlogr(): Opening $wrkFile\n"; open (WRK, "$wrkFile") or return 0; } elsif ( -f "$wrkFile.gz" ) { print "read_shipnavlogr(): Opening $wrkFile.gz\n"; open (WRK, "gzcat $wrkFile | ") or return 0; } elsif ( -f "$wrkFile.Z" ) { print "read_shipnavlogr(): Opening $wrkFile.Z\n"; open (WRK, "zcat $wrkFile | ") or return 0; } else { print "read_shipnavlogr(): Can't find $wrkFile\{.gz,.Z\}\n"; return 0; print "After return. Failed on trying to open $wrkFile\n"; } #-------------------------------------------------------------------------- # read in each line and process #-------------------------------------------------------------------------- while () { $line = $_; if ($line =~ /^#/) { s/^\s+//; @field = split('\s+'); ##print "field: ", join(" ", @field), "\n"; if ($field[0] =~ /^#CONST/) { # -- Check to see if the vehicle is in the water -- if ($field[1] eq "$np_rov.VEHICLE.IN_WATER") { @timVal = split /,/,$field[2]; $inWater = $timVal[1]; } } # End if ($field[0] =~ /^#CONST/) if ($field[0] =~ /^#LOG/) { # -- Figure out which column items are reported in -- $logLine++; ##print "logLine, field[1] = $logLine, $field[1]\n"; ##print "test = $np_ship.GPS.TIME\n\n"; if ($field[1] eq "LOGHOST.SYSTEM.UTC") { $colUsec = $logLine; } elsif ($field[1] eq "$np_ship.GPS.LATITUDE") { $colShipLat = $logLine; } elsif ($field[1] eq "$np_ship.GPS.LONGITUDE") { $colShipLon = $logLine; } elsif ($field[1] eq "$np_ship.GPS.PDOP") { $colQual = $logLine; } elsif ($field[1] eq "$np_ship.GPS.DIFFERENTIAL") { $colMode = $logLine; } elsif ($field[1] eq "$np_rov.POSITION.LATITUDE" || $field[1] eq "$np_rov.LATITUDE" ) { $colRovLat = $logLine; } elsif ($field[1] eq "$np_rov.POSITION.LONGITUDE" || $field[1] eq "$np_rov.LONGITUDE") { $colRovLon = $logLine; } elsif ($field[1] eq "$np_rov.SENSOR_IBC.PRESSURE" || $field[1] eq "$np_rov.DEPTH") { $colPres = $logLine; } elsif ($field[1] eq "$np_rov.SENSOR.COMPASS.DEGREES") { $colHead = $logLine; } elsif ($field[1] eq "$np_rov.SENSOR.ALTITUDE.METERS") { $colAlti = $logLine; } elsif ($field[1] eq "$np_rov.SENSOR.PITCH.DEGREES") { $colPitch = $logLine; } elsif ($field[1] eq "$np_rov.SENSOR.ROLL.DEGREES") { $colRoll = $logLine; } elsif ($field[1] eq "$np_ship.GYRO.DEGREES") { $colGyro = $logLine; } } } else { # -- An actual data line s/^\s+//; @field = split(','); if ( $colRovLat<0 || $colRovLon<0 || $colPres<0 || $colUsec<0) { print "read_shipnavlogr(): Error, log record indices not set\n"; print "colRovLat = $colRovLat, colRovLon = $colRovLon, "; print "colPres = $colPres, colUsec = $colUsec\n"; croak; } $ROVlat[$n] = $field[$colRovLat]; $ROVlon[$n] = $field[$colRovLon]; # All data logged with {pl,wf}logger pgm saves pres. not depth my $pres = $field[$colPres]; $ROVdepth[$n] = sprintf("%.1f", calcDepth($pres, $ROVlat[$n])); $ROVusecs[$n] = $field[$colUsec]; $n++; $logLine = -1; } } close (WRK); print "read_shipnavlogr(): n = $n records read \n"; return $n; } #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ # Read the Archived ROV nav file # Does check based on home name to see which marlin directory & file to read. #////////////////////////////////////////////////////////////////////////////// sub read_archivenav() { local $yyyyddd = $_[0]; my $yyyy = substr($yyyyddd,0,4); my $yy = substr($yyyyddd,2,2); my $ddd = substr($yyyyddd,4,3); #-------------------------------------------------------------------------- # Open the nav file #-------------------------------------------------------------------------- ##die "$thishost"; if ($thishost eq 'lobos') { $rov = 'vnta'; } elsif ($thishost eq 'shelf') { $rov = 'tibr'; } elsif ($thishost eq 'calypso') { $rov = 'vnta' if $vif_file =~ /PV/i; $rov = 'tibr' if $vif_file =~ /WT/i; } else { print "read_archivenav(): hostname = $thishost, assuming test mode:\n"; print "\tsetting rov = vnta.\n"; $rov = 'vnta'; # - Testing } $wrkFile = "$ARCHIVEdir/nav/$yyyy/$rov/nav${yyyyddd}vnta.txt"; $wrkFile = "/hosts/nautilus/ARCHIVE/nav/$yyyy/$rov/nav${yy}${ddd}vnta0" if $yyyy < 1998; # # Check if uncompressed file exists, if not then look for gzipped one # if (-f $wrkFile) { print "read_archivenav(): \nOpening $wrkFile\n"; open (WRK, "$wrkFile") or return 0; } else { print "read_archivenav(): No ARCHIVE rov nav file for this .vif file\n"; print "Failed on trying to open $wrkFile\n"; return 0; } my $colRovLat = 4; my $colRovLon = 5; my $colPres = 8; my $colDepth = 8; my $colUsec = 3; my $n = 0; #-------------------------------------------------------------------------- # read in each line and process #-------------------------------------------------------------------------- while () { s/^\s+//; next unless /^\d/; # -- An actual data line s/^\s+//; # Remove any leading white space $ROVlat[$n] = $field[$colRovLat]; $ROVlon[$n] = $field[$colRovLon]; $ROVusecs[$n] = $field[$colUsec]; if ($yyyy < 1998) { # Meters not Pressure @field = split('\s+'); $ROVdepth[$n] = $field[$colDepth]; } else { # Press. not Meters starting in 1998 @field = split(','); my $pres = $field[$colPres]; $ROVdepth[$n] = sprintf("%.1f", calcDepth($pres,$ROVlat[$n])); } $n++; } close (WRK); print "read_archivenav(): n = $n records read \n"; return $n; } # End read_archivenav() sub test_url { # Return 1 (yes the url exists) unless we get a '404' local $url = $_[0]; $lynx = 'lynx'; print "Testing for $url...\n"; open(LYNX, "$lynx -source $url |"); while () { return 0 if /404/; } print "done.\n"; return 1; } # End test_url() sub calcDepth { ## /** from Paul Rogers ## ## /************************ ## function: calcDepth ## Depth in meters ## ## Ref: Saunders & Fofnoff, DSR, 23, 109-111 (1976) ## ## Variables : ## P - pressure in dbars (not SI) ## L - latitude in degrees ## ## ************************/ ($P, $L) = @_; my $PI = 3.1415926; $deg2rad = $PI/180; $phi = $L * $deg2rad; $sinPhi = sin( $phi ); $sin2Phi = sin( 2*$phi ); $a0 = 5.3024e-3; $a1 = -5.9e-6; $g0 = 978.0318 * (1 + $a0 * $sinPhi * $sinPhi + $a1 * $sin2Phi * $sin2Phi); $c1 = 0.712953; $c2 = 1.113e-7; $c3 = -3.434e-12; $c4 = 14190.7; $c5 = 1.83e-5; $gv = 0.5 * 2.226e-4; $depth = 1000 * (($c1 + ($c2 + $c3 * $P) * $P) * $P + $c4 * log(1+$c5 * $P))/($g0 + $gv * $P); return $depth; }