Salome HOME
9021a8f3583d1849dcddee6495b1acab63044cb2
[modules/paravis.git] / src / Plugins / TableReader / plugin / TableReaderModule / vtkVisuTableReader.cxx
1 // Copyright (C) 2010-2021  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 <vtkInformation.h>
24 #include <vtkInformationVector.h>
25 #include <vtkObjectFactory.h>
26 #include <vtkStreamingDemandDrivenPipeline.h>
27 #include <vtkStringArray.h>
28 #include <vtkStringToNumeric.h>
29 #include <vtkTable.h>
30 #include <vtkVariantArray.h>
31
32 #include <sstream>
33 #include <stdexcept>
34 #include <string>
35 #include <vector>
36
37 using namespace std;
38
39 vtkStandardNewMacro(vtkVisuTableReader);
40
41 vtkVisuTableReader::vtkVisuTableReader()
42   : FileName(nullptr)
43 {
44   this->SetNumberOfInputPorts(0);
45   this->SetNumberOfOutputPorts(1);
46
47   this->FileName = nullptr;
48
49   this->DetectNumericColumns = true;
50   this->FirstStringAsTitles = false;
51
52   this->TableNumber = 0;
53
54   this->ValueDelimiter = nullptr;
55   this->SetValueDelimiter(" ");
56
57   this->AvailableTables = vtkStringArray::New();
58 }
59
60 vtkVisuTableReader::~vtkVisuTableReader()
61 {
62   this->SetFileName(nullptr);
63   this->SetValueDelimiter(nullptr);
64   this->AvailableTables->Delete();
65 }
66
67 int vtkVisuTableReader::CanReadFile(const char* fname)
68 {
69   return 1;
70 }
71
72 void vtkVisuTableReader::PrintSelf(ostream& os, vtkIndent indent)
73 {
74   this->Superclass::PrintSelf(os, indent);
75   os << indent << "FileName: " << (this->FileName ? this->FileName : "(none)") << endl;
76   os << indent << "DetectNumericColumns: " << (this->DetectNumericColumns ? "true" : "false")
77      << endl;
78   os << indent << "ValueDelimiter: " << (this->ValueDelimiter ? this->ValueDelimiter : "(none)")
79      << endl;
80   os << indent << "TableNumber: " << this->TableNumber << endl;
81 }
82
83 int vtkVisuTableReader::RequestData(
84   vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector)
85 {
86   vtkTable* const output_table = vtkTable::GetData(outputVector);
87
88   try
89   {
90     vtkInformation* const outInfo = outputVector->GetInformationObject(0);
91     if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) &&
92       outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
93     {
94       return 1;
95     }
96
97     // If the filename is not defined
98     if (!this->FileName || this->TableNumber < 0)
99     {
100       return 1;
101     }
102
103     // Read table with the given number from the file
104     Table2D table =
105       GetTable(this->FileName, this->ValueDelimiter, this->TableNumber, this->FirstStringAsTitles);
106
107     // Set table name
108     output_table->GetInformation()->Set(vtkDataObject::FIELD_NAME(), table.myTitle.c_str());
109
110     int nbRows = table.myRows.size();
111     int nbCols = table.myRows[0].myValues.size();
112
113     for (int col = 0; col < nbCols; col++)
114     {
115       vtkStringArray* newCol = vtkStringArray::New();
116       newCol->SetNumberOfValues(nbRows);
117
118       // Set value
119       for (int row = 0; row < nbRows; row++)
120       {
121         newCol->SetValue(row, table.myRows[row].myValues[col].c_str());
122       }
123
124       // Set title
125       bool hasUnit = !table.myColumnUnits[col].empty();
126
127       if (table.myColumnTitles[col].empty())
128       {
129         std::stringstream buffer;
130         if (hasUnit)
131         {
132           buffer << col << " [" << table.myColumnUnits[col].c_str() << "]";
133         }
134         else
135         {
136           buffer << col;
137         }
138         newCol->SetName(buffer.str().c_str());
139       }
140       else
141       {
142         if (hasUnit)
143         {
144           std::stringstream buffer;
145           buffer << table.myColumnTitles[col].c_str() << " [" << table.myColumnUnits[col].c_str()
146                  << "]";
147           newCol->SetName(buffer.str().c_str());
148         }
149         else
150         {
151           newCol->SetName(table.myColumnTitles[col].c_str());
152         }
153       }
154
155       output_table->AddColumn(newCol);
156       newCol->Delete();
157     }
158
159     // Detect numeric columns if needed
160     if (this->DetectNumericColumns)
161     {
162       vtkStringToNumeric* convertor = vtkStringToNumeric::New();
163       vtkTable* clone = output_table->NewInstance();
164       clone->ShallowCopy(output_table);
165       convertor->SetInputData(clone);
166       convertor->Update();
167       clone->Delete();
168       output_table->ShallowCopy(convertor->GetOutputDataObject(0));
169       convertor->Delete();
170     }
171   }
172   catch (std::exception& e)
173   {
174     vtkErrorMacro(<< "caught exception: " << e.what() << endl);
175     output_table->Initialize();
176   }
177   catch (...)
178   {
179     vtkErrorMacro(<< "caught unknown exception." << endl);
180     output_table->Initialize();
181   }
182
183   return 1;
184 }
185
186 vtkStringArray* vtkVisuTableReader::GetAvailableTables()
187 {
188   this->AvailableTables->Initialize();
189
190   vector<string> titles =
191     GetTableNames(this->FileName, this->ValueDelimiter, this->FirstStringAsTitles);
192
193   for (int i = 0; i < titles.size(); i++)
194   {
195     this->AvailableTables->InsertNextValue(titles[i].c_str());
196   }
197
198   return this->AvailableTables;
199 }