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

Last change on this file since 1170 was 1170, checked in by gah, 16 years ago

64-bit fixes

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