Salome HOME
bc3cce982178b3a5e73db69df29b9b78f02ba450
[modules/paravis.git] / src / Plugins / TableReader / Reader / vtkVisuTableReader.cxx
1 // Copyright (C) 2010-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "vtkVisuTableReader.h"
21 #include "TableParser.h"
22
23 #include "vtkObjectFactory.h"
24 #include "vtkTable.h"
25 #include "vtkInformationVector.h"
26 #include "vtkInformation.h"
27 #include "vtkStreamingDemandDrivenPipeline.h"
28 #include "vtkVariantArray.h"
29 #include "vtkStringArray.h"
30 #include "vtkStringToNumeric.h"
31
32 #include <vtksys/stl/stdexcept>
33 #include <vtksys/ios/sstream>
34
35 #include <vector> // STL include
36 #include <string> // STL include
37 using namespace std;
38
39 //vtkCxxRevisionMacro(vtkVisuTableReader, "$Revision$");
40 vtkStandardNewMacro(vtkVisuTableReader);
41
42 vtkVisuTableReader::vtkVisuTableReader():
43       FileName(0)
44 {
45   this->SetNumberOfInputPorts(0);
46   this->SetNumberOfOutputPorts(1);
47
48   this->FileName = NULL;
49
50   this->DetectNumericColumns = true;
51   this->FirstStringAsTitles = false;
52
53   this->TableNumber = 0;
54
55   this->ValueDelimiter = 0;
56   this->SetValueDelimiter(" ");
57
58   this->AvailableTables = vtkStringArray::New();
59 }
60
61 vtkVisuTableReader::~vtkVisuTableReader()
62 {
63   this->SetFileName(0);
64   this->SetValueDelimiter(0);
65   this->AvailableTables->Delete();
66 }
67
68 int vtkVisuTableReader::CanReadFile(const char* fname)
69 {
70   return 1;
71 }
72
73 void vtkVisuTableReader::PrintSelf(ostream& os, vtkIndent indent)
74 {
75   this->Superclass::PrintSelf(os, indent);
76   os << indent << "FileName: " 
77       << (this->FileName ? this->FileName : "(none)") << endl;
78   os << indent << "DetectNumericColumns: "
79       << (this->DetectNumericColumns? "true" : "false") << endl;
80   os << indent << "ValueDelimiter: "
81       << (this->ValueDelimiter ? this->ValueDelimiter : "(none)") << endl;
82   os << indent << "TableNumber: " << this->TableNumber<< endl;
83 }
84
85 int vtkVisuTableReader::RequestData(vtkInformation*, 
86     vtkInformationVector**,
87     vtkInformationVector* outputVector)
88 {
89   vtkTable* const output_table = vtkTable::GetData(outputVector);
90
91   try
92   {
93     vtkInformation* const outInfo = outputVector->GetInformationObject(0);
94     if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) &&
95         outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
96     {
97       return 1;
98     }
99
100     // If the filename is not defined
101     if(!this->FileName || this->TableNumber < 0)
102     {
103       return 1;
104     }
105
106     // Read table with the given number from the file
107     Table2D table = GetTable(this->FileName, this->ValueDelimiter,
108         this->TableNumber, this->FirstStringAsTitles);
109
110     // Set table name
111     output_table->GetInformation()->Set(vtkDataObject::FIELD_NAME(),
112         table.myTitle.c_str());
113
114     int nbRows = table.myRows.size();
115     int nbCols = table.myRows[0].myValues.size();
116
117     for (int col=0; col < nbCols; col++)
118     {
119       vtkStringArray* newCol = vtkStringArray::New();
120       newCol->SetNumberOfValues(nbRows);
121
122       // Set value
123       for (int row=0; row < nbRows; row++)
124       {
125         newCol->SetValue(row, table.myRows[row].myValues[col].c_str());
126       }
127
128       // Set title
129       bool hasUnit = !table.myColumnUnits[col].empty();
130
131       if (table.myColumnTitles[col].empty())
132       {
133         vtksys_ios::stringstream buffer;
134         if (hasUnit)
135         {
136           buffer << col <<" [" << table.myColumnUnits[col].c_str() << "]";
137         }
138         else
139         {
140           buffer << col;
141         }
142         newCol->SetName(buffer.str().c_str());
143       }
144       else
145       {
146         if (hasUnit)
147         {
148           vtksys_ios::stringstream buffer;
149           buffer << table.myColumnTitles[col].c_str()
150                  <<" [" << table.myColumnUnits[col].c_str() << "]";
151           newCol->SetName(buffer.str().c_str());
152         }
153         else
154         {
155           newCol->SetName(table.myColumnTitles[col].c_str());
156         }
157       }
158
159       output_table->AddColumn(newCol);
160       newCol->Delete();
161     }
162
163     // Detect numeric columns if needed
164     if (this->DetectNumericColumns)
165     {
166       vtkStringToNumeric* convertor = vtkStringToNumeric::New();
167       vtkTable* clone = output_table->NewInstance();
168       clone->ShallowCopy(output_table);
169       convertor->SetInputData(clone);
170       convertor->Update();
171       clone->Delete();
172       output_table->ShallowCopy(convertor->GetOutputDataObject(0));
173       convertor->Delete();
174     }
175   }
176   catch(vtksys_stl::exception& e)
177   {
178     vtkErrorMacro(<< "caught exception: " << e.what() << endl);
179     output_table->Initialize();
180   }
181   catch(...)
182   {
183     vtkErrorMacro(<< "caught unknown exception." << endl);
184     output_table->Initialize();
185   }
186
187   return 1;
188 }
189
190 vtkStringArray* vtkVisuTableReader::GetAvailableTables()
191 {
192   this->AvailableTables->Initialize();
193
194   vector<string> titles = 
195       GetTableNames(this->FileName, this->ValueDelimiter,
196           this->FirstStringAsTitles);
197
198   for(int i = 0; i < titles.size(); i++)
199   {
200     this->AvailableTables->InsertNextValue(titles[i].c_str());
201   }
202
203   return this->AvailableTables;
204 }