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

Last change on this file since 5119 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.

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.