GPLIB++
plotlayer.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <string>
3 #include "ThreeDMTModel.h"
4 #include <fstream>
5 #include "types.h"
6 #include <boost/filesystem/operations.hpp>
7 #include <boost/shared_ptr.hpp>
8 #include <boost/multi_array.hpp>
9 #include "netcdfcpp.h"
10 #include "Util.h"
11 
12 using namespace std;
13 using namespace boost::filesystem;
14 using namespace gplib;
15 
16 /*!
17  * \addtogroup UtilProgs Utility Programs
18  *@{
19  * \file plotlayer.cpp
20  * Write a single layer of a WinGLink or Mackie 3D model into a netcdf file for plotting with GMT.
21  */
22 
23 
24 int main(void)
25  {
26  string version = "$Id: plotlayer.cpp 1849 2010-05-07 11:53:45Z mmoorkamp $";
27  cout << endl << endl;
28  cout << "Program " << version << endl;
29  cout << "Reads in WinGLink or old Mackie format 3D Model grids " << endl;
30  cout
31  << "and outputs the resistivity of a single layer for plotting with GMT "
32  << endl;
33  cout << "No input parameters supported " << endl;
34 
35  string infilename, outfilename;
36  double maxdepth;
37 
38  double latmin, lonmin;
39  int mode;
40  //read in the filename and some information about the format
41  //as we cannot guess the format from the ending or typical information in the file
42  infilename = AskFilename("Modelfile name: ");
43  cout << "Type 1 for old Mackie, 2 for Winglink format: ";
44  cin >> mode;
45  //get information about what to plot
46  cout << "Depth of layer to plot: ";
47  cin >> maxdepth;
48  cout << "Latitude of lower border: ";
49  cin >> latmin;
50  cout << "Longitude of left border: ";
51  cin >> lonmin;
52  outfilename = AskFilename("Outfile name: ");
53  ThreeDMTModel Model;
54  //this is for the very basic conversion from
55  //a rectangular grid to latitude longitude , could be refined in the future.
56  const double kmlatitude = 111194;
57  const double kmlongitude = cos(latmin / 180. * PI) * kmlatitude;
58  //read in the model
59  if (mode == 1)
60  Model.ReadMackie(infilename);
61  else
62  Model.ReadWinGLink(infilename);
63  //setup the axis in x and y direction
64  const int xsize = Model.GetXSizes().size();
65  const int ysize = Model.GetYSizes().size();
66  typedef boost::multi_array<double, 1> tscalearray;
67  tscalearray lonscale(boost::extents[xsize]),
68  latscale(boost::extents[ysize]);
69  double currentdepth = 0;
70  int layerindex = 0;
71  //find out the index of the layer that lies in the depth we want to plot
72  while (currentdepth < maxdepth)
73  {
74  currentdepth += Model.GetZSizes()[layerindex] / 1000;
75  cout << currentdepth << endl;
76  ++layerindex;
77  }
78  lonscale[0] = 0.0;
79  latscale[0] = 0.0;
80  //convert the model axes and write the model to a file
81  //in the form lon lat resistivity
82  // this can be used for example in GMT
83  for (int i = 1; i < ysize; ++i)
84  latscale[i] = latscale[i - 1] + Model.GetYSizes()[i - 1];
85  for (int i = 1; i < xsize; ++i)
86  lonscale[i] = lonscale[i - 1] + Model.GetXSizes()[i - 1];
87  ofstream outfile(outfilename.c_str());
88  for (int i = 0; i < xsize; ++i)
89  for (int j = 0; j < ysize; ++j)
90  {
91  outfile << lonmin + lonscale[i] / kmlongitude << " " << latmin
92  + latscale[ysize - 1 - j] / kmlatitude << " "
93  << Model.GetResistivities()[Model.GetModel()[i][j][layerindex]]
94  << endl;
95  }
96  //also create a netcdf file with the same information
97  NcFile cdf((outfilename + ".nc").c_str(), NcFile::Replace);
98  NcDim* latd = cdf.add_dim("lat", ysize);
99  NcDim* lond = cdf.add_dim("lon", xsize);
100 
101  NcVar* lat = cdf.add_var("lat", ncFloat, latd);
102  lat->add_att("units", "degrees_north");
103  lat->add_att("long_name", "longitude");
104 
105  NcVar* lon = cdf.add_var("lon", ncFloat, lond);
106  lon->add_att("units", "degrees_east");
107  lon->add_att("long_name", "latitude");
108  NcVar* res = cdf.add_var("res", ncFloat, latd, lond);
109  res->add_att("units", "ohm meters");
110  res->add_att("long_name", "Resistivity");
111  res->add_att("coordinates", "lon lat");
112  float *lonvals = new float[lond->size()];
113  float *latvals = new float[latd->size()];
114 
115  float *resvals = new float[latd->size() * lond->size()];
116 
117  for (int i = 0; i < xsize; ++i)
118  {
119  lonvals[i] = lonmin + lonscale[i] / kmlongitude;
120  }
121  for (int i = 0; i < ysize; ++i)
122  {
123  latvals[i] = latmin + latscale[i] / kmlatitude;
124  }
125  for (int i = 0; i < xsize; ++i)
126  {
127  for (int j = 0; j < ysize; ++j)
128  {
129  resvals[(ysize - j - 1) * xsize + i]
130  = Model.GetResistivities()[Model.GetModel()[i][j][layerindex]];
131  //resvals[(ysize-j-1)*ysize+i] = Model.GetResistivities()[Model.GetModel()[i][j][layerindex]];
132  }
133  }
134  lon->put(lonvals, lond->size());
135  lat->put(latvals, latd->size());
136  res->put(resvals, res->edges());
137  }
138 /*@}*/
const t3DModelDim & GetZSizes()
Get the cell sizes in z-direction (down) in m.
Definition: ThreeDMTModel.h:45
void ReadMackie(std::string filename)
Read an ascii file in the format use by Mackie's old code.
const t3DModelDim & GetXSizes()
Get the cell sizes in x-direction (North) in m.
Definition: ThreeDMTModel.h:35
int main(void)
Definition: plotlayer.cpp:24
string version
Definition: makeinput.cpp:16
The class 3DMTModel manages 3D models for magnetotelluric model calculations, at this point this is o...
Definition: ThreeDMTModel.h:17
const t3DModelDim & GetYSizes()
Get the cell sizes in y-direction (East) in m.
Definition: ThreeDMTModel.h:40
void ReadWinGLink(std::string filename)
Read an ascii file in the format written by WinGLink.
const t3DModelData & GetModel()
Return a three dimensional multi-array with the indices of the resistivity values in each model cell...
Definition: ThreeDMTModel.h:55
const t3DModelRes & GetResistivities()
Return the table of resistivity values that correspond to the index values in GetModel.
Definition: ThreeDMTModel.h:50