source: trunk/src/objects/RpCurve.cc @ 5673

Last change on this file since 5673 was 5673, checked in by ldelgass, 9 years ago

Fix line endings, set eol-style to native on all C/C++ sources.

  • Property svn:eol-style set to native
File size: 11.1 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  Rappture 2.0 Curve Object Source
4 *
5 * ======================================================================
6 *  AUTHOR:  Derrick Kearney, Purdue University
7 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
8 *
9 *  See the file "license.terms" for information on usage and
10 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 * ======================================================================
12 */
13
14#include "RpCurve.h"
15
16using namespace Rappture;
17
18/*
19const char Curve::format[]  = "RAPPTURE::CURVE::FORMAT";
20const char Curve::id[]      = "RAPPTURE::CURVE::ID";
21const char Curve::creator[] = "RAPPTURE::CURVE::CREATOR";
22*/
23const char Curve::x[]   = "xaxis";
24const char Curve::y[]   = "yaxis";
25
26Curve::Curve ()
27    : Object (),
28      _axisList (NULL)
29{
30    this->name("");
31    this->path("run");
32    this->label("");
33    this->desc("");
34    this->group("");
35}
36
37Curve::Curve (const char *name)
38    : Object (),
39      _axisList (NULL)
40{
41    this->name(name);
42    this->path("run");
43    this->label("");
44    this->desc("");
45    this->group("");
46}
47
48Curve::Curve (const char *name, const char *label, const char *desc,
49              const char *group)
50    : Object (),
51      _axisList (NULL)
52{
53    this->name(name);
54    this->path("run");
55    this->label(label);
56    this->desc(desc);
57    this->group(group);
58}
59
60// copy constructor
61Curve::Curve ( const Curve& o )
62    :   Object(o)
63{
64    this->name(o.name());
65    this->path(o.path());
66    this->label(o.label());
67    this->desc(o.desc());
68    this->group(o.group());
69
70    // need to copy _axisList
71}
72
73// default destructor
74Curve::~Curve ()
75{
76    // clean up dynamic memory
77    // unallocate the _axisList?
78
79}
80
81/**********************************************************************/
82// METHOD: axis()
83/// Add an axis vector to the object
84/**
85 * Add an axis vector to the object.
86 * Axis label must be unique.
87 */
88
89Array1D *
90Curve::axis(
91    const char *name,
92    const char *label,
93    const char *desc,
94    const char *units,
95    const char *scale,
96    const double *val,
97    size_t size)
98{
99    Array1D *a = NULL;
100
101    a = new Array1D(val,size);
102    if (a == NULL) {
103        // raise error and exit
104        return NULL;
105    }
106    a->name(name);
107    a->label(label);
108    a->desc(desc);
109    a->units(units);
110    a->scale(scale);
111
112    if (_axisList == NULL) {
113        _axisList = Rp_ChainCreate();
114        if (_axisList == NULL) {
115            // raise error and exit
116            delete a;
117            return NULL;
118        }
119    }
120
121    Rp_ChainAppend(_axisList,a);
122
123    return a;
124}
125
126/**********************************************************************/
127// METHOD: delAxis()
128/// Delete an axis from this object's list of axis
129/**
130 * Delete an axis from the object
131 */
132
133Curve&
134Curve::delAxis(const char *name)
135{
136    Array1D *a = NULL;
137    Rp_ChainLink *l = NULL;
138    l = __searchAxisList(name);
139
140    if (l != NULL) {
141        a = (Array1D *) Rp_ChainGetValue(l);
142        delete a;
143        Rp_ChainDeleteLink(_axisList,l);
144    }
145
146    return *this;
147}
148
149/**********************************************************************/
150// METHOD: data()
151/// Return an Axis object's data based on its label
152/**
153 * Return an Axis object's data based on its label
154 */
155
156size_t
157Curve::data(
158    const char *label,
159    const double **arr) const
160{
161    if (arr == NULL) {
162        // arr should not be null
163        return 0;
164    }
165
166    size_t ret = 0;
167    Array1D *a = getAxis(label);
168    if (a != NULL) {
169        *arr = a->data();
170        ret = a->nmemb();
171    }
172    return ret;
173}
174
175/**********************************************************************/
176// METHOD: getAxis()
177/// Return an Axis object based on its label
178/**
179 * Return an Axis object based on its label
180 */
181
182Array1D *
183Curve::getAxis(const char *name) const
184{
185    Rp_ChainLink *l = NULL;
186    l = __searchAxisList(name);
187
188    if (l == NULL) {
189        return NULL;
190    }
191
192    return (Array1D *) Rp_ChainGetValue(l);
193}
194
195Rp_ChainLink *
196Curve::__searchAxisList(const char *name) const
197{
198    if (name == NULL) {
199        return NULL;
200    }
201
202    if (_axisList == NULL) {
203        return NULL;
204    }
205
206    Rp_ChainLink *l = NULL;
207    Path p;
208
209    // traverse the list looking for the match
210    l = Rp_ChainFirstLink(_axisList);
211    while (l != NULL) {
212        Array1D *a = (Array1D *) Rp_ChainGetValue(l);
213        const char *aname = a->name();
214        if ((*name == *aname) && (strcmp(name,aname) == 0)) {
215            // we found matching entry, return it
216            break;
217        }
218        l = Rp_ChainNextLink(l);
219    }
220
221    return l;
222}
223
224/**********************************************************************/
225// METHOD: getNthAxis()
226/// Return the Nth Axis object
227/**
228 * Return the Nth Axis
229 */
230
231Array1D *
232Curve::getNthAxis(size_t n) const
233{
234    Rp_ChainLink *l = NULL;
235    l = Rp_ChainGetNthLink(_axisList,n);
236
237    if (l == NULL) {
238        return NULL;
239    }
240
241    return (Array1D *) Rp_ChainGetValue(l);
242}
243
244/**********************************************************************/
245// METHOD: dims()
246/// Return the dimensionality of the object
247/**
248 * Return the dimensionality of the object
249 */
250
251size_t
252Curve::dims() const
253{
254    return (size_t) Rp_ChainGetLength(_axisList);
255}
256
257/**********************************************************************/
258// METHOD: configure(Rp_ParserXml *p)
259/// construct a number object from the provided tree
260/**
261 * construct a number object from the provided tree
262 */
263
264void
265Curve::configure(size_t as, void *p)
266{
267    if (as == RPCONFIG_XML) {
268        __configureFromXml((const char *)p);
269    } else if (as == RPCONFIG_TREE) {
270        __configureFromTree((Rp_ParserXml *)p);
271    }
272}
273
274/**********************************************************************/
275// METHOD: configureFromXml(const char *xmltext)
276/// configure the object based on Rappture1.1 xmltext
277/**
278 * Configure the object based on the provided xml
279 */
280
281void
282Curve::__configureFromXml(const char *xmltext)
283{
284    if (xmltext == NULL) {
285        // FIXME: setup error
286        return;
287    }
288
289    Rp_ParserXml *p = Rp_ParserXmlCreate();
290    Rp_ParserXmlParse(p, xmltext);
291    configure(RPCONFIG_TREE, p);
292
293    return;
294}
295
296
297// This is really, __configureFromTree_1.0
298// because it only allows for an xaxis and yaxis
299// and component.xy formated data
300void
301Curve::__configureFromTree(Rp_ParserXml *p)
302{
303    if (p == NULL) {
304        // FIXME: setup error
305        return;
306    }
307
308    Rp_TreeNode node = Rp_ParserXmlElement(p,NULL);
309
310    Rappture::Path pathObj(Rp_ParserXmlNodePath(p,node));
311
312    path(pathObj.parent());
313    name(Rp_ParserXmlNodeId(p,node));
314
315    pathObj.clear();
316    pathObj.add("about");
317    pathObj.add("label");
318    label(Rp_ParserXmlGet(p,pathObj.path()));
319
320    pathObj.del();
321    pathObj.add("description");
322    desc(Rp_ParserXmlGet(p,pathObj.path()));
323
324
325    Array1D *xaxis = axis(Curve::x,"","","","",NULL,0);
326    pathObj.del();
327    pathObj.del();
328    pathObj.add(Curve::x);
329    pathObj.add("label");
330    xaxis->label(Rp_ParserXmlGet(p,pathObj.path()));
331    pathObj.del();
332    pathObj.add("description");
333    xaxis->desc(Rp_ParserXmlGet(p,pathObj.path()));
334    pathObj.del();
335    pathObj.add("units");
336    xaxis->units(Rp_ParserXmlGet(p,pathObj.path()));
337    pathObj.del();
338    pathObj.add("scale");
339    xaxis->scale(Rp_ParserXmlGet(p,pathObj.path()));
340
341    Array1D *yaxis = axis(Curve::y,"","","","",NULL,0);
342    pathObj.del();
343    pathObj.del();
344    pathObj.add(Curve::y);
345    pathObj.add("label");
346    yaxis->label(Rp_ParserXmlGet(p,pathObj.path()));
347    pathObj.del();
348    pathObj.add("description");
349    yaxis->desc(Rp_ParserXmlGet(p,pathObj.path()));
350    pathObj.del();
351    pathObj.add("units");
352    yaxis->units(Rp_ParserXmlGet(p,pathObj.path()));
353    pathObj.del();
354    pathObj.add("scale");
355    yaxis->scale(Rp_ParserXmlGet(p,pathObj.path()));
356
357    pathObj.del();
358    pathObj.del();
359    pathObj.add("component");
360    pathObj.add("xy");
361    const char *values = Rp_ParserXmlGet(p,pathObj.path());
362
363    double x,y;
364    int n;
365    while (sscanf(values,"%lf%lf%n",&x,&y,&n) == 2) {
366        xaxis->append(&x,1);
367        yaxis->append(&y,1);
368        values += n;
369    }
370
371    return;
372}
373
374/**********************************************************************/
375// METHOD: dump(size_t as, void *p)
376/// construct a number object from the provided tree
377/**
378 * construct a number object from the provided tree
379 */
380
381void
382Curve::dump(size_t as, ClientData p)
383{
384    if (as == RPCONFIG_XML) {
385        __dumpToXml(p);
386    } else if (as == RPCONFIG_TREE) {
387        __dumpToTree(p);
388    }
389}
390
391/**********************************************************************/
392// METHOD: dumpToXml(ClientData p)
393/// configure the object based on Rappture1.1 xmltext
394/**
395 * Configure the object based on the provided xml
396 */
397
398void
399Curve::__dumpToXml(ClientData c)
400{
401    if (c == NULL) {
402        // FIXME: setup error
403        return;
404    }
405
406    ClientDataXml *d = (ClientDataXml *)c;
407    Rp_ParserXml *parser = Rp_ParserXmlCreate();
408    __dumpToTree(parser);
409    const char *xmltext = Rp_ParserXmlXml(parser);
410    _tmpBuf.appendf("%s",xmltext);
411    Rp_ParserXmlDestroy(&parser);
412    d->retStr = _tmpBuf.bytes();
413}
414
415/**********************************************************************/
416// METHOD: dumpToTree(ClientData p)
417/// dump the object to a Rappture1.1 based tree
418/**
419 * Dump the object to a Rappture1.1 based tree
420 */
421
422void
423Curve::__dumpToTree(ClientData c)
424{
425    if (c == NULL) {
426        // FIXME: setup error
427        return;
428    }
429
430    Rp_ParserXml *parser = (Rp_ParserXml *)c;
431
432    Path p;
433
434    p.parent(path());
435    p.last();
436
437    p.add("curve");
438    p.id(name());
439
440    p.add("about");
441
442    p.add("group");
443    Rp_ParserXmlPutF(parser,p.path(),"%s",group());
444
445    p.del();
446    p.add("label");
447    Rp_ParserXmlPutF(parser,p.path(),"%s",label());
448
449    p.del();
450    p.add("description");
451    Rp_ParserXmlPutF(parser,p.path(),"%s",desc());
452
453    p.del();
454    p.add("type");
455    Rp_ParserXmlPutF(parser,p.path(),"%s",propstr("type"));
456
457    p.del();
458    p.del();
459
460    const double *dataArr[dims()];
461    size_t nmemb = 0;
462    for (size_t dim = 0; dim < dims(); dim++) {
463        Array1D *a = getNthAxis(dim);
464        nmemb = a->nmemb();
465        dataArr[dim] = a->data();
466        p.add(a->name());
467
468        p.add("label");
469        Rp_ParserXmlPutF(parser,p.path(),"%s",a->label());
470        p.del();
471
472        p.add("description");
473        Rp_ParserXmlPutF(parser,p.path(),"%s",a->desc());
474        p.del();
475
476        p.add("units");
477        Rp_ParserXmlPutF(parser,p.path(),"%s",a->units());
478        p.del();
479
480        p.add("scale");
481        Rp_ParserXmlPutF(parser,p.path(),"%s",a->scale());
482        p.del();
483
484        p.del();
485    }
486
487    SimpleCharBuffer tmpBuf;
488    for (size_t idx=0; idx < nmemb; idx++) {
489        for(size_t dim=0; dim < dims(); dim++) {
490            tmpBuf.appendf("%10g",dataArr[dim][idx]);
491        }
492        tmpBuf.appendf("\n");
493    }
494    p.add("component");
495    p.add("xy");
496    Rp_ParserXmlPutF(parser,p.path(),"%s",tmpBuf.bytes());
497
498    return;
499}
500
501/**********************************************************************/
502// METHOD: is()
503/// what kind of object is this
504/**
505 * return hex value telling what kind of object this is.
506 */
507
508const int
509Curve::is() const
510{
511    // return "curv" in hex
512    return 0x63757276;
513}
514
515
516// -------------------------------------------------------------------- //
517
Note: See TracBrowser for help on using the repository browser.