@@ -5,7 +5,9 @@ use super::bindings::tsk_size_t;
55use super :: bindings:: tsk_tree_t;
66use super :: flags:: TreeFlags ;
77use super :: newtypes:: NodeId ;
8+ use super :: newtypes:: Position ;
89use super :: newtypes:: SizeType ;
10+ use super :: newtypes:: Time ;
911use super :: tskbox:: TskBox ;
1012use super :: TreeSequence ;
1113use super :: TskitError ;
@@ -205,6 +207,37 @@ impl<'treeseq> LLTree<'treeseq> {
205207 pub fn right_child_array ( & self ) -> & [ NodeId ] {
206208 super :: generate_slice ( self . as_ref ( ) . right_child , self . treeseq . num_nodes_raw ( ) + 1 )
207209 }
210+
211+ pub fn total_branch_length ( & self , by_span : bool ) -> Result < Time , TskitError > {
212+ let time: & [ Time ] = super :: generate_slice (
213+ unsafe { ( * ( * ( * self . as_ptr ( ) ) . tree_sequence ) . tables ) . nodes . time } ,
214+ self . treeseq . num_nodes_raw ( ) + 1 ,
215+ ) ;
216+ let mut b = Time :: from ( 0. ) ;
217+ for n in self . traverse_nodes ( NodeTraversalOrder :: Preorder ) {
218+ let p = self . parent ( n) . ok_or ( TskitError :: IndexError { } ) ?;
219+ if p != NodeId :: NULL {
220+ b += time[ p. as_usize ( ) ] - time[ n. as_usize ( ) ]
221+ }
222+ }
223+
224+ match by_span {
225+ true => Ok ( b * self . span ( ) ) ,
226+ false => Ok ( b) ,
227+ }
228+ }
229+
230+ pub fn interval ( & self ) -> ( Position , Position ) {
231+ (
232+ self . as_ref ( ) . interval . left . into ( ) ,
233+ self . as_ref ( ) . interval . right . into ( ) ,
234+ )
235+ }
236+
237+ pub fn span ( & self ) -> Position {
238+ let i = self . interval ( ) ;
239+ i. 1 - i. 0
240+ }
208241}
209242
210243// Trait defining iteration over nodes.
0 commit comments