csvdimagereader.cpp 7.23 KB
Newer Older
1
2
3
4
// ================================================================================================
// 
// This file is part of the CAMPVis Software Framework.
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
6
7
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
11
12
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// 
13
14
15
16
// 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
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18
19
20
21
// 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.
22
23
24
25
26
27
28
29
30
31
// 
// ================================================================================================

#include "csvdimagereader.h"

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

32
#include "cgt/filesystem.h"
33
34
35
36
37
38
39
40
41
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationdisk.h"
#include "core/datastructures/genericimagerepresentationlocal.h"
#include "core/tools/textfileparser.h"

namespace campvis {
    const std::string CsvdImageReader::loggerCat_ = "CAMPVis.modules.io.CsvdImageReader";

    CsvdImageReader::CsvdImageReader() 
42
        : AbstractImageReader()
43
44
        , p_imageOffset("ImageOffset", "Image Offset in mm", cgt::vec3(0.f), cgt::vec3(-10000.f), cgt::vec3(10000.f), cgt::vec3(0.1f))
        , p_voxelSize("VoxelSize", "Voxel Size in mm", cgt::vec3(1.f), cgt::vec3(-100.f), cgt::vec3(100.f), cgt::vec3(0.1f))
45
    {
46
        this->_ext.push_back("csv");
47
        this->p_targetImageID.setValue("CsvdImageReader.output");
48

49
50
51
52
        addProperty(p_url);
        addProperty(p_targetImageID);
        addProperty(p_imageOffset);
        addProperty(p_voxelSize);
53
54
55
56
57
58
    }

    CsvdImageReader::~CsvdImageReader() {

    }

59
    void CsvdImageReader::updateResult(DataContainer& data) {
60
61
62
63
64
65
        try {
            // start parsing
            TextFileParser tfp(p_url.getValue(), true, "=");
            tfp.parse<TextFileParser::ItemSeparatorLines>();

            // init optional parameters with sane default values
66
            cgt::svec3 size;
67
68
            WeaklyTypedPointer::BaseType pt;

69
70
            cgt::vec3 voxelSize(1.f);
            cgt::vec3 imageOffset(0.f);
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

            // dimensionality and size
            if (tfp.hasKey("Size")) {
                size = tfp.getSvec3("Size");
            }
            else {
                LERROR("Error while parsing CSVD header: No Size specified.");
                return;
            }

            // element type
            std::string et = tfp.getString("ElementType");
            if (et == "UINT8")
                pt = WeaklyTypedPointer::UINT8;
            else if (et == "INT8")
                pt = WeaklyTypedPointer::INT8;
            else if (et == "UINT16")
                pt = WeaklyTypedPointer::UINT16;
            else if (et == "INT16")
                pt = WeaklyTypedPointer::INT16;
            else if (et == "UINT32")
                pt = WeaklyTypedPointer::UINT32;
            else if (et == "INT32")
                pt = WeaklyTypedPointer::INT32;
            else if (et == "FLOAT")
                pt = WeaklyTypedPointer::FLOAT;
            else {
                LERROR("Error while parsing MHD header: Unsupported element type: " << et);
                return;
            }

            // dimensionality and size
            if (tfp.hasKey("CsvFileBaseName")) {
104
                size_t dimensionality = 3;
105
106
107
108
109
                ImageData* image = new ImageData(dimensionality, size, 1);
                ImageRepresentationLocal* rep = 0;
                size_t index = 0;

                std::string url = StringUtils::trim(tfp.getString("CsvFileBaseName"));
110
                url = cgt::FileSystem::cleanupPath(cgt::FileSystem::dirName(p_url.getValue()) + "/" + url);
111
112
113
114

                // start parsing of CSV files
#define DISPATCH_PARSING(WTP_TYPE, C_TYPE, TMP_TYPE) \
    if (pt == WTP_TYPE) {\
115
116
        C_TYPE* dataArray = new C_TYPE[cgt::hmul(size)]; \
        memset(dataArray, 0, sizeof(C_TYPE) * cgt::hmul(size)); \
117
118
119
120
121
122
123
        for (size_t slice = 0; slice < size.z; ++slice) { \
            std::stringstream ss; \
            ss << url << slice << ".csv"; \
            std::string concatenated = ss.str(); \
             \
            std::ifstream file(concatenated.c_str(), std::ifstream::in); \
            if (!file.is_open() || file.bad()) \
124
                throw cgt::FileException("Could not open file " + ss.str() + " for reading.", p_url.getValue()); \
125
126
                 \
            TMP_TYPE tmp; \
schultezub's avatar
schultezub committed
127
            for (size_t column = 0; column < size.y && file.good(); ++column) { \
128
129
130
131
132
133
                for (size_t row = 0; row < size.x && file.good(); ++row) { \
                    file >> tmp; \
                    dataArray[index++] = static_cast<C_TYPE>(tmp); \
                    file.get(); /* TODO: simple hack to advance to next character - but there might be more than one... */ \
                } \
            } \
schultezub's avatar
schultezub committed
134
135
            \
            file.close(); \
136
137
        } \
        rep = GenericImageRepresentationLocal<C_TYPE, 1>::create(image, dataArray); \
138
139
        if (rep == 0) \
            delete [] dataArray; \
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    }

                DISPATCH_PARSING(WeaklyTypedPointer::UINT8      , uint8_t, uint16_t)
                else DISPATCH_PARSING(WeaklyTypedPointer::INT8  , int8_t, int16_t)
                else DISPATCH_PARSING(WeaklyTypedPointer::UINT16, uint16_t, uint16_t)
                else DISPATCH_PARSING(WeaklyTypedPointer::INT16 , int16_t, int16_t)
                else DISPATCH_PARSING(WeaklyTypedPointer::UINT32, uint32_t, uint32_t)
                else DISPATCH_PARSING(WeaklyTypedPointer::INT32 , int32_t, int32_t)
                else DISPATCH_PARSING(WeaklyTypedPointer::FLOAT , float, float)
                
                if (rep != 0) {
                    // all parsing done - lets create the image:
                    image->setMappingInformation(ImageMappingInformation(size, imageOffset + p_imageOffset.getValue(), voxelSize + p_voxelSize.getValue()));
                    data.addData(p_targetImageID.getValue(), image);
                }
                else {
156
                    throw cgt::FileException("Error while parsing the data.", p_url.getValue());
157
158
159
160
161
162
163
                }
            }
            else {
                LERROR("Error while parsing CSVD header: No file names specified.");
                return;
            }
        }
164
        catch (cgt::Exception& e) {
165
166
167
168
169
170
171
172
            LERROR("Error while parsing MHD header: " << e.what());
            return;
        }
        catch (std::exception& e) {
            LERROR("Error while parsing MHD header: " << e.what());
            return;
        }
    }
173

174
}