Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 0eca23ec authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Merge branch 'mhdreader-fix' into 'development'

Mhdreader fix

Sorry for the huge commit - only couple of files changed (see commit) :-(
parents a065fec5 93b5551f
// ================================================================================================ // ================================================================================================
// //
// This file is part of the CAMPVis Software Framework. // This file is part of the CAMPVis Software Framework.
// //
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved, // If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de> // Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures // Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen // Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany // Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
// //
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt". // For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// //
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file // 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 // except in compliance with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software distributed under the // 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, // 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 // either express or implied. See the License for the specific language governing permissions
// and limitations under the License. // and limitations under the License.
// //
// ================================================================================================ // ================================================================================================
#include "mhdimagereader.h" #include "mhdimagereader.h"
#include <fstream> #include <fstream>
#include "tgt/filesystem.h" #include "tgt/filesystem.h"
#include "core/datastructures/imagedata.h" #include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationdisk.h" #include "core/datastructures/imagerepresentationdisk.h"
#include "core/datastructures/genericimagerepresentationlocal.h" #include "core/datastructures/genericimagerepresentationlocal.h"
#include "core/tools/textfileparser.h" #include "core/tools/textfileparser.h"
/* /*
* Full format specification at http://www.itk.org/Wiki/MetaIO/Documentation * Full format specification at http://www.itk.org/Wiki/MetaIO/Documentation
*/ */
namespace campvis { namespace campvis {
const std::string MhdImageReader::loggerCat_ = "CAMPVis.modules.io.MhdImageReader"; const std::string MhdImageReader::loggerCat_ = "CAMPVis.modules.io.MhdImageReader";
MhdImageReader::MhdImageReader() MhdImageReader::MhdImageReader()
: AbstractImageReader() : AbstractImageReader()
, p_imageOffset("ImageOffset", "Image Offset in mm", tgt::vec3(0.f), tgt::vec3(-10000.f), tgt::vec3(10000.f), tgt::vec3(0.1f)) , p_imageOffset("ImageOffset", "Image Offset in mm", tgt::vec3(0.f), tgt::vec3(-10000.f), tgt::vec3(10000.f), tgt::vec3(0.1f))
, p_voxelSize("VoxelSize", "Voxel Size in mm", tgt::vec3(1.f), tgt::vec3(-100.f), tgt::vec3(100.f), tgt::vec3(0.1f)) , p_voxelSize("VoxelSize", "Voxel Size in mm", tgt::vec3(1.f), tgt::vec3(-100.f), tgt::vec3(100.f), tgt::vec3(0.1f))
{ {
this->_ext.push_back(".mhd"); this->_ext.push_back(".mhd");
this->p_targetImageID.setValue("MhdImageReader.output"); this->p_targetImageID.setValue("MhdImageReader.output");
addProperty(p_url); addProperty(p_url);
addProperty(p_targetImageID); addProperty(p_targetImageID);
addProperty(p_imageOffset); addProperty(p_imageOffset);
addProperty(p_voxelSize); addProperty(p_voxelSize);
} }
MhdImageReader::~MhdImageReader() { MhdImageReader::~MhdImageReader() {
} }
void MhdImageReader::updateResult(DataContainer& data) { void MhdImageReader::updateResult(DataContainer& data) {
try { try {
// start parsing // start parsing
TextFileParser tfp(p_url.getValue(), true, "="); TextFileParser tfp(p_url.getValue(), true, "=");
tfp.parse<TextFileParser::ItemSeparatorLines>(); tfp.parse<TextFileParser::ItemSeparatorLines>();
// init optional parameters with sane default values // init optional parameters with sane default values
std::string url; std::string url;
size_t dimensionality; size_t dimensionality;
tgt::svec3 size; tgt::svec3 size;
WeaklyTypedPointer::BaseType pt; WeaklyTypedPointer::BaseType pt;
size_t numChannels = 1; size_t numChannels = 1;
size_t offset = 0; size_t offset = 0;
EndianHelper::Endianness e = EndianHelper::IS_LITTLE_ENDIAN; EndianHelper::Endianness e = EndianHelper::IS_LITTLE_ENDIAN;
tgt::vec3 voxelSize(1.f); tgt::vec3 voxelSize(1.f);
tgt::vec3 imageOffset(0.f); tgt::vec3 imageOffset(0.f);
// image type // image type
if (tfp.hasKey("ObjectType")) { if (tfp.hasKey("ObjectType")) {
if (tfp.getString("ObjectType") == "Image") { if (tfp.getString("ObjectType") == "Image") {
numChannels = 1; numChannels = 1;
} }
else if (tfp.getString("ObjectType") == "TensorImage") { else if (tfp.getString("ObjectType") == "TensorImage") {
numChannels = 6; numChannels = 6;
} }
else { else {
LERROR("Error while parsing MHD header: ObjectType = Image or ObjectType = TensorImage expected"); LERROR("Error while parsing MHD header: ObjectType = Image or ObjectType = TensorImage expected");
return; return;
} }
} }
else { else {
LWARNING("No Key 'ObjectType' found - assuming Image."); LWARNING("No Key 'ObjectType' found - assuming Image.");
} }
// dimensionality and size // dimensionality and size
dimensionality = tfp.getSizeT("NDims"); dimensionality = tfp.getSizeT("NDims");
if (dimensionality == 2) if (dimensionality == 2)
size = tgt::svec3(tfp.getSvec2("DimSize"), 1); size = tgt::svec3(tfp.getSvec2("DimSize"), 1);
else if (dimensionality == 3) else if (dimensionality == 3)
size = tfp.getSvec3("DimSize"); size = tfp.getSvec3("DimSize");
else { else {
LERROR("Error while parsing MHD header: Unsupported dimensionality: " << dimensionality); LERROR("Error while parsing MHD header: Unsupported dimensionality: " << dimensionality);
return; return;
} }
// element type // element type
std::string et = tfp.getString("ElementType"); std::string et = tfp.getString("ElementType");
if (et == "MET_UCHAR") if (et == "MET_UCHAR")
pt = WeaklyTypedPointer::UINT8; pt = WeaklyTypedPointer::UINT8;
else if (et == "MET_CHAR") else if (et == "MET_CHAR")
pt = WeaklyTypedPointer::INT8; pt = WeaklyTypedPointer::INT8;
else if (et == "MET_USHORT") else if (et == "MET_USHORT")
pt = WeaklyTypedPointer::UINT16; pt = WeaklyTypedPointer::UINT16;
else if (et == "MET_SHORT") else if (et == "MET_SHORT")
pt = WeaklyTypedPointer::INT16; pt = WeaklyTypedPointer::INT16;
else if (et == "MET_UINT") else if (et == "MET_UINT")
pt = WeaklyTypedPointer::UINT32; pt = WeaklyTypedPointer::UINT32;
else if (et == "MET_INT") else if (et == "MET_INT")
pt = WeaklyTypedPointer::INT32; pt = WeaklyTypedPointer::INT32;
else if (et == "MET_FLOAT") else if (et == "MET_FLOAT")
pt = WeaklyTypedPointer::FLOAT; pt = WeaklyTypedPointer::FLOAT;
else { else {
LERROR("Error while parsing MHD header: Unsupported element type: " << et); LERROR("Error while parsing MHD header: Unsupported element type: " << et);
return; return;
} }
// further optional parameters: // further optional parameters:
if (tfp.hasKey("HeaderSize")) { if (tfp.hasKey("HeaderSize")) {
// header size can be -1... // header size can be -1...
int tmp = tfp.getInt("HeaderSize"); int tmp = tfp.getInt("HeaderSize");
if (tmp >= 0) if (tmp >= 0)
offset = static_cast<int>(tmp); offset = static_cast<int>(tmp);
} }
if (tfp.hasKey("ElementByteOrderMSB")) if (tfp.hasKey("ElementByteOrderMSB"))
e = (tfp.getBool("ElementByteOrderMSB") ? EndianHelper::IS_BIG_ENDIAN : EndianHelper::IS_LITTLE_ENDIAN); e = (tfp.getBool("ElementByteOrderMSB") ? EndianHelper::IS_BIG_ENDIAN : EndianHelper::IS_LITTLE_ENDIAN);
// TODO: spacing, element size, etc. // TODO: spacing, element size, etc.
if (tfp.hasKey("ElementSpacing")) { if (tfp.hasKey("ElementSpacing")) {
if (dimensionality == 3) if (dimensionality == 3)
voxelSize = tfp.getVec3("ElementSpacing"); voxelSize = tfp.getVec3("ElementSpacing");
else if (dimensionality == 2) else if (dimensionality == 2)
voxelSize = tgt::vec3(tfp.getVec2("ElementSpacing"), 1.f); voxelSize = tgt::vec3(tfp.getVec2("ElementSpacing"), 1.f);
} }
if (tfp.hasKey("Position")) { if (tfp.hasKey("Position")) {
if (dimensionality == 3) if (dimensionality == 3)
imageOffset = tfp.getVec3("Position"); imageOffset = tfp.getVec3("Position");
else if (dimensionality == 2) else if (dimensionality == 2)
imageOffset = tgt::vec3(tfp.getVec2("Position"), 0.f); imageOffset = tgt::vec3(tfp.getVec2("Position"), 0.f);
} }
if (tfp.hasKey("VolumePosition")) { if (tfp.hasKey("Offset")) {
if (dimensionality == 3) if (dimensionality == 3)
imageOffset = tfp.getVec3("VolumePosition"); imageOffset = tfp.getVec3("Offset");
else if (dimensionality == 2) else if (dimensionality == 2)
imageOffset = tgt::vec3(tfp.getVec2("VolumePosition"), 0.f); imageOffset = tgt::vec3(tfp.getVec2("Offset"), 0.f);
} }
if (tfp.hasKey("ElementNumberOfChannels")) { if (tfp.hasKey("VolumePosition")) {
numChannels = tfp.getSizeT("ElementNumberOfChannels"); if (dimensionality == 3)
} imageOffset = tfp.getVec3("VolumePosition");
else if (dimensionality == 2)
// get raw image location: imageOffset = tgt::vec3(tfp.getVec2("VolumePosition"), 0.f);
url = StringUtils::trim(tfp.getString("ElementDataFile")); }
if (url == "LOCAL") { if (tfp.hasKey("ElementNumberOfChannels")) {
url = p_url.getValue(); numChannels = tfp.getSizeT("ElementNumberOfChannels");
// find beginning of local data: }
tgt::File* file = FileSys.open(p_url.getValue());
if (!file || !file->isOpen()) // get raw image location:
throw tgt::FileException("Could not open file " + p_url.getValue() + " for reading.", p_url.getValue()); url = StringUtils::trim(tfp.getString("ElementDataFile"));
if (url == "LOCAL") {
while (!file->eof()) { url = p_url.getValue();
std::string line = StringUtils::trim(file->getLine()); // find beginning of local data:
if (line.find("ElementDataFile") == 0) { tgt::File* file = FileSys.open(p_url.getValue());
offset = file->tell(); if (!file || !file->isOpen())
} throw tgt::FileException("Could not open file " + p_url.getValue() + " for reading.", p_url.getValue());
file->close();
delete file; while (!file->eof()) {
} std::string line = StringUtils::trim(file->getLine());
} if (line.find("ElementDataFile") == 0) {
else if (url == "LIST") { offset = file->tell();
LERROR("Error while loading MHD file: Image list currently not supported."); }
return; file->close();
} delete file;
else { }
url = tgt::FileSystem::cleanupPath(tgt::FileSystem::dirName(p_url.getValue()) + "/" + url); }
} else if (url == "LIST") {
LERROR("Error while loading MHD file: Image list currently not supported.");
return;
}
// all parsing done - lets create the image: else {
ImageData* image = new ImageData(dimensionality, size, numChannels); url = tgt::FileSystem::cleanupPath(tgt::FileSystem::dirName(p_url.getValue()) + "/" + url);
ImageRepresentationDisk::create(image, url, pt, offset, e); }
image->setMappingInformation(ImageMappingInformation(size, imageOffset + p_imageOffset.getValue(), voxelSize * p_voxelSize.getValue()));
data.addData(p_targetImageID.getValue(), image);
}
catch (tgt::Exception& e) { // all parsing done - lets create the image:
LERROR("Error while parsing MHD header: " << e.what()); ImageData* image = new ImageData(dimensionality, size, numChannels);
validate(INVALID_RESULT); ImageRepresentationDisk::create(image, url, pt, offset, e);
return; image->setMappingInformation(ImageMappingInformation(size, imageOffset + p_imageOffset.getValue(), voxelSize * p_voxelSize.getValue()));
} data.addData(p_targetImageID.getValue(), image);
catch (std::exception& e) { }
LERROR("Error while parsing MHD header: " << e.what()); catch (tgt::Exception& e) {
validate(INVALID_RESULT); LERROR("Error while parsing MHD header: " << e.what());
return; validate(INVALID_RESULT);
} return;
}
validate(INVALID_RESULT); catch (std::exception& e) {
} LERROR("Error while parsing MHD header: " << e.what());
validate(INVALID_RESULT);
return;
}
validate(INVALID_RESULT);
}
} }
\ No newline at end of file
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