GeoTessCPPExamples  2.0
InterrogateModel.cc
Go to the documentation of this file.
1 //- ****************************************************************************
2 //-
3 //- Copyright 2009 Sandia Corporation. Under the terms of Contract
4 //- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
5 //- retains certain rights in this software.
6 //-
7 //- BSD Open Source License.
8 //- All rights reserved.
9 //-
10 //- Redistribution and use in source and binary forms, with or without
11 //- modification, are permitted provided that the following conditions are met:
12 //-
13 //- * Redistributions of source code must retain the above copyright notice,
14 //- this list of conditions and the following disclaimer.
15 //- * Redistributions in binary form must reproduce the above copyright
16 //- notice, this list of conditions and the following disclaimer in the
17 //- documentation and/or other materials provided with the distribution.
18 //- * Neither the name of Sandia National Laboratories nor the names of its
19 //- contributors may be used to endorse or promote products derived from
20 //- this software without specific prior written permission.
21 //-
22 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 //- POSSIBILITY OF SUCH DAMAGE.
33 //-
34 //- ****************************************************************************
35 
36 #include "CPPUtils.h"
37 #include "CpuTimer.h"
38 #include "GeoTessModel.h"
39 #include "GeoTessUtils.h"
40 #include "GeoTessPosition.h"
41 #include "GeoTessException.h"
42 
43 using namespace geotess;
44 
45 /**
46  * This file contains an example application that demonstrates how to
47  * load an existing GeoTessModel into memory and interrogate it for
48  * information.
49  * <p>
50  * The program takes one command line argument which specifies the
51  * full path to the directory GeoTessModels
52  * that was delivered with the GeoTess package.
53  */
54 int main(int argc, char** argv)
55 {
56  try
57  {
58  string path;
59  if(argc < 2)
60  {
61  cout << "Must supply a single command line argument specifying path to the GeoTessModels directory" << endl;
62  return -1;
63  }
64 
65  path = CPPUtils::insertPathSeparator(argv[1], "crust10.geotess");
66 
67  cout << "GeoTess version " << GeoTessUtils::getVersion() << endl;
68 
69  cout << "Loading model from file: " << path << endl << endl;
70 
71  // instantiate a model and load the model from file
72  GeoTessModel* model = new GeoTessModel(path);
73 
74  cout << model->toString() << endl;
75 
76  cout << endl;
77  cout << "=============================================================================" << endl;
78  cout << endl;
79  cout << "Interpolate Data" << endl;
80  cout << endl;
81  cout << "=============================================================================" << endl;
82  cout << endl;
83 
84  // instantiate a GeoTessPosition object which will manage the
85  // geographic position of an interpolation point, the interpolation
86  // coefficients, etc.
87  GeoTessPosition* position = GeoTessPosition::getGeoTessPosition(
88  model, GeoTessInterpolatorType::LINEAR);
89 
90  // retrieve a reference to the ellipsoid stored in the model. This is usually a reference
91  // to the WGS84 ellipsoid, but not always. The EarthShape is used for converting between
92  // depth and radius and between geographic coordinates and geocentric unit vectors.
93  EarthShape& ellipsoid = model->getEarthShape();
94 
95  cout << "EarthShape is " << ellipsoid.getShapeName() << endl << endl;
96 
97  // set the position in the GeoTessPosition object to
98  // latitude = 30N, longitude = 90E, and radius equal to the
99  // top of layer 0.
100  double tibet[3];
101  ellipsoid.getVectorDegrees(30., 90., tibet);
102  position->setTop(0, tibet);
103 
104  // regurgitate the position
105  printf("Interpolated model properties at lat, lon = %1.4f, %1.4f:\n\n",
106  ellipsoid.getLatDegrees(position->getVector()),
107  ellipsoid.getLonDegrees(position->getVector()));
108 
109  // print a table with values interpolated from the model at the
110  // specified position
111  cout << "Layer Depth Thick vP vS density" << endl;
112  for (int layer = model->getMetaData().getNLayers() - 1; layer >= 0; --layer)
113  {
114  position->setTop(layer);
115  printf("%3d %10.4f %10.4f %10.4f %10.4f %10.4f\n",
116  layer, position->getDepth(),
117  position->getLayerThickness(), position->getValue(0),
118  position->getValue(1), position->getValue(2));
119  }
120 
121  cout << endl;
122 
123  // print out the index of the triangle in which the point resides.
124  printf("Interpolated point resides in triangle index = %d\n", position->getTriangle());
125 
126  // print out a table with information about the 3 nodes at the
127  // corners of the triangle that contains the interpolation point.
128  // The information output is:
129  // the index of the node,
130  // node latitude in degrees,
131  // node longitude in degrees,
132  // interpolation coefficient, and
133  // distance in degrees from interpolation point.
134 
135  cout << position->toString() << endl << endl;
136 
137  // call the getWeights function which will
138  // return a map from a pointIndex to the weight
139  // associated with that point, for the current
140  // interpolation position.
141  map<int, double> weights;
142  position->getWeights(weights, 1.);
143 
144  cout << "gposition->getWeights() returned weights for " << weights.size()
145  << " point indices:" << endl << endl;
146  cout << "pointIndex weight" << endl;
147  cout << fixed << setprecision(6);
148 
149  // iterate over all the entries in the map of weights
150  // print the point index and associated weight,
151  // and sum the wieghts.
152  double sumWeights = 0;
153  map<int,double>::iterator it;
154  for(it = weights.begin(); it != weights.end(); it++)
155  {
156  cout << setw(10) << it->first << setw(11) << it->second << endl;
157  sumWeights += it->second;
158  }
159  // the sum of the weights should equal 1.0
160  cout << endl << "Sum of the weights is " << sumWeights << endl << endl;
161 
162  delete position;
163 
164  cout << endl;
165  cout << "=============================================================================" << endl;
166  cout << endl;
167  cout << "Query Model Data" << endl;
168  cout << endl;
169  cout << "=============================================================================" << endl;
170  cout << endl;
171 
172  // now we will extract some information about model values stored
173  // on grid nodes in the model. These are not interpolated values.
174 
175  // consider just one vertex. Vertex 57 is located in Tibet
176  int vertexId = 57;
177 
178  const double* u = model->getGrid().getVertex(vertexId);
179 
180  double lat = ellipsoid.getLatDegrees(u);
181  double lon = ellipsoid.getLonDegrees(u);
182  double earthRadius = ellipsoid.getEarthRadius(u);
183 
184  printf("Vertex=%d lat = %1.4f lon = %1.4f ellipsoid_radius = %1.3f\n\n", vertexId,
185  lat, lon, earthRadius);
186 
187  // write out the first header line which includes the names of the attributes
188  cout << " layer profile depth ";
189  for (int attribute=0; attribute<model->getMetaData().getNAttributes(); ++attribute)
190  cout << setw(9) << model->getMetaData().getAttributeName(attribute);
191  cout << endl;
192 
193  // print out second header line which includes attribute units
194  cout << "layer name type (km) ";
195  for (int attribute=0; attribute<model->getMetaData().getNAttributes(); ++attribute)
196  cout << setw(9) << model->getMetaData().getAttributeUnit(attribute);
197  cout << endl;
198 
199  cout << "---------------------------------------------------------------------------" << endl;
200 
201  string layerName, profileType;
202  GeoTessProfile* profile;
203  double radius, value;
204 
205  for (int layer=model->getNLayers()-1; layer >= 0; --layer)
206  {
207  layerName = model->getMetaData().getLayerName(layer);
208 
209  profile = model->getProfile(vertexId, layer);
210 
211  profileType = profile->getType().toString();
212 
213  for (int node = profile->getNRadii()-1; node >= 0; --node)
214  {
215  radius = profile->getRadius(node);
216 
217  cout << setw(3) << right << layer;
218  cout << " " << setw(16) << left << layerName;
219  cout << " " << setw(16) << profileType;
220  cout << setw(9) << setprecision(3) << right << earthRadius - radius;
221  for (int attribute=0; attribute < model->getMetaData().getNAttributes(); ++attribute)
222  {
223  value = profile->getValue(attribute, node);
224  cout << setw(9) << value;
225  }
226  cout << endl;
227  }
228  }
229 
230  cout << endl;
231  cout << "=============================================================================" << endl;
232  cout << endl;
233  cout << "Get Weights for a GreatCircle Raypath" << endl;
234  cout << endl;
235  cout << "=============================================================================" << endl;
236  cout << endl;
237 
238  cout << "Compute travel time for a ray that travels along the top of the 'soft_sediments' " << endl <<
239  "layer of the Crust 1.0 model" << endl << endl;
240 
241  // define two unit vectors.
242  double pointA[3], pointB[3];
243 
244  // set pointA to lat,lon = 0, 0 and pointB to 10N, 10E.
245  ellipsoid.getVectorDegrees(0, 0, pointA);
246  ellipsoid.getVectorDegrees(-10, -10, pointB);
247 
248  // create GreatCircle object that run from pointA to pointB
249  GeoTessGreatCircle greatCircle(pointA, pointB);
250 
251  // specify the desired point spacing. Actual will be a little less
252  // so that points will be equally spaced.
253  double requestedSpacing = 0.5 * DEG_TO_RAD;
254 
255  // find the maximum number of points needed to populate a
256  // great circle of length 2*PI with point spacing of requestedSpacing
257  int maxPoints = GeoTessGreatCircle::getNPoints(2*PI, requestedSpacing, false);
258 
259  // get a new 2D array of doubles big enough to hold maxPoints
260  double** rayPath = CPPUtils::new2DArray<double>(maxPoints, 3);
261  double* radii = new double[maxPoints];
262 
263  int npoints;
264  double actualSpacing = greatCircle.getPoints(requestedSpacing, rayPath, npoints);
265 
266  for (int i=0; i<npoints; ++i) radii[i] = 6378.;
267 
268  // instantiate a map from pointIndex to weight value.
269  //map<int, double> weights;
270  weights.clear();
271 
272  int attributeIndex = 0; // p-wave velocity
273 
274  // get the pointIndex -> weight map using linear interpolation.
275  double integral = 0;
276  model->getWeights(rayPath, radii, NULL, npoints, GeoTessInterpolatorType::LINEAR, GeoTessInterpolatorType::LINEAR, weights);
277 
278  for(it = weights.begin(); it != weights.end(); it++)
279  integral += it->second/model->getPointMap()->getPointValue(it->first, attributeIndex);
280 
281  cout << "model->getWeights() returned weights for " << weights.size()
282  << " point indices:" << endl << endl;
283 
284  cout << "pointIndex weight lat lon depth vp [vtx, layer, node]" << endl;
285  cout << fixed << setprecision(3);
286 
287  int pointIndex;
288  double weight;
289 
290  // retrieve a reference to the PointMap owned by model.
291  GeoTessPointMap* pointMap = model->getPointMap();
292 
293  // iterate over all the entries in the map of weights. Print the point index
294  // and associated weight, and sum the weights.
295  sumWeights = 0;
296  //map<int,double>::iterator it;
297  for(it = weights.begin(); it != weights.end(); it++)
298  {
299  pointIndex = it->first;
300  weight = it->second;
301 
302  cout << setw(10) << pointIndex <<
303  setprecision(6) <<
304  setw(11) << weight <<
305  setprecision(2) <<
306  setw(22) << pointMap->getPointLatLonString(pointIndex) <<
307  setw(8) << pointMap->getPointDepth(pointIndex) <<
308  setw(8) << pointMap->getPointValue(pointIndex, attributeIndex) <<
309  " [" <<
310  setw(5) << pointMap->getVertexIndex(pointIndex) <<
311  setw(2) << pointMap->getLayerIndex(pointIndex) <<
312  setw(2) << pointMap->getNodeIndex(pointIndex) <<
313  "]" << endl;
314 
315  sumWeights += it->second;
316  }
317  cout << endl;
318 
319  cout << setprecision(6);
320  cout << "requested point spacing = " << setw(8) << requestedSpacing*RAD_TO_DEG <<
321  " degrees" << endl;
322  cout << "actual point spacing = " << setw(8) << actualSpacing*RAD_TO_DEG <<
323  " degrees" << endl;
324  cout << endl;
325 
326  cout << "integral = " << integral << " seconds" << endl;
327  // the sum of the weights should equal distance in km
328  cout << "sum of weights = " << sumWeights << " km" << endl;
329  cout << "distance * 6378 = " << greatCircle.getDistance() * radii[0] << " km" << endl;
330 
331  cout << "average velocity = " << sumWeights / integral << " km/sec" << endl;
332 
333  // delete the memory allocated for rayPath
334  CPPUtils::delete2DArray(rayPath);
335 
336  delete[] radii;
337 
338  delete model;
339 
340  cout << "Done." << endl << endl;
341 
342  }
343  catch (GeoTessException& ex)
344  {
345  cout << ex.emessage << endl;
346  return 1;
347  }
348  catch(...)
349  {
350  cout << endl << "Unidentified error detected " << endl
351  << __FILE__ << " " << __LINE__ << endl;
352  return 2;
353  }
354 
355  return 0;
356 }
geotess
Definition: AK135Model.h:55
main
int main(int argc, char **argv)
Definition: InterrogateModel.cc:54