package SAC; =head1 NAME SAC - a class to read SAC files =head1 SYNOPSIS use SAC; ################# # class methods # ################# $sac = SAC->new(SACfile]); # Optionally reads a SAC file $sac = SAC->parse(SACfile); # Expects a SAC file to read Data samples are available as an array using "@{$sac->{datasamples}}" ####################### # object data methods # ####################### ### get methods ### $level = $sac->print(level) # Print record information to stdout, returns print level $srcname = $sac->sourceName() # Return source name as Net_Sta_Loc_Chan (Loc == KHOLE) $samprate = $sac->sampleRate() # Return sample rate in samples/second. $timestr = $sac->startTimeString() # Return start time as an ASCII string $depoch = $sac->startTimeDepoch() # Return start time as double precision epoch $depoch = $sac->depoch(y,d,h,m,s,ms)# Return double precision epoch for (year,day,hour,min,sec,msec) ### get/set internal data methods ### $seqnum = $sac->seqnum([seqnum]) $headind = $sac->headind([headind]) $reserved = $sac->reserved([reserved]) $sta = $sac->sta([sta]) $loc = $sac->loc([loc]) $chan = $sac->chan([chan]) $net = $sac->net([net]) $stime = $sac->stime() # returns a MiniSEED::Time object $nsamp = $sac->nsamp([nsamp]) $sfact = $sac->sfact([sfact]) $smult = $sac->smult([smult]) $actflags = $sac->actflags([actflag]) $ioflags = $sac->ioflags([ioflag]) $dqflags = $sac->dqflags([dqflag]) $numblkt = $sac->numblkt([numblkt]) $timecorr = $sac->timecorr([timecorr]) $begdata = $sac->begdata([begdata]) $firstblkt = $sac->firstblkt([firstblkt]) =head1 NOTES Currently requires SAC files to be in host byte order. =head1 AUTHOR Chad Trabant, IRIS Data Management Center =cut require v5.6.0; # Might work with lesser versions use strict; use Carp; our $VERSION = '2008.129'; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; ($self->{SACfile}) = @_ if ( @_ == 1 ); # SAC header values $self->{delta} = undef; # float32 $self->{depmin} = undef; # float32 $self->{depmax} = undef; # float32 $self->{scale} = undef; # float32 $self->{odelta} = undef; # float32 $self->{b} = undef; # float32 $self->{e} = undef; # float32 $self->{o} = undef; # float32 $self->{a} = undef; # float32 $self->{fmt} = undef; # float32 $self->{t0} = undef; # float32 $self->{t1} = undef; # float32 $self->{t2} = undef; # float32 $self->{t3} = undef; # float32 $self->{t4} = undef; # float32 $self->{t5} = undef; # float32 $self->{t6} = undef; # float32 $self->{t7} = undef; # float32 $self->{t8} = undef; # float32 $self->{t9} = undef; # float32 $self->{f} = undef; # float32 $self->{resp0} = undef; # float32 $self->{resp1} = undef; # float32 $self->{resp2} = undef; # float32 $self->{resp3} = undef; # float32 $self->{resp4} = undef; # float32 $self->{resp5} = undef; # float32 $self->{resp6} = undef; # float32 $self->{resp7} = undef; # float32 $self->{resp8} = undef; # float32 $self->{resp9} = undef; # float32 $self->{stla} = undef; # float32 $self->{stlo} = undef; # float32 $self->{stel} = undef; # float32 $self->{stdp} = undef; # float32 $self->{evla} = undef; # float32 $self->{evlo} = undef; # float32 $self->{evel} = undef; # float32 $self->{evdp} = undef; # float32 $self->{mag} = undef; # float32 $self->{user0} = undef; # float32 $self->{user1} = undef; # float32 $self->{user2} = undef; # float32 $self->{user3} = undef; # float32 $self->{user4} = undef; # float32 $self->{user5} = undef; # float32 $self->{user6} = undef; # float32 $self->{user7} = undef; # float32 $self->{user8} = undef; # float32 $self->{user9} = undef; # float32 $self->{dist} = undef; # float32 $self->{az} = undef; # float32 $self->{baz} = undef; # float32 $self->{gcarc} = undef; # float32 $self->{sb} = undef; # float32 $self->{sdelta} = undef; # float32 $self->{depmen} = undef; # float32 $self->{cmpaz} = undef; # float32 $self->{cmpinc} = undef; # float32 $self->{xminimum} = undef; # float32 $self->{xmaximum} = undef; # float32 $self->{yminimum} = undef; # float32 $self->{ymaximum} = undef; # float32 $self->{xminimum} = undef; # float32 $self->{unused6} = undef; # float32 $self->{unused7} = undef; # float32 $self->{unused8} = undef; # float32 $self->{unused9} = undef; # float32 $self->{unused10} = undef; # float32 $self->{unused11} = undef; # float32 $self->{unused12} = undef; # float32 $self->{nzyear} = undef; # integer32 $self->{nzjday} = undef; # integer32 $self->{nzhour} = undef; # integer32 $self->{nzmin} = undef; # integer32 $self->{nzsec} = undef; # integer32 $self->{nzmsec} = undef; # integer32 $self->{nvhdr} = undef; # integer32 $self->{norid} = undef; # integer32 $self->{nevid} = undef; # integer32 $self->{npts} = undef; # integer32 $self->{nsnpts} = undef; # integer32 $self->{nwfid} = undef; # integer32 $self->{nxsize} = undef; # integer32 $self->{nysize} = undef; # integer32 $self->{unused15} = undef; # integer32 $self->{iftype} = undef; # integer32 $self->{idep} = undef; # integer32 $self->{iztype} = undef; # integer32 $self->{unused16} = undef; # integer32 $self->{iinst} = undef; # integer32 $self->{istreg} = undef; # integer32 $self->{ievreg} = undef; # integer32 $self->{ievtyp} = undef; # integer32 $self->{iqual} = undef; # integer32 $self->{isynth} = undef; # integer32 $self->{imagtyp} = undef; # integer32 $self->{imagsrc} = undef; # integer32 $self->{unused19} = undef; # integer32 $self->{unused20} = undef; # integer32 $self->{unused21} = undef; # integer32 $self->{unused22} = undef; # integer32 $self->{unused23} = undef; # integer32 $self->{unused24} = undef; # integer32 $self->{unused25} = undef; # integer32 $self->{unused26} = undef; # integer32 $self->{leven} = undef; # integer32 $self->{lpspol} = undef; # integer32 $self->{lovrok} = undef; # integer32 $self->{icalda} = undef; # integer32 $self->{unused27} = undef; # integer32 $self->{kstnm} = undef; # ascii8 $self->{kevnm} = undef; # ascii16 $self->{khole} = undef; # ascii8 $self->{ko} = undef; # ascii8 $self->{ka} = undef; # ascii8 $self->{kt0} = undef; # ascii8 $self->{kt1} = undef; # ascii8 $self->{kt2} = undef; # ascii8 $self->{kt3} = undef; # ascii8 $self->{kt4} = undef; # ascii8 $self->{kt5} = undef; # ascii8 $self->{kt6} = undef; # ascii8 $self->{kt7} = undef; # ascii8 $self->{kt8} = undef; # ascii8 $self->{kt9} = undef; # ascii8 $self->{kf} = undef; # ascii8 $self->{kuser0} = undef; # ascii8 $self->{kuser1} = undef; # ascii8 $self->{kuser2} = undef; # ascii8 $self->{kcmpnm} = undef; # ascii8 $self->{knetwk} = undef; # ascii8 $self->{kdatrd} = undef; # ascii8 $self->{kinst} = undef; # ascii8 $self->{datasamples} = (); # Data samples bless ($self, $class); # Parse if a file was supplied if ( $self->{SACfile} ) { $self->parse( $self->{SACfile} ); } return $self; } # # Parse a binary SAC file into this object (instance) # sub parse { my $self = shift; confess "usage: object->parse(SACfile)" unless @_ == 1; $self->{SACfile} = shift; if ( ! -f "$self->{SACfile}" ) { carp "SAC::parse Cannot find file $self->{SACfile}\n"; return undef; } my $filesize = -s "$self->{SACfile}"; # SAC binary header is 632, sanity check that the file is minimum size if ( $filesize < 632 ) { carp "SAC::parse File size is too small ($filesize bytes)\n"; return undef; } my $binblock = undef; open (IN, "<$self->{SACfile}") || croak "SAC::parse Cannot open input file '$self->{SACfile}': $!\n"; binmode (IN, ":raw") || croak "SAC::parse Cannot set binary file mode to raw for '$self->{SACfile}': $!\n"; read (IN, $binblock, $filesize) || croak "SAC::parse Error reading '$self->{SACfile}': $!\n"; close (IN) || croak "SAC::parse Error closing '$self->{SACfile}': $!\n"; # Parse SAC header values, set values to Perl undefined if undefined $self->{delta} = unpack("x0 f", $binblock); $self->{delta} = undef if ( $self->{delta} == -12345. ); $self->{depmin} = unpack("x4 f", $binblock); $self->{depmin} = undef if ( $self->{depmin} == -12345. ); $self->{depmax} = unpack("x8 f", $binblock); $self->{depmax} = undef if ( $self->{depmax} == -12345. ); $self->{scale} = unpack("x12 f", $binblock); $self->{scale} = undef if ( $self->{scale} == -12345. ); $self->{odelta} = unpack("x16 f", $binblock); $self->{odelta} = undef if ( $self->{odelta} == -12345. ); $self->{b} = unpack("x20 f", $binblock); $self->{b} = undef if ( $self->{b} == -12345. ); $self->{e} = unpack("x24 f", $binblock); $self->{e} = undef if ( $self->{e} == -12345. ); $self->{o} = unpack("x28 f", $binblock); $self->{o} = undef if ( $self->{o} == -12345. ); $self->{a} = unpack("x32 f", $binblock); $self->{a} = undef if ( $self->{a} == -12345. ); $self->{fmt} = unpack("x36 f", $binblock); $self->{fmt} = undef if ( $self->{fmt} == -12345. ); $self->{t0} = unpack("x40 f", $binblock); $self->{t0} = undef if ( $self->{t0} == -12345. ); $self->{t1} = unpack("x44 f", $binblock); $self->{t1} = undef if ( $self->{t1} == -12345. ); $self->{t2} = unpack("x48 f", $binblock); $self->{t2} = undef if ( $self->{t2} == -12345. ); $self->{t3} = unpack("x52 f", $binblock); $self->{t3} = undef if ( $self->{t3} == -12345. ); $self->{t4} = unpack("x56 f", $binblock); $self->{t4} = undef if ( $self->{t4} == -12345. ); $self->{t5} = unpack("x60 f", $binblock); $self->{t5} = undef if ( $self->{t5} == -12345. ); $self->{t6} = unpack("x64 f", $binblock); $self->{t6} = undef if ( $self->{t6} == -12345. ); $self->{t7} = unpack("x68 f", $binblock); $self->{t7} = undef if ( $self->{t7} == -12345. ); $self->{t8} = unpack("x72 f", $binblock); $self->{t8} = undef if ( $self->{t8} == -12345. ); $self->{t9} = unpack("x76 f", $binblock); $self->{t9} = undef if ( $self->{t9} == -12345. ); $self->{f} = unpack("x80 f", $binblock); $self->{f} = undef if ( $self->{f} == -12345. ); $self->{resp0} = unpack("x84 f", $binblock); $self->{resp0} = undef if ( $self->{resp0} == -12345. ); $self->{resp1} = unpack("x88 f", $binblock); $self->{resp1} = undef if ( $self->{resp1} == -12345. ); $self->{resp2} = unpack("x92 f", $binblock); $self->{resp2} = undef if ( $self->{resp2} == -12345. ); $self->{resp3} = unpack("x96 f", $binblock); $self->{resp3} = undef if ( $self->{resp3} == -12345. ); $self->{resp4} = unpack("x100 f", $binblock); $self->{resp4} = undef if ( $self->{resp4} == -12345. ); $self->{resp5} = unpack("x104 f", $binblock); $self->{resp5} = undef if ( $self->{resp5} == -12345. ); $self->{resp6} = unpack("x108 f", $binblock); $self->{resp6} = undef if ( $self->{resp6} == -12345. ); $self->{resp7} = unpack("x112 f", $binblock); $self->{resp7} = undef if ( $self->{resp7} == -12345. ); $self->{resp8} = unpack("x116 f", $binblock); $self->{resp8} = undef if ( $self->{resp8} == -12345. ); $self->{resp9} = unpack("x120 f", $binblock); $self->{resp9} = undef if ( $self->{resp9} == -12345. ); $self->{stla} = unpack("x124 f", $binblock); $self->{stla} = undef if ( $self->{stla} == -12345. ); $self->{stlo} = unpack("x128 f", $binblock); $self->{stlo} = undef if ( $self->{stlo} == -12345. ); $self->{stel} = unpack("x132 f", $binblock); $self->{stel} = undef if ( $self->{stel} == -12345. ); $self->{stdp} = unpack("x136 f", $binblock); $self->{stdp} = undef if ( $self->{stdp} == -12345. ); $self->{evla} = unpack("x140 f", $binblock); $self->{evla} = undef if ( $self->{evla} == -12345. ); $self->{evlo} = unpack("x144 f", $binblock); $self->{evlo} = undef if ( $self->{evlo} == -12345. ); $self->{evel} = unpack("x148 f", $binblock); $self->{evel} = undef if ( $self->{evel} == -12345. ); $self->{evdp} = unpack("x152 f", $binblock); $self->{evdp} = undef if ( $self->{evdp} == -12345. ); $self->{mag} = unpack("x156 f", $binblock); $self->{mag} = undef if ( $self->{mag} == -12345. ); $self->{user0} = unpack("x160 f", $binblock); $self->{user0} = undef if ( $self->{user0} == -12345. ); $self->{user1} = unpack("x164 f", $binblock); $self->{user1} = undef if ( $self->{user1} == -12345. ); $self->{user2} = unpack("x168 f", $binblock); $self->{user2} = undef if ( $self->{user2} == -12345. ); $self->{user3} = unpack("x172 f", $binblock); $self->{user3} = undef if ( $self->{user3} == -12345. ); $self->{user4} = unpack("x176 f", $binblock); $self->{user4} = undef if ( $self->{user4} == -12345. ); $self->{user5} = unpack("x180 f", $binblock); $self->{user5} = undef if ( $self->{user5} == -12345. ); $self->{user6} = unpack("x184 f", $binblock); $self->{user6} = undef if ( $self->{user6} == -12345. ); $self->{user7} = unpack("x188 f", $binblock); $self->{user7} = undef if ( $self->{user7} == -12345. ); $self->{user8} = unpack("x192 f", $binblock); $self->{user8} = undef if ( $self->{user8} == -12345. ); $self->{user9} = unpack("x196 f", $binblock); $self->{user9} = undef if ( $self->{user9} == -12345. ); $self->{dist} = unpack("x200 f", $binblock); $self->{dist} = undef if ( $self->{dist} == -12345. ); $self->{az} = unpack("x204 f", $binblock); $self->{az} = undef if ( $self->{az} == -12345. ); $self->{baz} = unpack("x208 f", $binblock); $self->{baz} = undef if ( $self->{baz} == -12345. ); $self->{gcarc} = unpack("x212 f", $binblock); $self->{gcarc} = undef if ( $self->{gcarc} == -12345. ); $self->{sb} = unpack("x216 f", $binblock); $self->{sb} = undef if ( $self->{sb} == -12345. ); $self->{sdelta} = unpack("x220 f", $binblock); $self->{sdelta} = undef if ( $self->{sdelta} == -12345. ); $self->{depmen} = unpack("x224 f", $binblock); $self->{depmen} = undef if ( $self->{depmen} == -12345. ); $self->{cmpaz} = unpack("x228 f", $binblock); $self->{cmpaz} = undef if ( $self->{cmpaz} == -12345. ); $self->{cmpinc} = unpack("x232 f", $binblock); $self->{cmpinc} = undef if ( $self->{cmpinc} == -12345. ); $self->{xminimum} = unpack("x236 f", $binblock); $self->{xminimum} = undef if ( $self->{xminimum} == -12345. ); $self->{xmaximum} = unpack("x240 f", $binblock); $self->{xmaximum} = undef if ( $self->{xmaximum} == -12345. ); $self->{yminimum} = unpack("x244 f", $binblock); $self->{yminimum} = undef if ( $self->{yminimum} == -12345. ); $self->{ymaximum} = unpack("x248 f", $binblock); $self->{ymaximum} = undef if ( $self->{ymaximum} == -12345. ); $self->{unused6} = unpack("x252 f", $binblock); $self->{unused6} = undef if ( $self->{unused6} == -12345. ); $self->{unused7} = unpack("x256 f", $binblock); $self->{unused7} = undef if ( $self->{unused7} == -12345. ); $self->{unused8} = unpack("x260 f", $binblock); $self->{unused8} = undef if ( $self->{unused8} == -12345. ); $self->{unused9} = unpack("x264 f", $binblock); $self->{unused9} = undef if ( $self->{unused9} == -12345. ); $self->{unused10} = unpack("x268 f", $binblock); $self->{unused10} = undef if ( $self->{unused10} == -12345. ); $self->{unused11} = unpack("x272 f", $binblock); $self->{unused11} = undef if ( $self->{unused11} == -12345. ); $self->{unused12} = unpack("x276 f", $binblock); $self->{unused12} = undef if ( $self->{unused12} == -12345. ); $self->{nzyear} = unpack("x280 l", $binblock); $self->{nzyear} = undef if ( $self->{nzyear} == -12345 ); $self->{nzjday} = unpack("x284 l", $binblock); $self->{nzjday} = undef if ( $self->{nzjday} == -12345 ); $self->{nzhour} = unpack("x288 l", $binblock); $self->{nzhour} = undef if ( $self->{nzhour} == -12345 ); $self->{nzmin} = unpack("x292 l", $binblock); $self->{nzmin} = undef if ( $self->{nzmin} == -12345 ); $self->{nzsec} = unpack("x296 l", $binblock); $self->{nzsec} = undef if ( $self->{nzsec} == -12345 ); $self->{nzmsec} = unpack("x300 l", $binblock); $self->{nzmsec} = undef if ( $self->{nzmsec} == -12345 ); $self->{nvhdr} = unpack("x304 l", $binblock); $self->{nvhdr} = undef if ( $self->{nvhdr} == -12345 ); $self->{norid} = unpack("x308 l", $binblock); $self->{norid} = undef if ( $self->{norid} == -12345 ); $self->{nevid} = unpack("x312 l", $binblock); $self->{nevid} = undef if ( $self->{nevid} == -12345 ); $self->{npts} = unpack("x316 l", $binblock); $self->{npts} = undef if ( $self->{npts} == -12345 ); $self->{nsnpts} = unpack("x320 l", $binblock); $self->{nsnpts} = undef if ( $self->{nsnpts} == -12345 ); $self->{nwfid} = unpack("x324 l", $binblock); $self->{nwfid} = undef if ( $self->{nwfid} == -12345 ); $self->{nxsize} = unpack("x338 l", $binblock); $self->{nxsize} = undef if ( $self->{nxsize} == -12345 ); $self->{nysize} = unpack("x332 l", $binblock); $self->{nysize} = undef if ( $self->{nysize} == -12345 ); $self->{unused15} = unpack("x336 l", $binblock); $self->{unused15} = undef if ( $self->{unused15} == -12345 ); $self->{iftype} = unpack("x340 l", $binblock); $self->{iftype} = undef if ( $self->{iftype} == -12345 ); $self->{idep} = unpack("x344 l", $binblock); $self->{idep} = undef if ( $self->{idep} == -12345 ); $self->{iztype} = unpack("x348 l", $binblock); $self->{iztype} = undef if ( $self->{iztype} == -12345 ); $self->{unused16} = unpack("x352 l", $binblock); $self->{unused16} = undef if ( $self->{unused16} == -12345 ); $self->{iinst} = unpack("x356 l", $binblock); $self->{iinst} = undef if ( $self->{iinst} == -12345 ); $self->{istreg} = unpack("x360 l", $binblock); $self->{istreg} = undef if ( $self->{istreg} == -12345 ); $self->{ievreg} = unpack("x364 l", $binblock); $self->{ievreg} = undef if ( $self->{ievreg} == -12345 ); $self->{ievtyp} = unpack("x368 l", $binblock); $self->{ievtyp} = undef if ( $self->{ievtyp} == -12345 ); $self->{iqual} = unpack("x372 l", $binblock); $self->{iqual} = undef if ( $self->{iqual} == -12345 ); $self->{isynth} = unpack("x376 l", $binblock); $self->{isynth} = undef if ( $self->{isynth} == -12345 ); $self->{imagtyp} = unpack("x380 l", $binblock); $self->{imagtyp} = undef if ( $self->{imagtyp} == -12345 ); $self->{imagsrc} = unpack("x384 l", $binblock); $self->{imagsrc} = undef if ( $self->{imagsrc} == -12345 ); $self->{unused19} = unpack("x388 l", $binblock); $self->{unused19} = undef if ( $self->{unused19} == -12345 ); $self->{unused20} = unpack("x392 l", $binblock); $self->{unused20} = undef if ( $self->{unused20} == -12345 ); $self->{unused21} = unpack("x396 l", $binblock); $self->{unused21} = undef if ( $self->{unused21} == -12345 ); $self->{unused22} = unpack("x400 l", $binblock); $self->{unused22} = undef if ( $self->{unused22} == -12345 ); $self->{unused23} = unpack("x404 l", $binblock); $self->{unused23} = undef if ( $self->{unused23} == -12345 ); $self->{unused24} = unpack("x408 l", $binblock); $self->{unused24} = undef if ( $self->{unused24} == -12345 ); $self->{unused25} = unpack("x412 l", $binblock); $self->{unused25} = undef if ( $self->{unused25} == -12345 ); $self->{unused26} = unpack("x416 l", $binblock); $self->{unused26} = undef if ( $self->{unused26} == -12345 ); $self->{leven} = unpack("x420 l", $binblock); $self->{leven} = undef if ( $self->{leven} == -12345 ); $self->{lpspol} = unpack("x424 l", $binblock); $self->{lpspol} = undef if ( $self->{lpspol} == -12345 ); $self->{lovrok} = unpack("x428 l", $binblock); $self->{lovrok} = undef if ( $self->{lovrok} == -12345 ); $self->{icalda} = unpack("x432 l", $binblock); $self->{icalda} = undef if ( $self->{icalda} == -12345 ); $self->{unused27} = unpack("x436 l", $binblock); $self->{unused27} = undef if ( $self->{unused27} == -12345 ); $self->{kstnm} = substr($binblock, 440, 8); $self->{kstnm} = undef if ( $self->{kstnm} eq "-12345 " ); $self->{kstnm} =~ s/\0//g; $self->{kevnm} = substr($binblock, 448, 16); $self->{kevnm} = undef if ( $self->{kevnm} eq "-12345 " ); $self->{kevnm} =~ s/\0//g; $self->{khole} = substr($binblock, 464, 8); $self->{khole} = undef if ( $self->{khole} eq "-12345 " ); $self->{khole} =~ s/\0//g; $self->{ko} = substr($binblock, 472, 8); $self->{ko} = undef if ( $self->{ko} eq "-12345 " ); $self->{ko} =~ s/\0//g; $self->{ka} = substr($binblock, 480, 8); $self->{ka} = undef if ( $self->{ka} eq "-12345 " ); $self->{ka} =~ s/\0//g; $self->{kt0} = substr($binblock, 488, 8); $self->{kt0} = undef if ( $self->{kt0} eq "-12345 " ); $self->{kt0} =~ s/\0//g; $self->{kt1} = substr($binblock, 496, 8); $self->{kt1} = undef if ( $self->{kt1} eq "-12345 " ); $self->{kt1} =~ s/\0//g; $self->{kt2} = substr($binblock, 504, 8); $self->{kt2} = undef if ( $self->{kt2} eq "-12345 " ); $self->{kt2} =~ s/\0//g; $self->{kt3} = substr($binblock, 512, 8); $self->{kt3} = undef if ( $self->{kt3} eq "-12345 " ); $self->{kt3} =~ s/\0//g; $self->{kt4} = substr($binblock, 520, 8); $self->{kt4} = undef if ( $self->{kt4} eq "-12345 " ); $self->{kt4} =~ s/\0//g; $self->{kt5} = substr($binblock, 528, 8); $self->{kt5} = undef if ( $self->{kt5} eq "-12345 " ); $self->{kt5} =~ s/\0//g; $self->{kt6} = substr($binblock, 536, 8); $self->{kt6} = undef if ( $self->{kt6} eq "-12345 " ); $self->{kt6} =~ s/\0//g; $self->{kt7} = substr($binblock, 544, 8); $self->{kt7} = undef if ( $self->{kt7} eq "-12345 " ); $self->{kt7} =~ s/\0//g; $self->{kt8} = substr($binblock, 552, 8); $self->{kt8} = undef if ( $self->{kt8} eq "-12345 " ); $self->{kt8} =~ s/\0//g; $self->{kt9} = substr($binblock, 560, 8); $self->{kt9} = undef if ( $self->{kt9} eq "-12345 " ); $self->{kt9} =~ s/\0//g; $self->{kf} = substr($binblock, 568, 8); $self->{kf} = undef if ( $self->{kf} eq "-12345 " ); $self->{kuser0} = substr($binblock, 576, 8); $self->{kuser0} = undef if ( $self->{kuser0} eq "-12345 " ); $self->{kuser0} =~ s/\0//g; $self->{kuser1} = substr($binblock, 584, 8); $self->{kuser1} = undef if ( $self->{kuser1} eq "-12345 " ); $self->{kuser1} =~ s/\0//g; $self->{kuser2} = substr($binblock, 592, 8); $self->{kuser2} = undef if ( $self->{kuser2} eq "-12345 " ); $self->{kuser2} =~ s/\0//g; $self->{kcmpnm} = substr($binblock, 600, 8); $self->{kcmpnm} = undef if ( $self->{kcmpnm} eq "-12345 " ); $self->{kcmpnm} =~ s/\0//g; $self->{knetwk} = substr($binblock, 608, 8); $self->{knetwk} = undef if ( $self->{knetwk} eq "-12345 " ); $self->{knetwk} =~ s/\0//g; $self->{kdatrd} = substr($binblock, 618, 8); $self->{kdatrd} = undef if ( $self->{kdatrd} eq "-12345 " ); $self->{kdatrd} =~ s/\0//g; $self->{kinst} = substr($binblock, 624, 8); $self->{kinst} = undef if ( $self->{kinst} eq "-12345 " ); $self->{kinst} =~ s/\0//g; if ( $filesize != (632 + ($self->{npts} * 4)) ) { carp "SAC::parse File was unexpected size for header and $self->npts samples\n"; return undef; } # Parse float32 data samples @{$self->{datasamples}} = unpack("x632 f$self->{npts}", $binblock); } # # Print out the object data (see main class notes) # sub print { my $self = shift; my $level = ( @_ ) ? shift : 0; # If level is 0 only print a single line for each record if ( $level == 0 ) { printf $self->sourceName; printf " %s,", $self->startTimeString(); printf " %s samps,", $self->{npts}; printf " %.6g sps\n", $self->sampleRate(); } elsif ( $level > 0 ) { printf $self->sourceName; printf " %s,", $self->startTimeString(); printf " %s samps,", $self->{npts}; printf " %.6g sps\n", $self->sampleRate(); # ToDo: scaling, units and event information } return $level; } # # Return the source name as Net_Sta_Loc_Chan (Loc == KHOLE) # sub sourceName { my $self = shift; return sprintf ("%s_%s_%s_%s", $self->{knetwk}, $self->{kstnm}, $self->{khole}, $self->{kcmpnm}); } # # Return the sample rate as samples/second # sub sampleRate { my $self = shift; return ($self->{delta}) ? 1 / $self->{delta} : 0; } # # Return an start time as an ASCII string. # sub startTimeString { my $self = shift; return sprintf ("%d,%d,%02d:%02d:%02d.%03d", $self->{nzyear}, $self->{nzjday}, $self->{nzhour}, $self->{nzmin}, $self->{nzsec}, $self->{nzmsec}); } # # Return start time as double precision POSIX epoch # sub startTimeDepoch { my $self = shift; return $self->depoch ( $self->{nzyear}, $self->{nzjday}, $self->{nzhour}, $self->{nzmin}, $self->{nzsec}, $self->{nzmsec} ); } # # Compute a double precision POSIX epoch from 6 arguments: # Year, Yday, Hour, Min, Sec, MilliSec # Arguments should be passed in the above order. # Lower significance values are interpreted as 0 if not given, # for example: '2002,201' == '2002,201,0,0,0,0' # sub depoch { my $self = shift; my $year = shift; my $yday = shift; my $hour = shift; my $min = shift; my $sec = shift; my $msec = shift; if ( ! defined $year ) { $year = 0; } if ( ! defined $yday ) { $yday = 1; } if ( ! defined $hour ) { $hour = 0; } if ( ! defined $min ) { $min = 0; } if ( ! defined $sec ) { $sec = 0; } if ( ! defined $msec ) { $msec = 0; } confess("usage: object->depoch(Year,Yday,Hour,Min,Sec,MSec).\n") unless $year; # Calculate epoch my $shortyear = $year - 1900; my $a4 = int (($shortyear >> 2) + 475 - ! ($shortyear & 3)); my $a100 = int ($a4 / 25 - (($a4 % 25) < 0)); my $a400 = int ($a100 >> 2); my $intervening_leap_days = ($a4 - 492) - ($a100 - 19) + ($a400 - 4); my $days = (365 * ($shortyear - 70) + $intervening_leap_days + ($yday - 1)); my $depoch = (60 * (60 * (24 * $days + $hour) + $min) + $sec) + $msec / 1000; return $depoch; } # # Swap 4 bytes if the host machine operates in little-endian word order # sub lsbswap4 { my $self = shift; confess "usage: object->lsbswap4(bytes). Passed $#_ arguments" unless @_ == 1; my $bytes = shift; if ( unpack( 'c', pack( 's', 1 ) ) ) { my @parts = unpack("a a a a", $bytes); return $parts[3] . $parts[2] . $parts[1] . $parts[0]; } else { return $bytes; } }