void newviewGenericAncestral (tree *tr, nodeptr p, boolean atRoot)
{  
  if(atRoot)
    {
      assert(!tr->multiGene);
      tr->td[0].count = 1;
      traversalInfoAncestralRoot(p, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches);
      
      if(tr->td[0].count > 1)
	{
#ifdef _USE_PTHREADS
	  masterBarrier(THREAD_NEWVIEW_ANCESTRAL, tr);
#else
	  newviewIterativeAncestral(tr);
#endif
	}
    }   
  else
    {
      if(isTip(p->number, tr->mxtips))
	return;
      
      if(tr->multiGene)       
	assert(0);     
      else
	{
	  tr->td[0].count = 1;
	  computeTraversalInfo(p, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches);
	  
	  if(tr->td[0].count > 1)
	    {
#ifdef _USE_PTHREADS
	      masterBarrier(THREAD_NEWVIEW_ANCESTRAL, tr);
#else
	      newviewIterativeAncestral(tr);
#endif
	    }
	}
    }
}
void evaluateGeneric (tree *tr, nodeptr p, boolean fullTraversal)
{
  /* now this may be the entry point of the library to compute 
     the log like at a branch defined by p and p->back == q */

  volatile double 
    result = 0.0;
  
  nodeptr 
    q = p->back; 
  
  int 
    i,
    model;

 
  /* set the first entry of the traversal descriptor to contain the indices
     of nodes p and q */

  tr->td[0].ti[0].pNumber = p->number;
  tr->td[0].ti[0].qNumber = q->number;          
  
  /* copy the branch lengths of the tree into the first entry of the traversal descriptor.
     if -M is not used tr->numBranches must be 1 */

  for(i = 0; i < tr->numBranches; i++)    
    tr->td[0].ti[0].qz[i] =  q->z[i];
  
  /* now compute how many conditionals must be re-computed/re-oriented by newview
     to be able to calculate the likelihood at the root defined by p and q.
  */

  /* one entry in the traversal descriptor is already used, hence set the tarversal length counter to 1 */
  tr->td[0].count = 1;

  /* do we need to recompute any of the vectors at or below p ? */
  
  if(fullTraversal)
    { 
      assert(isTip(p->number, tr->mxtips));
      computeTraversalInfo(q, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches, FALSE);     
    }
  else
    {
      if(!p->x)
	computeTraversalInfo(p, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches, TRUE);

      /* recompute/reorient any descriptors at or below q ? 
	 computeTraversalInfo computes and stores the newview() to be executed for the traversal descriptor */
      
      if(!q->x)
	computeTraversalInfo(q, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches, TRUE);  
    }
   
      /* now we copy this partition execute mask into the traversal descriptor which must come from the 
	 calling program, the logic of this should not form part of the library */

  storeExecuteMaskInTraversalDescriptor(tr);  
  
  /* also store in the traversal descriptor that something has changed i.e., in the parallel case that the 
     traversal descriptor list of nodes needs to be broadcast once again */
  
  tr->td[0].traversalHasChanged = TRUE;

  evaluateIterative(tr);  
    		


  if(0)
    {
      double 
	*recv = (double *)malloc(sizeof(double) * tr->NumberOfModels);
      
      MPI_Allreduce(tr->perPartitionLH, recv, tr->NumberOfModels, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
      
      for(model = 0; model < tr->NumberOfModels; model++)
	{
	  /* TODO ??? */
	  /*tr->perPartitionLH[model] = recv[model];	*/
	  result += recv[model];
	}
      
      rax_free(recv);
    }
  else
    {
      double 
	*recv = (double *)malloc(sizeof(double) * tr->NumberOfModels);
      
      MPI_Reduce(tr->perPartitionLH, recv, tr->NumberOfModels, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
      MPI_Bcast(recv, tr->NumberOfModels, MPI_DOUBLE, 0, MPI_COMM_WORLD);
      
      for(model = 0; model < tr->NumberOfModels; model++)
	{
	  /* TODO ??? */
	  tr->perPartitionLH[model] = recv[model];
	  result += recv[model];
	}           
      
      rax_free(recv);      
    }


  /* set the tree data structure likelihood value to the total likelihood */

  tr->likelihood = result;    
  
  /* 
     MPI_Barrier(MPI_COMM_WORLD);
     printf("Process %d likelihood: %f\n", processID, tr->likelihood);
     MPI_Barrier(MPI_COMM_WORLD);
  */

  /* do some bookkeeping to have traversalHasChanged in a consistent state */

  tr->td[0].traversalHasChanged = FALSE;  
}