pub fn assign_maxima(maxima: &[isize],
                     atoms: &Atoms,
                     grid: &Grid,
                     threads: usize,
                     progress_bar: Bar)
                     -> Result<(Vec<usize>, Vec<f64>)> {
    let mut assigned_atom = vec![0; maxima.len()];
    let mut minimum_distance = vec![0.0; maxima.len()];
    let pbar = &progress_bar;
    // this is basically a thread handling function for running the
    // maxima_to_atom function
    match threads.cmp(&1) {
        std::cmp::Ordering::Greater => {
            let chunk_size =
                (maxima.len() / threads) + (maxima.len() % threads).min(1);
            thread::scope(|s| {
                let spawned_threads =
                    maxima.chunks(chunk_size)
                          .enumerate()
                          .map(|(index, chunk)| {
                              s.spawn(move |_| {
                                  match maxima_to_atom(chunk, atoms, grid, pbar) {
                                      Ok(result) => (result, index),
                                      _ => panic!("Failed to match maxima to atom"),
                                  }
                               })
                          })
                          .collect::<Vec<_>>();
                for thread in spawned_threads {
                    if let Ok(((ass_atom, min_dist), chunk_index)) =
                        thread.join()
                    {
                        // is this required? is the collection of handles not
                        // already sorted like this, is it possible to join as
                        // they finish?
                        let i = chunk_index * chunk_size;
                        assigned_atom.splice(i..(i + ass_atom.len()), ass_atom);
                        minimum_distance.splice(i..(i + min_dist.len()),
                                                min_dist);
                    } else {
                        panic!("Failed to join thread in assign maxima.")
                    };
                }
            }).unwrap();
        }
        _ => {
            let (ass_atom, min_dist) =
                maxima_to_atom(maxima, atoms, grid, pbar).context("Failed to assign maxima to atom.")?;
            assigned_atom = ass_atom;
            minimum_distance = min_dist;
        }
    }
    Ok((assigned_atom, minimum_distance))
}
/// Assign the Bader maxima to the nearest atom.
/// Threading will split the slice of maxima into chunks and operate on each
/// chunk in parallel.
Assign the Bader maxima to the nearest atom.
Threading will split the slice of maxima into chunks and operate on each
chunk in parallel.
Assign the Bader maxima to the nearest atom . Threading will split the slice of maxima into chunks and operate on each chunk in parallel .
pub fn assign_maxima(maxima: &[isize],
                     atoms: &Atoms,
                     grid: &Grid,
                     threads: usize,
                     progress_bar: Bar)
                     -> Result<(Vec<usize>, Vec<f64>)> {
    let mut assigned_atom = vec![0; maxima.len()];
    let mut minimum_distance = vec![0.0; maxima.len()];
    let pbar = &progress_bar;
    // this is basically a thread handling function for running the
    // maxima_to_atom function
    match threads.cmp(&1) {
        std::cmp::Ordering::Greater => {
            let chunk_size =
                (maxima.len() / threads) + (maxima.len() % threads).min(1);
            thread::scope(|s| {
                let spawned_threads =
                    maxima.chunks(chunk_size)
                          .enumerate()
                          .map(|(index, chunk)| {
                              s.spawn(move |_| {
                                  match maxima_to_atom(chunk, atoms, grid, pbar) {
                                      Ok(result) => (result, index),
                                      _ => panic!("Failed to match maxima to atom"),
                                  }
                               })
                          })
                          .collect::<Vec<_>>();
                for thread in spawned_threads {
                    if let Ok(((ass_atom, min_dist), chunk_index)) =
                        thread.join()
                    {
                        // is this required? is the collection of handles not
                        // already sorted like this, is it possible to join as
                        // they finish?
                        let i = chunk_index * chunk_size;
                        assigned_atom.splice(i..(i + ass_atom.len()), ass_atom);
                        minimum_distance.splice(i..(i + min_dist.len()),
                                                min_dist);
                    } else {
                        panic!("Failed to join thread in assign maxima.")
                    };
                }
            }).unwrap();
        }
        _ => {
            let (ass_atom, min_dist) =
                maxima_to_atom(maxima, atoms, grid, pbar).context("Failed to assign maxima to atom.")?;
            assigned_atom = ass_atom;
            minimum_distance = min_dist;
        }
    }
    Ok((assigned_atom, minimum_distance))
}
pub fn assign_maxima ( maxima : & [ isize ] , atoms : & Atoms , grid : & Grid , threads : usize , progress_bar : Bar ) -> Result < ( Vec < usize > , Vec < f64 > ) > { let mut assigned_atom = vec ! [ 0 maxima len ( ) ] ; let mut minimum_distance = vec ! [ 0.0 maxima len ( ) ] ; let pbar = & progress_bar ; // this is basically a thread handling function for running the // maxima_to_atom function match threads . cmp ( & 1 ) { std :: cmp :: Ordering :: Greater => { let chunk_size = ( maxima . len ( ) / threads ) + ( maxima . len ( ) % threads ) . min ( 1 ) ; thread :: scope ( | s | { let spawned_threads = maxima . chunks ( chunk_size ) . enumerate ( ) . map ( | ( index , chunk ) | { s . spawn ( move | _ | { match maxima_to_atom ( chunk , atoms , grid , pbar ) { Ok ( result ) => ( result , index ) , _ => panic ! ( " " ) , } } ) } ) . collect :: < Vec < _ > > ( ) ; for thread in spawned_threads { if let Ok ( ( ( ass_atom , min_dist ) , chunk_index ) ) = thread . join ( ) { // is this required? is the collection of handles not // already sorted like this, is it possible to join as // they finish? let i = chunk_index * chunk_size ; assigned_atom . splice ( i .. ( i + ass_atom . len ( ) ) , ass_atom ) ; minimum_distance . splice ( i .. ( i + min_dist . len ( ) ) , min_dist ) ; } else { panic ! ( " " ) } ; } } ) . unwrap ( ) ; } _ => { let ( ass_atom , min_dist ) = maxima_to_atom ( maxima , atoms , grid , pbar ) . context ( " " ) ? ; assigned_atom = ass_atom ; minimum_distance = min_dist ; } } Ok ( ( assigned_atom , minimum_distance ) ) }
Assign the Bader maxima to the nearest atom.
Assign the Bader maxima to the nearest atom .
maxima
&[isize]
atoms
&Atoms
grid
&Grid
threads
usize
progress_bar
Bar
maxima
&[isize]
atoms
&Atoms
grid
&Grid
threads
usize
progress_bar
Bar