[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