MMap::~MMap() { if (!first) return; if (addr) { DEBUG ("unmapping file \"" + Entry::name + "\""); #ifdef MRTRIX_WINDOWS if (!UnmapViewOfFile ( (LPVOID) addr)) #else if (munmap (addr, msize)) #endif WARN ("error unmapping file \"" + Entry::name + "\": " + strerror (errno)); close (fd); } else { if (readwrite) { INFO ("writing back contents of mapped file \"" + Entry::name + "\"..."); File::OFStream out (Entry::name, std::ios::in | std::ios::out | std::ios::binary); out.seekp (start, out.beg); out.write ((char*) first, msize); if (!out.good()) throw Exception ("error writing back contents of file \"" + Entry::name + "\": " + strerror(errno)); } delete [] first; } }
std::unique_ptr<ImageIO::Base> MRtrix::create (Header& H) const { File::OFStream out (H.name(), std::ios::out | std::ios::binary); out << "mrtrix image\n"; write_mrtrix_header (H, out); bool single_file = Path::has_suffix (H.name(), ".mif"); int64_t offset = 0; out << "file: "; if (single_file) { offset = out.tellp() + int64_t(18); offset += ((4 - (offset % 4)) % 4); out << ". " << offset << "\nEND\n"; } else out << Path::basename (H.name().substr (0, H.name().size()-4) + ".dat") << "\n"; out.close(); std::unique_ptr<ImageIO::Base> io_handler (new ImageIO::Default (H)); if (single_file) { File::resize (H.name(), offset + footprint(H)); io_handler->files.push_back (File::Entry (H.name(), offset)); } else { std::string data_file (H.name().substr (0, H.name().size()-4) + ".dat"); File::create (data_file, footprint(H)); io_handler->files.push_back (File::Entry (data_file)); } return io_handler; }
std::shared_ptr<Handler::Base> MRtrix_sparse::create (Header& H) const { Header::const_iterator name_it = H.find (Image::Sparse::name_key); if (name_it == H.end()) throw Exception ("Cannot create sparse image " + H.name() + "; no knowledge of underlying data class type"); Header::const_iterator size_it = H.find (Image::Sparse::size_key); if (size_it == H.end()) throw Exception ("Cannot create sparse image " + H.name() + "; no knowledge of underlying data class size"); H.datatype() = DataType::UInt64; H.datatype().set_byte_order_native(); File::OFStream out (H.name(), std::ios::out | std::ios::binary); out << "mrtrix sparse image\n"; write_mrtrix_header (H, out); bool single_file = Path::has_suffix (H.name(), ".msf"); int64_t image_offset = 0, sparse_offset = 0; std::string image_path, sparse_path; if (single_file) { image_offset = out.tellp() + int64_t(54); image_offset += ((4 - (image_offset % 4)) % 4); sparse_offset = image_offset + Image::footprint(H); out << "file: . " << image_offset << "\nsparse_file: . " << sparse_offset << "\nEND\n"; File::resize (H.name(), sparse_offset); image_path = H.name(); sparse_path = H.name(); } else { image_path = Path::basename (H.name().substr (0, H.name().size()-4) + ".dat"); sparse_path = Path::basename (H.name().substr (0, H.name().size()-4) + ".sdat"); out << "file: " << image_path << "\nsparse_file: " << sparse_path << "\nEND\n"; File::create (image_path, Image::footprint(H)); File::create (sparse_path); } Handler::Default base_handler (H); base_handler.files.push_back (File::Entry (image_path, image_offset)); std::shared_ptr<Handler::Base> handler (new Handler::Sparse (base_handler, name_it->second, to<size_t>(size_it->second), File::Entry (sparse_path, sparse_offset))); return handler; }
void Default::unload (const Header& header) { if (mmaps.empty() && addresses.size()) { assert (addresses[0].get()); if (writable) { for (size_t n = 0; n < files.size(); n++) { File::OFStream out (files[n].name, std::ios::out | std::ios::binary); out.seekp (files[n].start, out.beg); out.write ((char*) (addresses[0].get() + n*bytes_per_segment), bytes_per_segment); if (!out.good()) throw Exception ("error writing back contents of file \"" + files[n].name + "\": " + strerror(errno)); } } } else { for (size_t n = 0; n < addresses.size(); ++n) addresses[n].release(); mmaps.clear(); } }
void run () { const bool weights_provided = get_options ("tck_weights_in").size(); float step_size = NAN; size_t count = 0, header_count = 0; float min_length = std::numeric_limits<float>::infinity(); float max_length = 0.0f; double sum_lengths = 0.0, sum_weights = 0.0; std::vector<double> histogram; std::vector<LW> all_lengths; all_lengths.reserve (header_count); { Tractography::Properties properties; Tractography::Reader<float> reader (argument[0], properties); if (properties.find ("count") != properties.end()) header_count = to<size_t> (properties["count"]); if (properties.find ("output_step_size") != properties.end()) step_size = to<float> (properties["output_step_size"]); else step_size = to<float> (properties["step_size"]); if (!std::isfinite (step_size) || !step_size) { WARN ("Streamline step size undefined in header"); if (get_options ("histogram").size()) WARN ("Histogram will be henerated using a 1mm interval"); } std::unique_ptr<File::OFStream> dump; Options opt = get_options ("dump"); if (opt.size()) dump.reset (new File::OFStream (std::string(opt[0][0]), std::ios_base::out | std::ios_base::trunc)); ProgressBar progress ("Reading track file... ", header_count); Tractography::Streamline<> tck; while (reader (tck)) { ++count; const float length = std::isfinite (step_size) ? tck.calc_length (step_size) : tck.calc_length(); min_length = std::min (min_length, length); max_length = std::max (max_length, length); sum_lengths += tck.weight * length; sum_weights += tck.weight; all_lengths.push_back (LW (length, tck.weight)); const size_t index = std::isfinite (step_size) ? std::round (length / step_size) : std::round (length); while (histogram.size() <= index) histogram.push_back (0.0); histogram[index] += tck.weight; if (dump) (*dump) << length << "\n"; ++progress; } } if (histogram.front()) WARN ("read " + str(histogram.front()) + " zero-length tracks"); if (count != header_count) WARN ("expected " + str(header_count) + " tracks according to header; read " + str(count)); const float mean_length = sum_lengths / sum_weights; float median_length = 0.0f; if (weights_provided) { // Perform a weighted median calculation std::sort (all_lengths.begin(), all_lengths.end()); size_t median_index = 0; double sum = sum_weights - all_lengths[0].get_weight(); while (sum > 0.5 * sum_weights) { sum -= all_lengths[++median_index].get_weight(); } median_length = all_lengths[median_index].get_length(); } else { median_length = Math::median (all_lengths).get_length(); } double stdev = 0.0; for (std::vector<LW>::const_iterator i = all_lengths.begin(); i != all_lengths.end(); ++i) stdev += i->get_weight() * Math::pow2 (i->get_length() - mean_length); stdev = std::sqrt (stdev / (((count - 1) / float(count)) * sum_weights)); const size_t width = 12; std::cout << " " << std::setw(width) << std::right << "mean" << " " << std::setw(width) << std::right << "median" << " " << std::setw(width) << std::right << "std. dev." << " " << std::setw(width) << std::right << "min" << " " << std::setw(width) << std::right << "max" << " " << std::setw(width) << std::right << "count\n"; std::cout << " " << std::setw(width) << std::right << (mean_length) << " " << std::setw(width) << std::right << (median_length) << " " << std::setw(width) << std::right << (stdev) << " " << std::setw(width) << std::right << (min_length) << " " << std::setw(width) << std::right << (max_length) << " " << std::setw(width) << std::right << (count) << "\n"; Options opt = get_options ("histogram"); if (opt.size()) { File::OFStream out (opt[0][0], std::ios_base::out | std::ios_base::trunc); if (!std::isfinite (step_size)) step_size = 1.0f; if (weights_provided) { out << "Length,Sum_weights\n"; for (size_t i = 0; i != histogram.size(); ++i) out << str(i * step_size) << "," << str(histogram[i]) << "\n"; } else { out << "Length,Count\n"; for (size_t i = 0; i != histogram.size(); ++i) out << str(i * step_size) << "," << str<size_t>(histogram[i]) << "\n"; } out << "\n"; out.close(); } }