Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
158 lines (120 sloc) 4.58 KB
/*
* Copyright (c) 2008-2018 the MRtrix3 contributors.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at http://mozilla.org/MPL/2.0/
*
* MRtrix3 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* For more details, see http://www.mrtrix.org/
*/
#ifndef __dwi_tractography_file_base_h__
#define __dwi_tractography_file_base_h__
#include <iomanip>
#include <map>
#include "types.h"
#include "file/key_value.h"
#include "file/ofstream.h"
#include "file/path.h"
#include "dwi/tractography/properties.h"
namespace MR
{
namespace DWI
{
namespace Tractography
{
//! \cond skip
class __ReaderBase__
{ NOMEMALIGN
public:
~__ReaderBase__ () {
if (in.is_open())
in.close();
}
void open (const std::string& file, const std::string& firstline, Properties& properties);
void close () { in.close(); }
protected:
std::ifstream in;
DataType dtype;
};
template <typename ValueType = float>
class __WriterBase__
{ NOMEMALIGN
public:
using value_type = ValueType;
__WriterBase__(const std::string& name) :
count (0),
total_count (0),
name (name),
dtype (DataType::from<ValueType>()),
count_offset (0),
open_success (false)
{
dtype.set_byte_order_native();
if (dtype != DataType::Float32LE && dtype != DataType::Float32BE &&
dtype != DataType::Float64LE && dtype != DataType::Float64BE)
throw Exception ("only supported datatype for tracks file are "
"Float32LE, Float32BE, Float64LE & Float64BE");
App::check_overwrite (name);
}
~__WriterBase__()
{
if (open_success) {
File::OFStream out (name, std::ios::in | std::ios::out | std::ios::binary);
update_counts (out);
}
}
void create (File::OFStream& out, const Properties& properties, const std::string& type) {
out << "mrtrix " + type + "\nEND\n";
for (const auto& i : properties) {
if ((i.first != "count") && (i.first != "total_count"))
out << i.first << ": " << i.second << "\n";
}
for (const auto& i : properties.comments)
out << "comment: " << i << "\n";
for (size_t n = 0; n < properties.seeds.num_seeds(); ++n)
out << "roi: seed " << properties.seeds[n]->get_name() << "\n";
for (size_t n = 0; n < properties.include.size(); ++n)
out << "roi: include " << properties.include[n].parameters() << "\n";
for (size_t n = 0; n < properties.exclude.size(); ++n)
out << "roi: exclude " << properties.exclude[n].parameters() << "\n";
for (size_t n = 0; n < properties.mask.size(); ++n)
out << "roi: mask " << properties.mask[n].parameters() << "\n";
for (const auto& it : properties.roi)
out << "roi: " << it.first << " " << it.second << "\n";
out << "datatype: " << dtype.specifier() << "\n";
int64_t data_offset = int64_t(out.tellp()) + 65;
data_offset += (4 - (data_offset % 4)) % 4;
out << "file: . " << data_offset << "\n";
out << "count: ";
count_offset = out.tellp();
out << "0\nEND\n";
out.seekp (0);
out << "mrtrix " + type + " ";
out.seekp (data_offset);
}
void skip() { ++total_count; }
uint64_t count, total_count;
protected:
std::string name;
DataType dtype;
int64_t count_offset;
bool open_success;
void verify_stream (const File::OFStream& out) {
if (!out.good())
throw Exception ("error writing file \"" + name + "\": " + strerror (errno));
}
void update_counts (File::OFStream& out) {
out.seekp (count_offset);
out << count << "\ntotal_count: " << total_count << "\nEND\n";
verify_stream (out);
}
};
//! \endcond
}
}
}
#endif