void KDPhotonsTree::FullHeap(const Point& center, const size_t index, double& d_square, size_t threadID) {

	if(m_treeArray[index].split != ST_LEAF) {
		double sigma = 0;
		switch(m_treeArray[index].split) {
		case ST_NON_EXIST:
			return;

		case ST_X_COORD:
			sigma = center.x() - m_treeArray[index].photon.position.x();
			break;
		
		case ST_Y_COORD:
			sigma = center.y() - m_treeArray[index].photon.position.y();
			break;
			
		case ST_Z_COORD:
			sigma = center.z() - m_treeArray[index].photon.position.z();
			break;
		default:
			throw Error("error in splitting dimension");
		}

		if(sigma < 0) 
		{
			FullHeap(center, index << 1, d_square, threadID);
			if(sigma*sigma < d_square)
			{
				FullHeap(center, (index << 1) | 1, d_square, threadID);
			}
		}
		else 
		{
			FullHeap(center, (index << 1) | 1, d_square, threadID);
			if(sigma*sigma < d_square) 
			{
				FullHeap(center, index << 1, d_square, threadID);
			}
		}

	}

	double sigma_square = (m_treeArray[index].photon.position - center).getSqLength();
	if(sigma_square < d_square)
	{
		if(m_photonsHeaps[threadID].Size() >= GLOBAL_PROPERTIES::kNearest) 
		{
			m_photonsHeaps[threadID].RemoveMax();
			m_photonsHeaps[threadID].Add(HeapElement(sigma_square, m_treeArray[index].photon));
			d_square = m_photonsHeaps[threadID].GetMax().distance;
		} else {
			m_photonsHeaps[threadID].Add(HeapElement(sigma_square, m_treeArray[index].photon));
		}
		
	}
}
 //! \brief Add a task to execute
 void addTask(Task& tsk) {
   lock();
   if(_tasks.append(tsk)) {
       PrivateTask& ptsk = _tasks.get(_tasks.indexOf(tsk));
       ptsk.setNextCall(_current + ptsk.period());
       TaskManager::instance()._heap.insert(HeapElement(ptsk));
     }
   unlock();
 }
 //! \brief Remove a Task
 void rmTask(Task& tsk) {
   lock();
   if(_tasks.remove(tsk)) {
       TaskManager::instance()._heap.flush();
       _tasks.doForeach([](PrivateTask& tsk) {
         TaskManager::instance()._heap.insert(HeapElement(tsk));
       });
     }
   unlock();
 }