1
2 /*=========================================================================
3
4 Program: Visualization Toolkit
5 Module: vtkRAdapter.cxx
6
7 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
8 All rights reserved.
9 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
10
11 This software is distributed WITHOUT ANY WARRANTY; without even
12 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 PURPOSE. See the above copyright notice for more information.
14
15 =========================================================================*/
16 /*-------------------------------------------------------------------------
17 Copyright 2009 Sandia Corporation.
18 Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
19 the U.S. Government retains certain rights in this software.
20 -------------------------------------------------------------------------*/
21
22 #include "vtkObjectFactory.h"
23 #include "vtkRAdapter.h"
24 #include "vtkAbstractArray.h"
25 #include "vtkStdString.h"
26 #include "vtkStringArray.h"
27 #include "vtkTable.h"
28 #include "vtkTree.h"
29 #include "vtkArray.h"
30 #include "vtkArrayExtents.h"
31 #include "vtkArrayCoordinates.h"
32 #include "vtkTypedArray.h"
33 #include "vtkVariantArray.h"
34 #include "vtkDoubleArray.h"
35 #include "vtkIntArray.h"
36 #include "vtkDataArrayCollection.h"
37 #include "vtkArrayData.h"
38 #include "vtkDataObjectCollection.h"
39 #include "vtkTreeDFSIterator.h"
40 #include "vtkSmartPointer.h"
41 #include "vtkNew.h"
42 #include "vtkEdgeListIterator.h"
43 #include "vtkDataSetAttributes.h"
44 #include "vtkMutableDirectedGraph.h"
45
46 #include <map>
47
48 #include <stdio.h>
49 #include <cassert>
50
51 #define R_NO_REMAP /* AVOID SOME SERIOUS STUPIDITY. DO NOT REMOVE. */
52
53 #include "R.h"
54 #include "Rdefines.h"
55 #include "R_ext/Parse.h"
56 #include "R_ext/Rdynload.h"
57
58
59 vtkStandardNewMacro(vtkRAdapter);
60
61 namespace
62 {
63
R_FindArrayIndex(vtkArrayCoordinates & coordinates,const vtkArrayExtents & extents)64 int R_FindArrayIndex(vtkArrayCoordinates& coordinates, const vtkArrayExtents& extents)
65 {
66
67 vtkIdType i;
68 int ret = 0;
69 vtkIdType divisor = 1;
70 vtkIdType d = coordinates.GetDimensions();
71
72 for(i = 0; i < d; ++i)
73 {
74 ret = ret + coordinates[i]*divisor;
75 divisor *= extents[i].GetSize();
76 }
77
78 return(ret);
79
80 }
81
82 } // End anonymous namespace
83
84 //----------------------------------------------------------------------------
vtkRAdapter()85 vtkRAdapter::vtkRAdapter()
86 {
87
88 this->vad = vtkArrayData::New();
89 this->vdoc = vtkDataObjectCollection::New();
90 this->vdac = vtkDataArrayCollection::New();
91
92 }
93
94 //----------------------------------------------------------------------------
~vtkRAdapter()95 vtkRAdapter::~vtkRAdapter()
96 {
97
98 if(this->vad)
99 {
100 this->vad->Delete();
101 }
102
103 if(this->vdoc)
104 {
105 this->vdoc->Delete();
106 }
107
108 if(this->vdac)
109 {
110 this->vdac->Delete();
111 }
112
113 }
114
RToVTKDataArray(SEXP variable)115 vtkDataArray* vtkRAdapter::RToVTKDataArray(SEXP variable)
116 {
117
118 int i;
119 int j;
120 int nr;
121 int nc;
122 vtkDoubleArray * result;
123 double * data;
124
125
126 if( Rf_isMatrix(variable) || Rf_isVector(variable) )
127 {
128 nc = Rf_ncols(variable);
129 nr = Rf_nrows(variable);
130
131 result = vtkDoubleArray::New();
132
133 result->SetNumberOfTuples(nr);
134 result->SetNumberOfComponents(nc);
135
136 data = new double[nc];
137
138 for(i=0;i<nr;i++)
139 {
140 for(j=0;j<nc;j++)
141 {
142 if ( isReal(variable) )
143 {
144 data[j] = REAL(variable)[j*nr + i];
145 }
146 else if ( isInteger(variable) )
147 {
148 data[j] = static_cast<double>(INTEGER(variable)[j*nr + i]);
149 }
150 else
151 {
152 vtkErrorMacro(<< "Bad return variable, tried REAL and INTEGER.");
153 }
154 result->InsertTuple(i,data);
155 }
156 }
157
158 delete [] data;
159 this->vdac->AddItem(result);
160 result->Delete();
161 return(result);
162 }
163 else
164 {
165 return(0);
166 }
167
168 }
169
170
VTKDataArrayToR(vtkDataArray * da)171 SEXP vtkRAdapter::VTKDataArrayToR(vtkDataArray* da)
172 {
173
174 SEXP a;
175 int nr;
176 int nc;
177 int i;
178 int j;
179 double* data;
180
181 nr = da->GetNumberOfTuples();
182 nc = da->GetNumberOfComponents();
183
184 PROTECT(a = Rf_allocMatrix(REALSXP,nr,nc));
185
186 for(i=0;i<nr;i++)
187 {
188 for(j=0;j<nc;j++)
189 {
190 data = da->GetTuple(i);
191 REAL(a)[j*nr + i] = data[j];
192 }
193 }
194
195 return(a);
196
197 }
198
RToVTKArray(SEXP variable)199 vtkArray* vtkRAdapter::RToVTKArray(SEXP variable)
200 {
201
202 vtkArray::SizeT i;
203 vtkArray::DimensionT j;
204 vtkArray::DimensionT ndim;
205 SEXP dims;
206 vtkArrayExtents extents;
207 vtkTypedArray<double>* da;
208 da = vtkTypedArray<double>::SafeDownCast(vtkArray::CreateArray(vtkArray::DENSE, VTK_DOUBLE));
209
210 dims = getAttrib(variable, R_DimSymbol);
211 ndim = static_cast<vtkArray::DimensionT>(length(dims));
212
213 if (!isMatrix(variable)&&!isArray(variable)&&isVector(variable))
214 {
215 ndim = 1;
216 }
217
218 extents.SetDimensions(ndim);
219
220 if (isMatrix(variable)||isArray(variable))
221 {
222 for(j=0;j<ndim;j++)
223 {
224 extents[j] = vtkArrayRange(0,INTEGER(dims)[j]);
225 }
226 }
227 else
228 {
229 extents[0] = vtkArrayRange(0,length(variable));
230 }
231
232 da->Resize(extents);
233
234 vtkArrayCoordinates index;
235
236 index.SetDimensions(ndim);
237
238 for(i=0;i<da->GetSize();i++)
239 {
240 da->GetCoordinatesN(i,index);
241 if ( isReal(variable) )
242 {
243 da->SetVariantValue(index,REAL(variable)[i]);
244 }
245 else if ( isInteger(variable) )
246 {
247 da->SetVariantValue(index,static_cast<double>(INTEGER(variable)[i]));
248 }
249 else
250 {
251 vtkErrorMacro(<< "Bad return variable, tried REAL and INTEGER.");
252 }
253 }
254
255 this->vad->AddArray(da);
256 da->Delete();
257 return(da);
258
259 }
260
VTKArrayToR(vtkArray * da)261 SEXP vtkRAdapter::VTKArrayToR(vtkArray* da)
262 {
263
264 SEXP a;
265 SEXP dim;
266 vtkArray::SizeT i;
267 vtkArray::DimensionT j;
268 vtkArrayCoordinates coords;
269
270 PROTECT(dim = Rf_allocVector(INTSXP, da->GetDimensions()));
271
272 assert(da->GetExtents().ZeroBased());
273 for(j=0;j<da->GetDimensions();j++)
274 {
275 INTEGER(dim)[j] = da->GetExtents()[j].GetSize();
276 }
277
278 PROTECT(a = Rf_allocArray(REALSXP, dim));
279
280 for(i=0;i<da->GetSize();i++)
281 {
282 REAL(a)[i] = 0.0;
283 }
284
285 assert(da->GetExtents().ZeroBased());
286 for(i=0;i<da->GetNonNullSize();i++)
287 {
288 da->GetCoordinatesN(i,coords);
289 REAL(a)[R_FindArrayIndex(coords,da->GetExtents())] = da->GetVariantValue(coords).ToDouble();
290 }
291
292 UNPROTECT(1);
293
294 return(a);
295
296 }
297
VTKTableToR(vtkTable * table)298 SEXP vtkRAdapter::VTKTableToR(vtkTable* table)
299 {
300
301 SEXP a;
302 SEXP b;
303 SEXP names;
304 int i;
305 int j;
306 int nr = table->GetNumberOfRows();
307 int nc = table->GetNumberOfColumns();
308 vtkVariant data;
309
310 PROTECT(a = allocVector(VECSXP, nc));
311 PROTECT(names = allocVector(STRSXP, nc));
312
313 for(j=0;j<nc;j++)
314 {
315 SET_STRING_ELT(names,j,mkChar(table->GetColumn(j)->GetName()));
316 if(vtkDataArray::SafeDownCast(table->GetColumn(j)))
317 {
318 PROTECT(b = allocVector(REALSXP,nr));
319 SET_VECTOR_ELT(a,j,b);
320 for(i=0;i<nr;i++)
321 {
322 data = table->GetValue(i,j);
323 REAL(b)[i] = data.ToDouble();
324 }
325 }
326 else
327 {
328 PROTECT(b = allocVector(STRSXP,nr));
329 SET_VECTOR_ELT(a,j,b);
330 for(i=0;i<nr;i++)
331 {
332 data = table->GetValue(i,j);
333 SET_STRING_ELT(b,i,mkChar(data.ToString().c_str()));
334 }
335 }
336 }
337
338 setAttrib(a,R_NamesSymbol,names);
339
340 return(a);
341
342 }
343
RToVTKTable(SEXP variable)344 vtkTable* vtkRAdapter::RToVTKTable(SEXP variable)
345 {
346
347 int i;
348 int j;
349 int nr;
350 int nc;
351 SEXP names;
352 vtkVariant v;
353 vtkTable* result;
354
355 if( isMatrix(variable) )
356 {
357 nc = Rf_ncols(variable);
358 nr = Rf_nrows(variable);
359 result = vtkTable::New();
360 names = getAttrib(variable, R_DimNamesSymbol);
361 if(!isNull(names))
362 {
363 vtkStringArray* rowNames = vtkStringArray::New();
364 for (i = 0; i < nr; ++i)
365 {
366 std::string rowName = CHAR(STRING_ELT(VECTOR_ELT(names,0),i));
367 rowNames->InsertNextValue(rowName);
368 }
369 result->AddColumn(rowNames);
370 rowNames->Delete();
371 }
372
373 for(j=0;j<nc;j++)
374 {
375 vtkDoubleArray* da = vtkDoubleArray::New();
376 da->SetNumberOfComponents(1);
377 if(!isNull(names))
378 {
379 da->SetName(CHAR(STRING_ELT(VECTOR_ELT(names,1),j)));
380 }
381 else
382 {
383 v = j;
384 da->SetName(v.ToString().c_str());
385 }
386 for(i=0;i<nr;i++)
387 {
388 da->InsertNextValue(REAL(variable)[j*nr + i]);
389 }
390 result->AddColumn(da);
391 da->Delete();
392 }
393 }
394 else if( isNewList(variable) )
395 {
396 nc = length(variable);
397 nr = length(VECTOR_ELT(variable,0));
398 for(j=1;j<nc;j++)
399 {
400 if(isReal(VECTOR_ELT(variable,j)) ||
401 isInteger(VECTOR_ELT(variable,j)) ||
402 isString(VECTOR_ELT(variable,j)) )
403 {
404 if(length(VECTOR_ELT(variable,j)) != nr)
405 {
406 vtkGenericWarningMacro(<<"Cannot convert R data type to vtkTable");
407 return(0);
408 }
409 }
410 else
411 {
412 vtkGenericWarningMacro(<<"Cannot convert R data type to vtkTable");
413 return(0);
414 }
415 }
416
417 result = vtkTable::New();
418 names = getAttrib(variable, R_NamesSymbol);
419 SEXP names2 = getAttrib(variable, R_RowNamesSymbol);
420 if (!isNull(names2))
421 {
422 vtkStringArray* rowNames = vtkStringArray::New();
423 for (i = 0; i < nr; ++i)
424 {
425 std::string rowName = CHAR(STRING_ELT(names2, i));
426 rowNames->InsertNextValue(rowName);
427 }
428 result->AddColumn(rowNames);
429 rowNames->Delete();
430 }
431
432 vtkAbstractArray *aa;
433 for(j=0;j<nc;j++)
434 {
435 if(isReal(VECTOR_ELT(variable,j)))
436 {
437 vtkDoubleArray* da = vtkDoubleArray::New();
438 da->SetNumberOfComponents(1);
439 aa = da;
440 for(i=0;i<nr;i++)
441 {
442 da->InsertNextValue(REAL(VECTOR_ELT(variable,j))[i]);
443 }
444 }
445 else if(isInteger(VECTOR_ELT(variable,j)))
446 {
447 vtkIntArray* da = vtkIntArray::New();
448 da->SetNumberOfComponents(1);
449 aa = da;
450 for(i=0;i<nr;i++)
451 {
452 da->InsertNextValue(INTEGER(VECTOR_ELT(variable,j))[i]);
453 }
454 }
455 else
456 {
457 vtkStringArray* da = vtkStringArray::New();
458 da->SetNumberOfComponents(1);
459 aa = da;
460 for(i=0;i<nr;i++)
461 {
462 da->InsertNextValue(CHAR(STRING_ELT(VECTOR_ELT(variable,j),i)));
463 }
464 }
465
466 if(!isNull(names))
467 {
468 aa->SetName(CHAR(STRING_ELT(names,j)));
469 }
470 else
471 {
472 v = j;
473 aa->SetName(v.ToString().c_str());
474 }
475 result->AddColumn(aa);
476 aa->Delete();
477 }
478 }
479 else
480 {
481 vtkGenericWarningMacro(<<"Cannot convert R data type to vtkTable");
482 return(0);
483 }
484
485 this->vdoc->AddItem(result);
486 result->Delete();
487 return(result);
488
489 }
490
VTKTreeToR(vtkTree * tree)491 SEXP vtkRAdapter::VTKTreeToR(vtkTree* tree)
492 {
493 SEXP r_tree;
494 SEXP names;
495 SEXP edge;
496 SEXP edge_length;
497 SEXP Nnode;
498 SEXP node_label;
499 SEXP tip_label;
500 SEXP classname;
501
502
503 int nedge, nnode, ntip;
504
505 // R phylo tree is a list of 5 elements
506 PROTECT(r_tree = allocVector(VECSXP, 5));
507 PROTECT(names = allocVector(STRSXP, 5));
508
509 // traverse the tree to reorder the leaf vertices according to the
510 // phylo tree numbering rule;
511 // newNodeId is the checkup table that maps a vertexId(starting from 0)
512 // to its corresponding R tree point id (starting from 1)
513 vtkIdType leafCount = 0;
514 vtkTreeDFSIterator* iter = vtkTreeDFSIterator::New();
515 iter->SetTree(tree);
516 int nVerts = tree->GetNumberOfVertices();
517 int *newNodeId = new int[nVerts];//including root vertex 0
518 while (iter->HasNext())
519 {// find out all the leaf nodes, and number them sequentially
520 vtkIdType vertexId = iter->Next();
521 newNodeId[vertexId] = 0;//initialize
522 if (tree->IsLeaf(vertexId))
523 {
524 leafCount++;
525 newNodeId[vertexId] = leafCount;
526 }
527 }
528
529 // second tree traverse to reorder the node vertices
530 int nodeId = leafCount;
531 iter->Restart();
532 vtkIdType vertexId;
533 while (iter->HasNext())
534 {
535 vertexId = iter->Next();
536 if (!tree->IsLeaf(vertexId))
537 {
538 nodeId++;
539 newNodeId[vertexId] = nodeId;
540 }
541 }
542
543 nedge = tree->GetNumberOfEdges();
544 ntip = leafCount;
545 nnode = nedge - ntip + 1;
546
547 // fill in R variables
548 PROTECT(edge = allocMatrix(INTSXP, nedge,2));
549 PROTECT(Nnode = allocVector(INTSXP, 1));
550 PROTECT(tip_label = allocVector(STRSXP, ntip));
551 PROTECT(edge_length = allocVector(REALSXP, nedge));
552 PROTECT(node_label = allocVector(STRSXP, nnode));
553 INTEGER(Nnode)[0] = nnode;
554
555 int * e = INTEGER(edge);
556 double * e_len = REAL(edge_length);
557
558 // fill in e and e_len
559 vtkSmartPointer<vtkEdgeListIterator> edgeIterator = vtkSmartPointer<vtkEdgeListIterator>::New();
560 tree->GetEdges(edgeIterator);
561 vtkEdgeType vEdge;
562 int i = 0;
563 vtkDoubleArray * weights = vtkDoubleArray::SafeDownCast((tree->GetEdgeData())->GetArray("weight"));
564 while(edgeIterator->HasNext())
565 {
566 vEdge = edgeIterator->Next();
567 e[i] = newNodeId[vEdge.Source] ;
568 e[i + nedge] = newNodeId[vEdge.Target];
569
570 int eNum = tree->GetEdgeId(vEdge.Source, vEdge.Target);
571 e_len[i] = weights->GetValue(eNum);
572 i++;
573 }
574
575 // fill in Nnode , tip_label and node_label
576 // use GetAbstractArray() instead of GetArray()
577 vtkStringArray * labels = vtkStringArray::SafeDownCast((tree->GetVertexData())->GetAbstractArray("node name"));
578 iter->Restart();
579 while (iter->HasNext())
580 {// find out all the leaf nodes, and number them sequentially
581 vertexId = iter->Next();
582 if (tree->IsLeaf(vertexId))
583 {
584 vtkStdString lab = labels->GetValue(vertexId);
585 SET_STRING_ELT(tip_label, newNodeId[vertexId]-1, mkChar(lab.c_str()));
586 }
587 else
588 {
589 vtkStdString lab = labels->GetValue(vertexId);
590 SET_STRING_ELT(node_label,newNodeId[vertexId]- ntip - 1, mkChar(lab.c_str())); //the starting id of the internal nodes is (ntip + 1)
591 }
592 }
593 iter->Delete();
594
595 // set all elements
596 SET_VECTOR_ELT(r_tree, 0, edge);
597 SET_VECTOR_ELT(r_tree, 1, Nnode);
598 SET_VECTOR_ELT(r_tree, 2, tip_label);
599 SET_VECTOR_ELT(r_tree, 3, edge_length);
600 SET_VECTOR_ELT(r_tree, 4, node_label);
601
602 SET_STRING_ELT(names, 0, mkChar("edge"));
603 SET_STRING_ELT(names, 1, mkChar("Nnode"));
604 SET_STRING_ELT(names, 2, mkChar("tip.label"));
605 SET_STRING_ELT(names, 3, mkChar("edge.length"));
606 SET_STRING_ELT(names, 4, mkChar("node.label"));
607
608 setAttrib(r_tree,R_NamesSymbol,names);
609
610 PROTECT(classname = allocVector(STRSXP, 1));
611 SET_STRING_ELT(classname, 0, mkChar("phylo"));
612 setAttrib(r_tree, R_ClassSymbol, classname);
613
614 delete [] newNodeId;
615
616 UNPROTECT(8);
617 return r_tree;
618 }
619
620
621
RToVTKTree(SEXP variable)622 vtkTree* vtkRAdapter::RToVTKTree(SEXP variable)
623 {
624 int numEdges = 0, numEdgeLengths = 0, numNodes = 0, numNodeLabels = 0;
625 int *edge = NULL;
626 double *edgeLength = NULL;
627 bool haveNodeLabels = false;
628 vtkTree * tree = vtkTree::New();
629
630 if (isNewList(variable))
631 {
632 int nELT = length(variable);
633 if (nELT < 4)
634 {
635 vtkErrorMacro(<<"RToVTKTree(): R tree list does not contain required four elements!");
636 return NULL;
637 }
638
639 vtkNew<vtkStringArray> nodeLabels;
640 vtkNew<vtkStringArray> tipLabels;
641 SEXP listNames = getAttrib(variable, R_NamesSymbol);
642 SEXP rTipLabels = NULL;
643 SEXP rNodeLabels = NULL;
644
645 // collect data from R. The elements of the tree list are apparently not
646 // guaranteed to be in any specific order.
647 for (int i = 0; i < nELT; ++i)
648 {
649 const char *name = CHAR(STRING_ELT(listNames, i));
650
651 if (strcmp(name, "edge") == 0)
652 {
653 SEXP rEdge = VECTOR_ELT(variable, i);
654 if (isInteger(rEdge))
655 {
656 edge = INTEGER(rEdge);
657 numEdges = length(rEdge)/2;
658 }
659 else
660 {
661 vtkErrorMacro(<<"RToVTKTree(): \"edge\" array is not integer type. ");
662 return NULL;
663 }
664 }
665
666 else if (strcmp(name, "Nnode") == 0)
667 {
668 SEXP rNnode = VECTOR_ELT(variable, i);
669 if (isInteger(rNnode))
670 {
671 numNodes = INTEGER(rNnode)[0];
672 if (length(rNnode) != 1)
673 {
674 vtkErrorMacro(<<"RToVTKTree(): Expect a single scalar of \"Nnode\". ");
675 return NULL;
676 }
677 }
678 else
679 {
680 vtkErrorMacro(<<"RToVTKTree(): \"Nnode\" is not integer type. ");
681 return NULL;
682 }
683 }
684
685 else if (strcmp(name, "tip.label") == 0)
686 {
687 rTipLabels = VECTOR_ELT(variable, i);
688 }
689
690 else if (strcmp(name, "edge.length") == 0)
691 {
692 SEXP rEdgeLength = VECTOR_ELT(variable, i);
693 numEdgeLengths = length(rEdgeLength);
694 if (isReal(rEdgeLength))
695 {
696 edgeLength = REAL(rEdgeLength);
697 }
698 }
699
700 else if (strcmp(name, "node.label") == 0)
701 {
702 // optional node labels
703 rNodeLabels = VECTOR_ELT(variable, i);
704 haveNodeLabels = true;
705 numNodeLabels = length(rNodeLabels);
706 }
707
708 else
709 {
710 vtkWarningMacro(<<"Unexpected tree element encountered: " << name);
711 }
712 }
713
714 // Perform some safety checks to make sure that the data extracted from R
715 // is sane.
716 if (numEdges != numEdgeLengths)
717 {
718 vtkErrorMacro(<<"RToVTKTree(): "
719 << "edgeLength's size does not match up with numEdges.");
720 return NULL;
721 }
722
723 if (haveNodeLabels && numNodeLabels != numNodes)
724 {
725 vtkErrorMacro(<<"RToVTKTree(): node.label's size does not match numNodes.");
726 return NULL;
727 }
728
729 // Populate node & tip label arrays. If no such labels were specified by R
730 // do so with empty strings.
731 nodeLabels->SetNumberOfValues(numNodes);
732 if (rNodeLabels != NULL && isString(rNodeLabels))
733 {
734 for (int i = 0; i < numNodes; i++)
735 {
736 nodeLabels->SetValue(i, CHAR(STRING_ELT(rNodeLabels, i)));
737 }
738 }
739 else
740 {
741 for (int i = 0; i < numNodes; i++)
742 {
743 nodeLabels->SetValue(i, "");
744 }
745 }
746
747 int numTips = numEdges - numNodes + 1;
748 tipLabels->SetNumberOfValues(numTips);
749 if (rTipLabels != NULL && isString(rTipLabels))
750 {
751 for (int i = 0; i < numTips; i++)
752 {
753 tipLabels->SetValue(i, CHAR(STRING_ELT(rTipLabels, i)));
754 }
755 }
756 else
757 {
758 for (int i = 0; i < numTips; i++)
759 {
760 tipLabels->SetValue(i, "");
761 }
762 }
763
764 //------------ Build the VTKTree -----------
765 vtkNew<vtkMutableDirectedGraph> builder;
766
767 // Create all of the tree vertices (number of edges +1)
768 for(int i = 0; i <= numEdges; i++)
769 {
770 builder->AddVertex();
771 }
772
773 for(int i = 0; i < numEdges; i++)
774 {
775 // -1 because R vertices begin with 1, whereas VTK vertices begin with 0.
776 vtkIdType source = edge[i] - 1;
777 vtkIdType target = edge[i+numEdges] - 1;
778 builder->AddEdge(source, target);
779 }
780
781 // Create the edge weight array
782 vtkNew<vtkDoubleArray> weights;
783 weights->SetNumberOfComponents(1);
784 weights->SetName("weight");
785 weights->SetNumberOfValues(numEdges);
786 for (int i = 0; i < numEdges; i++)
787 {
788 weights->SetValue(i, edgeLength[i]);
789 }
790 builder->GetEdgeData()->AddArray(weights.GetPointer());
791
792 // Create the names array
793 // In R tree, the numeric id of the vertice is ordered such that the tips
794 // are listed first followed by the internal nodes. Match up this order
795 // with the label arrays (tip.label and node.label).
796 vtkNew<vtkStringArray> names;
797 names->SetNumberOfComponents(1);
798 names->SetName("node name");
799 names->SetNumberOfValues(numTips + numNodes);
800 for (int i = 0; i < numTips; i++)
801 {
802 names->SetValue(i, tipLabels->GetValue(i));
803 }
804 for (int i = 0; i < numNodes; i++)
805 {
806 names->SetValue(i + numTips, nodeLabels->GetValue(i));
807 }
808 builder->GetVertexData()->AddArray(names.GetPointer());
809
810 if (!tree->CheckedShallowCopy(builder.GetPointer()))
811 {
812 vtkErrorMacro(<<"Edges do not create a valid tree.");
813 return NULL;
814 }
815
816 // Create the "node weight" array for the Vertices, in order to use
817 // vtkTreeLayoutStrategy for visualizing the tree using vtkTreeHeatmapItem
818 vtkNew<vtkDoubleArray> nodeWeights;
819 nodeWeights->SetNumberOfTuples(tree->GetNumberOfVertices());
820
821 vtkNew<vtkTreeDFSIterator> treeIterator;
822 treeIterator->SetStartVertex(tree->GetRoot());
823 treeIterator->SetTree(tree);
824 while (treeIterator->HasNext())
825 {
826 vtkIdType vertex = treeIterator->Next();
827 vtkIdType parent = tree->GetParent(vertex);
828 double weight = 0.0;
829 if (parent >= 0)
830 {
831 weight = weights->GetValue(tree->GetEdgeId(parent, vertex));
832 weight += nodeWeights->GetValue(parent);
833 }
834 nodeWeights->SetValue(vertex, weight);
835 }
836
837 nodeWeights->SetName("node weight");
838 tree->GetVertexData()->AddArray(nodeWeights.GetPointer());
839
840 this->vdoc->AddItem(tree);
841 tree->Delete();
842 return tree;
843 }
844 else
845 {
846 vtkErrorMacro(<<"RToVTKTree(): R variable is not a list. ");
847 return NULL;
848 }
849 }
850
851
PrintSelf(ostream & os,vtkIndent indent)852 void vtkRAdapter::PrintSelf(ostream& os, vtkIndent indent)
853 {
854
855 this->Superclass::PrintSelf(os,indent);
856
857 if(this->vad)
858 {
859 this->vad->PrintSelf(os,indent);
860 }
861
862 if(this->vdoc)
863 {
864 this->vdoc->PrintSelf(os,indent);
865 }
866
867 if(this->vdac)
868 {
869 this->vdac->PrintSelf(os,indent);
870 }
871
872
873 }
874
875