plotrecfunc.cpp
Go to the documentation of this file.00001 #include "SeismicStationList.h"
00002 #include <iostream>
00003 #include <string>
00004 #include <vector>
00005 #include <functional>
00006 #include <boost/bind.hpp>
00007 #include <boost/function.hpp>
00008 #include <fstream>
00009 #include "Util.h"
00010 #include "netcdfcpp.h"
00011 #include "statutils.h"
00012
00013 using namespace std;
00014 using namespace gplib;
00015
00016 void WriteToNetCDF(string filename, SeismicStationList &Stations,
00017 boost::function<double(SeismicDataComp *)> f)
00018 {
00019 const size_t nsamples = Stations.GetList().front()->GetData().size();
00020 const size_t nstations = Stations.GetList().size();
00021
00022 sort(Stations.GetList().begin(), Stations.GetList().end(), boost::bind(
00023 less<double> (), boost::bind(f, boost::bind(&boost::shared_ptr<
00024 SeismicDataComp>::get, _1)), boost::bind(f, boost::bind(
00025 &boost::shared_ptr<SeismicDataComp>::get, _2))));
00026 size_t nCompatStations = 0;
00027 for (size_t i = 0; i < nstations; ++i)
00028 {
00029 if (nsamples == Stations.GetList().at(i)->GetData().size())
00030 {
00031 ++nCompatStations;
00032 }
00033 }
00034
00035 NcFile combrescdf((filename + ".nc").c_str(), NcFile::Replace);
00036 NcDim* xd = combrescdf.add_dim("x", nCompatStations);
00037 NcDim* yd = combrescdf.add_dim("y", nsamples);
00038 NcVar* x = combrescdf.add_var("x", ncFloat, xd);
00039 NcVar* y = combrescdf.add_var("y", ncFloat, yd);
00040 NcVar* z = combrescdf.add_var("z", ncFloat, xd, yd);
00041 float *xvals = new float[xd->size()];
00042 float *yvals = new float[yd->size()];
00043 float *zvals = new float[xd->size() * yd->size()];
00044
00045 for (size_t j = 0; j < nsamples; ++j)
00046 yvals[j] = j * Stations.GetList().front()->GetDt()
00047 + Stations.GetList().front()->GetB();
00048 size_t dataindex = 0;
00049 size_t stationindex = 0;
00050 while (dataindex < nCompatStations)
00051 {
00052 xvals[dataindex] = f(Stations.GetList().at(stationindex).get());
00053 if (nsamples == Stations.GetList().at(stationindex)->GetData().size())
00054 {
00055 copy(Stations.GetList().at(stationindex)->GetData().begin(),
00056 Stations.GetList().at(stationindex)->GetData().end(),
00057 &zvals[dataindex * nsamples]);
00058 ++dataindex;
00059 }
00060 else
00061 {
00062 cerr << "File: " << Stations.GetList().at(stationindex)->GetName()
00063 << " " << "has incompatible length: " << Stations.GetList().at(
00064 stationindex)->GetData().size() << " not " << nsamples << endl;
00065 }
00066 ++stationindex;
00067 }
00068 x->put(xvals, xd->size());
00069 y->put(yvals, yd->size());
00070 z->put(zvals, z->edges());
00071
00072 delete[] xvals;
00073 delete[] yvals;
00074 delete[] zvals;
00075 }
00076
00077 int main(int argc, char* argv[])
00078 {
00079 SeismicStationList Stations;
00080 string listfilename, outfilename;
00081
00082 string version =
00083 "$Id: plotrecfunc.cpp 1816 2009-09-07 11:28:35Z mmoorkamp $";
00084 cout << endl << endl;
00085 cout << "Program " << version << endl;
00086 cout << " Print a number of receiver functions in one plot" << endl;
00087 cout
00088 << " Input is a list of files, output an ascii file for plotting with xmgrace and a netcdf file"
00089 << endl;
00090 cout
00091 << " Individual receiver functions are offset in y-direction by the chosen sorting criterion"
00092 << endl;
00093 cout << endl << endl;
00094 if (argc > 2)
00095 {
00096 listfilename = argv[1];
00097 outfilename = argv[2];
00098 }
00099 else
00100 {
00101 listfilename = AskFilename("List filename: ");
00102 outfilename = AskFilename("Output filename: ");
00103 }
00104 boost::function<double(SeismicDataComp*)> SortFunc;
00105 size_t sortchoice;
00106 cout << "Specify Sorting Criterion: " << endl;
00107 cout << " 1: Distance " << endl;
00108 cout << " 2: Backazimuth " << endl;
00109 cin >> sortchoice;
00110 switch (sortchoice)
00111 {
00112 case 1:
00113 SortFunc = &SeismicDataComp::GetGcarc;
00114 break;
00115 case 2:
00116 SortFunc = &SeismicDataComp::GetBaz;
00117 break;
00118 default:
00119 cerr << "Invalid choice !";
00120 return 100;
00121 break;
00122 }
00123 Stations.ReadList(listfilename);
00124 vector<double> distances(Stations.GetList().size(), 0.0);
00125 transform(Stations.GetList().begin(), Stations.GetList().end(),
00126 distances.begin(), boost::bind(SortFunc, boost::bind(
00127 &boost::shared_ptr<SeismicDataComp>::get, _1)));
00128 cout << "Parameters: " << endl;
00129 copy(distances.begin(), distances.end(), ostream_iterator<double> (cout,
00130 "\n"));
00131 cout << endl;
00132 double meandist = Mean(distances.begin(), distances.end());
00133 cout << "Mean Parameter: " << meandist << endl;
00134 vector<double> maxamps;
00135 for (SeismicStationList::tseiscompvector::iterator CurrentStation =
00136 Stations.GetList().begin(); CurrentStation != Stations.GetList().end(); CurrentStation++)
00137 {
00138 double currmax = *max_element(CurrentStation->get()->GetData().begin(),
00139 CurrentStation->get()->GetData().end());
00140 if (!isnan(currmax))
00141 maxamps.push_back(currmax);
00142 }
00143 double meanamp = Mean(maxamps.begin(), maxamps.end());
00144 double yshift = 5.0 * meanamp / meandist;
00145 cout << " Mean Amp: " << meanamp << endl;
00146 ofstream outfile(outfilename.c_str());
00147 for (SeismicStationList::tseiscompvector::iterator CurrentStation =
00148 Stations.GetList().begin(); CurrentStation != Stations.GetList().end(); CurrentStation++)
00149 {
00150 for (size_t i = 0; i < CurrentStation->get()->GetData().size(); ++i)
00151 {
00152 outfile << i * CurrentStation->get()->GetDt()
00153 + CurrentStation->get()->GetB() << " "
00154 << CurrentStation->get()->GetData().at(i) + (meandist
00155 - SortFunc(CurrentStation->get())) * yshift << endl;
00156 }
00157 outfile << endl << endl;
00158 }
00159 WriteToNetCDF(outfilename, Stations, SortFunc);
00160 }