<p><b>cahrens@lanl.gov</b> 2010-06-17 13:47:05 -0600 (Thu, 17 Jun 2010)</p><p>Version 1.2 of projlatlon: Revised to handle vectors (UReconstructZonal/Meridional)<br>
</p><hr noshade><pre><font color="gray">Modified: branches/ocean_projects/graphics/paraview/projection/projlatlon.cpp
===================================================================
--- branches/ocean_projects/graphics/paraview/projection/projlatlon.cpp        2010-06-17 19:00:55 UTC (rev 358)
+++ branches/ocean_projects/graphics/paraview/projection/projlatlon.cpp        2010-06-17 19:47:05 UTC (rev 359)
@@ -7,20 +7,20 @@
 // Assume variable data type is double.
 // Assume variable dims are (Time, nCells|nVertices, nVertLevels|nVertLevelsP1)
 // Assume no more than 100 vars each for cell and point data
-// Does not deal with tracers.
+// Deals with vectors.
 // Does not deal with edge data.
 // Only vis up to nVertLevels, not nVertLevelsP1.
 // Doubles converted to floats in .vtk files follow these rules:
-//  if a NaN, then become -FLT_MAX.
-//  if positive infinity, then become FLT_MAX
-//  if negative infinity, then become -FLT_MAX
-//  if smaller than a float, then become 0.
-//  if not zero, but between -FLT_MIN and FLT_MIN make -FLT_MIN or FLT_MIN
-//  if outside of -FLT_MAX and FLT_MAX make -FLT_MAX or FLT_MAX
+//        if a NaN, then become -FLT_MAX.
+//        if positive infinity, then become FLT_MAX
+//        if negative infinity, then become -FLT_MAX
+//        if smaller than a float, then become 0.
+//        if not zero, but between -FLT_MIN and FLT_MIN make -FLT_MIN or FLT_MIN
+//        if outside of -FLT_MAX and FLT_MAX make -FLT_MAX or FLT_MAX
 //
-// Version 1.0
+// Version 1.2
 // Christine Ahrens
-// 4/13/2010
+// 6/17/2010
 ////////////////////////////////////////////////////////////////////////////////
 
 
@@ -38,10 +38,10 @@
 using namespace std;
 
 #define CHECK_MALLOC(ptr) \
-    if (ptr == NULL) { \
-        cerr &lt;&lt; &quot;malloc failed!</font>
<font color="red">&quot;; \
-        exit(1); \
-    } 
+        if (ptr == NULL) { \
+                cerr &lt;&lt; &quot;malloc failed!</font>
<font color="gray">&quot;; \
+                exit(1); \
+        } 
 
 #define MAX_VARS 100
 #define DEFAULT_LAYER_THICKNESS 10
@@ -114,6 +114,15 @@
         return (float)inputData;
 }
 
+double convertXY2Lon(double x, double y, double lon) {
+    return ((-x * sin(lon)) + (y*cos(lon)));
+}
+
+double convertXYZ2Lat(double x, double y, double z, double lon, double lat) {
+    return ((((x*cos(lon)) + (y*sin(lon)))*sin(lat)) + (z*cos(lat)));
+}
+
+
 void printUsage() {
     cerr &lt;&lt; &quot;USAGE: projlatlon [OPTIONS] infile.nc outfile.vtk&quot; &lt;&lt; endl;
     cerr &lt;&lt; &quot;Create lat/lon projection of MPAS-style data from input file infile.nc &quot; &lt;&lt; endl;
@@ -128,16 +137,28 @@
     cerr &lt;&lt; &quot;   -t floatval   &quot; &lt;&lt; endl;
     cerr &lt;&lt; &quot;       layer_thickness -- use negative value for atmosphere, default is 0&quot; &lt;&lt; endl;
     cerr &lt;&lt; &quot;   -c floatval   &quot; &lt;&lt; endl; 
-    cerr &lt;&lt; &quot;      center_longitude in degrees, default is 180&quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;      display image with center_longitude in degrees, default is 180&quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;   -z &quot; &lt;&lt; endl; 
+    cerr &lt;&lt; &quot;      input grid has center longitude at 0, the default is 180 degree or PI radians&quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;   -a              &quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;       atmosphere data (longitude data is in range -PI to PI)  &quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;       The -a flag also converts the multilayer view to have the &quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;       vertical levels stack in the positive Z direction, rather &quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;       the negative Z direction, which is the default.&quot; &lt;&lt; endl;     
+    cerr &lt;&lt; &quot;   -s              &quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;       timestep to start on (defaults to 0) &quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;   -f              &quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;       timestep to finish on (defaults to last timestep available) &quot; &lt;&lt; endl;
     cerr &lt;&lt; &quot;Variables with time and vertical level are written out.&quot; &lt;&lt; endl;
     cerr &lt;&lt; &quot;Tracer vars are named tracer1, tracer2, etc.&quot; &lt;&lt; endl;
-    cerr &lt;&lt; &quot;[vtk datafile Version 2.0, projlatlon Version 1.0]&quot; &lt;&lt; endl;
+    cerr &lt;&lt; &quot;[vtk datafile Version 2.0, projlatlon Version 1.2]&quot; &lt;&lt; endl;
     exit(1);
 }
 
 void getArgs(int argc, char* argv[], int &amp;outputVertLevel, 
         float &amp;layerThickness, double &amp;centerLon, bool &amp;isMultilayer, 
-        char* &amp;inputFileName, char* &amp;outputFileName) {
+        bool &amp;isAtmosphere, int &amp;startTimeStep, int &amp;finishTimeStep,
+        bool &amp;isZeroCentered, char* &amp;inputFileName, char* &amp;outputFileName) {
 
     int c;
     bool selectedVar = false;
@@ -147,11 +168,15 @@
     bool tflag = false;
     bool cflag = false;
     bool mflag = false;
+    bool aflag = false;
+    bool sflag = false;
+    bool fflag = false;
+    bool zflag = false;
 
     // -l vertical level (if not specified, assume multilayer)
     // -t layer thickness (defaults to 1/10 * radius/#layers)
     // -c center longitude in degrees for latlon projection
-    while ((c=getopt(argc, argv, &quot;l:t:c:m&quot;)) != -1) {
+    while ((c=getopt(argc, argv, &quot;l:t:c:mazs:f:&quot;)) != -1) {
         switch(c) {
             case 'l':
                 lflag = true;
@@ -183,6 +208,22 @@
                 }
                 isMultilayer = true;
                 break;
+           case 'a':
+                aflag = true;
+                isAtmosphere = true;
+                break;
+            case 's':
+                sflag = true;
+                startTimeStep = atoi(optarg);
+                break;
+            case 'f':
+                sflag = true;
+                finishTimeStep = atoi(optarg);
+                break;
+            case 'z':
+                zflag = true;
+                isZeroCentered = true;
+                break;
             default:
                 cerr &lt;&lt; &quot;Unrecognized option: -&quot; &lt;&lt; c &lt;&lt; endl;
                 printUsage();
@@ -203,11 +244,15 @@
 {
 
     bool multilayer = false;
-    int outputVertLevel = 0;
+    bool atmosphere = false;
+        int outputVertLevel = 0;
     char* inputFileName = NULL;
     char* outputFileName =  NULL;
-    float layerThickness =  DEFAULT_LAYER_THICKNESS;
+        float layerThickness =  DEFAULT_LAYER_THICKNESS;
     double centerLon = 180;
+    int startTimeStep = 0;
+    int finishTimeStep = -1;
+    bool isZeroCentered = false;
 
     if (argc &lt; 3)   {
         printUsage();
@@ -215,30 +260,30 @@
     }
 
     getArgs(argc, argv, outputVertLevel, layerThickness, centerLon, multilayer, 
-        inputFileName, outputFileName); 
-    
-    NcFile ncFile(inputFileName);
+        atmosphere, startTimeStep, finishTimeStep, isZeroCentered, inputFileName, outputFileName); 
+        
+        NcFile ncFile(inputFileName);
 
-    if (!ncFile.is_valid()) 
-    {
-        cerr &lt;&lt; &quot;Couldn't open file: &quot; &lt;&lt; inputFileName &lt;&lt; endl;
-        exit(1);
-    }
+        if (!ncFile.is_valid()) 
+        {
+                cerr &lt;&lt; &quot;Couldn't open file: &quot; &lt;&lt; inputFileName &lt;&lt; endl;
+                exit(1);
+        }
 
-    NcDim* nCells = ncFile.get_dim(&quot;nCells&quot;);
-    NcDim* nVertices = ncFile.get_dim(&quot;nVertices&quot;);
-    NcDim* vertexDegree = ncFile.get_dim(&quot;vertexDegree&quot;);
-    NcDim* Time = ncFile.get_dim(&quot;Time&quot;);
-    NcDim* nVertLevels = ncFile.get_dim(&quot;nVertLevels&quot;);
+        NcDim* nCells = ncFile.get_dim(&quot;nCells&quot;);
+        NcDim* nVertices = ncFile.get_dim(&quot;nVertices&quot;);
+        NcDim* vertexDegree = ncFile.get_dim(&quot;vertexDegree&quot;);
+        NcDim* Time = ncFile.get_dim(&quot;Time&quot;);
+        NcDim* nVertLevels = ncFile.get_dim(&quot;nVertLevels&quot;);
     int maxNVertLevels = nVertLevels-&gt;size();
 
-    if ((vertexDegree-&gt;size() != 3) &amp;&amp; (vertexDegree-&gt;size() != 4))  {
-        cerr &lt;&lt; &quot;This code is only for hexagonal or quad grid projection&quot; &lt;&lt; endl;
-        exit(1);
-    }
+        if ((vertexDegree-&gt;size() != 3) &amp;&amp; (vertexDegree-&gt;size() != 4))  {
+                cerr &lt;&lt; &quot;This code is only for hexagonal or quad grid projection&quot; &lt;&lt; endl;
+                exit(1);
+        }
 
-    // Can't check for this, b/c if not there it crashes program    
-    //NcDim* nVertLevelsP1 = ncFile.get_dim(&quot;nVertLevelsP1&quot;);
+        // Can't check for this, b/c if not there it crashes program        
+        //NcDim* nVertLevelsP1 = ncFile.get_dim(&quot;nVertLevelsP1&quot;);
 
     bool singlelayer = !multilayer;
 
@@ -267,110 +312,158 @@
         maxNVertLevels = 1;
     }
 
-    cerr &lt;&lt; &quot;centerLon: &quot; &lt;&lt; centerLon &lt;&lt; &quot; singleLayer: &quot; &lt;&lt; singlelayer &lt;&lt; &quot; outputVertLevel: &quot; &lt;&lt; outputVertLevel &lt;&lt; endl;
+    if (atmosphere) {
+        layerThickness = -layerThickness;
+    }
 
-    // figure out what variables to visualize
-    NcVar* dualCellVars[MAX_VARS];
-    NcVar* dualPointVars[MAX_VARS];
-    int dualCellVarIndex = -1;
-    int dualPointVarIndex = -1;
-    int numDualCells = nVertices-&gt;size();
-    int numDualPoints = nCells-&gt;size()+1;
+    int availTimeSteps = Time-&gt;size();
+
+    if (startTimeStep &gt; (availTimeSteps-1)) {
+        cerr &lt;&lt; &quot;Start timestep is too large, last timestep is: &quot; &lt;&lt; availTimeSteps-1 &lt;&lt; endl;
+        exit(1);
+    }
+
+    if (startTimeStep &lt; 0) {
+        cerr &lt;&lt; &quot;Start timestep is too small, must be at least 0.&quot; &lt;&lt; endl;
+        exit(1);
+    }
+
+    if (finishTimeStep &gt; (availTimeSteps-1)) {
+        cerr &lt;&lt; &quot;Finish timestep is too large, last timestep is: &quot; &lt;&lt; availTimeSteps-1 &lt;&lt; endl;
+        exit(1);
+    }
     
-    int numVars = ncFile.num_vars();
+    if (finishTimeStep &lt; 0) {
+        finishTimeStep = availTimeSteps-1;
+    }
 
-    bool tracersExist = false;
+    cerr &lt;&lt; &quot;centerLon: &quot; &lt;&lt; centerLon &lt;&lt; &quot; singleLayer: &quot; &lt;&lt; singlelayer &lt;&lt; &quot; outputVertLevel: &quot; &lt;&lt; outputVertLevel &lt;&lt; &quot; start: &quot; &lt;&lt; startTimeStep &lt;&lt; &quot; finish: &quot; &lt;&lt; finishTimeStep &lt;&lt; &quot; atmosphere: &quot; &lt;&lt; atmosphere &lt;&lt; endl;
 
-    for (int i = 0; i &lt; numVars; i++) {
-        NcVar* aVar = ncFile.get_var(i);
+        // figure out what variables to visualize
+        NcVar* dualCellVars[MAX_VARS];
+        NcVar* dualPointVars[MAX_VARS];
+    NcVar* vectorVars[3];
+        int dualCellVarIndex = -1;
+        int dualPointVarIndex = -1;
+        int numDualCells = nVertices-&gt;size();
+        int numDualPoints = nCells-&gt;size()+1;
+        
+        int numVars = ncFile.num_vars();
 
-        // must have 3 dims 
-        // (Time, nCells | nVertices, nVertLevels | nVertLevelsP1)
+        bool tracersExist = false;
+    bool isUVector = false;
+    bool isVVector = false;
 
-        int numDims = aVar-&gt;num_dims();
-        //cout &lt;&lt; &quot;Num Dims of var: &quot; &lt;&lt; aVar-&gt;name() &lt;&lt; &quot; is &quot; &lt;&lt; numDims &lt;&lt; endl;
-        if ((numDims != 3) &amp;&amp; (strcmp(aVar-&gt;name(), &quot;tracers&quot;))) {
-            continue; // try the next var
-        } else {
-            // TODO, check if it is a double
-            // assume a double for now
+        for (int i = 0; i &lt; numVars; i++) {
+                NcVar* aVar = ncFile.get_var(i);
 
-            // check for Time dim 0
-            NcToken dim0Name = aVar-&gt;get_dim(0)-&gt;name();
-            if (strcmp(dim0Name, &quot;Time&quot;)) 
-                continue;
+                // must have 3 dims 
+                // (Time, nCells | nVertices, nVertLevels | nVertLevelsP1)
 
-            // check for dim 1 being num vertices or cells 
-            bool isVertexData = false;
-            bool isCellData = false;
-            NcToken dim1Name = aVar-&gt;get_dim(1)-&gt;name();
-            if (!strcmp(dim1Name, &quot;nVertices&quot;)) 
-                isVertexData = true;
-            else if (!strcmp(dim1Name, &quot;nCells&quot;)) 
-                isCellData = true; 
-            else continue;
+                int numDims = aVar-&gt;num_dims();
+                //cout &lt;&lt; &quot;Num Dims of var: &quot; &lt;&lt; aVar-&gt;name() &lt;&lt; &quot; is &quot; &lt;&lt; numDims &lt;&lt; endl;
+                if ((numDims != 3) &amp;&amp; (strcmp(aVar-&gt;name(), &quot;tracers&quot;))) {
+                        continue; // try the next var
+                } else {
+                        // TODO, check if it is a double
+                        // assume a double for now
 
-            // check if dim 2 is nVertLevels or nVertLevelsP1, too
-            NcToken dim2Name = aVar-&gt;get_dim(2)-&gt;name();
-            if ((strcmp(dim2Name, &quot;nVertLevels&quot;)) 
-                    &amp;&amp; (strcmp(dim2Name, &quot;nVertLevelsP1&quot;))) {
-                continue;
-            }
+                        // check for Time dim 0
+                        NcToken dim0Name = aVar-&gt;get_dim(0)-&gt;name();
+                        if (strcmp(dim0Name, &quot;Time&quot;)) 
+                                continue;
 
-            // Add to cell or point var array
-            if (isVertexData) {  // means it is dual cell data
-                dualCellVarIndex++;
-                if (dualCellVarIndex &gt; MAX_VARS-1) {
-                    cerr &lt;&lt; &quot;Exceeded number of cell vars.&quot; &lt;&lt; endl;
-                    exit(1);
-                }
-                dualCellVars[dualCellVarIndex] = aVar;
-                //cout &lt;&lt; &quot;Adding var &quot; &lt;&lt; aVar-&gt;name() &lt;&lt; &quot; to dualCellVars&quot; &lt;&lt; endl;
-            } else if (isCellData) { // means it is dual vertex data
-                if (strcmp(aVar-&gt;name(), &quot;tracers&quot;)) {
-                    dualPointVarIndex++;
-                    if (dualPointVarIndex &gt; MAX_VARS-1) {
-                        cerr &lt;&lt; &quot;Exceeded number of point vars.&quot; &lt;&lt; endl;
-                        exit(1);
+                        // check for dim 1 being num vertices or cells 
+                        bool isVertexData = false;
+                        bool isCellData = false;
+                        NcToken dim1Name = aVar-&gt;get_dim(1)-&gt;name();
+                        if (!strcmp(dim1Name, &quot;nVertices&quot;)) 
+                                isVertexData = true;
+                        else if (!strcmp(dim1Name, &quot;nCells&quot;)) 
+                                isCellData = true; 
+                        else continue;
+
+                        // check if dim 2 is nVertLevels or nVertLevelsP1, too
+                        NcToken dim2Name = aVar-&gt;get_dim(2)-&gt;name();
+                        if ((strcmp(dim2Name, &quot;nVertLevels&quot;)) 
+                                        &amp;&amp; (strcmp(dim2Name, &quot;nVertLevelsP1&quot;))) {
+                                continue;
+                        }
+
+                        // Add to cell or point var array
+                        if (isVertexData) {  // means it is dual cell data
+                                dualCellVarIndex++;
+                                if (dualCellVarIndex &gt; MAX_VARS-1) {
+                                        cerr &lt;&lt; &quot;Exceeded number of cell vars.&quot; &lt;&lt; endl;
+                                        exit(1);
+                                }
+                                dualCellVars[dualCellVarIndex] = aVar;
+                                //cout &lt;&lt; &quot;Adding var &quot; &lt;&lt; aVar-&gt;name() &lt;&lt; &quot; to dualCellVars&quot; &lt;&lt; endl;
+                        } else if (isCellData) { // means it is dual vertex data
+                // check for u/v/w vectors
+
+                if (!strncmp(aVar-&gt;name(), &quot;uReconstruct&quot;, 12)) {
+                    if (!strcmp(aVar-&gt;name(), &quot;uReconstructZonal&quot;)) {
+                            vectorVars[0] = aVar;
+                            isUVector = true;
+                    } else if (!strcmp(aVar-&gt;name(), &quot;uReconstructMeridional&quot;)) {
+                            vectorVars[1] = aVar;
+                            isVVector = true;
                     }
-                    dualPointVars[dualPointVarIndex] = aVar;
-                    //cout &lt;&lt; &quot;Adding var &quot; &lt;&lt; aVar-&gt;name() &lt;&lt; &quot; to dualPointVars&quot; &lt;&lt; endl;
-                } else { // case of tracers, add each as &quot;tracer0&quot;, &quot;tracer1&quot;, etc.
-                    tracersExist = true;
-                    int numTracers = aVar-&gt;get_dim(3)-&gt;size();
-                    for (int t = 0; t &lt; numTracers; t++) {
-                        dualPointVarIndex++;
-                        if (dualPointVarIndex &gt; MAX_VARS-1) {
-                            cerr &lt;&lt; &quot;Exceeded number of point vars.&quot; &lt;&lt; endl;
-                            exit(1);
-                        }
-                        dualPointVars[dualPointVarIndex] = aVar;
-                        //cout &lt;&lt; &quot;Adding var &quot; &lt;&lt; aVar-&gt;name() &lt;&lt; &quot; to dualPointVars&quot; &lt;&lt; endl;
-                    }
-                }
-            }
-        }
-    }
+                } else if (strcmp(aVar-&gt;name(), &quot;tracers&quot;)) {
+                                        dualPointVarIndex++;
+                                        if (dualPointVarIndex &gt; MAX_VARS-1) {
+                                                cerr &lt;&lt; &quot;Exceeded number of point vars.&quot; &lt;&lt; endl;
+                                                exit(1);
+                                        }
+                                        dualPointVars[dualPointVarIndex] = aVar;
+                                        //cout &lt;&lt; &quot;Adding var &quot; &lt;&lt; aVar-&gt;name() &lt;&lt; &quot; to dualPointVars&quot; &lt;&lt; endl;
+                                } else { // case of tracers, add each as &quot;tracer0&quot;, &quot;tracer1&quot;, etc.
+                                        tracersExist = true;
+                                        int numTracers = aVar-&gt;get_dim(3)-&gt;size();
+                                        for (int t = 0; t &lt; numTracers; t++) {
+                                                dualPointVarIndex++;
+                                                if (dualPointVarIndex &gt; MAX_VARS-1) {
+                                                        cerr &lt;&lt; &quot;Exceeded number of point vars.&quot; &lt;&lt; endl;
+                                                        exit(1);
+                                                }
+                                                dualPointVars[dualPointVarIndex] = aVar;
+                                                //cout &lt;&lt; &quot;Adding var &quot; &lt;&lt; aVar-&gt;name() &lt;&lt; &quot; to dualPointVars&quot; &lt;&lt; endl;
+                                        }
+                                }
+                        }
+                }
+        }
 
-    // TODO
-    // prompt the user to find out which fields are of interest?
-    // for now, assume all are of interest
-    
-    // get points  (centers of primal-mesh cells)
+        // TODO
+         // prompt the user to find out which fields are of interest?
+        // for now, assume all are of interest
+        
+        // get points  (centers of primal-mesh cells)
 
-    // TO DO check malloc return vals.
+        // TO DO check malloc return vals.
 
     const float BLOATFACTOR = .5;
-    int myCellSize = (int)floor(nCells-&gt;size()*(1.0 + BLOATFACTOR));
-    double *xCellData = (double*)malloc(myCellSize * sizeof(double));
-    CHECK_MALLOC(xCellData);
-    NcVar *xCellVar = ncFile.get_var(&quot;lonCell&quot;);
-    xCellVar-&gt;get(xCellData+1, nCells-&gt;size());
+        int myCellSize = (int)floor(nCells-&gt;size()*(1.0 + BLOATFACTOR));
+        double *xCellData = (double*)malloc(myCellSize * sizeof(double));
+        CHECK_MALLOC(xCellData);
+        NcVar *xCellVar = ncFile.get_var(&quot;lonCell&quot;);
+        xCellVar-&gt;get(xCellData+1, nCells-&gt;size());
     // point 0 is 0.0
     *xCellData = 0.0;
 
     const double PI = 3.141592;
 
+    // if atmospheric data, or zero centered, set center to 180 instead of 0
+    if (atmosphere || isZeroCentered) {
+        for (int j = 1; j &lt;= nCells-&gt;size(); j++) {
+            // need to shift over the point so center is at PI 
+            if (xCellData[j] &lt; 0) {
+                xCellData[j] += 2*PI;
+            }       
+        }       
+    }
+
     double centerRad = centerLon * PI / 180.0;
 
     if (centerLon != 180) {
@@ -388,51 +481,51 @@
         }
     }
 
-    double *yCellData = (double*)malloc(myCellSize * sizeof(double));
-    CHECK_MALLOC(yCellData);
-    NcVar *yCellVar = ncFile.get_var(&quot;latCell&quot;);
-    yCellVar-&gt;get(yCellData+1, nCells-&gt;size());
+        double *yCellData = (double*)malloc(myCellSize * sizeof(double));
+        CHECK_MALLOC(yCellData);
+        NcVar *yCellVar = ncFile.get_var(&quot;latCell&quot;);
+        yCellVar-&gt;get(yCellData+1, nCells-&gt;size());
     // point 0 is 0.0
     *yCellData = 0.0;
 
-    // get dual-mesh cells
+        // get dual-mesh cells
 
-    int *cellsOnVertex = (int *) malloc((nVertices-&gt;size()) * vertexDegree-&gt;size() * 
-        sizeof(int));
-    CHECK_MALLOC(cellsOnVertex);
+        int *cellsOnVertex = (int *) malloc((nVertices-&gt;size()) * vertexDegree-&gt;size() * 
+                sizeof(int));
+        CHECK_MALLOC(cellsOnVertex);
 
-    int myCOVSize = (int)floor(nVertices-&gt;size()*(1.0 + BLOATFACTOR))+1;
-    int *myCellsOnVertex = (int *) malloc(myCOVSize * vertexDegree-&gt;size() * sizeof(int));
-    CHECK_MALLOC(myCellsOnVertex);
+        int myCOVSize = (int)floor(nVertices-&gt;size()*(1.0 + BLOATFACTOR))+1;
+        int *myCellsOnVertex = (int *) malloc(myCOVSize * vertexDegree-&gt;size() * sizeof(int));
+        CHECK_MALLOC(myCellsOnVertex);
 
-    NcVar *cellsOnVertexVar = ncFile.get_var(&quot;cellsOnVertex&quot;);
-    //cout &lt;&lt; &quot;getting cellsOnVertexVar</font>
<font color="red">&quot;;
-    cellsOnVertexVar-&gt;get(cellsOnVertex, nVertices-&gt;size(), vertexDegree-&gt;size());
+        NcVar *cellsOnVertexVar = ncFile.get_var(&quot;cellsOnVertex&quot;);
+        //cout &lt;&lt; &quot;getting cellsOnVertexVar</font>
<font color="gray">&quot;;
+        cellsOnVertexVar-&gt;get(cellsOnVertex, nVertices-&gt;size(), vertexDegree-&gt;size());
 
-    // allocate an array to map the extra points and cells to the original
-    // so that when obtaining data, we know where to get it
-    int *pointMap = (int*)malloc((int)floor(nCells-&gt;size()*BLOATFACTOR) * sizeof(int));
-    CHECK_MALLOC(pointMap);
-    int *cellMap = (int*)malloc((int)floor(nVertices-&gt;size()*BLOATFACTOR) * sizeof(int));
-    CHECK_MALLOC(cellMap);
+        // allocate an array to map the extra points and cells to the original
+        // so that when obtaining data, we know where to get it
+        int *pointMap = (int*)malloc((int)floor(nCells-&gt;size()*BLOATFACTOR) * sizeof(int));
+        CHECK_MALLOC(pointMap);
+        int *cellMap = (int*)malloc((int)floor(nVertices-&gt;size()*BLOATFACTOR) * sizeof(int));
+        CHECK_MALLOC(cellMap);
 
-    
-    int *myptr = myCellsOnVertex;
-    int *myExtraX;
-    int *myExtraY;
-    int currentExtraPoint = numDualPoints;
-    int currentExtraCell = numDualCells;
+        
+        int *myptr = myCellsOnVertex;
+        int *myExtraX;
+        int *myExtraY;
+        int currentExtraPoint = numDualPoints;
+        int currentExtraCell = numDualCells;
 
     // For each cell, examine vertices
-    // Add new points and cells where needed to account for wraparound.
+        // Add new points and cells where needed to account for wraparound.
 
     int acell = 775;
     int mirrorcell;
     int apoint;
     int mirrorpoint;
 
-    for (int j = 0; j &lt; numDualCells; j++ ) {
-        int *dualCells = cellsOnVertex + (j * vertexDegree-&gt;size());
+        for (int j = 0; j &lt; numDualCells; j++ ) {
+                int *dualCells = cellsOnVertex + (j * vertexDegree-&gt;size());
 
         // go through and make sure none of the referenced points are
         // out of range (&lt;=0 or &gt;nCells-&gt;size())
@@ -446,65 +539,89 @@
             } 
         }
 
-        int lastk = vertexDegree-&gt;size()-1;
-        bool xWrap = false;
-        bool yWrap = false;
-        for (int k = 0; k &lt; vertexDegree-&gt;size(); k++) {
-            if (abs(xCellData[dualCells[k]]  - xCellData[dualCells[lastk]]) &gt; 5.5) xWrap = true;
-            //if (abs(yCellData[dualCells[k]]  - yCellData[dualCells[lastk]]) &gt; 2) yWrap = true;
-            lastk = k;
-        }
+        int lastk;
 
-        if (xWrap || yWrap) {
-            //cerr &lt;&lt; &quot;Cell wrap: &quot; &lt;&lt; j &lt;&lt; endl;
+        /////BUG FIX for problem where cells are stretching to a faraway point
+                lastk = vertexDegree-&gt;size()-1;
+        //const double thresh = .139626340159546; // 8 degrees
+        const double thresh = .06981317007977; // 8 degrees
+        for (int k = 0; k &lt; vertexDegree-&gt;size(); k++)  {
+            double xdiff = abs(xCellData[dualCells[k]]  - xCellData[dualCells[lastk]]);
+            double ydiff = abs(yCellData[dualCells[k]]  - yCellData[dualCells[lastk]]);
+            // Don't look at cells at map border
+                        //if ((xdiff &lt;= 5.5) &amp;&amp; (xdiff &gt; (2*.06981317))) {
+                        //if (((xdiff &lt;= 6) &amp;&amp; (xdiff &gt; 3)) || (ydiff &gt; .06981317)) {
+                        if (((xdiff &gt; thresh) &amp;&amp; (ydiff &gt; thresh))
+                 //  || ((xdiff &lt;= 6) &amp;&amp; (xdiff &gt; 3))
+                   || (ydiff &gt; thresh)
+                   ) {
+                for (int m = 0; m &lt; vertexDegree-&gt;size(); m++)  {
+                    dualCells[m] = 0;
+                }
+                break;
+            } 
         }
 
-        if (xWrap) {
-            //cerr &lt;&lt; &quot;It wrapped in x direction&quot; &lt;&lt; endl;
-            double anchorX = xCellData[dualCells[0]];
-            double anchorY = yCellData[dualCells[0]];
-            *myptr = *(dualCells);
-            myptr++;
 
+                lastk = vertexDegree-&gt;size()-1;
+                bool xWrap = false;
+                bool yWrap = false;
+                for (int k = 0; k &lt; vertexDegree-&gt;size(); k++) {
+                        if (abs(xCellData[dualCells[k]]  - xCellData[dualCells[lastk]]) &gt; 5.5) xWrap = true;
+                        //if (abs(yCellData[dualCells[k]]  - yCellData[dualCells[lastk]]) &gt; 2) yWrap = true;
+                        lastk = k;
+                }
+
+                if (xWrap || yWrap) {
+                        //cerr &lt;&lt; &quot;Cell wrap: &quot; &lt;&lt; j &lt;&lt; endl;
+                }
+
+                if (xWrap) {
+                        //cerr &lt;&lt; &quot;It wrapped in x direction&quot; &lt;&lt; endl;
+                        double anchorX = xCellData[dualCells[0]];
+                        double anchorY = yCellData[dualCells[0]];
+                        *myptr = *(dualCells);
+                        myptr++;
+
             if (j == acell) { 
                //cout &lt;&lt; &quot;cell &quot; &lt;&lt; acell &lt;&lt; &quot; anchor x: &quot; &lt;&lt; anchorX &lt;&lt; &quot; y: &quot; &lt;&lt; anchorY &lt;&lt; endl;
             }
 
-            // modify existing cell, so it doesn't wrap
-            // move points to one side
+                        // modify existing cell, so it doesn't wrap
+                        // move points to one side
 
-            // first point is anchor it doesn't move
+                        // first point is anchor it doesn't move
             for (int k = 1; k &lt; vertexDegree-&gt;size(); k++) {
-                double neighX = xCellData[dualCells[k]];
-                double neighY = yCellData[dualCells[k]];
+                                double neighX = xCellData[dualCells[k]];
+                                double neighY = yCellData[dualCells[k]];
 
                 if (j == acell) { 
                    //cout &lt;&lt; &quot;cell &quot; &lt;&lt; acell &lt;&lt; &quot; k: &quot; &lt;&lt; k &lt;&lt; &quot; x: &quot; &lt;&lt; neighX &lt;&lt; &quot; y: &quot; &lt;&lt; neighY &lt;&lt; endl;
                 }
 
-                // add a new point, figure out east or west
-                if (abs(neighX - anchorX) &gt; 5.5)  {
-                    double neighEastX;
-                    double neighWestX;
+                                // add a new point, figure out east or west
+                                if (abs(neighX - anchorX) &gt; 5.5)  {
+                                        double neighEastX;
+                                        double neighWestX;
 
-                    // add on east
-                    if (neighX &lt; anchorX) {
+                                        // add on east
+                                        if (neighX &lt; anchorX) {
                         if (j == acell) { 
                            //cout &lt;&lt; &quot;add on east&quot; &lt;&lt; endl;
                         }
-                        neighEastX = neighX + (2*PI);
-                        xCellData[currentExtraPoint] = neighEastX;
-                        yCellData[currentExtraPoint] = neighY;
-                    } else { 
-                        // add on west
+                                                neighEastX = neighX + (2*PI);
+                                                xCellData[currentExtraPoint] = neighEastX;
+                                                yCellData[currentExtraPoint] = neighY;
+                                        } else { 
+                                                // add on west
                         if (j == acell) { 
                            //cout &lt;&lt; &quot;add on west&quot; &lt;&lt; endl;
                         }
-                        neighWestX = neighX - (2*PI);
-                        xCellData[currentExtraPoint] = neighWestX;
-                        yCellData[currentExtraPoint] = neighY;
-                    }
-            
+                                                neighWestX = neighX - (2*PI);
+                                                xCellData[currentExtraPoint] = neighWestX;
+                                                yCellData[currentExtraPoint] = neighY;
+                                        }
+                        
                     if (j == acell) {    
                            //cout &lt;&lt; &quot;x: &quot; &lt;&lt; xCellData[currentExtraPoint] &lt;&lt; &quot; y: &quot; &lt;&lt; yCellData[currentExtraPoint] &lt;&lt; endl;
                     }
@@ -513,11 +630,11 @@
                        //cout &lt;&lt; &quot;currentExtraPoint: &quot; &lt;&lt; currentExtraPoint &lt;&lt; endl;
                     }
 
-                    // add the new point to list of vertices
-                    *myptr = currentExtraPoint;
+                                        // add the new point to list of vertices
+                                        *myptr = currentExtraPoint;
 
-                    // record mapping
-                    *(pointMap + (currentExtraPoint - numDualPoints)) = dualCells[k];
+                                        // record mapping
+                                        *(pointMap + (currentExtraPoint - numDualPoints)) = dualCells[k];
 
                     if (j == acell) { 
                        mirrorpoint = currentExtraPoint;
@@ -525,28 +642,28 @@
                        //cout &lt;&lt; &quot;mirror point &quot; &lt;&lt; mirrorpoint &lt;&lt; &quot; has pointMap to: &quot; &lt;&lt; dualCells[k] &lt;&lt; endl;
                     }
 
-                    myptr++;
-                    currentExtraPoint++;
-                } else {
-                    // use existing kth point 
+                                        myptr++;
+                                        currentExtraPoint++;
+                                } else {
+                                        // use existing kth point 
                     if (j == acell) {
                         //cout &lt;&lt; &quot;use existing point&quot; &lt;&lt; endl;
                     }
-                    *myptr = dualCells[k];
-                    myptr++;
-                }
-            }
+                                        *myptr = dualCells[k];
+                                        myptr++;
+                                }
+                        }
 
-            // add a mirror image cell on other side so there are no
-            // gaps in the map
+                        // add a mirror image cell on other side so there are no
+                        // gaps in the map
 
-            // move anchor to other side
-            if (anchorX &gt; centerRad) {
-                anchorX = anchorX - (2*PI);
-            } else {
-                anchorX = anchorX + (2*PI);
-            }
-    
+                        // move anchor to other side
+                        if (anchorX &gt; centerRad) {
+                                anchorX = anchorX - (2*PI);
+                        } else {
+                                anchorX = anchorX + (2*PI);
+                        }
+        
             if (j == acell) { 
                //cout &lt;&lt; &quot;add new cell &quot; &lt;&lt; currentExtraCell &lt;&lt; &quot; to mirror &quot; &lt;&lt; acell &lt;&lt; &quot; anchorX: &quot; &lt;&lt; anchorX &lt;&lt; &quot; anchorY: &quot; &lt;&lt; anchorY &lt;&lt; endl;
                mirrorcell = currentExtraCell;
@@ -556,110 +673,110 @@
             int* addedCellsPtr = myCellsOnVertex + (currentExtraCell * vertexDegree-&gt;size());
 
             // add point coord and add to list of cells
-            xCellData[currentExtraPoint] = anchorX;
-            yCellData[currentExtraPoint] = anchorY;
-            *addedCellsPtr = currentExtraPoint;
+                        xCellData[currentExtraPoint] = anchorX;
+                        yCellData[currentExtraPoint] = anchorY;
+                        *addedCellsPtr = currentExtraPoint;
 
-            // record mapping
-            *(pointMap + (currentExtraPoint - numDualPoints)) = dualCells[0];
+                        // record mapping
+                        *(pointMap + (currentExtraPoint - numDualPoints)) = dualCells[0];
 
-            addedCellsPtr++;
-            currentExtraPoint++;
+                        addedCellsPtr++;
+                        currentExtraPoint++;
 
-            for (int k = 1; k &lt; vertexDegree-&gt;size(); k++) {
-                double neighX = xCellData[dualCells[k]];
-                double neighY = yCellData[dualCells[k]];
+                        for (int k = 1; k &lt; vertexDegree-&gt;size(); k++) {
+                                double neighX = xCellData[dualCells[k]];
+                                double neighY = yCellData[dualCells[k]];
 
-                // add a new point, figure out east or west
-                if (abs(neighX - anchorX) &gt; 5.5)  {
-                    double neighEastX;
-                    double neighWestX;
+                                // add a new point, figure out east or west
+                                if (abs(neighX - anchorX) &gt; 5.5)  {
+                                        double neighEastX;
+                                        double neighWestX;
 
-                    // add on east
-                    if (neighX &lt; anchorX) {
-                        neighEastX = neighX + (2*PI);
-                        xCellData[currentExtraPoint] = neighEastX;
-                        yCellData[currentExtraPoint] = neighY;
-                    } else { 
-                        // add on west
-                        neighWestX = neighX - (2*PI);
-                        xCellData[currentExtraPoint] = neighWestX;
-                        yCellData[currentExtraPoint] = neighY;
-                    }
+                                        // add on east
+                                        if (neighX &lt; anchorX) {
+                                                neighEastX = neighX + (2*PI);
+                                                xCellData[currentExtraPoint] = neighEastX;
+                                                yCellData[currentExtraPoint] = neighY;
+                                        } else { 
+                                                // add on west
+                                                neighWestX = neighX - (2*PI);
+                                                xCellData[currentExtraPoint] = neighWestX;
+                                                yCellData[currentExtraPoint] = neighY;
+                                        }
 
-                    // add the new point to list of vertices
-                    *addedCellsPtr = currentExtraPoint;
+                                        // add the new point to list of vertices
+                                        *addedCellsPtr = currentExtraPoint;
 
-                    // record mapping
-                    *(pointMap + (currentExtraPoint - numDualPoints)) = dualCells[k];
+                                        // record mapping
+                                        *(pointMap + (currentExtraPoint - numDualPoints)) = dualCells[k];
 
-                    addedCellsPtr++;
-                    currentExtraPoint++;
-                } else {
-                    // use existing kth point 
-                    *addedCellsPtr = dualCells[k];
-                    addedCellsPtr++;
-                }
-            }
-            *(cellMap + (currentExtraCell - numDualCells)) = j;
-            currentExtraCell++;
-        }
-        if (yWrap) {
-            //cerr &lt;&lt; &quot;It wrapped in y direction&quot; &lt;&lt; endl;
-        }
+                                        addedCellsPtr++;
+                                        currentExtraPoint++;
+                                } else {
+                                        // use existing kth point 
+                                        *addedCellsPtr = dualCells[k];
+                                        addedCellsPtr++;
+                                }
+                        }
+                        *(cellMap + (currentExtraCell - numDualCells)) = j;
+                        currentExtraCell++;
+                }
+                if (yWrap) {
+                        //cerr &lt;&lt; &quot;It wrapped in y direction&quot; &lt;&lt; endl;
+                }
 
-        // if cell doesn't extend past lat/lon perimeter, then add it to myCellsOnVertex
-        if (!xWrap &amp;&amp; !yWrap) {
-            for (int k=0; k&lt; vertexDegree-&gt;size(); k++) {
-                *myptr = *(dualCells+k);
-                myptr++;
-            }
-        }
-        if (currentExtraCell &gt; myCOVSize) {
-            cerr &lt;&lt; &quot;Exceeded storage for extra cells!&quot; &lt;&lt; endl;
-            return 1;
-        }
-        if (currentExtraPoint &gt; myCellSize) {
-            cerr &lt;&lt; &quot;Exceeded storage for extra points!&quot; &lt;&lt; endl;
-            return 1;
-        }
-    }   
-                        
-    // decls for data storage
-    double* dualCellVarData;
-    double* dualPointVarData;
+                // if cell doesn't extend past lat/lon perimeter, then add it to myCellsOnVertex
+                if (!xWrap &amp;&amp; !yWrap) {
+                        for (int k=0; k&lt; vertexDegree-&gt;size(); k++) {
+                                *myptr = *(dualCells+k);
+                                myptr++;
+                        }
+                }
+                if (currentExtraCell &gt; myCOVSize) {
+                        cerr &lt;&lt; &quot;Exceeded storage for extra cells!&quot; &lt;&lt; endl;
+                        return 1;
+                }
+                if (currentExtraPoint &gt; myCellSize) {
+                        cerr &lt;&lt; &quot;Exceeded storage for extra points!&quot; &lt;&lt; endl;
+                        return 1;
+                }
+        }        
+                                                
+        // decls for data storage
+        double* dualCellVarData;
+        double* dualPointVarData;
 
-    // for each variable, allocate space for variables
+        // for each variable, allocate space for variables
 
-    //cout &lt;&lt; &quot;dualCellVarIndex: &quot; &lt;&lt; dualCellVarIndex &lt;&lt; endl;
+        //cout &lt;&lt; &quot;dualCellVarIndex: &quot; &lt;&lt; dualCellVarIndex &lt;&lt; endl;
 
-    int varVertLevels = 0;
-    
-    // write a file with the geometry.
+        int varVertLevels = 0;
+        
+        // write a file with the geometry.
 
-    ostringstream geoFileName;
+        ostringstream geoFileName;
 
-    geoFileName &lt;&lt; &quot;geo_&quot; &lt;&lt; outputFileName;    
+        geoFileName &lt;&lt; &quot;geo_&quot; &lt;&lt; outputFileName;         
 
-    ofstream geoFile(geoFileName.str().c_str(), ios::out);
+        ofstream geoFile(geoFileName.str().c_str(), ios::out);
 
-    if (!geoFile)
-    {
-        cerr &lt;&lt; &quot;vtk output file could not be opened&quot; &lt;&lt;endl;
-        exit(1);
-    }
+        if (!geoFile)
+        {
+                cerr &lt;&lt; &quot;vtk output file could not be opened&quot; &lt;&lt;endl;
+                exit(1);
+        }
 
 
-    // write header
+        // write header
 
-    geoFile &lt;&lt; &quot;# vtk DataFile Version 2.0&quot; &lt;&lt; endl;
-    geoFile &lt;&lt; &quot;Project newpop geometry to lat/lon projection from netCDF by Christine Ahrens&quot; 
-        &lt;&lt; endl;
-    geoFile &lt;&lt; &quot;ASCII&quot; &lt;&lt; endl;
-    geoFile &lt;&lt; &quot;DATASET UNSTRUCTURED_GRID&quot; &lt;&lt; endl;
+        geoFile &lt;&lt; &quot;# vtk DataFile Version 2.0, projlatlon Version 1.2&quot; &lt;&lt; endl;
+        geoFile &lt;&lt; &quot;Project newpop geometry to lat/lon projection from netCDF by Christine Ahrens&quot; 
+                &lt;&lt; endl;
+        geoFile &lt;&lt; &quot;ASCII&quot; &lt;&lt; endl;
+        geoFile &lt;&lt; &quot;DATASET UNSTRUCTURED_GRID&quot; &lt;&lt; endl;
 
 
-    // write points  (the points are the primal-grid cell centers)
+        // write points  (the points are the primal-grid cell centers)
 
     if (singlelayer) {
         geoFile &lt;&lt; &quot;POINTS &quot; &lt;&lt; currentExtraPoint &lt;&lt; &quot; float&quot; &lt;&lt; endl;
@@ -667,69 +784,69 @@
         geoFile &lt;&lt; &quot;POINTS &quot; &lt;&lt; currentExtraPoint*(maxNVertLevels+1) &lt;&lt; &quot; float&quot; &lt;&lt; endl;
     }
 
-    // write the point at each vertical level, plus one level for last layer
+        // write the point at each vertical level, plus one level for last layer
 
-    //cout &lt;&lt; &quot;Writing points at each level&quot; &lt;&lt; endl;
+        //cout &lt;&lt; &quot;Writing points at each level&quot; &lt;&lt; endl;
 
-    for (int j = 0; j &lt; currentExtraPoint; j++ )
-    {
-        geoFile.precision(16);
+        for (int j = 0; j &lt; currentExtraPoint; j++ )
+        {
+                geoFile.precision(16);
 
-        if (abs(xCellData[j]) &lt; 1e-126) xCellData[j] = 0;
-        if (abs(yCellData[j]) &lt; 1e-126) yCellData[j] = 0;
+                if (abs(xCellData[j]) &lt; 1e-126) xCellData[j] = 0;
+                if (abs(yCellData[j]) &lt; 1e-126) yCellData[j] = 0;
 
-        float xLon = xCellData[j] * 180.0 / PI;
-        float yLon = yCellData[j] * 180.0 / PI;
+                float xLon = xCellData[j] * 180.0 / PI;
+                float yLat = yCellData[j] * 180.0 / PI;
 
         if (singlelayer) {
-            geoFile &lt;&lt; xLon &lt;&lt; &quot;\t&quot; &lt;&lt; yLon &lt;&lt; &quot;\t&quot; &lt;&lt; 0 &lt;&lt; endl;
+                        geoFile &lt;&lt; xLon &lt;&lt; &quot;\t&quot; &lt;&lt; yLat &lt;&lt; &quot;\t&quot; &lt;&lt; 0 &lt;&lt; endl;
         } else {
             for (int levelNum = 0; levelNum &lt; maxNVertLevels+1; levelNum++) {
-                geoFile &lt;&lt; xLon &lt;&lt; &quot;\t&quot; &lt;&lt; yLon &lt;&lt; &quot;\t&quot; &lt;&lt; -(((float)levelNum)*layerThickness) &lt;&lt; endl;
+                geoFile &lt;&lt; xLon &lt;&lt; &quot;\t&quot; &lt;&lt; yLat &lt;&lt; &quot;\t&quot; &lt;&lt; -(((float)levelNum)*layerThickness) &lt;&lt; endl;
             }
         }
-    }   
+        }        
 
-        geoFile &lt;&lt; endl;
+                geoFile &lt;&lt; endl;
 
 
-        // Write dual-mesh cells
-        // Dual-mesh cells are triangles with primal-mesh cell 
-        // centers as the vertices.
-        // The number of dual-mesh cells is the number of vertices in the
-        // primal mesh.
+                // Write dual-mesh cells
+                // Dual-mesh cells are triangles with primal-mesh cell 
+                // centers as the vertices.
+                // The number of dual-mesh cells is the number of vertices in the
+                // primal mesh.
 
-        int degree = multilayer?vertexDegree-&gt;size()*2:vertexDegree-&gt;size();
+                int degree = multilayer?vertexDegree-&gt;size()*2:vertexDegree-&gt;size();
 
         if (singlelayer) {
             geoFile &lt;&lt; &quot;CELLS &quot; &lt;&lt; currentExtraCell &lt;&lt; &quot; &quot; 
-                &lt;&lt; currentExtraCell * (degree + 1) &lt;&lt; endl; 
+                &lt;&lt; currentExtraCell * (degree + 1) &lt;&lt; endl;        
         } else {
             geoFile &lt;&lt; &quot;CELLS &quot; &lt;&lt; currentExtraCell*maxNVertLevels &lt;&lt; &quot; &quot; 
-                &lt;&lt; currentExtraCell * (degree + 1) * maxNVertLevels &lt;&lt; endl;    
+                &lt;&lt; currentExtraCell * (degree + 1) * maxNVertLevels &lt;&lt; endl;        
         }
 
-        // for each dual-mesh cell, write number of points for each
-        // and then list the points by number
+                // for each dual-mesh cell, write number of points for each
+                // and then list the points by number
 
-        //cout &lt;&lt; &quot;Writing Cells&quot; &lt;&lt; endl;
+                //cout &lt;&lt; &quot;Writing Cells&quot; &lt;&lt; endl;
 
-        for (int j = 0; j &lt; currentExtraCell ; j++) {
+                for (int j = 0; j &lt; currentExtraCell ; j++) {
 
-            // since primal vertex(pt) numbers  == dual cell numbers
-            // we go through the primal vertices, find the cells around
-            // them, and since those primal cell numbers are dual 
-            // point numbers,  
-            // we can write the cell numbers for the cellsOnVertex
-            // and those will be the numbers of the dual vertices (pts).
-            
-            int* dualCells = myCellsOnVertex + (j * vertexDegree-&gt;size());
+                        // since primal vertex(pt) numbers  == dual cell numbers
+                        // we go through the primal vertices, find the cells around
+                        // them, and since those primal cell numbers are dual 
+                        // point numbers,  
+                        // we can write the cell numbers for the cellsOnVertex
+                        // and those will be the numbers of the dual vertices (pts).
+                        
+                        int* dualCells = myCellsOnVertex + (j * vertexDegree-&gt;size());
 
-            // for each level, write the cell
+                        // for each level, write the cell
             if (singlelayer) {
-                geoFile &lt;&lt; degree &lt;&lt; &quot;\t&quot; ;
-                for (int k = 0; k &lt; vertexDegree-&gt;size(); k++) 
-                    geoFile &lt;&lt; dualCells[k] &lt;&lt; &quot;\t&quot;;
+                                geoFile &lt;&lt; degree &lt;&lt; &quot;\t&quot; ;
+                                for (int k = 0; k &lt; vertexDegree-&gt;size(); k++) 
+                                        geoFile &lt;&lt; dualCells[k] &lt;&lt; &quot;\t&quot;;
                 geoFile &lt;&lt; endl;
             } else {
                 for (int levelNum = 0; levelNum &lt; maxNVertLevels; levelNum++) {
@@ -737,20 +854,20 @@
                     geoFile &lt;&lt; degree &lt;&lt; &quot;\t&quot; ;
 
                     for (int k = 0; k &lt; vertexDegree-&gt;size(); k++) 
-                    {       
+                    {                
                         geoFile &lt;&lt; (dualCells[k]*(maxNVertLevels+1)) + levelNum &lt;&lt; &quot;\t&quot;;
                     }
                     for (int k = 0; k &lt; vertexDegree-&gt;size(); k++) 
-                    {       
+                    {                
                         geoFile &lt;&lt; (dualCells[k]*(maxNVertLevels+1)) + levelNum+1 &lt;&lt; &quot;\t&quot;;
                     }
                     geoFile &lt;&lt; endl;
                 }
             }
-        }
+                }
 
-        // write cell types 
-        int cellType;
+                // write cell types 
+                int cellType;
         switch (vertexDegree-&gt;size()) {
             case 3:
                if (singlelayer) {
@@ -770,7 +887,7 @@
                break;
         }
 
-        if (singlelayer) {
+                if (singlelayer) {
             geoFile &lt;&lt; &quot;CELL_TYPES &quot; &lt;&lt; currentExtraCell &lt;&lt; endl;
         } else {
             geoFile &lt;&lt; &quot;CELL_TYPES &quot; &lt;&lt; currentExtraCell*maxNVertLevels &lt;&lt; endl;
@@ -789,45 +906,58 @@
             }
         }
 
-    // release resources
-    geoFile.close();
-    free(xCellData);
-    free(yCellData);
-    free(cellsOnVertex);
-    free(myCellsOnVertex);
+        // release resources
+        geoFile.close();
+        //free(xCellData);
+        //free(yCellData);
+        free(cellsOnVertex);
+        free(myCellsOnVertex);
 
-    // For each timestep, write data for each level
+        // For each timestep, write data for each level
 
-    dualCellVarData = (double*)malloc((sizeof(double))  * currentExtraCell * maxNVertLevels);
-    CHECK_MALLOC(dualCellVarData);
+        dualCellVarData = (double*)malloc((sizeof(double))  * currentExtraCell * maxNVertLevels);
+        CHECK_MALLOC(dualCellVarData);
 
-    dualPointVarData = (double*)malloc((sizeof(double)) * currentExtraPoint * maxNVertLevels);
-    CHECK_MALLOC(dualPointVarData);
+        dualPointVarData = (double*)malloc((sizeof(double)) * currentExtraPoint * maxNVertLevels);
+        CHECK_MALLOC(dualPointVarData);
 
-    // for each timestep, copy the geometry file, since we don't want to
-    // have to recompute the points
-    for (int i = 0; i &lt; Time-&gt;size(); i++) {
-        ostringstream vtkFileName;
-        vtkFileName &lt;&lt; i &lt;&lt; outputFileName;
+    double *vectorData[3] = {NULL, NULL, NULL};
 
-        string geoFileNameString = geoFileName.str();
-        string vtkFileNameString = vtkFileName.str();
-        int copyRetVal = myCopyFile(&amp;geoFileNameString, &amp;vtkFileNameString);
-        //cout &lt;&lt; &quot;myCopyFile returned: &quot; &lt;&lt; copyRetVal &lt;&lt; endl;
-
-        ofstream vtkFile(vtkFileName.str().c_str(), ios::out|ios::app);
-        if (!vtkFile)
-        {
-            cerr &lt;&lt; &quot;vtk output file could not be opened&quot; &lt;&lt;endl;
-            exit(1);
+    if (isUVector)  {
+        for (int d = 0; d &lt; 3; d++) {
+            if (singlelayer) {
+                vectorData[d] = (double*)malloc((sizeof(double)) * (nCells-&gt;size() + 1));
+            } else {
+                vectorData[d] = (double*)malloc((sizeof(double)) * (nCells-&gt;size() + 1) * maxNVertLevels);
+            }
+            CHECK_MALLOC(vectorData[d]);
         }
+    }
 
-        vtkFile.precision(16);
+        // for each timestep, copy the geometry file, since we don't want to
+        // have to recompute the points
+        for (int i = startTimeStep; i &lt;= finishTimeStep; i++) {
+                ostringstream vtkFileName;
+                vtkFileName &lt;&lt; i &lt;&lt; outputFileName;
 
+                string geoFileNameString = geoFileName.str();
+                string vtkFileNameString = vtkFileName.str();
+                int copyRetVal = myCopyFile(&amp;geoFileNameString, &amp;vtkFileNameString);
+                //cout &lt;&lt; &quot;myCopyFile returned: &quot; &lt;&lt; copyRetVal &lt;&lt; endl;
+
+                ofstream vtkFile(vtkFileName.str().c_str(), ios::out|ios::app);
+                if (!vtkFile)
+                {
+                        cerr &lt;&lt; &quot;vtk output file could not be opened&quot; &lt;&lt;endl;
+                        exit(1);
+                }
+
+                vtkFile.precision(16);
+
         int vertLevelIndex = 0;
         if (singlelayer) vertLevelIndex = outputVertLevel;
 
-        // If by point, write out point data
+                // If by point, write out point data
 
         if (singlelayer) {
             if (dualPointVarIndex &gt;= 0) vtkFile &lt;&lt; &quot;POINT_DATA &quot; &lt;&lt; currentExtraPoint &lt;&lt; endl;
@@ -835,62 +965,62 @@
             if (dualPointVarIndex &gt;= 0) vtkFile &lt;&lt; &quot;POINT_DATA &quot; &lt;&lt; currentExtraPoint*(maxNVertLevels+1) &lt;&lt; endl;
         }
 
-        int printstep = -1;
+                int printstep = -1;
 
-        if (i == printstep) cout &lt;&lt; &quot;TIME STEP: &quot; &lt;&lt; i &lt;&lt; endl;
+                if (i == printstep) cout &lt;&lt; &quot;TIME STEP: &quot; &lt;&lt; i &lt;&lt; endl;
 
-        int tracerNum = 0;
+                int tracerNum = 0;
 
-        for (int v = 0; v &lt;= dualPointVarIndex; v++) {
+                for (int v = 0; v &lt;= dualPointVarIndex; v++) {
 
-            // Read variable number v data for that timestep
+                        // Read variable number v data for that timestep
 
-            varVertLevels = dualPointVars[v]-&gt;get_dim(2)-&gt;size();
+                        varVertLevels = dualPointVars[v]-&gt;get_dim(2)-&gt;size();
 
-            bool isTracer = false;
+                        bool isTracer = false;
 
-            if (!strcmp(dualPointVars[v]-&gt;name(), &quot;tracers&quot;)) {
-                isTracer = true;
-            // Uncomment if want to exclude tracers.  
-            //  continue;
-            }
+                        if (!strcmp(dualPointVars[v]-&gt;name(), &quot;tracers&quot;)) {
+                                isTracer = true;
+                        // Uncomment if want to exclude tracers.  
+                        //        continue;
+                        }
 
-            // Write variable number v data for that timestep
-            vtkFile &lt;&lt; &quot;SCALARS &quot; &lt;&lt; dualPointVars[v]-&gt;name();
-            if (isTracer) vtkFile &lt;&lt; tracerNum+1;
-            vtkFile &lt;&lt; &quot; float 1&quot; &lt;&lt;  endl;
-            vtkFile &lt;&lt; &quot;LOOKUP_TABLE default&quot; &lt;&lt; endl;
+                        // Write variable number v data for that timestep
+                        vtkFile &lt;&lt; &quot;SCALARS &quot; &lt;&lt; dualPointVars[v]-&gt;name();
+                        if (isTracer) vtkFile &lt;&lt; tracerNum+1;
+                        vtkFile &lt;&lt; &quot; float 1&quot; &lt;&lt;  endl;
+                        vtkFile &lt;&lt; &quot;LOOKUP_TABLE default&quot; &lt;&lt; endl;
 
-            if (isTracer) {
-                dualPointVars[v]-&gt;set_cur(i, 0, vertLevelIndex, tracerNum);
+                        if (isTracer) {
+                                dualPointVars[v]-&gt;set_cur(i, 0, vertLevelIndex, tracerNum);
                 if (singlelayer) {
                     dualPointVars[v]-&gt;get(dualPointVarData+1, 1, nCells-&gt;size(), 1, 1);
                 } else {
                     dualPointVars[v]-&gt;get(dualPointVarData+maxNVertLevels, 1, nCells-&gt;size(), maxNVertLevels, 1);
                 }
-            } else {
-                dualPointVars[v]-&gt;set_cur(i, 0, vertLevelIndex);
+                        } else {
+                                dualPointVars[v]-&gt;set_cur(i, 0, vertLevelIndex);
                 if (singlelayer) {
                     dualPointVars[v]-&gt;get(dualPointVarData+1, 1, nCells-&gt;size(), 1);
                 } else {
                     dualPointVars[v]-&gt;get(dualPointVarData+maxNVertLevels, 1, nCells-&gt;size(), maxNVertLevels);
                 }
-            }
+                        }
 
 
-            float defaultPointVal = 0.0;
+                        float defaultPointVal = 0.0;
 
-            double *var_target;
-            float validData;
+                        double *var_target;
+                        float validData;
 
-            //write dummy
+                        //write dummy
             if (singlelayer) {
-                var_target = dualPointVarData + 1;
-                validData = convertDouble2ValidFloat (*var_target);
+                            var_target = dualPointVarData + 1;
+                                validData = convertDouble2ValidFloat (*var_target);
 
-                // write dummy
-                vtkFile &lt;&lt; validData &lt;&lt; endl;
-            } else {
+                                // write dummy
+                                vtkFile &lt;&lt; validData &lt;&lt; endl;
+                        } else {
             //write dummy
                 var_target = dualPointVarData + maxNVertLevels;
                 for (int levelNum = 0; levelNum &lt; maxNVertLevels; levelNum++) {
@@ -908,12 +1038,12 @@
                 var_target = dualPointVarData + maxNVertLevels;
             }
 
-            for (int j = 1; j &lt; numDualPoints; j++) {
+                        for (int j = 1; j &lt; numDualPoints; j++) {
 
                 if (singlelayer) {
-                    validData = convertDouble2ValidFloat (*var_target);
-                    vtkFile &lt;&lt; validData &lt;&lt; endl;
-                    var_target++;
+                                        validData = convertDouble2ValidFloat (*var_target);
+                                        vtkFile &lt;&lt; validData &lt;&lt; endl;
+                                        var_target++;
                 } else {
 
                     // write data for one point -- lowest level to highest
@@ -927,20 +1057,20 @@
                     // Need Mark's input on this one
                     vtkFile &lt;&lt; validData &lt;&lt; endl;
                 }
-            }
+                        }
 
-            // put out data for extra points
-            for (int j = numDualPoints; j &lt; currentExtraPoint; j++) {
+                        // put out data for extra points
+                        for (int j = numDualPoints; j &lt; currentExtraPoint; j++) {
                 if (j == mirrorpoint) {
                     //cout &lt;&lt; &quot;data for mirror point &quot; &lt;&lt; mirrorpoint &lt;&lt; &quot; from point &quot; &lt;&lt; *(pointMap + j - numDualPoints) &lt;&lt; endl;
                 }
                 // use map to find out what point data we are using
-                var_target = dualPointVarData + ((*(pointMap + j - numDualPoints))*maxNVertLevels);
+                                var_target = dualPointVarData + ((*(pointMap + j - numDualPoints))*maxNVertLevels);
 
                 if (singlelayer) {
-                    validData = convertDouble2ValidFloat (*var_target);
-                    vtkFile &lt;&lt; validData &lt;&lt; endl;
-                    var_target++;
+                                        validData = convertDouble2ValidFloat (*var_target);
+                                        vtkFile &lt;&lt; validData &lt;&lt; endl;
+                                        var_target++;
                 } else {
                     // write data for one point -- lowest level to highest
                     for (int levelNum = 0; levelNum &lt; maxNVertLevels; levelNum++) {
@@ -953,11 +1083,154 @@
                     // Need Mark's input on this one
                     vtkFile &lt;&lt; validData &lt;&lt; endl;
                 }
+                        }
+                        if (isTracer) tracerNum++;
+                }
+
+        float validData;
+        int maxDim = 2;  // z is always 0 for vectors in lat/lon projection 
+
+        if (isUVector) {
+            cout &lt;&lt; &quot;isUVector:&quot; &lt;&lt; endl;
+
+            for (int d = 0; d &lt; maxDim; d++) {
+                // read data in
+                vectorVars[d]-&gt;set_cur(i, 0, vertLevelIndex);
+                if (singlelayer) {
+                    vectorVars[d]-&gt;get(vectorData[d]+1, 1, nCells-&gt;size(), 1);
+                } else {
+                    vectorVars[d]-&gt;get(vectorData[d]+maxNVertLevels, 1, nCells-&gt;size(), maxNVertLevels);
+                }
             }
-            if (isTracer) tracerNum++;
+           
+#ifdef NO_NEED_TO_DO_THIS  
+            // Convert all vector data to lat/lon
+            if (singlelayer) {
+                for (int j = 1; j &lt;= nCells-&gt;size(); j++) {
+                    double x = *(vectorData[0] + j);
+                    double y = *(vectorData[1] + j);
+                    double z = *(vectorData[2] + j);
+                            float lon = xCellData[j];
+                            float lat = yCellData[j];
+                    *(vectorData[0] + j) = convertXY2Lon(x, y, lon);
+                    *(vectorData[1] + j) = convertXYZ2Lat(x, y, z, lon, lat);
+                }
+            } else {
+                for (int j = 1; j &lt;= nCells-&gt;size(); j++) {
+                    float lon = xCellData[j];
+                    float lat = yCellData[j];
+                    for (int levelNum = 0; levelNum &lt; maxNVertLevels; levelNum++) {
+                        double x = *(vectorData[0] + (j*maxNVertLevels) + levelNum);
+                        double y = *(vectorData[1] + (j*maxNVertLevels) + levelNum);
+                        double z = *(vectorData[2] + (j*maxNVertLevels) + levelNum);
+                        *(vectorData[0] + (j*maxNVertLevels) + levelNum) = 
+                            convertXY2Lon(x, y, lon);
+                        *(vectorData[1] + (j*maxNVertLevels) + levelNum) = 
+                            convertXYZ2Lat(x, y, z, lon, lat);
+                    }
+                }
+            }
+#endif
+
+            vtkFile &lt;&lt; &quot;VECTORS uReconstruct double&quot; &lt;&lt; endl;
+
+            // dummy first
+            if (singlelayer) {
+                for (int d= 0; d &lt; maxDim; d++) {
+                    validData = convertDouble2ValidFloat (*(vectorData[d] + 1));
+                    vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                }
+                //vtkFile &lt;&lt; endl;
+                vtkFile &lt;&lt; 0 &lt;&lt; endl;
+            } else {
+                for (int levelNum = 0; levelNum &lt; maxNVertLevels; levelNum++) {
+                    for (int d= 0; d &lt; maxDim; d++) {
+                        validData = convertDouble2ValidFloat (*(vectorData[d] + maxNVertLevels+ levelNum));
+                        vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                    }
+                    //vtkFile &lt;&lt; endl;
+                    vtkFile &lt;&lt; 0 &lt;&lt; endl;
+                }
+            }
+            // write highest level dummy point
+            if (multilayer) {
+                for (int d= 0; d &lt; maxDim; d++) {
+                    validData = convertDouble2ValidFloat (*(vectorData[d] + maxNVertLevels + (maxNVertLevels-1)));
+                    vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                }
+                //vtkFile &lt;&lt; endl;
+                vtkFile &lt;&lt; 0 &lt;&lt; endl;
+            }
+
+            // rest of data
+            for (int j = 1; j &lt; numDualPoints; j++)
+            {
+                if (singlelayer) {
+                    for (int d= 0; d &lt; maxDim; d++) {
+                        validData = convertDouble2ValidFloat (*(vectorData[d] + j));
+                        vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                    }
+                    //vtkFile &lt;&lt; endl;
+                    vtkFile &lt;&lt; 0 &lt;&lt; endl;
+                } else {
+                    for (int levelNum = 0; levelNum &lt; maxNVertLevels; levelNum++) {
+                        for (int d= 0; d &lt; maxDim; d++) {
+                            validData = convertDouble2ValidFloat (*(vectorData[d] + (j * maxNVertLevels) + levelNum));
+                            vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                            if (j ==  1000) {
+                                cout &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                            }
+                        }
+                        //vtkFile &lt;&lt; endl;
+                        vtkFile &lt;&lt; 0 &lt;&lt; endl;
+                    }
+                    // for last layer of dual points, repeat last level's values
+                    // Need Mark's input on this one
+                    for (int d= 0; d &lt; maxDim; d++) {
+                        validData = convertDouble2ValidFloat (*(vectorData[d] + (j * maxNVertLevels) + maxNVertLevels-1));
+                        vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                    }
+                    //vtkFile &lt;&lt; endl;
+                    vtkFile &lt;&lt; 0 &lt;&lt; endl;
+                }
+            }
+
+                        // put out data for extra points
+                        for (int j = numDualPoints; j &lt; currentExtraPoint; j++) {
+
+                // use map to find out what point data we are using
+                                int var_target = ((*(pointMap + j - numDualPoints))*maxNVertLevels);
+
+                if (singlelayer) {
+                    for (int d= 0; d &lt; maxDim; d++) {
+                        validData = convertDouble2ValidFloat (*(vectorData[d] + var_target));
+                        vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                    }
+                    //vtkFile &lt;&lt; endl;
+                    vtkFile &lt;&lt; 0 &lt;&lt; endl;
+                } else {
+                    // write data for one point -- lowest level to highest
+                    for (int levelNum = 0; levelNum &lt; maxNVertLevels; levelNum++) {
+                        for (int d= 0; d &lt; maxDim; d++) {
+                            validData = convertDouble2ValidFloat (*(vectorData[d] + var_target + levelNum));
+                            vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                        }
+                        //vtkFile &lt;&lt; endl;
+                        vtkFile &lt;&lt; 0 &lt;&lt; endl;
+                    }
+                
+                    // for last layer of dual points, repeat last level's values
+                    for (int d= 0; d &lt; maxDim; d++) {
+                        validData = convertDouble2ValidFloat (*(vectorData[d] + var_target + maxNVertLevels-1));
+                        vtkFile &lt;&lt; validData &lt;&lt; &quot; &quot;;
+                    }
+                    //vtkFile &lt;&lt; endl;
+                    vtkFile &lt;&lt; 0 &lt;&lt; endl;
+                }
+            }
         }
 
-        // if by cell, then write out cell data
+                // if by cell, then write out cell data
 
         if (singlelayer) {
             if (dualCellVarIndex &gt;= 0) vtkFile &lt;&lt; &quot;CELL_DATA &quot; &lt;&lt; currentExtraCell &lt;&lt; endl;
@@ -965,14 +1238,14 @@
             if (dualCellVarIndex &gt;= 0) vtkFile &lt;&lt; &quot;CELL_DATA &quot; &lt;&lt; currentExtraCell*maxNVertLevels &lt;&lt; endl;
         }
 
-        for (int v = 0; v &lt;= dualCellVarIndex; v++) {
+                for (int v = 0; v &lt;= dualCellVarIndex; v++) {
 
-            // Write variable number v data for that timestep
-            vtkFile &lt;&lt; &quot;SCALARS &quot; &lt;&lt; dualCellVars[v]-&gt;name() &lt;&lt; &quot; float 1&quot; &lt;&lt;  endl;
-            vtkFile &lt;&lt; &quot;LOOKUP_TABLE default&quot; &lt;&lt; endl;
+                        // Write variable number v data for that timestep
+                        vtkFile &lt;&lt; &quot;SCALARS &quot; &lt;&lt; dualCellVars[v]-&gt;name() &lt;&lt; &quot; float 1&quot; &lt;&lt;  endl;
+                        vtkFile &lt;&lt; &quot;LOOKUP_TABLE default&quot; &lt;&lt; endl;
 
-            // Read variable number v data for that timestep and level
-            dualCellVars[v]-&gt;set_cur(i, 0, vertLevelIndex);
+                        // Read variable number v data for that timestep and level
+                        dualCellVars[v]-&gt;set_cur(i, 0, vertLevelIndex);
             if (singlelayer) {
                 dualCellVars[v]-&gt;get(dualCellVarData, 1, numDualCells, 1);
             } else {
@@ -981,12 +1254,12 @@
 
             double *var_target = dualCellVarData;
 
-            for (int j = 0; j &lt; numDualCells; j++) {
+                        for (int j = 0; j &lt; numDualCells; j++) {
 
                 if (singlelayer) {
-                    float validData = convertDouble2ValidFloat (*var_target);
-                    vtkFile &lt;&lt; validData &lt;&lt; endl;
-                    var_target++;
+                                        float validData = convertDouble2ValidFloat (*var_target);
+                                        vtkFile &lt;&lt; validData &lt;&lt; endl;
+                                        var_target++;
                 } else {
                     for (int levelNum = 0; levelNum &lt; maxNVertLevels; levelNum++)
                     {
@@ -997,7 +1270,7 @@
                 }
             }
 
-            for (int j = numDualCells; j &lt; currentExtraCell; j++) {
+                        for (int j = numDualCells; j &lt; currentExtraCell; j++) {
                 if (j == mirrorcell) { 
                    //cout &lt;&lt; &quot;data for mirror cell &quot; &lt;&lt; mirrorcell &lt;&lt; &quot; from cell &quot; &lt;&lt; *(cellMap + j - numDualCells) &lt;&lt; endl;
                 }

</font>
</pre>