bool load_data (const Image::Iterator& pos) { Image::voxel_assign (dwi, pos); Image::voxel_assign (dt, pos); size_t nvox = dwi.dim (row_axis); if (mask) { size_t N = 0; Image::voxel_assign (*mask, pos); for ((*mask)[row_axis] = 0; (*mask)[row_axis] < mask->dim(row_axis); ++(*mask)[row_axis]) if (mask->value()) ++N; nvox = N; } if (!nvox) return false; signals.allocate (nvox, dwi.dim (sig_axis)); logsignals.allocate (nvox, dwi.dim (sig_axis)); tensors.allocate (nvox, 7); size_t N = 0; for (dwi[row_axis] = 0; dwi[row_axis] < dwi.dim(row_axis); ++dwi[row_axis]) { if (mask) { (*mask)[row_axis] = dwi[row_axis]; if (!mask->value()) continue; } for (dwi[sig_axis] = 0; dwi[sig_axis] < dwi.dim(sig_axis); ++dwi[sig_axis]) { cost_value_type val = std::max (cost_value_type (dwi.value()), cost_value_type (1.0)); signals(N, dwi[sig_axis]) = val; logsignals(N, dwi[sig_axis]) = -Math::log (val); } ++N; } return true; }
void run () { Image::Buffer<value_type> SH_data (argument[0]); Math::SH::check (SH_data); Options opt = get_options ("mask"); std::unique_ptr<Image::Buffer<bool> > mask_data; if (opt.size()) mask_data.reset (new Image::Buffer<bool> (opt[0][0])); opt = get_options ("seeds"); Math::Matrix<value_type> dirs; if (opt.size()) dirs.load (opt[0][0]); else { dirs.allocate (60,2); dirs = Math::Matrix<value_type> (default_directions, 60, 2); } if (dirs.columns() != 2) throw Exception ("expecting 2 columns for search directions matrix"); opt = get_options ("num"); int npeaks = opt.size() ? opt[0][0] : 3; opt = get_options ("direction"); std::vector<Direction> true_peaks; for (size_t n = 0; n < opt.size(); ++n) { Direction p (Math::pi*to<float> (opt[n][0]) /180.0, Math::pi*float (opt[n][1]) /180.0); true_peaks.push_back (p); } if (true_peaks.size()) npeaks = true_peaks.size(); opt = get_options ("threshold"); value_type threshold = -INFINITY; if (opt.size()) threshold = opt[0][0]; Image::Header header (SH_data); header.datatype() = DataType::Float32; opt = get_options ("peaks"); std::unique_ptr<Image::Buffer<value_type> > ipeaks_data; if (opt.size()) { if (true_peaks.size()) throw Exception ("you can't specify both a peaks file and orientations to be estimated at the same time"); if (opt.size()) ipeaks_data.reset (new Image::Buffer<value_type> (opt[0][0])); Image::check_dimensions (header, *ipeaks_data, 0, 3); npeaks = ipeaks_data->dim (3) / 3; } header.dim(3) = 3 * npeaks; Image::Buffer<value_type> peaks_data (argument[1], header); DataLoader loader (SH_data, mask_data.get()); Processor processor (peaks_data, dirs, Math::SH::LforN (SH_data.dim (3)), npeaks, true_peaks, threshold, ipeaks_data.get()); Thread::run_queue (loader, Item(), Thread::multi (processor)); }