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   }

Generated on Tue May 4 16:52:14 2010 for GPLIB++ by  doxygen 1.5.8