00001 #include "ThreeDMTModel.h"
00002 #include "FatalException.h"
00003 #include "netcdfcpp.h"
00004 #include <fstream>
00005 #include <boost/lambda/lambda.hpp>
00006 #include <boost/lambda/bind.hpp>
00007 using namespace std;
00008 using namespace boost::lambda;
00009
00010 namespace gplib
00011 {
00012 ThreeDMTModel::ThreeDMTModel()
00013 {
00014 airlayers = 0;
00015 }
00016
00017 ThreeDMTModel::~ThreeDMTModel()
00018 {
00019 }
00020
00021 double ThreeDMTModel::LookupResistivity(const int index)
00022 {
00023 return Resistivities[index];
00024 }
00025
00026 int ThreeDMTModel::LookupIndex(const double resistivity)
00027 {
00028 const size_t nresistivity = Resistivities.size();
00029 for (size_t i = 0; i < nresistivity; ++i)
00030 if (Resistivities[i] == resistivity)
00031 return i;
00032
00033 Resistivities.push_back(resistivity);
00034 return (nresistivity);
00035 }
00036
00037 void ThreeDMTModel::ReadWinGLink(std::string filename)
00038 {
00039 ifstream infile(filename.c_str());
00040 size_t xlength, ylength, zlength = 0;
00041 int currentlayer = 0;
00042 size_t i, j, k = 0;
00043 double currentres = 0;
00044 char dummy[255];
00045 infile >> xlength >> ylength >> zlength >> airlayers;
00046 if (infile.fail())
00047 throw FatalException("Cannot read file: " + filename);
00048 infile.getline(dummy, 255);
00049
00050 Model.resize(t3DModelData::extent_gen()[xlength][ylength][zlength]);
00051 xsize.resize(xlength);
00052 ysize.resize(ylength);
00053 zsize.resize(zlength);
00054
00055 for (i = 0; i < xlength; ++i)
00056 infile >> xsize[i];
00057 for (i = 0; i < ylength; ++i)
00058 infile >> ysize[i];
00059 for (i = 0; i < zlength; ++i)
00060 infile >> zsize[i];
00061
00062 for (i = 0; i < zlength; ++i)
00063 {
00064 infile >> currentlayer;
00065 for (j = 0; j < ylength; ++j)
00066 for (k = 0; k < xlength; ++k)
00067 {
00068 infile >> currentres;
00069 Model[k][j][currentlayer - 1] = LookupIndex(currentres);
00070 }
00071 }
00072
00073 if (infile.fail())
00074 throw FatalException("Problem reading file: " + filename);
00075 }
00076
00077 void ThreeDMTModel::ReadMackie(std::string filename)
00078 {
00079 ifstream infile(filename.c_str());
00080 size_t xlength, ylength, zlength;
00081 int currentlayer;
00082 size_t i, j, k;
00083
00084 infile >> xlength >> ylength >> zlength;
00085 if (infile.fail())
00086 throw FatalException("Cannot read file: " + filename);
00087 Model.resize(t3DModelData::extent_gen()[xlength][ylength][zlength]);
00088 xsize.resize(xlength);
00089 ysize.resize(ylength);
00090 zsize.resize(zlength);
00091
00092 for (i = 0; i < xlength; ++i)
00093 infile >> xsize[i];
00094 for (i = 0; i < ylength; ++i)
00095 infile >> ysize[i];
00096 for (i = 0; i < zlength; ++i)
00097 infile >> zsize[i];
00098
00099 for (i = 0; i < zlength; ++i)
00100 {
00101 infile >> currentlayer;
00102 for (j = 0; j < ylength; ++j)
00103 for (k = 0; k < xlength; ++k)
00104 infile >> Model[k][j][currentlayer - 1];
00105 }
00106
00107 while (infile.good())
00108 {
00109 double currvalue = 0.0;
00110 infile >> currvalue;
00111 Resistivities.push_back(currvalue);
00112 }
00113
00114 if (!infile.eof())
00115 throw FatalException("Problem reading file: " + filename);
00116
00117 }
00118
00119 void ThreeDMTModel::WriteWinGLink(std::string filename)
00120 {
00121 ofstream outfile(filename.c_str());
00122 size_t i, j, k;
00123 const size_t xlength = xsize.size();
00124 const size_t ylength = ysize.size();
00125 const size_t zlength = zsize.size();
00126
00127
00128 outfile << xlength << " " << ylength << " " << zlength << " "
00129 << airlayers << " VALUES" << endl;
00130
00131 std::copy(xsize.begin(), xsize.end(), std::ostream_iterator<double>(
00132 outfile, " "));
00133 outfile << endl;
00134
00135 std::copy(ysize.begin(), ysize.end(), std::ostream_iterator<double>(
00136 outfile, " "));
00137 outfile << endl;
00138
00139 std::copy(zsize.begin(), zsize.end(), std::ostream_iterator<double>(
00140 outfile, " "));
00141 outfile << endl;
00142
00143
00144 for (i = 0; i < zlength; ++i)
00145 {
00146 outfile << i + 1 << endl;
00147 for (j = 0; j < ylength; ++j)
00148 {
00149 for (k = 0; k < xlength; ++k)
00150 outfile << LookupResistivity(Model[k][j][i]) << " ";
00151 outfile << endl;
00152 }
00153 }
00154 if (outfile.fail())
00155 throw FatalException("Problem writing file: " + filename);
00156 }
00157
00158 void ThreeDMTModel::WriteMackie(std::string filename)
00159 {
00160 ofstream outfile(filename.c_str());
00161 size_t i, j, k;
00162 const size_t xlength = xsize.size();
00163 const size_t ylength = ysize.size();
00164 const size_t zlength = zsize.size();
00165
00166 outfile << xlength << " " << ylength << " " << zlength << endl;
00167
00168 std::copy(xsize.begin(), xsize.end(), std::ostream_iterator<double>(
00169 outfile, " "));
00170 outfile << endl;
00171
00172 std::copy(ysize.begin(), ysize.end(), std::ostream_iterator<double>(
00173 outfile, " "));
00174 outfile << endl;
00175
00176 std::copy(zsize.begin(), zsize.end(), std::ostream_iterator<double>(
00177 outfile, " "));
00178 outfile << endl;
00179
00180 for (i = 0; i < zlength; ++i)
00181 {
00182 outfile << i + 1 << endl;
00183 for (j = 0; j < ylength; ++j)
00184 {
00185 for (k = 0; k < xlength; ++k)
00186 outfile << Model[k][j][i] << " ";
00187 outfile << endl;
00188 }
00189 }
00190
00191 std::copy(Resistivities.begin(), Resistivities.end(),
00192 std::ostream_iterator<double>(outfile, " "));
00193 if (outfile.fail())
00194 throw FatalException("Problem writing file: " + filename);
00195 }
00196
00197 void ThreeDMTModel::WriteNetCDF(std::string filename)
00198 {
00199
00200 NcFile cdf(filename.c_str(), NcFile::Replace);
00201 if (!cdf.is_valid())
00202 throw FatalException("Problem writing cdf file");
00203
00204 NcDim* xd = cdf.add_dim("x", xsize.size());
00205 NcDim* yd = cdf.add_dim("y", ysize.size());
00206 NcDim* zd = cdf.add_dim("z", zsize.size());
00207 NcVar* x = cdf.add_var("x", ncDouble, xd);
00208
00209 x->add_att("units", "meters");
00210 x->add_att("long_name", "x-coordinate in Cartesian system");
00211 NcVar* y = cdf.add_var("y", ncDouble, yd);
00212 y->add_att("units", "meters");
00213 y->add_att("long_name", "y-coordinate in Cartesian system");
00214 NcVar* z = cdf.add_var("z", ncDouble, zd);
00215 z->add_att("units", "meters");
00216 z->add_att("long_name", "z-coordinate in Cartesian system");
00217 z->add_att("positive", "down");
00218 NcVar* res = cdf.add_var("res", ncDouble, xd, yd, zd);
00219 res->add_att("units", "ohm meters");
00220 res->add_att("long_name", "Resistivity");
00221 res->add_att("coordinates", "x y z");
00222 std::vector<double> xvals, yvals, zvals, resvals;
00223
00224 std::partial_sum(xsize.begin(), xsize.end(), std::back_inserter(xvals));
00225 std::partial_sum(ysize.begin(), xsize.end(), std::back_inserter(xvals));
00226 std::partial_sum(xsize.begin(), xsize.end(), std::back_inserter(xvals));
00227 const size_t nres = Model.num_elements();
00228
00229 std::transform(Model.origin(), Model.origin() + nres, back_inserter(
00230 resvals), _1 = var(Resistivities)[_1]);
00231
00232 x->put(&xvals[0], xd->size());
00233 y->put(&yvals[0], yd->size());
00234 z->put(&zvals[0], zd->size());
00235 res->put(&resvals[0], res->edges());
00236 }
00237
00238 void ThreeDMTModel::WriteVTK(std::string filename)
00239 {
00240 ofstream outfile(filename.c_str());
00241
00242
00243 outfile << "# vtk DataFile Version 2.0" << endl;
00244 outfile << "3D Model data" << endl;
00245 outfile << "ASCII" << endl;
00246 outfile << "DATASET RECTILINEAR_GRID" << endl;
00247
00248
00249 outfile << "DIMENSIONS " << xsize.size() + 1 << " " << ysize.size() + 1
00250 << " " << zsize.size() + 1 << endl;
00251
00252 outfile << "X_COORDINATES " << xsize.size() + 1 << " double" << endl;
00253 double currcoord = 0.0;
00254 outfile << currcoord << " ";
00255 std::partial_sum(xsize.begin(),xsize.end(),std::ostream_iterator<double>(outfile," "));
00256 outfile << endl;
00257 outfile << "Y_COORDINATES " << ysize.size() + 1 << " double" << endl;
00258 currcoord = 0;
00259 outfile << currcoord << " ";
00260 std::partial_sum(ysize.begin(),ysize.end(),std::ostream_iterator<double>(outfile," "));
00261 outfile << endl;
00262 outfile << "Z_COORDINATES " << zsize.size() + 1 << " double" << endl;
00263 currcoord = 0;
00264 outfile << currcoord << " ";
00265 std::partial_sum(zsize.begin(),zsize.end(),std::ostream_iterator<double>(outfile," "));
00266 outfile << endl;
00267 outfile << "CELL_DATA " << xsize.size() * ysize.size() * zsize.size()
00268 << endl;
00269 outfile << "SCALARS Resistivity double" << endl;
00270 outfile << "LOOKUP_TABLE default" << endl;
00271
00272 for (size_t i = 0; i < zsize.size(); ++i)
00273 {
00274 for (size_t j = 0; j < ysize.size(); ++j)
00275 {
00276 for (size_t k = 0; k < xsize.size(); ++k)
00277 {
00278 outfile << Resistivities[Model[k][j][i]] << " ";
00279 }
00280 outfile << endl;
00281 }
00282 }
00283 if (outfile.fail())
00284 throw FatalException("Problem writing vtk file");
00285 }
00286 }