Esempio n. 1
0
void run ()
{

  DWI::Tractography::Properties properties;

  DWI::Tractography::Writer<> writer (argument.back(), properties);

  for (size_t n = 0; n < argument.size()-1; n++) {
    Math::Matrix<float> M;
    try {
      M.load (argument[n]);
      if (M.columns() != 3)
        throw Exception ("file \"" + argument[n] + "\" does not contain 3 columns - ignored");

      DWI::Tractography::Streamline<float> tck (M.rows());
      for (size_t i = 0; i < M.rows(); i++) {
        tck[i].set (M (i,0), M (i,1), M (i,2));
      }
      writer (tck);
      writer.total_count++;
    }
    catch (Exception) { }
  }

}
Esempio n. 2
0
 DWI2QBI (const Math::Matrix<value_type>& FRT_SHT, Math::Matrix<value_type>& normalise_SHT, const DWI::Shells& shells) :
   FRT_SHT (FRT_SHT), 
   normalise_SHT (normalise_SHT), 
   shells (shells),
   dwi (FRT_SHT.columns()),
   qbi (FRT_SHT.rows()),
   amps (normalise ? normalise_SHT.rows() : 0) { }
Esempio n. 3
0
void
TestMatrix::runSubTest18(double& res, double& expected, std::string& subTestName)
{
    expected = 1;
    subTestName = "simple_symmetric_invert";

#ifdef COSMO_LAPACK
    Math::SymmetricMatrix<double> mat(2, 2);
    mat(0, 0) = 2;
    mat(1, 1) = 3;
    mat(1, 0) = 1;

    mat.writeIntoTextFile("test_files/matrix_test_18_original.txt");

    Math::SymmetricMatrix<double> invMat = mat;
    invMat.invert();

    invMat.writeIntoTextFile("test_files/matrix_test_18_inverse.txt");

    Math::Matrix<double> prod = mat;
    prod *= invMat;
    prod.writeIntoTextFile("test_files/matrix_test_18_product.txt");

    res = 1;
    for(int i = 0; i < prod.rows(); ++i)
    {
        for(int j = 0; j < prod.rows(); ++j)
        {
            if(i == j)
            {
                if(!Math::areEqual(prod(i, j), 1.0, 1e-5))
                {
                    output_screen("FAIL! Diagonal element " << i << " must be 1 but it is " << prod(i, j) << std::endl);
                    res = 0;
                }
            }
            else
            {
                if(!Math::areEqual(prod(i, j), 0.0, 1e-5))
                {
                    output_screen("FAIL! Non-diagonal element " << i << " " << j << " must be 0 but it is " << prod(i, j) << std::endl);
                    res = 0;
                }
            }
        }
    }
#else
    output_screen_clean("This test (below) is skipped because Cosmo++ has not been linked to lapack" << std::endl);
    res = 1;
#endif
}
Esempio n. 4
0
  void writeAsciiMatrix(const std::string& fname, const Math::Matrix<T,P,S>& M,
                        const std::string& meta, const bool trans = false) {
    Math::Range start(0,0);
    Math::Range end(M.rows(), M.cols());

    std::ofstream ofs(fname.c_str());
    if (!ofs.is_open())
      throw(std::runtime_error("Cannot open " + fname + " for writing."));
    MatrixWriteImpl<T,P,S,internal::BasicMatrixFormatter<T> >::write(ofs, M, meta, start, end, trans);
  }
Esempio n. 5
0
void verify_matrix (Math::Matrix<float>& in, const node_t num_nodes)
{
  if (in.rows() != in.columns())
    throw Exception ("Connectome matrix is not square (" + str(in.rows()) + " x " + str(in.columns()) + ")");
  if (in.rows() != num_nodes)
    throw Exception ("Connectome matrix contains " + str(in.rows()) + " nodes; expected " + str(num_nodes));

  for (node_t row = 0; row != num_nodes; ++row) {
    for (node_t column = row+1; column != num_nodes; ++column) {

      const float lower_value = in (column, row);
      const float upper_value = in (row, column);

      if (upper_value && lower_value && (upper_value != lower_value))
        throw Exception ("Connectome matrix is not symmetrical");

      if (!upper_value && lower_value)
        in (row, column) = lower_value;

      in (column, row) = 0.0f;

  } }
}
Esempio n. 6
0
void run () 
{
  try {
    Math::Matrix<value_type> directions = DWI::Directions::load_cartesian<value_type> (argument[0]);
    report (str(argument[0]), directions);
  }
  catch (Exception& E) {
    Math::Matrix<value_type> directions (str(argument[0]));
    DWI::normalise_grad (directions);
    if (directions.columns() < 3) 
      throw Exception ("unexpected matrix size for DW scheme \"" + str(argument[0]) + "\"");

    print (str(argument[0]) + " [ " + str(directions.rows()) + " volumes ]\n");
    DWI::Shells shells (directions);

    for (size_t n = 0; n < shells.count(); ++n) {
      Math::Matrix<value_type> subset (shells[n].count(), 3);
      for (size_t i = 0; i < subset.rows(); ++i)
        subset.row(i) = directions.row(shells[n].get_volumes()[i]).sub(0,3);
      report ("\nb = " + str(shells[n].get_mean()), subset);
    }
  }
}
Esempio n. 7
0
void run()
{
  InputBufferType dwi_buffer (argument[0], Image::Stride::contiguous_along_axis (3));
  Math::Matrix<cost_value_type> grad = DWI::get_valid_DW_scheme<cost_value_type> (dwi_buffer);

  size_t dwi_axis = 3;
  while (dwi_buffer.dim (dwi_axis) < 2) ++dwi_axis;
  INFO ("assuming DW images are stored along axis " + str (dwi_axis));

  Math::Matrix<cost_value_type> bmatrix;
  DWI::grad2bmatrix (bmatrix, grad);

  Math::Matrix<cost_value_type> binv (bmatrix.columns(), bmatrix.rows());
  Math::pinv (binv, bmatrix);

  int method = 1;
  Options opt = get_options ("method");
  if (opt.size()) method = opt[0][0];

  opt = get_options ("regularisation");
  cost_value_type regularisation = 5000.0;
  if (opt.size()) regularisation = opt[0][0];

  opt = get_options ("mask");
  Ptr<MaskBufferType> mask_buffer;
  Ptr<MaskBufferType::voxel_type> mask_vox;
  if (opt.size()){
    mask_buffer = new MaskBufferType (opt[0][0]);
    Image::check_dimensions (*mask_buffer, dwi_buffer, 0, 3);
    mask_vox = new MaskBufferType::voxel_type (*mask_buffer);
  }


  Image::Header dt_header (dwi_buffer);
  dt_header.set_ndim (4);
  dt_header.dim (3) = 6;
  dt_header.datatype() = DataType::Float32;
  dt_header.DW_scheme() = grad;

  OutputBufferType dt_buffer (argument[1], dt_header);

  InputBufferType::voxel_type dwi_vox (dwi_buffer);
  OutputBufferType::voxel_type dt_vox (dt_buffer);

  Image::ThreadedLoop loop ("estimating tensor components...", dwi_vox, 1, 0, 3);
  Processor processor (dwi_vox, dt_vox, mask_vox, bmatrix, binv, method, regularisation, loop.inner_axes()[0], dwi_axis);

  loop.run_outer (processor);
}
Esempio n. 8
0
    void save_bvecs_bvals (const Image::Header& header, const std::string& path)
    {

      std::string bvecs_path, bvals_path;
      if (path.size() >= 5 && path.substr (path.size() - 5, path.size()) == "bvecs") {
        bvecs_path = path;
        bvals_path = path.substr (0, path.size() - 5) + "bvals";
      } else if (path.size() >= 5 && path.substr (path.size() - 5, path.size()) == "bvals") {
        bvecs_path = path.substr (0, path.size() - 5) + "bvecs";
        bvals_path = path;
      } else {
        bvecs_path = path + "bvecs";
        bvals_path = path + "bvals";
      }

      const Math::Matrix<float>& grad (header.DW_scheme());
      Math::Matrix<float> G (grad.rows(), 3);

      // rotate vectors from scanner space to image space
      Math::Matrix<float> D (header.transform());
      Math::Permutation p (4);
      int signum;
      Math::LU::decomp (D, p, signum);
      Math::Matrix<float> image2scanner (4,4);
      Math::LU::inv (image2scanner, D, p);
      Math::Matrix<float> rotation = image2scanner.sub (0,3,0,3);
      Math::Matrix<float> grad_G = grad.sub (0, grad.rows(), 0, 3);
      Math::mult (G, float(0.0), float(1.0), CblasNoTrans, grad_G, CblasTrans, rotation);

      // deal with FSL requiring gradient directions to coincide with data strides
      // also transpose matrices in preparation for file output
      std::vector<size_t> order = Image::Stride::order (header, 0, 3);
      Math::Matrix<float> bvecs (3, grad.rows());
      Math::Matrix<float> bvals (1, grad.rows());
      for (size_t n = 0; n < G.rows(); ++n) {
        bvecs(0,n) = header.stride(order[0]) > 0 ? G(n,order[0]) : -G(n,order[0]);
        bvecs(1,n) = header.stride(order[1]) > 0 ? G(n,order[1]) : -G(n,order[1]);
        bvecs(2,n) = header.stride(order[2]) > 0 ? G(n,order[2]) : -G(n,order[2]);
        bvals(0,n) = grad(n,3);
      }

      bvecs.save (bvecs_path);
      bvals.save (bvals_path);

    }
Esempio n. 9
0
void
AAKR::computeDistance(Math::Matrix query)
{
    if (query.rows() != 1)
        throw std::runtime_error("unable to compute distance: reference is not row vector.");

    if ((unsigned)query.columns() != sampleSize())
        throw std::runtime_error("unable to compute distance: sample size does not match.");

    m_distances.fill(0.0);

    // Fill distances vector.
    for (unsigned i = 0; i < m_num_values; i++)
    {
        Math::Matrix q = query - m_norm.row(i);
        m_distances(i) = std::sqrt(sum(q * transpose(q)));
    };
}
Esempio n. 10
0
void
AAKR::add(Math::Matrix v)
{
    if (dataSize() == 0)
        throw std::runtime_error("unable to add: data window size is undefined.");

    if (v.rows() != 1)
        throw std::runtime_error("unable to add: new sample is not a row vector.");

    if (sampleSize() == 0)
        m_data.resize(dataSize(), v.columns());

    if ((unsigned)v.columns() != sampleSize())
        throw std::runtime_error("unable to add: sample size does not match.");

    // Write to the data set.
    m_data.set(m_index, m_index, 0, sampleSize() - 1, v);

    // Increment data set index.
    increment();
}
Esempio n. 11
0
void run () 
{
  Math::Matrix<value_type> directions = DWI::Directions::load_cartesian<value_type> (argument[0]);

  size_t num_permutations = 1e8;
  Options opt = get_options ("permutations");
  if (opt.size())
    num_permutations = opt[0][0];

  Shared eddy_shared (directions, num_permutations);
  Thread::run (Thread::multi (Processor (eddy_shared)), "eval thread");

  auto& signs = eddy_shared.get_best_signs();

  for (size_t n = 0; n < directions.rows(); ++n) 
    if (signs[n] < 0)
      directions.row(n) *= -1.0;

  bool cartesian = get_options("cartesian").size();
  DWI::Directions::save (directions, argument[1], cartesian);
}
Esempio n. 12
0
    void solve_nonlinear () {
      for (size_t i = 0; i < signals.rows(); ++i) {
        const Math::Vector<cost_value_type> signal (signals.row(i));
        Math::Vector<cost_value_type> values (tensors.row(i));

        cost.set_voxel (&signal, &values);

        Math::Vector<cost_value_type> x (cost.size());
        cost.init (x);
        //Math::check_function_gradient (cost, x, 1e-10, true);

        Math::GradientDescent<Cost> optim (cost);
        try { optim.run (10000, 1e-8); }
        catch (Exception& E) {
          E.display();
        }

        //x = optim.state();
        //Math::check_function_gradient (cost, x, 1e-10, true);

        cost.get_values (values, optim.state());
      }
    }
Esempio n. 13
0
 Shared (const Math::Matrix<value_type>& directions, size_t target_num_permutations) :
   directions (directions), target_num_permutations (target_num_permutations), num_permutations(0),
   progress ("optimising directions for eddy-currents...", target_num_permutations),
   best_signs (directions.rows(), 1), best_eddy (std::numeric_limits<value_type>::max()) { }
Esempio n. 14
0
void report (const std::string& title, const Math::Matrix<value_type>& directions) 
{
  std::vector<value_type> NN_bipolar (directions.rows(), 0.0);
  std::vector<value_type> NN_unipolar (directions.rows(), 0.0);

  std::vector<value_type> E_bipolar (directions.rows(), 0.0);
  std::vector<value_type> E_unipolar (directions.rows(), 0.0);

  for (size_t i = 0; i < directions.rows()-1; ++i) {
    for (size_t j = i+1; j < directions.rows(); ++j) {
      value_type cos_angle = Math::dot (directions.row(i).sub(0,3), directions.row(j).sub(0,3));
      NN_unipolar[i] = std::max (NN_unipolar[i], cos_angle);
      NN_unipolar[j] = std::max (NN_unipolar[j], cos_angle);
      cos_angle = std::abs(cos_angle);
      NN_bipolar[i] = std::max (NN_bipolar[i], cos_angle);
      NN_bipolar[j] = std::max (NN_bipolar[j], cos_angle);

      value_type E = 
        Math::pow2 (directions(i,0) - directions(j,0)) + 
        Math::pow2 (directions(i,1) - directions(j,1)) + 
        Math::pow2 (directions(i,2) - directions(j,2));
      E = value_type (1.0) / E;

      E_unipolar[i] += E;
      E_unipolar[j] += E;

      value_type E2 = 
        Math::pow2 (directions(i,0) + directions(j,0)) + 
        Math::pow2 (directions(i,1) + directions(j,1)) + 
        Math::pow2 (directions(i,2) + directions(j,2));
      E += value_type (1.0) / E2;

      E_bipolar[i] += E;
      E_bipolar[j] += E;

    }
  }




  auto report_NN = [](const std::vector<value_type>& NN) {
    value_type min = std::numeric_limits<value_type>::max();
    value_type mean = 0.0;
    value_type max = 0.0;
    for (auto a : NN) {
      a = (180.0/Math::pi) * std::acos (a);
      mean += a;
      min = std::min (min, a);
      max = std::max (max, a);
    }
    mean /= NN.size();

    print ("    nearest-neighbour angles: mean = " + str(mean) + ", range [ " + str(min) + " - " + str(max) + " ]\n");
  };



  auto report_E = [](const std::vector<value_type>& E) {
    value_type min = std::numeric_limits<value_type>::max();
    value_type total = 0.0;
    value_type max = 0.0;
    for (auto e : E) {
      total += e;
      min = std::min (min, e);
      max = std::max (max, e);
    }
    print ("    energy: total = " + str(total) + ", mean = " + str(total/E.size()) + ", range [ " + str(min) + " - " + str(max) + " ]\n");
  };




  print (title + " [ " + str(directions.rows()) + " directions ]\n\n");

  print ("  Bipolar electrostatic repulsion model:\n");
  report_NN (NN_bipolar);
  report_E (E_bipolar);

  print ("\n  Unipolar electrostatic repulsion model:\n");
  report_NN (NN_unipolar);
  report_E (E_unipolar);

  std::string lmax_results;
  for (size_t lmax = 2; lmax <= Math::SH::LforN (directions.rows()); lmax += 2) 
    lmax_results += " " + str(DWI::condition_number_for_lmax (directions, lmax));
  print ("\n  Spherical Harmonic fit:\n    condition numbers for lmax = " + str(2) + " -> " 
      + str(Math::SH::LforN (directions.rows())) + ":" + lmax_results + "\n\n");
}
Esempio n. 15
0
void run() {
  Image::BufferPreload<float> data_in (argument[0], Image::Stride::contiguous_along_axis (3));
  auto voxel_in = data_in.voxel();

  Math::Matrix<value_type> grad (DWI::get_valid_DW_scheme<float> (data_in));

  // Want to support non-shell-like data if it's just a straight extraction
  //   of all dwis or all bzeros i.e. don't initialise the Shells class
  std::vector<size_t> volumes;
  bool bzero = get_options ("bzero").size();
  Options opt = get_options ("shell");
  if (opt.size()) {
    DWI::Shells shells (grad);
    shells.select_shells (false, false);
    for (size_t s = 0; s != shells.count(); ++s) {
      DEBUG ("Including data from shell b=" + str(shells[s].get_mean()) + " +- " + str(shells[s].get_stdev()));
      for (std::vector<size_t>::const_iterator v = shells[s].get_volumes().begin(); v != shells[s].get_volumes().end(); ++v)
        volumes.push_back (*v);
    }
    // Remove DW information from header if b=0 is the only 'shell' selected
    bzero = (shells.count() == 1 && shells[0].is_bzero());
  } else {
    const float bzero_threshold = File::Config::get_float ("BValueThreshold", 10.0);
    for (size_t row = 0; row != grad.rows(); ++row) {
      if ((bzero && (grad (row, 3) < bzero_threshold)) || (!bzero && (grad (row, 3) > bzero_threshold)))
        volumes.push_back (row);
    }
  }

  if (volumes.empty())
    throw Exception ("No " + str(bzero ? "b=0" : "dwi") + " volumes present");

  std::sort (volumes.begin(), volumes.end());

  Image::Header header (data_in);

  if (volumes.size() == 1)
    header.set_ndim (3);
  else
    header.dim (3) = volumes.size();

  Math::Matrix<value_type> new_grad (volumes.size(), grad.columns());
  for (size_t i = 0; i < volumes.size(); i++)
    new_grad.row (i) = grad.row (volumes[i]);
  header.DW_scheme() = new_grad;

  Image::Buffer<value_type> data_out (argument[1], header);
  auto voxel_out = data_out.voxel();

  Image::Loop outer ("extracting volumes...", 0, 3);

  if (voxel_out.ndim() == 4) {

    for (auto i = outer (voxel_out, voxel_in); i; ++i) {
      for (size_t i = 0; i < volumes.size(); i++) {
        voxel_in[3] = volumes[i];
        voxel_out[3] = i;
        voxel_out.value() = voxel_in.value();
      }
    }

  } else {

    const size_t volume = volumes[0];
    for (auto i = outer (voxel_out, voxel_in); i; ++i) {
      voxel_in[3] = volume;
      voxel_out.value() = voxel_in.value();
    }

  }


}