/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkCSVNumericObjectFileWriter_hxx #define itkCSVNumericObjectFileWriter_hxx #include "itksys/SystemTools.hxx" #include #include namespace itk { template CSVNumericObjectFileWriter::CSVNumericObjectFileWriter() { this->m_FieldDelimiterCharacter = ','; this->m_InputObject = nullptr; } template void CSVNumericObjectFileWriter::SetInput(const vnlMatrixType * obj) { this->m_InputObject = const_cast(obj->data_block()); this->m_Rows = obj->rows(); this->m_Columns = obj->cols(); } template void CSVNumericObjectFileWriter::SetInput(const vnlFixedMatrixType * obj) { this->m_InputObject = const_cast(obj->data_block()); this->m_Rows = obj->rows(); this->m_Columns = obj->cols(); } template void CSVNumericObjectFileWriter::SetInput(const itkMatrixType * obj) { this->m_InputObject = const_cast(obj->GetVnlMatrix().data_block()); this->m_Rows = obj->RowDimensions; this->m_Columns = obj->ColumnDimensions; } template void CSVNumericObjectFileWriter::ColumnHeadersPushBack(const std::string & header) { this->m_ColumnHeaders.push_back(header); } template void CSVNumericObjectFileWriter::RowHeadersPushBack(const std::string & header) { this->m_RowHeaders.push_back(header); } template void CSVNumericObjectFileWriter::SetColumnHeaders(const StringVectorType & columnheaders) { this->m_ColumnHeaders = columnheaders; } template void CSVNumericObjectFileWriter::SetRowHeaders(const StringVectorType & rowheaders) { this->m_RowHeaders = rowheaders; } template void CSVNumericObjectFileWriter::PrepareForWriting() { // throw an exception if no filename is provided if (this->m_FileName.empty()) { itkExceptionMacro("A filename for writing was not specified!"); } // throw an exception if no input object is provided if (this->m_InputObject == nullptr) { itkExceptionMacro("An input object was not specified!"); } // output a warning if the number of row headers and number of rows in the // object are not the same if (!this->m_RowHeaders.empty() && (this->m_RowHeaders.size() != this->m_Rows)) { itkWarningMacro("Warning: The number of row headers and the number of rows in" << " the input object is not consistent."); } // output a warning if the number of column headers and number of columns in // the object are not the same if (!this->m_ColumnHeaders.empty()) { if (!this->m_RowHeaders.empty() && this->m_ColumnHeaders.size() != (this->m_Columns + 1)) { itkWarningMacro("Warning: The number of column headers and the number of" << " columns in the input object is not consistent."); } if (this->m_RowHeaders.empty() && this->m_ColumnHeaders.size() != this->m_Columns) { itkWarningMacro("Warning: The number of column headers and the number of" << " columns in the input object is not consistent."); } } } template void CSVNumericObjectFileWriter::Write() { this->PrepareForWriting(); std::ofstream outputStream(this->m_FileName.c_str()); if (outputStream.fail()) { itkExceptionMacro("The file " << this->m_FileName << " cannot be opened for writing!" << std::endl << "Reason: " << itksys::SystemTools::GetLastSystemError()); } try { if (!this->m_ColumnHeaders.empty()) { for (unsigned int i = 0; i < this->m_ColumnHeaders.size(); ++i) { outputStream << this->m_ColumnHeaders[i]; if (i < this->m_ColumnHeaders.size() - 1) { outputStream << this->m_FieldDelimiterCharacter; } } outputStream << std::endl; } for (unsigned int i = 0; i < this->m_Rows; ++i) { if (!this->m_RowHeaders.empty()) { if (i < this->m_RowHeaders.size()) { outputStream << this->m_RowHeaders[i] << this->m_FieldDelimiterCharacter; } } for (unsigned int j = 0; j < this->m_Columns; ++j) { outputStream << std::setprecision(std::numeric_limits::digits10) << *(this->m_InputObject++); if (j < this->m_Columns - 1) { outputStream << this->m_FieldDelimiterCharacter; } } outputStream << std::endl; } } catch (const itk::ExceptionObject & exp) { std::cerr << "Exception caught! " << std::endl << exp << std::endl; outputStream.close(); throw; } catch (...) { outputStream.close(); throw; } outputStream.close(); } template void CSVNumericObjectFileWriter::Update() { this->Write(); } template void CSVNumericObjectFileWriter::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "File name: " << this->m_FileName << std::endl; os << indent << "Field Delimiter Character: " << this->m_FieldDelimiterCharacter << std::endl; } } // end namespace itk #endif