[Shake-dev] cdmg2xml with NSMP xml files

Bill Gustafson billg at ess.washington.edu
Fri Apr 20 17:05:49 GMT 2007


Vince Quitoriano wrote:
>
> Hi,
>
> Try this program we use for Global ShakeMap.
Hi Vince,

I tested it this morning, and it worked great.

Thanks,

Bill
>
> - Vince
>
> Bill Gustafson wrote:
>> Hi All,
>>
>> I want to take NSMP xml files and convert them into shakemap readable 
>> xml files.  I tried using cdmg2xml with the -nsmp flag and it didn't 
>> work.  It created a file called nsmp_dat.xml but the data didn't seem 
>> to be translated correctly.  I have taken the same NSMP file, and 
>> manually inserted it into a shakemap format xml file, and it appeared 
>> to work correctly.
>>
>> Before I get carried away with rewriting cdmg2xml I thought I would 
>> check with this list, and see if anyone out there had already done 
>> this.  Also, it occurs to me that maybe the format of the NSMP xml 
>> files I have is odd in some way, or maybe I ran cdmg2xml 
>> incorrectly.  I am using Shakemap 3.1 on Solaris.
>> Any advice that people out there have would be helpful.
>>
>> Thanks,
>>
>> Bill
>>
>> _______________________________________________
>> Shake-dev mailing list
>> Shake-dev at scsnmail.gps.caltech.edu
>> http://unix1.gps.caltech.edu/mailman/listinfo/shake-dev
>>
> ------------------------------------------------------------------------
>
> #!/usr/bin/perl 
>
> #	@(#)nsmp2xml	1.14	11/19/03	TriNet
>
> use File::Path;
> use IO::File;
> use FindBin;
> use lib "$FindBin::Bin/../lib";
> use ShakeConfig;
> use lib "$shake_perl_lib";
> use Shake::Die;
> use Shake::Opt;
> use XML::Writer;
> use XML::Simple;
> use strict;
>
> #######################################################################
> # Global variables
> #######################################################################
>
> my $fh;			# The output (XML) filehandle
> my $fin;		# The input (jb) filehandle
> my $writer;		# The XML::Writer object
> my $outfile;
> my $filetag = 'nsmp';
> my $dtdfile = "$shake_home/lib/xml/stationlist.dtd";
> my $agency  = 'NSMP';
>
> #######################################################################
> # End global variables
> #######################################################################
>
> #######################################################################
> # Stuff to handle command line options and program documentation:
> #######################################################################
>
> my $desc = "Generate XML file (following the stationlist.dtd spec) "
> 	 . "in '$shake_home/data/<EVENTID>/input' "
> 	 . "from NSMP xml file.";
>
> my $flgs = [{ FLAG => 'event',
>               ARG  => 'event_id',
>               TYPE => 's',
>               REQ  => 'y',
>               DESC => 'Specifies the id of the event to process'},
> 		{ FLAG => 'file',
> 		  ARG  => 'filename',
> 		  REQ  => 'y',
> 		  DESC => 'NSMP XML file'},
>             { FLAG => 'help',
>               DESC => 'Print program documentation and quit.'}
>            ];
>
> my $options = Opt::setOptions($flgs) or Die "Error in setOptions";
>
> if (defined $options->{'help'}) {
>   Opt::printDoc($desc);
>   exit 0;
> }
>
> defined $options->{'event'}
>         or Die "Must specify an event with -event flag";
>
> my $evid    = $options->{'event'};
> my $input   = $options->{'file'};
>
> my $outfile = $input;
> $outfile =~ s/\.[^.]+$//;
> $outfile .= "_dat.xml";
>
> Die "Unknown argument(s): @ARGV" if (@ARGV);
>
> #######################################################################
> # End of command line option stuff
> #######################################################################
>
> main();
> 0;
>
> sub main {
>
>   my $ctime = time;
>   #----------------------------------------------------------------------
>   # Open the DTD file for reading
>   #----------------------------------------------------------------------
>   my $dtdfh = new IO::File($dtdfile) or Die "Couldn't open $dtdfile";
>   #----------------------------------------------------------------------
>   # Open the input and output files
>   #----------------------------------------------------------------------
>   my $basepath = "$shake_home/data/$evid";
>   if (-e "$basepath/raw/$input") {
>     $input = "$basepath/raw/$input";
>   }
>   elsif (!-e $input) {
>     Die "Couldn't find file '$basepath/raw/$input'";
>   }
>   $fin = new IO::File "< $input" 
> 		or Die "Couldn't open $input";
>
>   $basepath .= "/input";
>   if (!-e "$basepath") {
>     mkpath("$basepath", 0, 0755) 
> 		or Die "Couldn't create $basepath";
>   }
>   $fh = new IO::File "> $basepath/$outfile" 
> 		or Die "Couldn't open $basepath/$outfile";
>
>   #----------------------------------------------------------------------
>   # Create the XML::Writer object; the "NEWLINES" implementation is a 
>   # disaster so we don't use it, and hence have to add our own all
>   # over the place
>   #----------------------------------------------------------------------
>   $writer = new XML::Writer(OUTPUT => \*$fh, NEWLINES => 0);
>
>   #----------------------------------------------------------------------
>   # Start the document with the XML declaration, and add the
>   # document type declaration just in case anyone cares; also 
>   # print the root element
>   #----------------------------------------------------------------------
>   $writer->xmlDecl("US-ASCII", "yes");
> #  print $fh '<!DOCTYPE stationlist [', "\n";
> #  while (<$dtdfh>) {
> #    print $fh $_;
> #  }
> #  $dtdfh->close;
> #  print $fh ']>', "\n";
>
>   $writer->startTag("stationlist", "created" => $ctime);
>   $writer->characters("\n");
>
>   my $amps = parse_xml($input);
>     
>   my $comps = $amps->{record}{station};
>   my $source = $amps->{agency};
> #  my $trigger = triggertime($station->{timing});
>
>   my ($sta,$loc,$lat,$lon,$compname,$pga,$pgv,$sp03,$sp10,$sp30);
>   my @complist;
>   foreach my $comp (@$comps) {
>     $sta = $comp->{code};
>     $lat = $comp->{lat};
>     $lon = $comp->{lon};
>     $loc = $comp->{name};
>
>     my $c = $comp->{component};
>     $pga = $c->{acc}{value};
>     $pgv = $c->{vel}{value};
>     $sp03 = $c->{sa}{'0.3'}{value}; 
>     $sp10 = $c->{sa}{'1.0'}{value};
>     $sp30 = $c->{sa}{'3.0'}{value};
>     $compname = $c->{name};
>     push @complist,[$compname,$pga,$pgv,$sp03,$sp10,$sp30];
>   }
>   new_sta($sta, $loc, $lat, $lon, $source);
>   foreach my $comp (@complist) {
>     ($compname,$pga,$pgv,$sp03,$sp10,$sp30) = @$comp;
>     new_comp($compname);
>     write_amp('acc', fmt($pga/9.8));
>     write_amp('vel', fmt($pgv));
>     if ($sp03 or $sp10 or $sp30) {
>       write_amp('psa03', fmt($sp03/9.8)); print "Got $sp03\n";
>       write_amp('psa10', fmt($sp10/9.8));
>       write_amp('psa30', fmt($sp30/9.8));
>     }
>     end_comp();
>   }
>   end_sta();
>   $fin->close;
>
>   $writer->characters("\n");
>   $writer->endTag("stationlist");
>   $writer->end();
>   $fh->close;
>   0;
> }
>
> sub new_sta {
>   
>   my $sta  = shift;
>   my $name = shift;
>
>   my $lat  = shift;
>   my $lon  = shift;
>   my $source = shift;
>
>
>   $writer->startTag("station", "code"     => $sta, 
> 			       "name"     => $name, 
> 			       "insttype" => 'UNK', 
> 			       "lat"      => $lat, 
> 			       "lon"      => $lon, 
> 			       "source"   => $source, 
> 			       "commtype" => 'UNK');
>   $writer->characters("\n");
>   return 1;
> }
>
> sub end_sta {
>
>   $writer->endTag("station");
>   $writer->characters("\n");
>   return 0;
> }
>
> sub new_comp {
>
>   my $comp = shift;
>
>   $writer->startTag("comp", "name" => "$comp");
>   $writer->characters("\n");
>   return 0;
> }
>
> sub end_comp {
>
>   $writer->endTag("comp");
>   $writer->characters("\n");
>   return 0;
> }
>
> sub write_amp {
>
>   my ($type, $amp) = @_;
>
>   if (not defined $type or not defined $amp) {
>     Die "nsmp2xml::write_amp: (type, amp) must be specified";
>     return 1;
>   }
>   $writer->emptyTag("$type", "value", "$amp");
>   $writer->characters("\n");
>   return 0;
> }
>
> sub fmt {
>
>   return sprintf "%.4f", shift;
> }
>
> sub parse_xml {
>   my $file = shift;
>
>   my $ref = XMLin($file,'KeyAttr'=>['period']);
>   
>   return $ref;
> }
>
>   
>
>    
>
>
>   


-- 
Bill Gustafson          Res Eng/Sr Comp Spc
KSRSL/PNSN              Phone: (206)685-8266/(206)543-8928
Dept. of Earth and Space Sciences
Box 351310, UW, Seattle, WA  98195-1310
http://alumnus.caltech.edu/~billg/bill.htm





More information about the Shake-dev mailing list