ThreeDMTModel.cpp

Go to the documentation of this file.
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         //Resistivities.resizeAndPreserve(nresistivity);
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         //write out the number of cells in each direction and the number of airlayers
00127         //followed by the keyword values
00128         outfile << xlength << " " << ylength << " " << zlength << " "
00129             << airlayers << " VALUES" << endl;
00130         //write out the cell sizes in x-direction
00131         std::copy(xsize.begin(), xsize.end(), std::ostream_iterator<double>(
00132             outfile, " "));
00133         outfile << endl;
00134         //write out the cell sizes in y-direction
00135         std::copy(ysize.begin(), ysize.end(), std::ostream_iterator<double>(
00136             outfile, " "));
00137         outfile << endl;
00138         //write out the cell sizes in z-direction
00139         std::copy(zsize.begin(), zsize.end(), std::ostream_iterator<double>(
00140             outfile, " "));
00141         outfile << endl;
00142         //write out the resistivity values for each cell
00143         //by looking up the resistivity from the index of each cell
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         //write out the number of values in each direction
00166         outfile << xlength << " " << ylength << " " << zlength << endl;
00167         //write out the cell sizes in x-direction
00168         std::copy(xsize.begin(), xsize.end(), std::ostream_iterator<double>(
00169             outfile, " "));
00170         outfile << endl;
00171         //write out the cell sizes in y-direction
00172         std::copy(ysize.begin(), ysize.end(), std::ostream_iterator<double>(
00173             outfile, " "));
00174         outfile << endl;
00175         //write out the cell sizes in z-direction
00176         std::copy(zsize.begin(), zsize.end(), std::ostream_iterator<double>(
00177             outfile, " "));
00178         outfile << endl;
00179         //write out the resistivity index for each cell
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         //write out the resistivities that correspond to each index
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         //prepare the netcdf file object
00200         NcFile cdf(filename.c_str(), NcFile::Replace);
00201         if (!cdf.is_valid())
00202           throw FatalException("Problem writing cdf file");
00203         //write dimension information
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         //write some attributes to make the file understandable
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         //the netcdf file need the coordinates not the sizes
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         //get the resistivity values from the indices
00229         std::transform(Model.origin(), Model.origin() + nres, back_inserter(
00230             resvals), _1 = var(Resistivities)[_1]);
00231         //store everything in the file
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         //write header information for the vtk file
00242         //this is the legacy vtk format
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         //we want to write grid cells, so we need one more value than cells
00248         //this is for the left/right boundaries
00249         outfile << "DIMENSIONS " << xsize.size() + 1 << " " << ysize.size() + 1
00250             << " " << zsize.size() + 1 << endl;
00251         //write out the information for each coordinate axis
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         //and finally write out the resistivity values, x varies fastest
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   }

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