#!/opt/local/bin/perl -w # ngoes2engr --Reads the NOPPS GOES data and write lines to separate files # Hacked version of simpletube1b.pl and simpletube3b, June 1998 # USAGE: ngoes2engr [datafile calfile ALL_dir_path] # (DAT_dir_path is hardwired). # # # - Active buoys are specified in ProcHeader.pl # Patch 98-08-19 ENGR bufs can be length 15 or 21. Handled in read and proc. # Version 3.0 98/08/26 GCT - Writes dat files to hardwired dat dir. # Version 3.0b 98/08/28 GCT - Data header expanded to 5 lines # Version 3.0c 98/08/31 GCT - Read puts badHexFill for non-ASCII and proc replaces with badDataVal. # Version 3.0d 98/09/04 GCT - Use GOES time if NOPP time bad, in read. # Mins, secs come from GOES either way. # Version 3.0e 98/09/11 GCT - Write latest engr vals to .new files in ALL area. # (like a 1DY_ALL file). # Version 3.0f 98/09/12 GCT - CURRENTS no longer in transmissions -> removed. # Adding checksum to engr. # Removed skin temp. # sst2 is now at end of raw temp buffer, # move to after sst1 in processing stage. # ssc2 is now between CONDS and PRESSURES. # Move to after SSC1 in processing stage. # Version 3.0g 98/09/22 GCT - Kludged things to work with duplicate sensors. # Added arg is senstype (eg RNA or RNB for RAIN). # Using GoesCalNew instead of GoesCal. # Version 3.0h 98/09/28 GCT - Getting the LW rad by adding the case radiation # term. The first term should be negative. # Version 3.0j 98/10/19 GCT - Changed time_stamp to top of hour # (in processing stage--raw time still in dat files). #-----built in packages---# #use strict; use Carp; use File::Basename; use FileHandle; #----home brew packages---# #use lib 'DISK2:[atlasrt.prog.taoperl]'; #use lib '/home/summer/franzen/prldir'; #use lib '/home/corona/nopp/bin/pl/PM'; #use GoesCal; #use JulianTime; # Still haven't figured out this 'compile time' thingy with the uses. require ( "/home/corona/nopp/.profileNopp.pl" ); #--Defines nopp_lib require ( $nopp_lib . "ProcHeader.pl" ); use lib '/home/corona/nopp/NOPP/lib'; #--Don't like this line; want next two like above--# use GoesCalNew; use JulianTime; #-----BOGUS to suppress output----# my $dum = $nopp_lib; $dum = $stage1; $dum = scalar ( @active_ids ); $dum = $cronpath; #-------------------------# use vars qw($badDecFill $badHexFill $binFlag $vmsflag %nwords %increm %goeswords %goestypes); $badDecFill = -9.99; #$badHexFill = q/!bad/; $hexpat = '[0-9a-fA-F]'; $badHexFill = 'Z'; $badDataVal = 0; %nwords = ('RAD '=>4,'RAIN'=>1,'MET '=>3,'ARG '=>16); %increm = ('RAD '=>120,'RAIN'=>60,'MET '=>600,'ARG '=>86400); if ($^O eq 'VMS') { $vmsflag = 1; require VMS::FileSpec } else { $vmsflag = 0 } # Correct value for COND is 52 %goeswords = ('OPS '=>30,'MET '=>31,'RAD '=>52,'TEMP'=>76,'COND'=>53,'ENGR'=>15); %goestypes = (30=>'OPS ',31=>'MET ',52=>'RAD ',76=>'TEMP',53=>'COND',15=>'ENGR'); MAIN:{ my ($datafname, $calfname, $outpath, $dname, $dsuffix); my ($start_of_data); my $headerInfo_ref; #--Need to do something with this. # my $platform_id = "1403C31C"; my $platform_id; # Input data hash - note that each key has 4 characters - trailing space my $dh_in = { 'HEAD'=>[], 'POS '=>[], 'OPS '=>[], 'MET '=>[], 'RAD '=>[], 'RAIN'=>[], 'TEMP'=>[], 'COND'=>[], 'ENGR'=>[],}; my $dh_out = { 'HEAD'=>[], 'POS '=>[], 'OPS '=>[], 'MET '=>[], 'RAD '=>[], 'RAIN'=>[], 'TEMP'=>[], 'COND'=>[], 'ENGR'=>[],}; my $dh_dat = { 'HEAD'=>[], 'POS '=>[], 'OPS '=>[], 'MET '=>[], 'RAD '=>[], 'RAIN'=>[], 'TEMP'=>[], 'COND'=>[], 'ENGR'=>[],}; #-----organize files and filenames------- $n2engrlogfile = $cronpath . "ngoes2engr.log"; #-- Open logfile open LOGFILE, ">>".$n2engrlogfile or die "ERROR ($0): Could not open logfile $n2engrlogfile.\n"; print LOGFILE "\n#\n#\n$0 run at local time " . localtime( time ) . "\n\n"; #--Opening of files should occurr within the subroutines, not in main--# unless ($datafname = $ARGV[0]){ print STDOUT "Enter path and name of data file: "; $datafname = ; chomp $datafname; print LOGFILE "EXIT ($0): Unable to open datafile $datafname.\n"; close LOGFILE; die "no such file" unless -e $datafname; } print LOGFILE "Data file: $datafname.\n"; # my $datafh = new FileHandle($datafname); # unless ($datafh){ die "can't open $datafname: $!\n"}; # binmode $datafh if $binFlag; # GOES in ASCII - June 98 unless ($calfname = $ARGV[1]){ print STDOUT "Enter path and name of cal file: "; $calfname = ; chomp $calfname; unless ( -e $calfname ) { print LOGFILE "EXIT ($0): Calfile does not exist: $calfname.\n"; close LOGFILE; die "ERROR ($0): No such file: $calfname." ; } } my $calfh = new FileHandle($calfname); unless ($calfh){ print LOGFILE "EXIT ($0): Unable to open calfile: $calfname.\n"; close LOGFILE; die "ERROR ($0): Can't open $calfname: $!\n"; } print LOGFILE "Calfile: $calfname.\n"; # Path may or may not have the trailing slash unless (($outpath = $ARGV[2]) and (-d $outpath)){ print STDOUT "Enter directory for output files: "; chomp ($outpath = ); print "Outpath is $outpath\n"; print LOGFILE "EXIT ($0): Unable to open to use outpath $outpath.\n"; close LOGFILE; die "not a directory - " unless -d $outpath; } print LOGFILE "Output path: $outpath.\n"; $platform_id = infilename2platform_id ( $datafname ); unless ( $platform_id ) { print LOGFILE "EXIT ($0): $platform_id is not an active id.\n"; close LOGFILE; die "ERROR ($0): Data filename $datafname does not contain an active NOPP platform_id.\n"; } print LOGFILE "Ready to start reading data\n"; readGoesFile( $datafname, $dh_in, $platform_id ); print LOGFILE "Finished reading data, ready to write dat files.\n"; my $datpath = $stage1; write_dat( $platform_id, $datpath, $dh_in, $dh_dat ); process_Goesdata($calfname, $dh_dat, $dh_out); # $outpath = $stage2; write_all($platform_id, $outpath, $dh_out); close LOGFILE; exit; }; #------------------ End of main program ----------------------------------# #---------------------------------------------------------------------# # infilename2platform_id --search infilename for active ids. # Return active id if found or 0 if not found #---------------------------------------------------------------------# sub infilename2platform_id{ # use strict; my ( $buoycode, $platform_id ) ; my ( $infilename ) = @_; $platform_id = 0; foreach $buoycode ( @active_ids ){ if ( $infilename =~ $buoycode ) { $platform_id = $buoycode; last; } } return $platform_id; } #-----------------------------------------------------------------# # readGoesFile --read ASCII encoded hex values from input file and # push each buffer into appropriate buffer-array #-----------------------------------------------------------------# sub readGoesFile{ use strict; use FileHandle; my ($infilename, $dh_in, $platform_id ) = @_; my %headerInfo = ( softversion => 0, serialnum => 0, numrecords => 0, ); # my ($start_of_header, $start_data); my ($line, $date, $numHexWords, $hexb, $numLines, @datelist); my ($mode, $datatype, $type, $prevmode); my (@rain_loc, @rad_loc, @met1_loc, @arg_loc); # my $hexpat = '[0-9a-fA-F]{4}'; my ($data_ref, $error_flag, $reset_flag); my $pos; my $linecount; my $Ndatatrans; my ($datalen, $arrsize); my $olddatalen = 0; my $fh = new FileHandle; my $start_of_header = 0; my $start_data = 0; my $channel_string = "NN082"; #-----# #--These two should go into a header--# #--Note that the RAD buffer is split into a RAIN and a RAD buffer--# my @rawbuftype = ('HEAD', 'POS ', 'OPS ', 'MET ', 'RAIN', 'RAD ', 'TEMP', 'COND', 'ENGR', 'EXTR'); #--New engr = 15 + 12 + 4, old = 15--# my %rawbuflen = ('HEAD'=>37, 'POS '=>34, 'OPS '=>30, 'MET '=>31, 'RAIN'=>20, 'RAD '=>32, 'TEMP'=>72, 'COND'=>52, 'ENGR'=>15, 'EXTR'=>16,); my $txdatelen = 10; # Pat's TX time CCYYMMDDHH, eg., 1998073122 # my $gultimelen = 11; # Goes Uplink time from sat, YYJJJHHMMSS, eg., 98212223805 # my ($data, $Ntrans, $expected_len, $rawdatatype, $fsize, $tt, $currbuflen, $currbuf); my ($currTX, $currTXlen, $start, $txdate, $nptxdate, $gultime); #--Determine expected length of TX--# $expected_len = 0; foreach $rawdatatype ( @rawbuftype ){ $expected_len += $rawbuflen{$rawdatatype}; } #--Read Infile--# print LOGFILE "Ready to open data file\n"; open INFILE, "<".$infilename or die "FATAL ERROR ($0): Unable to open input file $infilename\n"; $fsize = (-s $infilename); print LOGFILE "fsize is $fsize, ready to read file\n"; # read INFILE, $data, $fsize*1000; !!!! read INFILE, $data, $fsize; print LOGFILE "Ready to close infile.\n"; close INFILE; print LOGFILE "Reading finished, ready to parse\n"; #--Parse infile--# $_ = $data . " ENDOFLINE "; s/$platform_id/ ENDOFLINE $platform_id/g; #--Store all TXes into an array--# my @data = (); push @data, /($platform_id\d.+?) ENDOFLINE /sg; print LOGFILE "finished parsing into array\n"; #--Check size of input data--# $Ntrans = $#data; if ( $Ntrans < 0 ) { print "WARNING ($0): No data found in file $infilename.\n"; } print LOGFILE "Found " .( $Ntrans + 1 ). " TXes in file $infilename.\n"; # print "Found " .( $Ntrans + 1 ). " TXes in file $infilename.\n"; #--Parse TXes into buffers and push those into appropriate arrays for ( $tt = 0; $tt <= $Ntrans; ++$tt ){ $currTX = $data[$tt]; #--Write goofed TXes to an errs file--# if ( $currTX =~ /MISSING/ ) { print LOGFILE "\n"; print LOGFILE $currTX; next; } if ( $currTX =~ /MESSAGE/ ) { print LOGFILE "\n"; print LOGFILE $currTX; next; } #--Patch for some testing stuff --# #-- Bail on TXes that just have non-standard position (look for slash / )--# if ( $currTX =~ /\// ) { print LOGFILE "\n"; print LOGFILE $currTX; next; } #--Patch for engr in transition-- -> remove the extra_len --# if ( length($currTX) < ( $expected_len - $rawbuflen{'EXTR'} ) ) { print LOGFILE "WARNING ($0): Incomplete TX:\n$currTX\n---END OF INCOMPLETE TX----\n"; # next; } #--Remove all carriage-returns, DOS newlines, and leading spaces $currTX =~ s/\n//g; $currTX =~ s/\r//g; $currTX =~ s/^\s*//g; #--Get the TXtime from buoy, and uplink time from GOES (should be the same!)--# $start = $rawbuflen{"HEAD"}; $nptxdate = unpack "x$start a$txdatelen", $currTX; $start = length ( $platform_id ); $gultime = unpack "x$start a$gultimelen", $currTX; #--Handle time inconsistencies here--# my $tmptime = goes_time2nptx_time ( $gultime ); if ( ( $nptxdate =~ /\D/ ) || ( $tmptime != $nptxdate ) ) { print LOGFILE "Using time $tmptime from GOES. Raw GOES is $gultime, and Nopptime is $nptxdate.\n"; $txdate = $tmptime; } else { $txdate = $nptxdate; } #----Get minutes and seconds from GOES time, convert to New Atlas fmt, YYYYDDDHHMMSS my $txtime = nptx_time2timestr( $txdate, $gultime ); $txtime = timestr2jdstr($txtime); $txtime = jdstr2newatlas($txtime); #--Parse TX and push buffers into arrays--# $currTXlen = length ( $currTX ); $start = 0; my $fullTX = 0; my $spotSST = ""; #--Step through expected buffers in sequence--# foreach $rawdatatype ( @rawbuftype ) { $currbuflen = $rawbuflen{$rawdatatype}; if ( ( $start + $currbuflen ) <= $currTXlen ) { $currbuf = unpack "x$start a$currbuflen", $currTX; $start += $currbuflen; #--Look for non-ASCII characters - subsitute with badHexFill --# my $hexpat = '[0-9a-fA-F]'; if ( ( $rawdatatype ne 'HEAD' ) && ( $rawdatatype ne 'POS ' ) ) { unless ( $currbuf =~ m/^($hexpat)*$/o ) { $currbuf =~ s/(\W)/$badHexFill/g; # $currbuf =~ tr/$hexpat/$badHexFill/c; print LOGFILE "Bad Buffer:\n"; print LOGFILE "$txtime $rawdatatype $currbuf.\n"; } } #-- (look for non-ASCII in HEAD and POS --# if ( ( $rawdatatype eq 'HEAD' ) || ( $rawdatatype eq 'POS ' ) ) { unless ( $currbuf =~ m/[0-9a-zA-Z ]/o ) { $currbuf =~ s/(\W)/$badHexFill/g; print LOGFILE "Bad Buffer:\n"; print LOGFILE "$txtime $rawdatatype $currbuf.\n"; } } #--Copy spot SST from OPS into TEMP on successive iterations--# if ( $rawdatatype eq 'OPS ') { my $spotSSTlen = 8; my $spotSSTstart = $currbuflen - $spotSSTlen; $spotSST = unpack "x$spotSSTstart a$spotSSTlen", $currbuf; } if ( $rawdatatype eq 'TEMP') { $currbuf .= $spotSST } #-- Patch for transition stage of ENGR buffer of two different lengths #--When ready, remove this block and change the ENGR buflen from old to new if ( $rawdatatype eq 'EXTR') { #--Copy ENGR co1,va1,sp1,co2,va2,sp2 into MET. my ( $wind_stuff, $checksum ) = unpack "a12 a4", $currbuf; my $index = $#{$dh_in->{'MET '}}; $dh_in->{'MET '}[$index] .= $wind_stuff; #--Copy ENGR co1,va1,sp1,co2,va2,sp2 and checksum into ENGR. $index = $#{$dh_in->{'ENGR'}}; $dh_in->{'ENGR'}[$index] .= $currbuf; } #--Push this buffer into approprate array--# unless ( $rawdatatype eq 'EXTR') { push (@{$dh_in->{$rawdatatype}}, "$txtime $currbuf"); } # print "$rawdatatype $txtime $currbuf.\n"; } else { last; #--Skip remaining buffers for this TX--# } $fullTX = 1; } } } #-----------------------------------------------------------------# # process_Goesdata --read a calfile and process raw data #-----------------------------------------------------------------# sub process_Goesdata{ use strict; use FileHandle; my ($calfname, $dh_in, $dh_out) = @_; my %headerInfo = ( softversion => 0, serialnum => 0, numrecords => 0, ); my $type; my $Tdone = 0; my $cal = Calibrate -> new($calfname) or die "Can't get calibration object: $!"; # No header in Goes data yet my ($caltube) = ($cal->{DEPLOYMENT}{tube} =~ m/(\d*)/); my $tube = $caltube; unless ($tube == $caltube){ print LOGFILE "Tube number from data file ($tube)"; print LOGFILE "does not match tube number ($caltube) from $calfname\n"; die "Tube number from data file ($tube) does not match tube number ($caltube) from $calfname\n"; } # Change the time stamp from TX_time to end_of_averaging_interval, # (hour:min:sec) -> 00:00:00 foreach $type ( keys %{$dh_in} ){ for ( my $i = 0; $i <= $#{$dh_in->{$type}}; ++$i ) { my $line = $dh_in->{$type}[$i]; chomp($line); my ($time, $databuf) = split (/\s+/, $line, 2); my $new_time = newatlas2topofhour( $time ); #print "Old = $time, new = $new_time\n"; $line = sprintf ("%s %s", $new_time, $databuf ); $dh_in->{$type}[$i] = $line; } } # Process each buffer in the data hash # Input is raw space-delimited hex values, # with raw TXtime prepended to the data. (YYYYMMDDHH) # Output is engineering units in space-delimited float values, # with TXtime in a different format. (YYYYJJJHH) # # Make sure that Temps are done before Conductivities foreach $type (keys %{$dh_in}) { # print "Type is $type.\n"; if ($type eq 'HEAD') { process_goeshead($dh_in, $dh_out, $type, $cal); } elsif ($type eq 'POS ') { process_goespos($dh_in, $dh_out, $type, $cal); } elsif ($type eq 'OPS ') { process_goesops($dh_in, $dh_out, $type, $cal); } elsif ($type eq 'MET ') { process_goesmet($dh_in, $dh_out, $type, $cal); } elsif ($type eq 'RAIN') { process_goesrain($dh_in, $dh_out, $type, $cal); } elsif ($type eq 'RAD ') { process_goesrad($dh_in, $dh_out, $type, $cal); } elsif ($type eq 'TEMP') { if (not $Tdone){ process_goestemp($dh_in, $dh_out, $type, $cal); $Tdone = 1; } } elsif ($type eq 'COND') { if (not $Tdone){ my $T_type = 'TEMP'; process_goestemp($dh_in, $dh_out, $T_type, $cal); $Tdone = 1; } process_goescond($dh_in, $dh_out, $type, $cal); } elsif ($type eq 'CURR') { process_goescurr($dh_in, $dh_out, $type, $cal); } elsif ($type eq 'ENGR') { process_goesengr($dh_in, $dh_out, $type, $cal); } else { # die "data type $type is unknown!\n" # print "This TX has an unknown type:\n"; print LOGFILE "WARNING ($0): This buffer is an unknown type: $type. NOT PROCESSED.\n"; # print "$dh_in\n"; # next; } } } #-------------------------# # process_goeshead #-------------------------# sub process_goeshead{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; my ($len, $line, $i); my $type; for (my $i = 0; $i<= $#{$dh_in->{$datatype}}; ++$i){ $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, @data) = split (/\s+/, $line); # Write output with space-delimited values $line = sprintf ("%s %s", $txtime, join(' ', @data) ); $dh_out->{$datatype}[$i] = $line; # print "Modified hash value is $dh_out->{$datatype}[$i]\n"; } } #-------------------------# # process_goespos #-------------------------# sub process_goespos{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; my ($len, $data, $line, $txtime, $i); my $type; for (my $i = 0; $i<= $#{$dh_in->{$datatype}}; ++$i){ $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, $nopp_time, $lon, $lonmin_str, $lat, $latmin_str) = split (/\s+/, $line); # Only processing here is to convert buoy time format to julian day # Much more needed: speed,dir, etc. Steal from Atlas stuff. # Modify write routine if this changes. # (Flat or Round earth coordinate system.) # Overwrite data buffer with space-delimited floats print $txtime."\t"; print $nopp_time."\t"; print $lon."\t"; print $lonmin_str."\t"; print $lat."\t"; print $latmin_str."\n";; $line = sprintf ("%s %s %s %s %s %s", $txtime, $nopp_time, $lon, $lonmin_str, $lat, $latmin_str); $dh_out->{$datatype}[$i] = $line; # print "Modified hash value is $dh_out->{$datatype}[$i]\n"; } } #-------------------------# # process_goesops - similar to goesmet #-------------------------# sub process_goesops{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; my ($line, $len); my $metval = 0; # printf $outfh "%15s%8s%8s% 8s%8s %8s%8s\n", qw(DATE U V SPEED DIR AIRT HUM); # printf $outfh "%15s%8s%8s% 8s%8s %8s%8s\n", "", qw( -4 -4 -4 -4 -3 -3); for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, @data) = split (/\s+/, $line); my ( $at1, $at2, $rh1, $rh2, $u1, $v1, $u2, $v2, $sst1, $sst2 ); #-- Look for bad data if necessary --# for ( my $jj = 0; $jj < ( scalar @data ); ++$jj) { if ( ( $data[$jj] =~ $badHexFill ) || ( $data[$jj] !~ /^($hexpat)*$/ ) ) { $data[$jj] = $badDataVal; } } #--Get raw values for signed quantities ( undef, undef, undef, undef, $u1, $v1, $u2, $v2, undef, undef ) = @data; #--Get decimal values for unsigned quantities ( $at1, $at2, $rh1, $rh2, undef, undef, undef, undef, $sst1, $sst2 ) = map ( hex, @data ); # Winds are 9 bits encoded into ASCII - leading char (0 or 1) represents sign # Should still work if expanded to 12 bits (eg, 14f -> 74f or f4f) my @winds = ($u1, $v1, $u2, $v2); my $bad_raw_value = "7FF"; my $bogus_raw_value = 5000; if ( ( $u1 eq $bad_raw_value ) && ( $v1 eq $bad_raw_value ) && ( $u2 eq $bad_raw_value ) && ( $v2 eq $bad_raw_value ) ) { # Force the failure to occurr in the calibrate routine for (my $j = 0; $j <= $#winds; ++$j){ $winds[$j] = $bogus_raw_value; } } else { for (my $j = 0; $j <= $#winds; ++$j){ my $windsign = unpack "axx", $winds[$j]; my $windval = unpack "xa2", $winds[$j]; if ($windsign){ $windval = hex(unpack "h2", ~(pack "h2", $windval)); $windval = -(++$windval); } else { $windval = hex($windval); } $winds[$j] = $windval; } } ($u1, $v1, $u2, $v2) = @winds; # print "Signed winds are $u1 $v1 $u2 $v2\n"; # This in klunky until we decide what to do with this GOES format # Write both sets of values to the same buffer - split in the writing # Write data a space-delimited floats my ($uw_r, $vw_r, $speed_r, $dir_r) = $cal->calwind($u1, $v1, "WNDA"); if ($dir_r == -9.99 ) { $dir_r = -99.9; } my $airt_r = $cal->calair( $at1, "ATA" ); # my $rh_r = $cal->calrh( $rh1, "RH" ); my $rh_r = $cal->calrh( $rh1, "RHA" ); # my $sst_r = $cal->caltemp( $sst1, "SST" ); my $sst_r = $cal->caltemp( $sst1, "T1" ); #--Write space-delimited float values to output hash $line = sprintf ("%s %.2f %.2f %.2f %.2f %.2f %.2f %.1f", $txtime, $airt_r, $rh_r, $sst_r, $uw_r, $vw_r, $speed_r, $dir_r); ($uw_r, $vw_r, $speed_r, $dir_r) = $cal->calwind($u2, $v2, "WNDB"); if ($dir_r == -9.99 ) { $dir_r = -99.9; } $airt_r = $cal->calair( $at2, "ATB" ); $rh_r = $cal->calrh( $rh2, "RHB" ); # $sst_r = $cal->caltemp( $sst2, "SST" ); $sst_r = $cal->caltemp( $sst2, "T2" ); # Patch to fix the RMY wind sensor which may have been mounted at the wrong orientation if ( $speed_r > -0.1 ) { my $pi = 3.141592654; my $rmy_offset = 62.2; # degrees $dir_r += $rmy_offset; if ( $dir_r > 360 ) { $dir_r -= 360.0; } my $psi = $dir_r * $pi / 180.0; $uw_r = $speed_r * sin ( $psi ); $vw_r = $speed_r * cos ( $psi ); } $line .= sprintf (" %.2f %.2f %.2f %.2f %.2f %.2f %.1f\n", $airt_r, $rh_r, $sst_r, $uw_r, $vw_r, $speed_r, $dir_r); $dh_out->{$datatype}[$i] = $line; # print "Mod ops[$i] is $dh_out->{$datatype}[$i]\n"; } } #-------------------------# # process_goesmet #-------------------------# sub process_goesmet{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; my ($line, $len); my $metval = 0; my $temptype = "SST"; my ( $co1, $va1, $sp1, $co2, $va2, $sp2 ); # $co1 = $va1 = $sp1 = $co2 = $va2 = $sp2 = 0; my ( $at1, $at2, $rh1, $rh2, $u1, $v1, $u2, $v2, $bp1, $bp2, $bp3); for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, @data) = split (/\s+/, $line); #-- Look for bad data if necessary --# for ( my $jj = 0; $jj < ( scalar @data ); ++$jj) { if ( ( $data[$jj] =~ $badHexFill ) || ( $data[$jj] !~ /^($hexpat)*$/ ) ) { $data[$jj] = $badDataVal; } } #--Get raw values for signed quantities ( undef, undef, undef, undef, $u1, $v1, $u2, $v2, undef, undef, undef, undef, undef, undef, undef, undef, undef ) = @data; #--Get decimal values for unsigned quantities ( $at1, $at2, $rh1, $rh2, undef, undef, undef, undef, $bp1, $bp2, $bp3, $co1, $va1, $sp1, $co2, $va2, $sp2 ) = map ( hex, @data ); # Winds are 9 bits encoded into ASCII - leading char (0 or 1) represents sign # Should still work if expanded to 12 bits (eg, 14f -> 74f or f4f) my @winds = ($u1, $v1, $u2, $v2); my $bad_raw_value = "7FF"; my $bogus_raw_value = 5000; if ( ( $u1 eq $bad_raw_value ) && ( $v1 eq $bad_raw_value ) && ( $u2 eq $bad_raw_value ) && ( $v2 eq $bad_raw_value ) ) { # Force the failure to occurr in the calibrate routine for (my $j = 0; $j <= $#winds; ++$j){ $winds[$j] = $bogus_raw_value; } } else { for (my $j = 0; $j <= $#winds; ++$j){ my $windsign = unpack "axx", $winds[$j]; my $windval = unpack "xa2", $winds[$j]; if ($windsign){ $windval = hex(unpack "h2", ~(pack "h2", $windval)); $windval = -(++$windval); } else { $windval = hex($windval); } $winds[$j] = $windval; } } ($u1, $v1, $u2, $v2) = @winds; # print "Signed winds are $u1 $v1 $u2 $v2\n"; # This in klunky until we decide what to do with this GOES format # Write both sets of values to the same buffer - split in the writing # Write data a space-delimited floats my ($uw_r, $vw_r, $speed_r, $dir_r) = $cal->calwind($u1, $v1, "WNDA"); if ($dir_r == -9.99 ) { $dir_r = -99.9; } my $airt_r = $cal->calair( $at1, "ATA" ); my $rh_r = $cal->calrh( $rh1, "RHA" ); $line = sprintf ("%s %.2f %.2f %.2f %.2f %.2f %.1f", $txtime, $airt_r, $rh_r, $uw_r, $vw_r, $speed_r, $dir_r); ($uw_r, $vw_r, $speed_r, $dir_r) = $cal->calwind($u2, $v2, "WNDB"); if ($dir_r == -9.99 ) { $dir_r = -99.9; } $airt_r = $cal->calair( $at2, "ATB" ); $rh_r = $cal->calrh( $rh2, "RHB" ); $bp1_r = $cal->calap( $bp1 ); $bp2_r = $cal->calap( $bp2 ); $bp3_r = $cal->calap( $bp3 ); # Patch to fix the RMY wind sensor which may have been mounted at the wrong orientation if ( $speed_r > -0.1 ) { my $pi = 3.141592654; my $rmy_offset = 62.2; # degrees $dir_r += $rmy_offset; if ( $dir_r > 360 ) { $dir_r -= 360.0; } my $psi = $dir_r * $pi / 180.0; $uw_r = $speed_r * sin ( $psi ); $vw_r = $speed_r * cos ( $psi ); } #--Write space-delimited floats to output hash $line .= sprintf (" %.2f %.2f %.2f %.2f %.2f %.1f %.1f %.1f %.1f", $airt_r, $rh_r, $uw_r, $vw_r, $speed_r, $dir_r, $bp1_r, $bp2_r, $bp3_r ); $line .= sprintf (" %.1f %.1f %.1f %.1f %.1f %.1f\n", $co1, $va1, $sp1, $co2, $va2, $sp2 ); $dh_out->{$datatype}[$i] = $line; my ( $bptime1, $bptime2, $bptime3 ) = get_bptimes( $txtime ); my $bptype = 'BP '; $line = $bptime1 . " " . $bp1_r; $line .= " ". $bptime2 . " " . $bp2_r; $line .= " ". $bptime3 . " " . $bp3_r; $dh_out->{$bptype}[$i] = $line; # print "Mod met[$i] is $dh_out->{$datatype}[$i]\n"; } } #-------------------------# # process_goesrain #-------------------------# sub process_goesrain{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; my ($len, $line); my $dumptype = "ARGOS"; # RAM or ARGOS for( my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i ) { $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, @data) = split (/\s+/, $line); #-- Look for bad data if necessary --# for ( my $jj = 0; $jj < ( scalar @data ); ++$jj) { if ( ( $data[$jj] =~ $badHexFill ) || ( $data[$jj] !~ /^($hexpat)*$/ ) ) { $data[$jj] = $badDataVal; } } # Convert hex values to decimal @data = map ( hex, @data ); my ( $rainav1, $rainsd1, $rainfrac1, $rainav2, $rainsd2, $rainfrac2 ) = @data; my $senstype = "RNA"; my $rain_r1 = $cal->calrain( $rainav1, $dumptype, $senstype ); my $rainstd_r1 = $cal->calrain( $rainsd1, $dumptype, $senstype ); $senstype = "RNB"; my $rain_r2 = $cal->calrain( $rainav2, $dumptype, $senstype ); my $rainstd_r2 = $cal->calrain( $rainsd2, $dumptype, $senstype ); #--Write space-delimited floats to output hash $line = sprintf ("%s %.2f %.2f %.2f %.2f %.2f %.2f\n", $txtime, $rain_r1, $rainstd_r1, $rainfrac1, $rain_r2, $rainstd_r2, $rainfrac2); $dh_out->{$datatype}[$i] = $line; # print "Final rain[$i] is $dh_out->{$datatype}[$i]\n"; } } #-------------------------# # process_goesrad #-------------------------# sub process_goesrad{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ my $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, @data) = split (/\s+/, $line); #-- Look for bad data if necessary --# for ( my $jj = 0; $jj < ( scalar @data ); ++$jj) { if ( ( $data[$jj] =~ $badHexFill ) || ( $data[$jj] !~ /^($hexpat)*$/ ) ) { $data[$jj] = $badDataVal; } } # Convert hex values to decimal @data = map ( hex, @data ); my ( $swavg, $swstd, $swmax, $lwavg, $lwstd, $lwmax, $lwr1, $lwr2 ) = @data; # $lwavg /= 120; # $lwstd /= 120; # $lwmax /= 120; # The raw values are expected to be negative for the LW. Since they # are not, I fix that down below. my $swavg_r = $cal->calrad ( $swavg, 'RADA' ); my $swstd_r = $cal->calrad ( $swstd, 'RADA' ); my $swmax_r = $cal->calrad ( $swmax, 'RADA' ); my $lwavg_r = $cal->calrad ( $lwavg, 'RADB' ); my $lwstd_r = $cal->calrad ( $lwstd, 'RADB' ); my $lwmax_r = $cal->calrad ( $lwmax, 'RADB' ); # Add the radiation from the case temperature. # Temp is from a standard algorithm, except for the counts2resistance. # LWT1 is T_case and TWT2 is T_dome, I think. Usually the same. # A0, A1 from Alex, c1,c2,c3 from Tom Kirk at Eppley. my $a0 = 0.0034277; my $a1 = 0.015339; $lwr1 = $lwr1 * $a1 + $a0; $a0 = 0.0053287; $a1 = 0.015387; $lwr2 = $lwr2 * $a1 + $a0; $lwr1 *= 1000; # k-ohms to ohms $lwr2 *= 1000; # k-ohms to ohms # print "r1 is $lwr1, and r2 is $lwr2\n"; # Resistance to temp in Kelvin; uses natural logs. my $c1 = 1.0295E-03; my $c2 = 2.391E-04; my $c3 = 1.568E-07; my $ln10 = log(10); $lwt1 = 1.0 / ( $c1 + $c2 * log($lwr1) + $c3 * ( log($lwr1)**3 ) ); $lwt2 = 1.0 / ( $c1 + $c2 * log($lwr2) + $c3 * ( log($lwr2)**3 ) ); # print "t1 = $lwt1, and t2 = $lwt2\n"; # Case radiation term my $sigma = 5.6696E-08; my $case = $sigma * $lwt1 ** 4; $lwavg_r = -$lwavg_r; # $lwstd_r = -$lwstd_r; $lwmax_r = -$lwmax_r; $lwavg_r += $case; # $lwstd_r += $case; # No, doesn't apply to this one. $lwmax_r += $case; # print "Case is $case, sigma is $sigma.\n"; # Convert temps back to Celsius for more readability. my $kelvin_offset = 273.15; $lwt1 -= $kelvin_offset; $lwt2 -= $kelvin_offset; # Write space-delimited floats to output hash $line = sprintf ("%s %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n", $txtime, $swavg_r, $swstd_r, $swmax_r, $lwavg_r, $lwstd_r, $lwmax_r, $lwt1, $lwt2); $dh_out->{$datatype}[$i] = $line; # print "New rad[$i] is $dh_out->{$datatype}[$i]\n"; } } #-------------------------# # process_goestemp #-------------------------# sub process_goestemp{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; my $Ntemps = 16; my @t = (); my @t_r = (); my $temptype = "SST"; my $templabel = "T2"; # Bogus my $type; for (my $i = 0; $i<= $#{$dh_in->{$datatype}}; ++$i){ my $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, @data) = split (/\s+/, $line); #-- Look for bad data if necessary --# for ( my $jj = 0; $jj < ( scalar @data ); ++$jj) { if ( ( $data[$jj] =~ $badHexFill ) || ( $data[$jj] !~ /^($hexpat)*$/ ) ) { $data[$jj] = $badDataVal; } } # Convert hex values to decimal @data = map ( hex, @data ); # Assign values; do violence to the data array my $sst1 = shift @data; for ( my $jj = 0; $jj < $Ntemps; ++$jj ) { $t[$jj] = shift @data; } my $sst2 = shift @data; my $sst_ops1 = shift @data; my $sst_ops2 = shift @data; # Check number of temps if ( scalar @t != $Ntemps ) { print LOGFILE "Warning. Incorrect number of temps for time $txtime.\n"; print "WARNING ($0): Incorrect number of temps for time $txtime.\n"; } # Convert to engineering units # my $sst1_r = $cal->caltemp($sst1, $temptype); # my $sst2_r = $cal->caltemp($sst2, $temptype); # my $sst1_r = $cal->caltemp($sst1, "STA"); # my $sst2_r = $cal->caltemp($sst2, "STB"); # my $sst_ops1_r = $cal->caltemp($sst_ops1, $temptype); # my $sst_ops2_r = $cal->caltemp($sst_ops2, $temptype); my $sst1_r = $cal->caltemp($sst1, 'T1'); my $sst2_r = $cal->caltemp($sst2, 'T2'); my $sst_ops1_r = $cal->caltemp($sst_ops1, 'T1'); my $sst_ops2_r = $cal->caltemp($sst_ops2, 'T2'); for ( my $jj = 0; $jj < $Ntemps; ++$jj ) { $templabel = "T" . ( $jj+3 ); $t_r[$jj] = $cal->caltemp( $t[$jj], $templabel ); } # Write space-delimited floats to output hash $line = sprintf ("%s %.2f %.2f %.2f %.2f", $txtime, $sst1_r, $sst2_r, $sst_ops1_r, $sst_ops2_r); for ( my $jj = 0; $jj < $Ntemps; ++$jj ) { $line .= sprintf ( " %.2f", $t_r[$jj] ); } $line .= sprintf ( "\n" ); $dh_out->{$datatype}[$i] = $line; # print "Modified hash value is $dh_out->{$datatype}[$i]\n"; } } #-------------------------# # process_goescond #-------------------------# # The T-C-depth mapping needs to be done correctly using the CALfile. # sub process_goescond{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; my @c_r = (); my $Ncond = 8; my $Npres = 3; my $temptype = "SST"; my ($condlabel, $foundflag); # Bogus # This needs to come from the calfile # my @c_depth = ( 5, 10, 20, 40, 60, 80, 100, 140 ); my @c_depth = ( 6, 10, 20, 40, 60, 100, 140, 180 ); my @ssc_depth = ( 1, 2 ); my @sal = (); my @ss_sal = (); for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ my $line = $dh_in->{$datatype}[$i]; chomp($line); ($txtime, @data) = split (/\s+/, $line); #-- Look for bad data if necessary --# for ( my $jj = 0; $jj < ( scalar @data ); ++$jj) { if ( ( $data[$jj] =~ $badHexFill ) || ( $data[$jj] !~ /^($hexpat)*$/ ) ) { $data[$jj] = $badDataVal; } } # Convert hex values to decimal @data = map ( hex, @data ); # Patch: Reading COND out of sequence, assuming some mapping problems 98/10/03 -GCT # my ( $sc1, $c1, $c2, $c3, $c4, $c5, $c7, $c8, $c6, $sc2, $p1, $p2, $p3 ) = @data; my ( $sc1, $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $sc2, $p1, $p2, $p3 ) = @data; my @c = ( $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8 ); # Convert to engineering units # Get the reference temperatures from the corresponding depths # Start at expected place and search only if necessary. my $T_type = 'TEMP'; my $T_line = $dh_out->{$T_type}[$i]; # Check for time match if (! ($T_line =~ $txtime)){ $foundflag = 0; for (my $jj = 0; $jj <= $#{$dh_out->{$T_type}}; ++$jj){ $T_line = $dh_out->{$T_type}[$jj]; if ($T_line =~ $txtime){ $foundflag = 1; last; } } } else { $foundflag = 1; } if (! $foundflag){ # Write some errors to an error log and don't process cond. print LOGFILE "Can't find temperature data to process cond. for time $txtime\n"; print "WARNING ($0): Can't find temperature data to process cond. for time $txtime\n"; next; } # Force the temperatures instead of using the labels my ($T_time, $sst1_ref, $sst2_ref, $sst_spot1, $sst_spot2, @T_all) = split(/\s+/, $T_line); # my $sst1_ref = $T_all[0]; # my $sst2_ref = $T_all[1]; my @temp_ref = ($T_all[0], $T_all[1], $T_all[3], $T_all[5], $T_all[7], $T_all[9], $T_all[11], $T_all[12], $T_all[13], $T_all[14], $T_all[15]); my $sc1_r = $cal->calcond( $sc1, $sst1_ref, 'C1', $ssc_depth[0] ); my $sc2_r = $cal->calcond( $sc2, $sst2_ref, 'C2', $ssc_depth[1] ); $ss_sal[0] = $cal->_sal781( $sc1_r, $sst1_ref, $ssc_depth[0] ); $ss_sal[1] = $cal->_sal781( $sc2_r, $sst2_ref, $ssc_depth[0] ); for (my $jj = 0; $jj < $Ncond; ++$jj){ $condlabel = "C" . ($jj+3); # if ( $jj+3 == 8 ) { $condlabel = "C9"; } # if ( $jj+3 == 9 ) { $condlabel = "C10"; } $c_r[$jj] = $cal->calcond($c[$jj], $temp_ref[$jj], $condlabel, $c_depth[$jj]); $sal[$jj] = $cal->_sal781( $c_r[$jj], $temp_ref[$jj], $c_depth[$jj] ); # print "Calling calcond with $c[$jj], $temp_ref[$jj], $condlabel, $c_depth[$jj]\n"; # print "Calling calsal with $c_r[$jj], $temp_ref[$jj], $c_depth[$jj] .. $sal[$jj]\n"; } # This hardwired mapping could change also my $p1_r = $cal->calpres($p1, $temp_ref[$Ncond], 'P1'); my $p2_r = $cal->calpres($p2, $temp_ref[$Ncond+1], 'P2'); my $p3_r = $cal->calpres($p3, $temp_ref[$Ncond+2], 'P3'); # Write space-delimited floats to output hash $line = sprintf ("%s %.2f %.2f", $txtime, $sc1_r, $sc2_r); for (my $jj = 0; $jj < $Ncond; ++$jj){ $line .= sprintf (" %.2f", $c_r[$jj]); } $line .= sprintf (" %.1f %.1f %.1f\n", $p1_r, $p2_r, $p3_r); $dh_out->{$datatype}[$i] = $line; $line = sprintf ("%s %.2f %.2f", $txtime, $ss_sal[0], $ss_sal[1]); for (my $jj = 0; $jj < $Ncond; ++$jj){ $line .= sprintf (" %.2f", $sal[$jj]); } my $saltype = 'SAL '; $dh_out->{$saltype}[$i] = $line; # print "New Cond[$i] is $dh_out->{$datatype}[$i]\n"; } } #-------------------------# # process_goescurr #-------------------------# sub process_goescurr{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; for ( my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i ) { my $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, @data) = split (/\s+/, $line); #-- Look for bad data if necessary --# for ( my $jj = 0; $jj < ( scalar @data ); ++$jj) { if ( ( $data[$jj] =~ $badHexFill ) || ( $data[$jj] !~ /^($hexpat)*$/ ) ) { $data[$jj] = $badDataVal; } } # Convert twos-complement to decimal, like the winds # Thus, these are 13 bits encoded into 16 (four ASCII characters). # This should still work if negative sign is represented as 1, 7, or F. my @winds = @data; for (my $jj = 0; $jj <= $#winds; ++$jj){ my $windsign = unpack "axxx", $winds[$jj]; my $windval = unpack "xa3", $winds[$jj]; if ($windsign){ # hex2bin, complement, bin2hex, hex2dec, increment, change sign. $windval = hex(unpack "h3", ~(pack "h3", $windval)); $windval = -(++$windval); } else { $windval = hex($windval); } $winds[$jj] = $windval; } my ($u1, $v1, $u2, $v2, $u3, $v3, $u4, $v4, $u5, $v5) = @winds; #--Process currents here. # Write space-delimited values to output hash # # Writing bogus speed and dir until I get the sub-currents calibrated $line = sprintf ( "%s %d %d 11 11 %d %d 22 22 %d %d 33 33 %d %d 44 44 %d %d 55 55\n", $txtime, $u1, $v1, $u2, $v2, $u3, $v3, $u4, $v4, $u5, $v5 ); $dh_out->{$datatype}[$i] = $line; # print "New raw curr[$i] is $dh_out->{$datatype}[$i]\n"; } return; } #-------------------------# # process_goesengr #-------------------------# sub process_goesengr{ my ( $dh_in, $dh_out, $datatype, $cal) = @_; my ( $co1, $va1, $sp1, $co2, $va2, $sp2 ); $co1 = $va1 = $sp1 = $co2 = $va2 = $sp2 = 0; for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ my $line = $dh_in->{$datatype}[$i]; chomp($line); my ($txtime, @data) = split (/\s+/, $line); #-- Look for bad data if necessary --# for ( my $jj = 0; $jj < ( scalar @data ); ++$jj) { if ( ( $data[$jj] =~ $badHexFill ) || ( $data[$jj] !~ /^($hexpat)*$/ ) ) { $data[$jj] = $badDataVal; } } # Do something with the checksum here # Convert hex values to decimal @data = map ( hex, @data ); my ( $logicvolt, $goesbatt, $loop1, $loop2, $loop3, $engrflags, $co1, $va1, $sp1, $co2, $va2, $sp2, $checksum ) = @data; #--Any processing would go here #--Batt equation based on some raw data. Appears somewhat different than ARGOS--# $a = 0.1355; $b = 0.2826; if ( ( $logicvolt != $badDataVal) && ( $logicvolt != 0 ) ) { $logicvolt = $a * $logicvolt + $b; } $a = 0.1613; $b = -1.4194; if ( ( $goesbatt != $badDataVal) && ( $goesbatt != 0 ) && ( $goesbatt != 255 ) ) { $goesbatt = $a * $goesbatt + $b; } #--Write space delimited values to output hash $line = sprintf ("%s %.1f %.1f %d %d %d %d %d %d %d %d %d %d %d %d\n", $txtime, $logicvolt, $goesbatt, $loop1, $loop2, $loop3, $engrflags, $co1, $va1, $sp1, $co2, $va2, $sp2, $checksum); $dh_out->{$datatype}[$i] = $line; # print "New raw engr[$i] is $dh_out->{$datatype}[$i]\n"; } return; } #------------------# # newatlas2topofhour --Example input: 1998183192512, example output: 1998183190000 #------------------# sub newatlas2topofhour{ my ( $newatlas_time ) = @_; my ( $year, $day_of_year, $hour, $min, $sec ) = unpack "a4a3a2a2a2", $newatlas_time; my $datatime = sprintf( "%04d%03d%02d", $year, $day_of_year, $hour ); $datatime .= "0000"; return $datatime; } #------------------# # nptx_time2timestr --convert the time in TX to a readable format. No minutes:seconds TXed. # Example input: 1998070219, example output: 1998/07/02 19:00:00 #------------------# sub nptx_time2timestr{ # my $nptx_time = "1998070219"; my ( $nptx_time, $gultime ) = @_; my ( $nopp_year, $nopp_mon, $nopp_dom, $nopp_hour ) = unpack "a4 a2 a2 a2 a2", $nptx_time; if ( $nopp_year =~ /\D/){ $nopp_year = 0; } if ( $nopp_mon =~ /\D/){ $nopp_mon = 0; } if ( $nopp_dom =~ /\D/){ $nopp_dom = 0; } if ( $nopp_hour =~ /\D/){ $nopp_hour = 0; } my ($goes_year, $goes_jday, $goes_hour, $goes_min, $goes_sec ) = unpack "a2 a3 a2 a2 a2", $gultime; if ( $goes_min =~ /\D/ ) { $goes_min = 0; } if ( $goes_sec =~ /\D/ ) { $goes_sec = 0; } $nopp_min = $goes_min; $nopp_sec = $goes_sec; my $timestr = sprintf "%04d/%02d/%02d %02d:%02d:%02d", $nopp_year, $nopp_mon, $nopp_dom, $nopp_hour, $nopp_min, $nopp_sec; return $timestr; } #------------------# # goes_time2nptx_time --Example input: 98183192512, example output: 1998070219 #------------------# sub goes_time2nptx_time{ my ( $goes_time ) = @_; my ( $goes_jd, $goes_sec ) = goes_time2jdfmt ( $goes_time ); my ( $year, $mon, $dom ) = inverse_julian_day ( $goes_jd ); my ( $hour, $min, $sec ) = secs2hms ( $goes_sec ); my $timestr = sprintf "%04d%02d%02d%02d", $year, $mon, $dom, $hour; return $timestr; } #------------------# # goes_time2jdfmt --Example input: 98183192512, example output: , # Identical to atdoy2jdfmt in functionality but hopefully y2k compliant #------------------# sub goes_time2jdfmt{ my $epoch_start = 1972; my $year_thresh = $epoch_start - 1900; my ( $goes_time ) = @_; my ($goes_year, $goes_jday, $goes_hour, $goes_min, $goes_sec ) = unpack "a2 a3 a2 a2 a2", $goes_time; if ( $goes_year < $year_thresh ) { $goes_year += 2000; } else { $goes_year += 1900; } my $jd = julian_day ( $goes_year, 1, 1 ); $jd += $goes_jday - 1; $sec = $goes_hour * 3600 + $goes_min * 60 + $goes_sec; return ( $jd, $sec ); } #------------------# # get_bptimes --Input is TXtime, output is TXtime-2hours, TXtime-1hour, and TXtime. # All in newatlas fmt (YYYYJJJJHHMMSS). #------------------# sub get_bptimes{ my $one_hour = 1 * 3600; my $two_hours = 2 * 3600; my ( $tx_time ) = @_; my ($jd, $secs) = newatlas2jdfmt( $tx_time ); $secs -= $two_hours; my $first_time = normalize_jds( $jd, $secs ); $first_time = jdfmt2newatlas( $jd, $secs ); ($jd, $secs) = newatlas2jdfmt( $tx_time ); $secs -= $one_hour; my $second_time = normalize_jds( $jd, $secs ); $second_time = jdfmt2newatlas( $jd, $secs ); return ( $first_time, $second_time, $tx_time ); } #-----------------------------------------------------------------# # write_all --take the data hash as input, loop over data sets # reformat, sort, and write each to a file #-----------------------------------------------------------------# sub write_all{ use strict; use FileHandle; my ($platform_id, $outpath, $dh_out) = @_; my ($datatype, $outfilename, $latestfilename); # Loop over datatypes in hash, writing each set to a file foreach $datatype (keys %{$dh_out}){ ( $outfilename, $latestfilename ) = type2outfname($platform_id, $outpath, $datatype); if ( ! ($outfilename) ){ next; } if ( ! ($latestfilename) ){ next; } my $outfh = new FileHandle("$outfilename", "w") or die "Can't open outfile $outfilename: $!"; my $latestfh = new FileHandle("$latestfilename", "w") or die "Can't open latest file (1DY_all) $latestfilename: $!"; # Write some of the data header # Changing header to a length of five lines printf $outfh "%s \n", $platform_id ; printf $outfh " DEPLOYED \n TUBE \n", ; # Write the data to the outfile if ($datatype eq 'HEAD') { write_allhead($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'POS ') { write_allpos($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'RAIN') { write_allrain($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'MET ') { write_allmet($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'BP ') { write_allbp($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'OPS ') { write_allops($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'RAD ') { write_allrad($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'TEMP') { write_alltemp($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'COND') { write_allcond($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'SAL ') { write_allsal($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'CURR') { # write_allcurr($dh_out, $datatype, $outfh, $latestfh); } elsif ($datatype eq 'ENGR') { write_allengr($dh_out, $datatype, $outfh, $latestfh); } else { print "data type $datatype is unknown. NOT WRITTEN!\n" } } } # # type2outfname -- Generate an outfilename based on datafilename and datatype # sub type2outfname{ my ($platform_id, $outpath, $datatype) = @_; #--This should go in ProcHead.pl--# my %gsuffix = ( 'HEAD'=>'.head', 'POS '=>'.pos', 'OPS '=>'.ops', 'MET '=>'.met', 'BP '=>'.bp', 'RAIN'=>'.rain', 'RAD '=>'.rad', 'TEMP'=>'.temp', 'COND'=>'.cond', 'SAL '=>'.sal', 'ENGR'=>'.engr'); my $outfilename; my $suffix = $gsuffix{$datatype}; if ($suffix) { $outfilename = $outpath . $platform_id . $suffix; $suffix =~ s/\./\_/; $latestfilename = $outpath . $platform_id . $suffix . ".new"; } else { $outfilename = "0"; $latestfilename = "0"; print LOGFILE "Unknown datatype $datatype is NOT being processed.\n"; print "WARNING ($0): Unable to write files for datatype $datatype.\n"; } return ( $outfilename, $latestfilename ); } # # write_allheader -reformat data for output, sort, and write to output file # sub write_allhead{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %9s%12s %1s %6s%8s %6s%6s %4s%4s %6s%8s\n", qw(DATE PLATFORM GOESDATE Q SIGSTR FREQOFF MODIND DATAQ CHAN SAT UPSTAT DATALEN ); printf $outfh "%15s %8s\n", "","-3"; printf $latestfh "%15s %9s%12s %1s %6s%8s %6s%6s %4s%4s %6s%8s\n", qw(DATE PLATFORM GOESDATE Q SIGSTR FREQOFF MODIND DATAQ CHAN SAT UPSTAT DATALEN ); printf $latestfh "%15s %8s\n", "","-3"; # Reformat the data for output - all data on one line # This is mostly the same as write_dathead. for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $pid, $gdate, $q, $sigstr, $freqoff, $modind, $dataq, $chan, $goes, $upstat, $datalen) = split(/\s+/,$line); $line = sprintf ( "%9s%12s %1s %6s%8s %6s%6s %4s%4s %6s%8s\n", $pid, $gdate, $q, $sigstr, $freqoff, $modind, $dataq, $chan, $goes, $upstat, $datalen ); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allpos -reformat data for output, sort, and write to output file # sub write_allpos{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header printf $outfh "%15s %10s %4s %7s %4s %7s \n", qw(DATE TX-DATE LON LONMIN LAT LATMIN ); printf $outfh "%15s %8s\n", "","-3"; printf $latestfh "%15s %10s %4s %7s %4s %7s \n", qw(DATE TX-DATE LON LONMIN LAT LATMIN ); printf $latestfh "%15s %8s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $nptx_time, $lon, $lonmin_str, $lat, $latmin_str) = split(/\s+/,$line); $line = sprintf ( "%10s %4s %7s %4s %7s\n", $nptx_time, $lon, $lonmin_str, $lat, $latmin_str); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allops -reformat data for output, sort, and write to output file # sub write_allops{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %8s%8s%8s %8s%8s %8s%8s %8s%8s%8s %8s%8s %8s%8s\n", qw(DATE AIRT1 RH1 SST1 U1 V1 SPD1 DIR1 AIRT2 RH2 SST2 U2 V2 SPD2 DIR2 ); printf $outfh "%15s %8s\n", "","-3"; printf $latestfh "%15s %8s%8s%8s %8s%8s %8s%8s %8s%8s%8s %8s%8s %8s%8s\n", qw(DATE AIRT1 RH1 SST1 U1 V1 SPD1 DIR1 AIRT2 RH2 SST2 U2 V2 SPD2 DIR2 ); printf $latestfh "%15s %8s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $at1, $rh1, $sst1, $u1, $v1, $spd1, $dir1, $at2, $rh2, $sst2, $u2, $v2, $spd2, $dir2) = split(/\s+/,$line); $line = sprintf ( "%8.2f%8.2f%8.2f %8.2f%8.2f %8.2f%8.1f", $at1, $rh1, $sst1, $u1, $v1, $spd1, $dir1); $line .= sprintf ( " %8.2f%8.2f%8.2f %8.2f%8.2f %8.2f%8.1f\n", $at2, $rh2, $sst2, $u2, $v2, $spd2, $dir2); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allmet -reformat output, sort, and write to output file # sub write_allmet{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %6s%6s %7s%7s %6s%6s %4s%4s%4s", qw(DATE AT1 RH1 U1 V1 SPD1 DIR1 CO1 VA1 SP1); printf $outfh " %5s%6s %7s%7s %6s%6s %4s%4s%4s %7s%7s%7s\n", qw(AT2 RH2 U2 V2 SPD2 DIR2 CO2 VA2 SP2 BP1 BP2 BP3); printf $outfh "%15s %6s\n", "","-3"; printf $latestfh "%15s %6s%6s %7s%7s %6s%6s %4s%4s%4s", qw(DATE AT1 RH1 U1 V1 SPD1 DIR1 CO1 VA1 SP1); printf $latestfh " %5s%6s %7s%7s %6s%6s %4s%4s%4s %7s%7s%7s\n", qw(AT2 RH2 U2 V2 SPD2 DIR2 CO2 VA2 SP2 BP1 BP2 BP3); printf $latestfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $at1, $rh1, $u1, $v1, $spd1, $dir1, $at2, $rh2, $u2, $v2, $spd2, $dir2, $bp1, $bp2, $bp3, $co1, $va1, $sp1, $co2, $va2, $sp2 ) = split(/\s+/,$line); $line = sprintf ( "%6.2f%6.2f %7.2f%7.2f %6.2f%6.1f %4d%4d%4d", $at1, $rh1, $u1, $v1, $spd1, $dir1, $co1, $va1, $sp1); $line .= sprintf ( "%6.2f%6.2f %7.2f%7.2f %6.2f%6.1f %4d%4d%4d %7.1f%7.1f%7.1f\n", $at2, $rh2, $u2, $v2, $spd2, $dir2, $co2, $va2, $sp2, $bp1, $bp2, $bp3); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allbp -reformat output, sort, and write to output file # sub write_allbp{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %6s\n", qw(DATE BP); printf $latestfh "%15s %6s\n", qw(DATE BP); printf $outfh "%15s %6s\n", "","-3"; printf $latestfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime1, $bp1, $txtime2, $bp2, $txtime3, $bp3 ) = split(/\s+/,$line); $line = sprintf ( "%6.1f\n",$bp1); chomp($line); $currdh{$txtime1} = $line; $line = sprintf ( "%6.1f\n",$bp2); chomp($line); $currdh{$txtime2} = $line; $line = sprintf ( "%6.1f\n",$bp3); chomp($line); $currdh{$txtime3} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allrain -reformat data for output, sort, and write to output file # sub write_allrain{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %8s%10s%8s%8s%10s%8s\n", qw(DATE RN1-AV RN1-SD FRAC1 RN2-AV RN2-SD FRAC2); printf $outfh "%15s %8s\n", "","-3"; printf $latestfh "%15s %8s%10s%8s%8s%10s%8s\n", qw(DATE RN1-AV RN1-SD FRAC1 RN2-AV RN2-SD FRAC2); printf $latestfh "%15s %8s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $rainav1, $rainsd1, $frac1, $rainav2, $rainsd2, $frac2) = split(/\s+/,$line); $line = sprintf ( "%8.2f%10.2f%8.2f%8.2f%10.2f%8.2f\n", $rainav1, $rainsd1, $frac1, $rainav2, $rainsd2, $frac2); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allrad -reformat output, sort, and write to output file # sub write_allrad{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %8s%8s%8s %8s%8s%8s %8s%8s\n", qw(DATE RAD-SW STDDEV SW-MAX RAD-LW STDDEV LW-MAX LWT1 LWT2); printf $outfh "%15s %8s%8s%8s %8s%8s%8s %8s%8s\n", "",qw(-4 -3 -3 -3 -2 -2 -2 -2 -2); printf $latestfh "%15s %8s%8s%8s %8s%8s%8s %8s%8s\n", qw(DATE RAD-SW STDDEV SW-MAX RAD-LW STDDEV LW-MAX LWT1 LWT2); printf $latestfh "%15s %8s%8s%8s %8s%8s%8s %8s%8s\n", "",qw(-4 -3 -3 -3 -2 -2 -2 -2 -2); # Reformat the data for output - all data on one line # Sort the data by txdate (chronological order) and write to file for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $swavg, $swstd, $swmax, $lwavg, $lwstd, $lwmax, $lwt1, $lwt2) = split(/\s+/,$line); $line = sprintf ( "%8.1f%8.1f%8.1f %8.1f%8.1f%8.1f", $swavg, $swstd, $swmax, $lwavg, $lwstd, $lwmax); $line .= sprintf ( " %8.1f%8.1f\n", $lwt1, $lwt2); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_alltemp -reformat output, sort, and write to output file # sub write_alltemp{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line if (0){ printf $outfh "%15s %6s%6s%6s%6s%6s%6s%6s%6s", qw(DATE SST1 SST2 T1 T2 T3 T4 T5 T6); printf $outfh "%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s\n", qw(T7 T8 T9 T10 T11 T12 T13 T14 T15 T16); printf $outfh "%15s %6s\n", "","-3"; } #--Patch to add the spot SST's. printf $outfh "%15s %6s%6s%6s%6s%6s%6s%6s%6s%6s%6s", qw(DATE SST1 SST2 SSTO1 SSTO2 T1 T2 T3 T4 T5 T6); printf $outfh "%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s\n", qw(T7 T8 T9 T10 T11 T12 T13 T14 T15 T16); printf $outfh "%15s %6s%6s%6s%6s%6s%6s%6s%6s%6s%6s", qw(- 1 2 1 2 6 10 15 20 30 40); printf $outfh "%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s\n", qw(50 60 80 100 120 140 180 225 300 400); printf $latestfh "%15s %6s%6s%6s%6s%6s%6s%6s%6s%6s%6s", qw(DATE SST1 SST2 SSTO1 SSTO2 T1 T2 T3 T4 T5 T6); printf $latestfh "%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s\n", qw(T7 T8 T9 T10 T11 T12 T13 T14 T15 T16); printf $latestfh "%15s %6s%6s%6s%6s%6s%6s%6s%6s%6s%6s", qw(- 1 2 1 2 6 10 15 20 30 40); printf $latestfh "%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s\n", qw(50 60 80 100 120 140 180 225 300 400); # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $sst1, $sst2, $sstop1, $sstop2, $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t14, $t15, $t16) = split(/\s+/,$line); $line = sprintf ( "%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f", $sst1, $sst2, $sstop1, $sstop2, $t1, $t2, $t3, $t4, $t5, $t6); $line .= sprintf ("%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f%6.2f\n", $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t14, $t15, $t16); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allcurr -reformat data for output, sort, and write to output file # sub write_allcurr{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %7s%7s%6s%6s %7s%7s%6s%6s", qw(DATE SSU1 SSV1 SPD1 DIR1 SSU2 SSV2 SPD2 DIR2); printf $outfh " %7s%7s%6s%6s %7s%7s%6s%6s %7s%7s%6s%6s\n", qw(SSU3 SSV3 SPD3 DIR3 SSU4 SSV4 SPD4 DIR4 SSU5 SSV5 SPD5 DIR5); printf $outfh "%15s %6s\n", "","-3"; printf $latestfh "%15s %7s%7s%6s%6s %7s%7s%6s%6s", qw(DATE SSU1 SSV1 SPD1 DIR1 SSU2 SSV2 SPD2 DIR2); printf $latestfh " %7s%7s%6s%6s %7s%7s%6s%6s %7s%7s%6s%6s\n", qw(SSU3 SSV3 SPD3 DIR3 SSU4 SSV4 SPD4 DIR4 SSU5 SSV5 SPD5 DIR5); printf $latestfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $u1, $v1, $sp1, $dir1, $u2, $v2, $sp2, $dir2, $u3, $v3, $sp3, $dir3, $u4, $v4, $sp4, $dir4, $u5, $v5, $sp5, $dir5) = split(/\s+/,$line); $line = sprintf ( "%7.1f%7.1f%6.1f%6.1f", $u1, $v1, $sp1, $dir1); $line .= sprintf ( " %7.1f%7.1f%6.1f%6.1f", $u2, $v2, $sp2, $dir2); $line .= sprintf ( " %7.1f%7.1f%6.1f%6.1f", $u3, $v3, $sp3, $dir3); $line .= sprintf ( " %7.1f%7.1f%6.1f%6.1f", $u4, $v4, $sp4, $dir4); $line .= sprintf ( " %7.1f%7.1f%6.1f%6.1f\n", $u5, $v5, $sp5, $dir5); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allcond -reformat data for output, sort, and write to output file # sub write_allcond{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n", qw(DATE SSC1 SSC2 C1 C2 C3 C4 C5 C6 C7 C8 P1 P2 P3); printf $outfh "%15s %8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n", qw(- 1 2 6 10 20 40 60 100 140 180 225 300 400); printf $latestfh "%15s %8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n", qw(DATE SSC1 SSC2 C1 C2 C3 C4 C5 C6 C7 C8 P1 P2 P3); printf $latestfh "%15s %8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n", qw(- 1 2 6 10 20 40 60 100 140 180 225 300 400); # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $ssc1, $ssc2, $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $p1, $p2, $p3) = split(/\s+/,$line); $line = sprintf ( "%8.2f%8.2f", $ssc1, $ssc2); $line .= sprintf ( "%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f", $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8); $line .= sprintf ( "%8.1f%8.1f%8.1f\n", $p1, $p2, $p3); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allsal -reformat data for output, sort, and write to output file # sub write_allsal{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n", qw(DATE SSS1 SSS2 SAL1 SAL2 SAL3 SAL4 SAL5 SAL6 SAL7 SAL8); printf $outfh "%15s %8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n", qw(- 1 2 6 10 20 40 60 100 140 180); printf $latestfh "%15s %8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n", qw(DATE SSS1 SSS2 SAL1 SAL2 SAL3 SAL4 SAL5 SAL6 SAL7 SAL8); printf $latestfh "%15s %8s%8s%8s%8s%8s%8s%8s%8s%8s%8s\n", qw(- 1 2 6 10 20 40 60 100 140 180); # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $sss1, $sss2, $sal1, $sal2, $sal3, $sal4, $sal5, $sal6, $sal7, $sal8) = split(/\s+/,$line); $line = sprintf ( "%8.2f%8.2f", $sss1, $sss2); $line .= sprintf ( "%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f", $sal1, $sal2, $sal3, $sal4, $sal5, $sal6, $sal7, $sal8); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } # # write_allengr -reformat data for output, sort, and write to output file # sub write_allengr{ use strict; use FileHandle; my ($dh_out, $datatype, $outfh, $latestfh, $latest_txtime) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %6s%6s %6s%6s%6s %6s %4s%4s%4s %4s%4s%4s %6s\n", qw(DATE LBV GBV LOOP1 LOOP2 LOOP3 GFL CO1 VA1 SP1 CO2 VA2 SP2 CKSUM); printf $outfh "%15s %6s\n", "","-3"; printf $latestfh "%15s %6s%6s %6s%6s%6s %6s %4s%4s%4s %4s%4s%4s %6s\n", qw(DATE LBV GBV LOOP1 LOOP2 LOOP3 GFL CO1 VA1 SP1 CO2 VA2 SP2 CKSUM); printf $latestfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_out->{$datatype}}; ++$i){ my $line = $dh_out->{$datatype}[$i]; my ($txtime, $logicvolt, $goesbatt, $loop1, $loop2, $loop3, $engrflags, $co1, $va1, $sp1, $co2, $va2, $sp2, $checksum) = split(/\s+/,$line); #--Patch for engr transition stage if ( not $co1 ){ $co1 = $va1 = $sp1 = $co2 = $va2 = $sp2 = 0; } $line = sprintf ( "%6.1f%6.1f %6d%6d%6d %6.1f %4d%4d%4d %4d%4d%4d %6s\n", $logicvolt, $goesbatt, $loop1, $loop2, $loop3, $engrflags, $co1, $va1, $sp1, $co2, $va2, $sp2, $checksum); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; $latest_txtime = $txtime; } # Write newest data to the .new file (like a 1dy file) printf $latestfh "%15s %s\n", $latest_txtime, $currdh{$latest_txtime}; } #-----------------------------------------------------------------# # write_dat --take the goes data hash as input, loop over data sets # reformat (white space between values), and write each # to dat_data_hash and to dat file (stage1); #-----------------------------------------------------------------# sub write_dat{ use strict; use FileHandle; my ($platform_id, $datpath, $dh_in, $dh_out ) = @_; my ($datatype, $outfilename); # Loop over datatypes in hash, writing each set to a file foreach $datatype (keys %{$dh_in}){ $outfilename = type2datfname($platform_id, $datpath, $datatype); if ( ! ($outfilename) ){ next; } my $outfh = new FileHandle("$outfilename", "w") or die "Can't open outfile $outfilename: $!"; # Write the data to the outfile if ($datatype eq 'HEAD') { write_dathead($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'POS ') { write_datpos($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'OPS ') { write_datops($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'MET ') { write_datmet($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'RAIN') { write_datrain($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'RAD ') { write_datrad($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'TEMP') { write_dattemp($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'COND') { write_datcond($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'CURR') { write_datcurr($dh_in, $dh_out, $datatype, $outfh); } elsif ($datatype eq 'ENGR') { write_datengr($dh_in, $dh_out, $datatype, $outfh); } else { print "data type $datatype is unknown. NOT WRITTEN!\n" } } } # # type2datfname -- Generate an outfilename based on datafilename and datatype # sub type2datfname{ my ($platform_id, $datpath, $datatype) = @_; #--This should go in ProcHead.pl--# my %dat_suffix = ( 'HEAD'=>'_head.dat', 'POS '=>'_pos.dat', 'OPS '=>'_ops.dat', 'MET '=>'_met.dat', 'RAIN'=>'_rain.dat', 'RAD '=>'_rad.dat', 'TEMP'=>'_temp.dat', 'COND'=>'_cond.dat', 'CURR'=>'_curr.dat', 'ENGR'=>'_engr.dat', ); my $outfilename; if ($dat_suffix{$datatype}) { $outfilename = $datpath . $platform_id . $dat_suffix{$datatype}; } else { $outfilename = "0"; print LOGFILE "Unknown datatype $datatype is NOT written to DAT file.\n"; print "WARNING ($0): Unable to write dat files for datatype $datatype.\n"; } return $outfilename; } # # write_datheader -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_dathead{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %9s%12s %1s %6s%8s %6s%6s %4s%4s %6s%8s\n", qw(DATE PLATFORM GOESDATE Q SIGSTR FREQOFF MODIND DATAQ CHAN SAT UPSTAT DATALEN ); printf $outfh "%15s %8s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ my $line = $dh_in->{$datatype}[$i]; my ($txtime, $data) = split(/\s+/,$line); my ($pid, $gdate, $q, $sigstr, $freqoff, $modind, $dataq, $chan, $goes, $upstat, $datalen) = unpack "a8 a11 a1 a2 a2 a1 a1 a3 a1 a2 a5", $data; #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s %s %s %s %s %s %s %s %s %s %s\n", $txtime, $pid, $gdate, $q, $sigstr, $freqoff, $modind, $dataq, $chan, $goes, $upstat, $datalen); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%9s%12s %1s %6s%8s %6s%6s %4s%4s %6s%8s", $pid, $gdate, $q, $sigstr, $freqoff, $modind, $dataq, $chan, $goes, $upstat, $datalen ); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_datpos -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_datpos{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %10s %4s %7s %4s %7s \n", qw(DATE TX-DATE LON LONMIN LAT LATMIN ); printf $outfh "%15s %8s\n", "","-3"; # Read position data for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ my $line = $dh_in->{$datatype}[$i]; my ($txtime, $nptx_time, $lon, $lonmin_str, $lat, $latmin_str) = split(/\s+/,$line); #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s %s %s %s %s", $txtime, $nptx_time, $lon, $lonmin_str, $lat, $latmin_str); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%10s %4s %7s %4s %7s\n", $nptx_time, $lon, $lonmin_str, $lat, $latmin_str); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_datops -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_datops{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %8s%8s %5s%5s %4s%4s %4s%4s %6s%6s\n", qw(DATE AIRT1 AIRT2 HUM1 HUM2 U1 V1 U2 V2 SST1 SST2 ); printf $outfh "%15s %8s\n", "","-3"; for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ #--Read buffer, parse values. my $line = $dh_in->{$datatype}[$i]; my ($txtime, $data) = split(/\s+/,$line); my ($at1, $at2, $rh1, $rh2, $u1, $v1, $u2, $v2, $sst1, $sst2) = unpack "a3 a3 a2 a2 a3 a3 a3 a3 a4 a4", $data; #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s %s %s %s %s %s %s %s %s %s", $txtime, $at1, $at2, $rh1, $rh2, $u1, $v1, $u2, $v2, $sst1, $sst2); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%8s%8s %5s%5s %4s%4s %4s%4s %6s%6s", $at1, $at2, $rh1, $rh2, $u1, $v1, $u2, $v2, $sst1, $sst2); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_datmet -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_datmet{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %4s%4s %5s%5s %4s%4s %4s%4s", qw(DATE AT1 AT2 RH1 RH2 U1 V1 U2 V2); printf $outfh " %4s%4s%4s %4s%4s%4s %4s%4s%4s\n", qw(BP1 BP2 BP3 CO1 VA1 SP1 CO2 VA2 SP2 ); printf $outfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ #--Read buffer, parse values. my $line = $dh_in->{$datatype}[$i]; my ($txtime, $data) = split(/\s+/,$line); my ($at1, $at2, $rh1, $rh2, $u1, $v1, $u2, $v2, $bp1, $bp2, $bp3 ) = unpack "a3 a3 a2 a2 a3 a3 a3 a3 a3 a3 a3" , $data; #--Patch for variable length ENGR buffers with copied extra into met. my ($co1, $va1, $sp1, $co2, $va2, $sp2); $co1 = $va1 = $sp1 = $co2 = $va2 = $sp2 = 0; my $start = 31; my $extra_len = 12; if ( length ( $data ) == $start + $extra_len ) { ($co1, $va1, $sp1, $co2, $va2, $sp2) = unpack "x$start a2 a2 a2 a2 a2 a2", $data; } #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", $txtime, $at1, $at2, $rh1, $rh2, $u1, $v1, $u2, $v2, $bp1, $bp2, $bp3, $co1, $va1, $sp1, $co2, $va2, $sp2); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%4s%4s %5s%5s %4s%4s %4s%4s", $at1, $at2, $rh1, $rh2, $u1, $v1, $u2, $v2); $line .= sprintf (" %4s%4s%4s %4s%4s%4s %4s%4s%4s", $bp1, $bp2, $bp3, $co1, $va1, $sp1, $co2, $va2, $sp2 ) ; chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_datrain -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_datrain{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %8s%8s%8s%8s%8s%8s\n", qw(DATE RN1-AV RN1-SD FRAC1 RN2-AV RN2-SD FRAC2); printf $outfh "%15s %8s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ #--Read buffer, parse values. my $line = $dh_in->{$datatype}[$i]; my ($txtime, $data ) = split(/\s+/,$line); my ( $rainav1, $rainsd1, $frac1, $rainav2, $rainsd2, $frac2 ) = unpack " a4 a4 a2 a4 a4 a2 ", $data; #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s %s %s %s %s %s\n", $txtime, $rainav1, $rainsd1, $frac1, $rainav2, $rainsd2, $frac2); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%8s%8s%8s%8s%8s%8s\n", $rainav1, $rainsd1, $frac1, $rainav2, $rainsd2, $frac2); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_datrad -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_datrad{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %8s%8s%8s %8s%8s%8s %8s%8s\n", qw(DATE RAD-SW STDDEV SW-MAX RAD-LW STDDEV LW-MAX LWT1 LWT2); printf $outfh "%15s %8s%8s%8s %8s%8s%8s %8s%8s\n", "",qw(-4 -3 -3 -3 -2 -2 -2 -2 -2); # Reformat the data for output - all data on one line # Sort the data by txdate (chronological order) and write to file for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ #--Read buffer, parse values. my $line = $dh_in->{$datatype}[$i]; my ($txtime, $data ) = split(/\s+/,$line); my ($swavg, $swstd, $swmax, $lwavg, $lwstd, $lwmax, $lwt1, $lwt2) = unpack " a4 a4 a4 a4 a4 a4 a4 a4 ", $data; #--Put space-delimited unformatted data into the out_hash $line = sprintf ("%s %s %s %s %s %s %s %s %s\n", $txtime, $swavg, $swstd, $swmax, $lwavg, $lwstd, $lwmax, $lwt1, $lwt2); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%8s%8s%8s %8s%8s%8s %8s%8s", $swavg, $swstd, $swmax, $lwavg, $lwstd, $lwmax, $lwt1, $lwt2); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_dattemp -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_dattemp{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); my $Nsst = 3; my $Ntemps = 16; # Whoa -- whole lotta temps! my $Nspot_sst = 2; # Added the spot SST from OPS # Write the header # Write the data header - all data on one line if (0){ printf $outfh "%15s %6s%6s%6s%6s%6s%6s%6s", qw(DATE SST1 T1 T2 T3 T4 T5 T6); printf $outfh "%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s\n", qw(T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 SST2); printf $outfh "%15s %6s\n", "","-3"; } #--Patch to add the spot SST's. printf $outfh "%15s %6s %5s%5s%5s%5s%5s%5s%5s%5s", qw(DATE SST1 T1 T2 T3 T4 T5 T6 T7 T8); printf $outfh "%5s%5s%5s%5s%5s%5s%5s%5s %6s%6s%6s\n", qw( T9 T10 T11 T12 T13 T14 T15 T16 SST2 SSTO1 SSTO2 ); printf $outfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ #--Read buffer, parse values. my $line = $dh_in->{$datatype}[$i]; my ($txtime, $data ) = split(/\s+/,$line); my ($sst1, $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12, $t13, $t14, $t15, $t16, $sst2, $sstop1, $sstop2 ) = unpack "a4" . "a4" x $Ntemps . "a4" . "a4" x $Nspot_sst, $data; #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s %s %s %s %s %s %s %s %s ", $txtime, $sst1, $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8); $line .= sprintf ("%s %s %s %s %s %s %s %s %s %s %s\n", $t9, $t10, $t11, $t12, $t13, $t14, $t15, $t16, $sst2, $sstop1, $sstop2); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%6s %5s%5s%5s%5s%5s%5s%5s%5s", $sst1, $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8 ); $line .= sprintf ("%5s%5s%5s%5s%5s%5s%5s%5s %6s%6s%6s\n", $t9, $t10, $t11, $t12, $t13, $t14, $t15, $t16, $sst2, $sstop1, $sstop2); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_datcond -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_datcond{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); my $Nssc = 2; my $Ncond = 8; my $Npress = 3; # Write the header # Write the data header - all data on one line printf $outfh "%15s %6s %5s%5s%5s%5s%5s%5s%5s%5s%6s %6s%6s%6s\n", qw(DATE SSC1 C1 C2 C3 C4 C5 C6 C7 C8 SSC2 P1 P2 P3); printf $outfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ #--Read buffer, parse values. my $line = $dh_in->{$datatype}[$i]; my ($txtime, $data ) = split(/\s+/,$line); my ($ssc1, $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $ssc2, $p1, $p2, $p3) = unpack "a4" x $Nssc . "a4" x $Ncond . "a4" x $Npress, $data; #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s", $txtime, $ssc1); $line .= sprintf ( " %s %s %s %s %s %s %s %s %s", $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $ssc2); $line .= sprintf ( " %s %s %s\n", $p1, $p2, $p3); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%6s", $ssc1); $line .= sprintf ( " %5s%5s%5s%5s%5s%5s%5s%5s%6s", $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $ssc2); $line .= sprintf ( " %6s%6s%6s\n", $p1, $p2, $p3); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_datcurr -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_datcurr{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); my $Nsensors = 5; # Write the header # Write the data header - all data on one line printf $outfh "%15s %5s%5s%5s%5s%5s", qw(DATE SSU1 SSU2 SSU3 SSU4 SSU5); printf $outfh " %5s%5s%5s%5s%5s\n", qw(SSV1 SSV2 SSV3 SSV4 SSV5); printf $outfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ #--Read buffer, parse values. my $line = $dh_in->{$datatype}[$i]; my ( $txtime, $data ) = split( /\s+/, $line ); my ($u1, $u2, $u3, $u4, $u5, $v1, $v2, $v3, $v4, $v5) = unpack "a4" x $Nsensors . "a4" x $Nsensors, $data; #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s %s %s %s %s %s %s %s %s %s\n", $txtime, $u1, $u2, $u3, $u4, $u5, $v1, $v2, $v3, $v4, $v5); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%5s%5s%5s%5s%5s", $u1, $u2, $u3, $u4, $u5); $line .= sprintf ( " %5s%5s%5s%5s%5s\n", $v1, $v2, $v3, $v4, $v5); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # # write_datengr -read in_hash, add spaces between values, write to out_hash, # write sorted output to file. # sub write_datengr{ use strict; use FileHandle; my ( $dh_in, $dh_out, $datatype, $outfh ) = @_; my %currdh = (); # Write the header # Write the data header - all data on one line printf $outfh "%15s %6s%6s %6s%6s%6s %6s %4s%4s%4s %4s%4s%4s %6s\n", qw(DATE LBV GBV LOOP1 LOOP2 LOOP3 GFL CO1 VA1 SP1 CO2 VA2 SP2 CKSUM); printf $outfh "%15s %6s\n", "","-3"; # Reformat the data for output - all data on one line for (my $i = 0; $i <= $#{$dh_in->{$datatype}}; ++$i){ #--Read buffer, parse values. my $line = $dh_in->{$datatype}[$i]; my ($txtime, $data ) = split(/\s+/,$line); my ($logicvolt, $goesbatt, $loop1, $loop2, $loop3, $engrflags) = unpack " a2 a2 a3 a3 a3 a2 ", $data; #print "Data is $data.\n"; #--Patch for engr transition stage my $start = 15; my $extra_len = 16; my ( $co1, $va1, $sp1, $co2, $va2, $sp2, $checksum ); $co1 = $va1 = $sp1 = $co2 = $va2 = $sp2 = $checksum = 0; if ( length ( $data ) == $start + $extra_len ) { ( $co1, $va1, $sp1, $co2, $va2, $sp2, $checksum ) = unpack "x$start " . "a2" x 6 . "a4" , $data; } #--Put space-delimited unformatted data into the out_hash $line = sprintf ( "%s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", $txtime, $logicvolt, $goesbatt, $loop1, $loop2, $loop3, $engrflags, $co1, $va1, $sp1, $co2, $va2, $sp2, $checksum); chomp($line); $dh_out->{$datatype}[$i] = $line; #--Copy formatted version into a local hash for writing output $line = sprintf ( "%6s%6s %6s%6s%6s %6s %4s%4s%4s %4s%4s%4s %6s\n", $logicvolt, $goesbatt, $loop1, $loop2, $loop3, $engrflags, $co1, $va1, $sp1, $co2, $va2, $sp2, $checksum); chomp($line); $currdh{$txtime} = $line; } # Sort the data by txdate (chronological order) and write to file foreach my $txtime (sort keys %currdh){ printf $outfh "%15s %s\n", $txtime, $currdh{$txtime}; } } # #--Th' Th' Th' .... so long, Folks! #