Commit c0ff488b authored by Zack Galbreath's avatar Zack Galbreath
Browse files

new writer: vtkPhyloXMLTreeWriter

This new class allows us to output vtkTrees in the PhyloXML format.

Change-Id: I9d4f0baaea6c0eba4ebb92730777473cf7b67ecf
parent 74564a02
......@@ -9,6 +9,7 @@ set(Module_SRCS
vtkMultiNewickTreeReader.cxx
vtkNewickTreeReader.cxx
vtkNewickTreeWriter.cxx
vtkPhyloXMLTreeWriter.cxx
vtkRISReader.cxx
vtkTulipReader.cxx
vtkXGMLReader.cxx
......
......@@ -6,6 +6,7 @@ vtk_add_test_cxx(NO_VALID
TestNewickTreeReader.cxx
TestNewickTreeWriter.cxx
TestMultiNewickTreeReader.cxx
TestPhyloXMLTreeWriter.cxx
TestRISReader.cxx
TestTulipReaderProperties.cxx
TestDelimitedTextReader2.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestPhyloXMLTreeWriter.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkAbstractArray.h"
#include "vtkNew.h"
#include "vtkNewickTreeReader.h"
#include "vtkPhyloXMLTreeWriter.h"
#include "vtkTestUtilities.h"
#include "vtkTree.h"
int TestPhyloXMLTreeWriter(int argc, char* argv[])
{
// get the full path to the input file
char* file = vtkTestUtilities::ExpandDataFileName(argc, argv,
"Data/Infovis/rep_set.tre");
cout << "reading from a file: "<< file << endl;
// read the input file into a vtkTree
vtkNew<vtkNewickTreeReader> reader;
reader->SetFileName(file);
reader->Update();
vtkTree *tree = reader->GetOutput();
delete[] file;
// write this vtkTree out to disk in PhyloXML format
vtkNew<vtkPhyloXMLTreeWriter> writer;
writer->SetInputData(tree);
writer->SetFileName("TestPhyloXMLTreeWriter.xml");
writer->IgnoreArray("node weight");
writer->Update();
return EXIT_SUCCESS;
}
......@@ -7,6 +7,7 @@ vtk_module(vtkIOInfovis
vtkCommonMisc
vtkIOCore
vtkIOLegacy
vtkIOXML
vtkInfovisCore
PRIVATE_DEPENDS
vtklibxml2
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPhyloXMLTreeWriter.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkPhyloXMLTreeWriter.h"
#include "vtkDataSetAttributes.h"
#include "vtkErrorCode.h"
#include "vtkInformation.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkStringArray.h"
#include "vtkTree.h"
#include "vtkXMLDataElement.h"
vtkStandardNewMacro(vtkPhyloXMLTreeWriter);
//----------------------------------------------------------------------------
vtkPhyloXMLTreeWriter::vtkPhyloXMLTreeWriter()
{
this->EdgeWeightArrayName = "weight";
this->NodeNameArrayName = "node name";
this->EdgeWeightArray = NULL;
this->NodeNameArray = NULL;
this->Blacklist = vtkSmartPointer<vtkStringArray>::New();
}
//----------------------------------------------------------------------------
int vtkPhyloXMLTreeWriter::StartFile()
{
ostream& os = *(this->Stream);
os.imbue(std::locale::classic());
// Open the document-level element. This will contain the rest of
// the elements.
os << "<phyloxml xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
<< " xmlns=\"http://www.phyloxml.org\" xsi:schemaLocation=\""
<< "http://www.phyloxml.org http://www.phyloxml.org/1.10/phyloxml.xsd\">"
<< endl;
os.flush();
if (os.fail())
{
this->SetErrorCode(vtkErrorCode::GetLastSystemError());
return 0;
}
return 1;
}
//----------------------------------------------------------------------------
int vtkPhyloXMLTreeWriter::EndFile()
{
ostream& os = *(this->Stream);
// Close the document-level element.
os << "</phyloxml>\n";
os.flush();
if (os.fail())
{
this->SetErrorCode(vtkErrorCode::GetLastSystemError());
return 0;
}
return 1;
}
//----------------------------------------------------------------------------
int vtkPhyloXMLTreeWriter::WriteData()
{
vtkDebugMacro(<<"Writing vtk tree data as PhyloXML...");
vtkTree* const input = this->GetInput();
this->EdgeWeightArray =
input->GetEdgeData()->GetAbstractArray(this->EdgeWeightArrayName.c_str());
this->NodeNameArray =
input->GetVertexData()->GetAbstractArray(this->NodeNameArrayName.c_str());
if(this->StartFile() == 0)
{
return 0;
}
vtkNew<vtkXMLDataElement> rootElement;
rootElement->SetName("phylogeny");
rootElement->SetAttribute("rooted", "true");
// PhyloXML also supports name & description for the entire tree.
// I don't think we have any equivalent data field in vtkTree currently...
this->ConvertVertexToXML(input, input->GetRoot(), rootElement.GetPointer());
rootElement->PrintXML(*this->Stream, vtkIndent());
this->EndFile();
return 1;
}
//----------------------------------------------------------------------------
void vtkPhyloXMLTreeWriter::ConvertVertexToXML(vtkTree* const input,
vtkIdType vertex,
vtkXMLDataElement *parentElement)
{
vtkNew<vtkXMLDataElement> cladeElement;
cladeElement->SetName("clade");
if (this->EdgeWeightArray)
{
vtkIdType parent = input->GetParent(vertex);
if (parent != -1)
{
vtkIdType edge = input->GetEdgeId(parent, vertex);
if (edge != -1)
{
double weight = this->EdgeWeightArray->GetVariantValue(edge).ToDouble();
cladeElement->SetDoubleAttribute("branch_length", weight);
}
}
}
if (this->NodeNameArray)
{
vtkStdString name = this->NodeNameArray->GetVariantValue(vertex).ToString();
if (name != "")
{
vtkNew<vtkXMLDataElement> nameElement;
nameElement->SetName("name");
nameElement->SetCharacterData(name, name.length());
cladeElement->AddNestedElement(nameElement.GetPointer());
}
}
// support for other VertexData.
for (int i = 0; i < input->GetVertexData()->GetNumberOfArrays(); ++i)
{
vtkAbstractArray *arr = input->GetVertexData()->GetAbstractArray(i);
if (arr == this->NodeNameArray || arr == this->EdgeWeightArray)
{
continue;
}
std::string arrName = arr->GetName();
if (this->Blacklist->LookupValue(arrName) != -1)
{
continue;
}
vtkStdString val = arr->GetVariantValue(vertex).ToString();
std::string type = "xsd:";
type += arr->GetVariantValue(vertex).GetTypeAsString();
vtkNew<vtkXMLDataElement> propertyElement;
propertyElement->SetName("property");
propertyElement->SetAttribute("datatype", type.c_str());
propertyElement->SetAttribute("ref", arrName.c_str());
propertyElement->SetAttribute("applies_to", "clade");
propertyElement->SetCharacterData(val, val.length());
cladeElement->AddNestedElement(propertyElement.GetPointer());
}
vtkIdType numChildren = input->GetNumberOfChildren(vertex);
if (numChildren > 0)
{
for (vtkIdType child = 0; child < numChildren; ++child)
{
this->ConvertVertexToXML(input, input->GetChild(vertex, child),
cladeElement.GetPointer());
}
}
parentElement->AddNestedElement(cladeElement.GetPointer());
}
//----------------------------------------------------------------------------
int vtkPhyloXMLTreeWriter::FillInputPortInformation(int, vtkInformation *info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTree");
return 1;
}
//----------------------------------------------------------------------------
vtkTree* vtkPhyloXMLTreeWriter::GetInput()
{
return vtkTree::SafeDownCast(this->Superclass::GetInput());
}
//----------------------------------------------------------------------------
vtkTree* vtkPhyloXMLTreeWriter::GetInput(int port)
{
return vtkTree::SafeDownCast(this->Superclass::GetInput(port));
}
//----------------------------------------------------------------------------
const char* vtkPhyloXMLTreeWriter::GetDefaultFileExtension()
{
return "xml";
}
//----------------------------------------------------------------------------
const char* vtkPhyloXMLTreeWriter::GetDataSetName()
{
if (!this->InputInformation)
{
return "vtkTree";
}
vtkDataObject *hdInput = vtkDataObject::SafeDownCast(
this->InputInformation->Get(vtkDataObject::DATA_OBJECT()));
if (!hdInput)
{
return 0;
}
return hdInput->GetClassName();
}
//----------------------------------------------------------------------------
void vtkPhyloXMLTreeWriter::IgnoreArray(const char * arrayName)
{
this->Blacklist->InsertNextValue(arrayName);
}
//----------------------------------------------------------------------------
void vtkPhyloXMLTreeWriter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "EdgeWeightArrayName: " << this->EdgeWeightArrayName << endl;
os << indent << "NodeNameArrayName: " << this->NodeNameArrayName << endl;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPhyloXMLTreeWriter.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkPhyloXMLTreeWriter - write vtkTree data to PhyloXML format.
// .SECTION Description
// vtkPhyloXMLTreeWriter is writes a vtkTree to a PhyloXML formatted file
// or string.
#ifndef __vtkPhyloXMLTreeWriter_h
#define __vtkPhyloXMLTreeWriter_h
#include "vtkIOInfovisModule.h" // For export macro
#include "vtkXMLWriter.h"
#include "vtkSmartPointer.h" // For SP ivars
#include "vtkStdString.h" // For get/set ivars
class vtkStringArray;
class vtkTree;
class vtkXMLDataElement;
class VTKIOINFOVIS_EXPORT vtkPhyloXMLTreeWriter : public vtkXMLWriter
{
public:
static vtkPhyloXMLTreeWriter *New();
vtkTypeMacro(vtkPhyloXMLTreeWriter,vtkXMLWriter);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Get the input to this writer.
vtkTree* GetInput();
vtkTree* GetInput(int port);
// Description:
// Get the default file extension for files written by this writer.
virtual const char* GetDefaultFileExtension();
// Description:
// Get/Set the name of the input's tree edge weight array.
// This array must be part of the input tree's EdgeData.
// The default name is "weight". If this array cannot be
// found, then no edge weights will be included in the
// output of this writer.
vtkGetMacro(EdgeWeightArrayName, vtkStdString);
vtkSetMacro(EdgeWeightArrayName, vtkStdString);
// Description:
// Get/Set the name of the input's tree node name array.
// This array must be part of the input tree's VertexData.
// The default name is "node name". If this array cannot
// be found, then no node names will be included in the
// output of this writer.
vtkGetMacro(NodeNameArrayName, vtkStdString);
vtkSetMacro(NodeNameArrayName, vtkStdString);
// Description:
// Do not include name the VertexData array in the PhyloXML output
// of this writer. Call this function once for each array that
// you wish to ignore.
void IgnoreArray(const char * arrayName);
protected:
vtkPhyloXMLTreeWriter();
~vtkPhyloXMLTreeWriter() {}
virtual int WriteData();
virtual const char* GetDataSetName();
virtual int StartFile();
virtual int EndFile();
vtkInformation* InputInformation;
// Description:
// Write one vertex. This function calls itself recursively for
// any children of the input vertex.
void ConvertVertexToXML(vtkTree* const input, vtkIdType vertex,
vtkXMLDataElement *parentElement);
virtual int FillInputPortInformation(int port, vtkInformation *info);
vtkStdString EdgeWeightArrayName;
vtkStdString NodeNameArrayName;
vtkAbstractArray *EdgeWeightArray;
vtkAbstractArray *NodeNameArray;
vtkSmartPointer<vtkStringArray> Blacklist;
private:
vtkPhyloXMLTreeWriter(const vtkPhyloXMLTreeWriter&); // Not implemented.
void operator=(const vtkPhyloXMLTreeWriter&); // Not implemented.
};
#endif
......@@ -300,9 +300,9 @@ protected:
// Utility methods for subclasses.
vtkDataSet* GetInputAsDataSet();
int StartFile();
virtual int StartFile();
virtual void WriteFileAttributes();
int EndFile();
virtual int EndFile();
void DeleteAFile();
void DeleteAFile(const char* name);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment