source: trunk/packages/vizservers/nanovis/RpDX.cpp @ 3335

Last change on this file since 3335 was 3177, checked in by mmc, 12 years ago

Updated all of the copyright notices to reference the transfer to
the new HUBzero Foundation, LLC.

  • Property svn:eol-style set to native
File size: 9.8 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * ----------------------------------------------------------------------
4 *  Rappture::DX
5 *
6 *  Rappture DX object for file reading and interacting
7 *  with libDX and friends.
8 *
9 * ======================================================================
10 *  AUTHOR:  Derrick S. Kearney, Purdue University
11 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
12 *
13 *  See the file "license.terms" for information on usage and
14 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15 * ======================================================================
16 */
17#include <math.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <float.h>
21
22#include "nvconf.h"
23#ifdef HAVE_DX_DX_H
24#include "RpDX.h"
25#undef ERROR
26#include "Trace.h"
27
28using namespace Rappture;
29
30DX::DX(Outcome &result, const char* filename) :
31    _dataMin(FLT_MAX),
32    _dataMax(-FLT_MAX),
33    _nzero_min(FLT_MAX),
34    _numAxis(0),
35    _axisLen(NULL),
36    _data(NULL),
37    _n(0),
38    _rank(0),
39    _shape(0),
40    _positions(NULL),
41    _delta(NULL),
42    _max(NULL),
43    _origin(NULL)
44{
45    Array dxpos;
46    Array dxdata;
47    Array dxgrid;
48    // category and type are probably not needed
49    // we keep them around in case they hold useful info for the future
50    // we could replace them with NULL inthe DXGetArrayInfo fxn call
51    Category category;
52    Type type;
53
54    if (filename == NULL) {
55        result.addError("filename is NULL");
56        return;
57    }
58    // open the file with libdx
59    TRACE("Calling DXImportDX(%s)\n", filename);
60    DXenable_locks(0);
61    _dxobj = DXImportDX((char*)filename,NULL,NULL,NULL,NULL);
62    if (_dxobj == NULL) {
63        result.addError("can't import DX file \"%s\"", filename);
64        return;
65    }
66
67    // parse out the positions array
68
69    // FIXME: nanowire will need a different way to parse out the positions
70    //        array since it uses a productarray to store its positions.
71    //        Possibly use DXGetProductArray().
72    dxpos = (Array) DXGetComponentValue((Field) _dxobj, (char *)"positions");
73    if (dxpos == NULL) {
74        result.addError("can't get component value of \"positions\"");
75        return;
76    }
77    DXGetArrayInfo(dxpos, &_n, &type, &category, &_rank, &_shape);
78
79    TRACE("_n = %d\n",_n);
80    if (type != TYPE_FLOAT) {
81        result.addError("\"positions\" is not type float (type=%d)\n", type);
82        return;
83    }
84    TRACE("_rank = %d\n",_rank);
85    TRACE("_shape = %d\n",_shape);
86
87    float* pos = NULL;
88    pos = (float*) DXGetArrayData(dxpos);
89    if (pos == NULL) {
90        result.addError("DXGetArrayData failed to return positions array");
91        return;
92    }
93
94    // first call to get the number of axis needed
95    dxgrid = (Array) DXGetComponentValue((Field) _dxobj, (char *)"connections");
96    if (DXQueryGridConnections(dxgrid, &_numAxis, NULL) == NULL) {
97        // raise error, data is not a regular grid and we cannot handle it
98        result.addError("DX says our grid is not regular, we cannot handle this data");
99        return;
100    }
101
102    _positions = new float[_n*_numAxis];
103    if (_positions == NULL) {
104        // malloc failed, raise error
105        result.addError("malloc of _positions array failed");
106        return;
107    }
108    memcpy(_positions,pos,sizeof(float)*_n*_numAxis);
109
110    _axisLen = new int[_numAxis];
111    if (_axisLen == NULL) {
112        // malloc failed, raise error
113        result.addError("malloc of _axisLen array failed");
114        return;
115    }
116    memset(_axisLen, 0, _numAxis);
117
118    _delta = new float[_numAxis*_numAxis];
119    if (_delta == NULL) {
120        result.addError("malloc of _delta array failed");
121        return;
122    }
123    memset(_delta, 0, _numAxis*_numAxis);
124
125    _origin = new float[_numAxis];
126    if (_origin == NULL) {
127        result.addError("malloc of _origin array failed");
128        return;
129    }
130    memset(_origin, 0, _numAxis);
131
132    _max = new float[_numAxis];
133    if (_max == NULL) {
134        result.addError("malloc of _max array failed");
135        return;
136    }
137    memset(_max, 0, _numAxis);
138
139    findPosMax();
140
141    // parse out the gridconnections (length of each axis) array
142    // dxgrid = (Array) DXQueryGridConnections(dxpos, &_numAxis, _axisLen);
143    DXQueryGridPositions(dxpos, NULL, _axisLen, _origin, _delta);
144
145    TRACE("_max = [%g,%g,%g]\n",_max[0],_max[1],_max[2]);
146    TRACE("_delta = [%g,%g,%g]\n",_delta[0],_delta[1],_delta[2]);
147    TRACE("         [%g,%g,%g]\n",_delta[3],_delta[4],_delta[5]);
148    TRACE("         [%g,%g,%g]\n",_delta[6],_delta[7],_delta[8]);
149    TRACE("_origin = [%g,%g,%g]\n",_origin[0],_origin[1],_origin[2]);
150    TRACE("_axisLen = [%i,%i,%i]\n",_axisLen[0],_axisLen[1],_axisLen[2]);
151
152    // grab the data array from the dx object and store it in _data
153    dxdata = (Array) DXGetComponentValue((Field) _dxobj, (char *)"data");
154    DXGetArrayInfo(dxdata, NULL, &type, NULL, NULL, NULL);
155    _data = new float[_n];
156    if (_data == NULL) {
157        result.addError("malloc of _data array failed");
158        return;
159    }
160
161    switch (type) {
162    case TYPE_FLOAT:
163        float *float_data;
164
165        float_data = (float *)DXGetArrayData(dxdata);
166        memcpy(_data, float_data, sizeof(float)*_n);
167        break;
168
169    case TYPE_DOUBLE:
170        double *double_data;
171        double_data = (double *)DXGetArrayData(dxdata);
172        for (int i = 0; i < _n; i++) {
173            _data[i] = double_data[i];
174        }
175        break;
176
177    default:
178        result.addError("don't know how to handle data of type %d\n", type);
179        return;
180    }
181
182    // print debug info
183    for (int lcv = 0, pt = 0; lcv < _n; lcv +=3, pt+=9) {
184        TRACE("(%f,%f,%f)|->% 8e\n(%f,%f,%f)|->% 8e\n(%f,%f,%f)|->% 8e\n",
185            _positions[pt],_positions[pt+1],_positions[pt+2], _data[lcv],
186            _positions[pt+3],_positions[pt+4],_positions[pt+5],_data[lcv+1],
187            _positions[pt+6],_positions[pt+7],_positions[pt+8],_data[lcv+2]);
188    }
189    collectDataStats();
190}
191
192DX::~DX()
193{
194    delete[] _axisLen;
195    delete[] _delta;
196    delete[] _origin;
197    delete[] _max;
198    delete[] _data;
199    delete[] _positions;
200}
201
202void
203DX::findPosMax()
204{
205    int lcv = 0;
206
207    // initialize the max array and delta array
208    // max holds the maximum value found for each index
209    for (lcv = 0; lcv < _numAxis; lcv++) {
210        _max[lcv] = _positions[lcv];
211    }
212
213    for (lcv=lcv; lcv < _n*_numAxis; lcv++) {
214        int maxIdx = lcv%_numAxis;
215        if (_positions[lcv] > _max[maxIdx]) {
216            _max[maxIdx] = _positions[lcv];
217        }
218    }
219}
220
221void
222DX::collectDataStats()
223{
224    _dataMin = FLT_MAX;
225    _dataMax = -FLT_MAX;
226    _nzero_min = FLT_MAX;
227
228    // populate _dataMin, _dataMax, _nzero_min
229    for (int lcv = 0; lcv < _n; lcv++) {
230        if (_data[lcv] < _dataMin) {
231            _dataMin = _data[lcv];
232        }
233        if (_data[lcv] > _dataMax) {
234            _dataMax = _data[lcv];
235        }
236        if ((_data[lcv] > 0.0f) && (_data[lcv] < _nzero_min)) {
237            _nzero_min = _data[lcv];
238        }
239    }
240    if (_nzero_min == FLT_MAX) {
241        ERROR("could not find a positive minimum value\n");
242    }
243}
244
245/*
246 * getInterpPos()
247 *
248 * creates a new grid of positions which can be used for interpolation.
249 * we create the positions array using the function DXMakeGridPositionsV
250 * which creates an n-dimensional grid of regularly spaced positions.
251 * This function overwrites the original positions array
252 */
253void
254DX::getInterpPos()
255{
256    Array dxpos;
257    float* pos = NULL;
258
259    // gather the positions we want to interpolate over
260    dxpos = DXMakeGridPositionsV(_numAxis, _axisLen, _origin, _delta);
261    DXGetArrayInfo(dxpos, &_n, NULL, NULL, &_rank, &_shape);
262    pos = (float*) DXGetArrayData(dxpos);
263    if (pos == NULL) {
264        TRACE("DXGetArrayData failed to return positions array\n");
265    }
266
267    if (_positions != NULL) {
268        delete[] _positions;
269    }
270    _positions = new float[_n*_numAxis];
271    if (_positions == NULL) {
272        // malloc failed, raise error
273        TRACE("malloc of _axisLen array failed");
274    }
275    memcpy(_positions,pos,sizeof(float)*_n*_numAxis);
276
277    pos = NULL;
278    DXDelete((object*)dxpos);
279}
280
281/*
282 * getInterpData()
283 *
284 * this function interpolates over a positions array to produce data for each
285 * point in the positions array. we use the position data stored in _positions
286 * array.
287 */
288void
289DX::getInterpData()
290{
291    int pts = _n;
292    int interppts = pts;
293    Interpolator interpolator;
294
295    _data = new float[_n];
296    if (_data == NULL) {
297        // malloc failed, raise error
298        TRACE("malloc of _data array failed");
299    }
300    memset(_data,0,_n);
301
302    // build the interpolator and interpolate
303    TRACE("creating DXNewInterpolator...\n");
304    interpolator = DXNewInterpolator(_dxobj,INTERP_INIT_IMMEDIATE,-1.0);
305    TRACE("_rank = %i\n",_rank);
306    TRACE("_shape = %i\n",_shape);
307    TRACE("_n = %i\n",_n);
308    TRACE("start interppts = %i\n",interppts);
309    DXInterpolate(interpolator,&interppts,_positions,_data);
310    TRACE("interppts = %i\n",interppts);
311
312    // print debug info
313    for (int lcv = 0, pt = 0; lcv < pts; lcv+=3,pt+=9) {
314        TRACE("(%f,%f,%f)|->% 8e\n(%f,%f,%f)|->% 8e\n(%f,%f,%f)|->% 8e\n",
315            _positions[pt],_positions[pt+1],_positions[pt+2], _data[lcv],
316            _positions[pt+3],_positions[pt+4],_positions[pt+5],_data[lcv+1],
317            _positions[pt+6],_positions[pt+7],_positions[pt+8],_data[lcv+2]);
318    }
319
320    collectDataStats();
321}
322
323/*
324 * interpolate()
325 *
326 * generate a positions array with optional new axis length and
327 * interpolate to get the new data values at each point in
328 * the positions array. this function currently only works if you
329 * do not change the axis length (i.e. newAxisLen == NULL).
330 */
331DX&
332DX::interpolate(int* newAxisLen)
333{
334    TRACE("----begin interpolation----\n");
335    if (newAxisLen != NULL) {
336        for (int i = 0; i < _numAxis; i++) {
337            _axisLen[i] = newAxisLen[i];
338        }
339    }
340    getInterpPos();
341    getInterpData();
342    TRACE("----end interpolation----\n");
343    return *this;
344}
345
346#endif /*HAVE_DX_DX_H*/
Note: See TracBrowser for help on using the repository browser.