double* ForwardEulerSolver::SolveEquation(){
    double* output = new double[GetIterationNumber()];
    double y = GetInitialValue();
    output[0] = y;
    
    for (int i = 1; i < GetIterationNumber(); ++i) {
        output[i] = y + GetStepSize()*RightHandSide(y, GetInitialTime() + i*GetStepSize());
        y = output[i];
    }
    return output;
}
Exemple #2
0
double RungeKuttaSolver::SolveEquation()
{
    double h = GetStepSize();
    double t_previous = GetInitialTime();
    double t1 = GetFinalTime();
    double y_previous = getInitialValue();

    double y_current = getInitialValue();
    double k1, k2, k3, k4;

    while (t_previous + h < t1)
    {
        k1 = h * RightHandSide(y_previous, t_previous);
        k2 = h * RightHandSide(y_previous + 0.5 * k1, t_previous + 0.5 * h);
        k3 = h * RightHandSide(y_previous + 0.5 * k2, t_previous + 0.5 * h);
        k4 = h * RightHandSide(y_previous + k3, t_previous + h);

        y_current = y_previous + (1.0 / 6.0) * (k1 + 2 * k2 + 2 * k3 + k4);

        t_previous += h;
        y_previous = y_current;
    }

    return y_current;
}
ForwardEulerSolver::ForwardEulerSolver(int N, double startTime, double endTime, double initialValue){
    if (endTime > startTime){
        if (N > 1){
            SetIterationNumber(N);
            SetInitialValue(initialValue);
            SetTimeInterval(startTime, endTime);
            SetStepSize((endTime - startTime)/(N - 1));
            double* output = SolveEquation();
            for (int i = 0; i < GetIterationNumber(); ++i) {
                std::cout << output[i] << " " << GetInitialTime() + i*GetStepSize() << " " << test(GetInitialTime() + i*GetStepSize())<< "\n";
            }
        }
        else{
            std::cerr << "The number of iterations needs to be > 1!!\n";
        }
    }
    else{
        std::cerr << "Final time needs to be after initial!!\n";
    }
}
void RungeKuttaSolver::SolveEquation(std::ostream& stream)
{
	double y = GetInitialValue();

	double t = GetInitialTime();

	double h = GetStepSize();
	assert(h > 1e-6);
	std::cout << "Step size: " << h << std::endl;

	int n = static_cast<int>(
			std::floor((GetFinalTime() - GetInitialTime()) / h));

	stream << t << " " << y << "\n";

	for (int i = 1; i <= n; ++i) {
		double k1 = h * RightHandSide(y, t);
		double k2 = h * RightHandSide(y + 0.5 * k1, t + 0.5 * h);
		double k3 = h * RightHandSide(y + 0.5 * k2, t + 0.5 * h);
		double k4 = h * RightHandSide(y + k3, t + h);

		double temp = y + 1.0/6.0 * (k1 + 2 * k2 + 2 * k3 + k4);
		if (-1e-6 <= temp && temp <= 0.0) {
			y = 0.0;
		} else if (1.0 <= temp && temp <= (1.0 + 1e-6) ) {
			y = 1.0;
		} else if (0.0 < temp && temp < 1.0) {
			y = temp;
		} else {
			// Freak out!
			throw Exception("STEP", "Step size too large.");
		}
		t += h;

		stream << t << " " << y << "\n";
	}
}
Exemple #5
0
	void cGame::Run()
	{
		//Log line that ends user init.
		Log("--------------------------------------------------------\n\n");
		
		bool bDone = false;
		double fNumOfTimes=0;
		double fMediumTime=0;

		mpUpdater->OnStart();
		
		mpLogicTimer->Reset();

		//Loop the game... fix the var...
		unsigned long lTempTime = GetApplicationTime();
		
		//reset the mouse, really reset the damn thing :P
		for(int i=0;i<10;i++) mpInput->GetMouse()->Reset();
		
		
		Log("Game Running\n");
		Log("--------------------------------------------------------\n");

		mfFrameTime = 0;
		unsigned long lTempFrameTime = GetApplicationTime();
		
		bool mbIsUpdated = true;
		
		//cMemoryManager::SetLogCreation(true);

		while(!mbGameIsDone)
		{
			//Log("-----------------\n");
			//////////////////////////
			//Update logic.
			while(mpLogicTimer->WantUpdate() && !mbGameIsDone)
			{
				unsigned int lUpdateTime = GetApplicationTime();
				
				mpUpdater->Update(GetStepSize());
				
				unsigned int lDeltaTime = GetApplicationTime() - lUpdateTime;
				mfUpdateTime = (float)(lDeltaTime) / 1000.0f;

				mbIsUpdated = true;

				glClearUpdateCheck++;
				if(glClearUpdateCheck % 500 == 0)
				{
					if(mpUpdater->GetCurrentContainerName() == "Default") ClearUpdateLogFile();
				}

				mfGameTime += GetStepSize();
			}
			mpLogicTimer->EndUpdateLoop();

			
			//If not making a single rendering is better to use gpu and 
			//cpu at the same time and make query checks etc after logic update.
			//If any delete has occured in the update this might crash. so skip it for now.
			/*if(mbRenderOnce==false)	{
				mpGraphics->GetRenderer3D()->FetchOcclusionQueries();
				mpUpdater->OnPostBufferSwap();
			}*/
			
			//Draw graphics!
			if(mbRenderOnce && bDone)continue;
			if(mbRenderOnce)bDone = true;
			
			
			if(mbIsUpdated)
			{
				mpScene->UpdateRenderList(mfFrameTime);
				if(mbLimitFPS==false) mbIsUpdated = false;
			}
			
			if(mbLimitFPS==false || mbIsUpdated)
			{
				//LogUpdate("----------- RENDER GFX START --------------\n");

				mbIsUpdated = false;

           		//Get the the from the last frame.
				mfFrameTime = ((float)(GetApplicationTime() - lTempFrameTime))/1000;
				lTempFrameTime = GetApplicationTime();
				
				//Draw this frame
				//unsigned long lFTime = GetApplicationTime();
				mpUpdater->OnDraw();
				mpScene->Render(mpUpdater,mfFrameTime);
				//if(mpScene->GetDrawScene()) LogUpdate("FrameTime: %d ms\n", GetApplicationTime() - lFTime);
				
				//Update fps counter.
				mpFPSCounter->AddFrame();
	           	
				//Update the screen.
				mpGraphics->GetLowLevel()->SwapBuffers();
				//Log("Swap done: %d\n", GetApplicationTime());
				//if(mbRenderOnce)
				{
					mpScene->FetchOcclusionQueries();
					mpUpdater->OnPostBufferSwap();
				}
				
				fNumOfTimes++;
			}

			//if(cMemoryManager::GetLogCreation())
			//{
				//cMemoryManager::SetLogCreation(false);
				//Log("----\nCreations made: %d\n------\n",cMemoryManager::GetCreationCount());
			//}
		}
		Log("--------------------------------------------------------\n\n");
	
		Log("Statistics\n");
		Log("--------------------------------------------------------\n");

		unsigned long lTime = GetApplicationTime() - lTempTime;
		fMediumTime = fNumOfTimes/(((double)lTime)/1000);
		
		Log(" Medium framerate: %f\n", fMediumTime);
		Log("--------------------------------------------------------\n\n");

		Log("User Exit\n");
		Log("--------------------------------------------------------\n");
		
		mpUpdater->OnExit();
	}
Exemple #6
0
//All the *_grad is the gradient of pos_score - neg_score w.r.t. the parameter *
void CRelation::TrainRelatTriple(int head, bool head_is_word, int r, int tail)
{
	real head_grads[MAX_EMBEDDING_SIZE], tail_grads[MAX_EMBEDDING_SIZE], grads_tmp[MAX_EMBEDDING_SIZE], relat_grads[MAX_EMBEDDING_SIZE], negh_grads[MAX_EMBEDDING_SIZE], negt_grads[MAX_EMBEDDING_SIZE], negr_grads[MAX_EMBEDDING_SIZE];
	real head_left_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], head_right_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], tail_left_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], tail_right_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK];
	real negr_head_left_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], negr_head_right_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], negr_tail_left_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK], negr_tail_right_mat_grads[MAX_EMBEDDING_SIZE * MAX_RELAT_RANK];
	
	real head_mat_grads[MAX_RELAT_RANK], tail_mat_grads[MAX_RELAT_RANK]; 
	real negr_head_mat_grads[MAX_RELAT_RANK], negr_tail_mat_grads[MAX_RELAT_RANK]; //Used for the diag case

	real off_vec[MAX_EMBEDDING_SIZE], neg_off_vec[MAX_EMBEDDING_SIZE];
	real Qh_h[MAX_RELAT_RANK], Qh_negh[MAX_RELAT_RANK], Qt_t[MAX_RELAT_RANK], Qt_negt[MAX_RELAT_RANK];
	real PhT_offvec[MAX_RELAT_RANK], PtT_offvec[MAX_RELAT_RANK];
	
	memset(head_grads, 0, sizeof(real)* Opt::embeding_size);
	memset(tail_grads, 0, sizeof(real)* Opt::embeding_size);
	memset(relat_grads, 0, sizeof(real)* Opt::embeding_size);
	memset(negh_grads, 0, sizeof(real)* Opt::embeding_size);
	memset(negt_grads, 0, sizeof(real)* Opt::embeding_size);
	memset(negr_grads, 0, sizeof(real)* Opt::embeding_size);

	if (Opt::update_mat && !Opt::is_diag)
	{
		memset(head_left_mat_grads, 0, sizeof(real)* Opt::head_relat_rank * Opt::embeding_size);
		memset(head_right_mat_grads, 0, sizeof(real)* Opt::head_relat_rank * Opt::embeding_size);

		if (Opt::use_tail_mat)
		{
			memset(tail_left_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::tail_relat_rank);
			memset(tail_right_mat_grads, 0, sizeof(real)* Opt::tail_relat_rank * Opt::embeding_size);
		}

		memset(negr_head_left_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::head_relat_rank);
		memset(negr_head_right_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::head_relat_rank);

		if (Opt::use_tail_mat)
		{
			memset(negr_tail_left_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::tail_relat_rank);
			memset(negr_tail_right_mat_grads, 0, sizeof(real)* Opt::embeding_size * Opt::tail_relat_rank);
		}
	}

	if (Opt::update_mat && Opt::is_diag)
	{
		memset(head_mat_grads, 0, sizeof(real)* Opt::embeding_size);
		memset(tail_mat_grads, 0, sizeof(real)* Opt::embeding_size);
		memset(negr_head_mat_grads, 0, sizeof(real)* Opt::embeding_size);
		memset(negr_tail_mat_grads, 0, sizeof(real)* Opt::embeding_size);
	}

	//Sample neg head word and neg tail word
	int neg_head, neg_tail, neg_r;
	do
	{
		neg_head = SampleWordIdx();
	} while (neg_head == head || neg_head == tail);

	do
	{
		neg_tail = SampleWordIdx();
	} while (neg_tail == head || neg_tail == tail);

	do
	{
		neg_r = SampleRelatIdx();
	} while (neg_r == r);

	real* head_embedding = WordParams::p_embedding[head];
	real* tail_embedding = WordParams::p_embedding[tail];
	real* relat_embedding = p_relat_emb[r];
	real* relat_act_embedding = Opt::act_relat ? p_relat_act_emb[r] : NULL;

	real* neg_head_embedding = WordParams::p_embedding[neg_head];
	real* neg_tail_embedding = WordParams::p_embedding[neg_tail];
	real* neg_r_embedding = p_relat_emb[neg_r];
	real* neg_r_act_embedding = Opt::act_relat ? p_relat_act_emb[neg_r] : NULL;

	real pos_score = ComputeScore(head, r, tail, Qh_h, Qt_t, off_vec); 
	real negh_score = ComputeScore(neg_head, r, tail, Qh_negh, Qt_t, neg_off_vec);
	
	real hgap;
	bool is_negh_margin_satisfied;

	hgap = negh_score - pos_score;
	is_negh_margin_satisfied = hgap > Opt::margin;
	if (!is_negh_margin_satisfied) //margin is not satisfied
		ComputeGradient(1, Opt::relat_neg_weight, r, grads_tmp, negh_grads, tail_grads, relat_grads,
			head_left_mat_grads, head_right_mat_grads, tail_left_mat_grads, tail_right_mat_grads,
			neg_off_vec, Qh_negh, Qt_t, PhT_offvec, PtT_offvec, neg_head_embedding, tail_embedding,
			head_mat_grads, tail_mat_grads);
	
	//Begin updating the loss and grads for ||LR(h - t)||_2^2 - ||LR(h - negt)||_2^2
	real negt_score = ComputeScore(head, r, neg_tail, Qh_h, Qt_negt, neg_off_vec);
	real tgap;
	bool is_negt_margin_satisfied;

	tgap = negt_score - pos_score;
	is_negt_margin_satisfied = tgap > Opt::margin;
	if (!is_negt_margin_satisfied)
		ComputeGradient(1, Opt::relat_neg_weight, r, grads_tmp, head_grads, negt_grads, relat_grads,
			head_left_mat_grads, head_right_mat_grads, tail_left_mat_grads, tail_right_mat_grads, neg_off_vec,
			Qh_h, Qt_negt, PhT_offvec, PtT_offvec, head_embedding, neg_tail_embedding,
			head_mat_grads, tail_mat_grads);
	
	real negr_score = ComputeScore(head, neg_r, tail, Qh_negh, Qt_negt, neg_off_vec);
	real rgap;
	bool is_negr_margin_satisfied = true;;
	
	rgap = negr_score - pos_score;
	is_negr_margin_satisfied = rgap > Opt::margin;
	if (!is_negr_margin_satisfied)
		ComputeGradient(1, Opt::relat_neg_weight, neg_r, grads_tmp, head_grads, tail_grads, negr_grads,
			negr_head_left_mat_grads, negr_head_right_mat_grads, negr_tail_left_mat_grads, negr_tail_right_mat_grads, neg_off_vec,
			Qh_negh, Qt_negt, PhT_offvec, PtT_offvec, head_embedding, tail_embedding,
			negr_head_mat_grads, negr_tail_mat_grads);
	
	if (!Opt::sig_relat && is_negh_margin_satisfied && is_negt_margin_satisfied && is_negr_margin_satisfied)
		return;

	int effect_cnt = (is_negh_margin_satisfied ? 0 : 1) + (is_negt_margin_satisfied ? 0 : 1) + (is_negr_margin_satisfied ? 0 : 1);
	ComputeGradient(-1, effect_cnt, r, grads_tmp, head_grads, tail_grads, relat_grads,
		head_left_mat_grads, head_right_mat_grads, tail_left_mat_grads, tail_right_mat_grads, off_vec,
		Qh_h, Qt_t, PhT_offvec, PtT_offvec, head_embedding, tail_embedding,
		head_mat_grads, tail_mat_grads);

	//Gradient Checking
	/*real gap = (is_negh_margin_satisfied ? 0 : negh_score - pos_score) + (is_negt_margin_satisfied ? 0 : negt_score - pos_score) + (is_negr_margin_satisfied ? 0 : negr_score - pos_score);

	
	if (rand() < 20)
	{
		const double epsilon = 1e-6;
		//head_embedding[idx] += epsilon;
		//p_head_left_mat[r][idx] += epsilon;
		//p_tail_right_mat[r][idx] += epsilon;
		//tail_embedding[idx] += epsilon;
		//p_actual_left_mat[r][idx] = 2 * Util::Sigmoid(p_left_mat[r][41]) - 1;
		//p_tail_left_mat[r][idx] += epsilon;
		//p_head_left_mat[neg_r][idx] += epsilon;
		//p_actual_right_mat[r][idx] = 2 * Util::Sigmoid(p_right_mat[r][idx]) - 1;
		//p_relat_emb[neg_r][idx] += epsilon;
		//p_relat_act_emb[neg_r][idx] = 2 * Util::Sigmoid(p_relat_emb[neg_r][idx]) - 1;

		idx = -1;
		for (auto x : tail_diag_mat_ele[r])
			idx = x.first;

		printf("\n");

		tail_diag_mat_ele[neg_r][idx] += epsilon;
		
		real new_gap = 0, pos_score = ComputeLoss(head, tail, r);
		//ComputeLoss(head, tail, neg_r) - ComputeLoss(head, tail, r);
		real neg_gap = ComputeLoss(neg_head, tail, r) - pos_score;
		if (neg_gap <= Opt::margin)
			new_gap += neg_gap;
		neg_gap = ComputeLoss(head, neg_tail, r) - pos_score;
		if (neg_gap <= Opt::margin)
			new_gap += neg_gap;
		neg_gap = ComputeLoss(head, tail, neg_r) - pos_score;
		if (neg_gap <= Opt::margin)
			new_gap += neg_gap;

		printf("real gradient: %.5f, our gradient %.5f, idx:%d\n", (new_gap - gap) / epsilon, negr_tail_mat_grads[idx], idx);
		//p_tail_right_mat[r][idx] -= epsilon;
		//p_head_left_mat[neg_r][idx] -= epsilon;
		//tail_embedding[idx] -= epsilon;
		//p_actual_right_mat[r][idx] = 2 * Util::Sigmoid(p_right_mat[r][idx]) - 1;
		//head_embedding[idx] -= epsilon;
		//p_relat_emb[neg_r][idx] -= epsilon;
		//p_relat_act_emb[neg_r][idx] = 2 * Util::Sigmoid(p_relat_emb[neg_r][idx]) - 1;
		//p_actual_left_mat[neg_r][idx] = 2 * Util::Sigmoid(p_left_mat[r][41]) - 1;
		tail_diag_mat_ele[neg_r][idx] -= epsilon;
	}*/

	double step_size = GetStepSize(head, r, tail);
	step_size /= effect_cnt;

	Util::MatPlusMat(relat_embedding, relat_grads, step_size, Opt::embeding_size, 1);
	
	Util::MatPlusMat(head_embedding, head_grads, step_size, Opt::embeding_size, 1);
	
	Util::MatPlusMat(tail_embedding, tail_grads, step_size, Opt::embeding_size, 1);

	if (!is_negt_margin_satisfied)
		Util::MatPlusMat(neg_tail_embedding, negt_grads, step_size, Opt::embeding_size, 1);

	if (!is_negh_margin_satisfied)
		Util::MatPlusMat(neg_head_embedding, negh_grads, step_size, Opt::embeding_size, 1);

	if (!is_negr_margin_satisfied)
		Util::MatPlusMat(neg_r_embedding, negr_grads, step_size, Opt::embeding_size, 1);

	if (Opt::update_mat && !Opt::is_diag)
	{
		Util::MatPlusMat(p_head_left_mat[r], head_left_mat_grads, step_size, Opt::embeding_size, Opt::head_relat_rank);
		Util::MatPlusMat(p_head_right_mat[r], head_right_mat_grads, step_size, Opt::head_relat_rank, Opt::embeding_size);
		if (Opt::use_tail_mat)
		{
			Util::MatPlusMat(p_tail_left_mat[r], tail_left_mat_grads, step_size, Opt::embeding_size, Opt::tail_relat_rank);
			Util::MatPlusMat(p_tail_right_mat[r], tail_right_mat_grads, step_size, Opt::tail_relat_rank, Opt::embeding_size);
		}

		if (!is_negr_margin_satisfied)
		{
			Util::MatPlusMat(p_head_left_mat[neg_r], negr_head_left_mat_grads, step_size, Opt::embeding_size, Opt::head_relat_rank);
			Util::MatPlusMat(p_head_right_mat[neg_r], negr_head_right_mat_grads, step_size, Opt::embeding_size, Opt::head_relat_rank);
			if (Opt::use_tail_mat)
			{
				Util::MatPlusMat(p_tail_left_mat[neg_r], negr_tail_left_mat_grads, step_size, Opt::embeding_size, Opt::tail_relat_rank);
				Util::MatPlusMat(p_tail_right_mat[neg_r], negr_tail_right_mat_grads, step_size, Opt::embeding_size, Opt::tail_relat_rank);
			}
		}
	}
	else if (Opt::update_mat && Opt::is_diag)
	{
		for (auto x : head_diag_mat_ele[r])
			head_diag_mat_ele[r][x.first] += step_size *  head_mat_grads[x.first];
		if (Opt::use_tail_mat)
			for (auto x : tail_diag_mat_ele[r])
				tail_diag_mat_ele[r][x.first] += step_size * tail_mat_grads[x.first];
		if (!is_negr_margin_satisfied)
		{
			for (auto x : head_diag_mat_ele[neg_r])
				head_diag_mat_ele[neg_r][x.first] += step_size *  negr_head_mat_grads[x.first];
			if (Opt::use_tail_mat)
				for (auto x : tail_diag_mat_ele[neg_r])
					tail_diag_mat_ele[neg_r][x.first] += step_size * negr_tail_mat_grads[x.first];
		}
	}

	ConstrainParameters(r);
	if (!is_negr_margin_satisfied)
		ConstrainParameters(neg_r);
}
CDrawingObject* CPathLine::Duplicate() const
{
	CPathLine* pRetVal = new CPathLine(GetOrigin(), GetMaxIntegrationLen(), GetStartFrame(), GetArrowSize(), GetColor(), GetStepSize());
	
	pRetVal->CopyVertices(this);
	pRetVal->CopyParams(this);

	pRetVal->CalcBoundingRect();

	return pRetVal;
}
void KVVAMOSReconGeoNavigator::ParticleEntersNewVolume(KVNucleus* nuc)
{
   // Overrides method in KVGeoNavigator base class.
   // Every time a particle enters a new volume, we check the material to see
   // if it is known (i.e. contained in the range table fRangeTable).
   // If so, then we calculate the step through the material (STEP) of the nucleus
   // and the distance (DPATH in cm) between the intersection point at the focal plane
   // and the point at the entrance of the volume if it is the first active volume of a detector.
   // DPATH has the sign + if the volume is behind the focal plane or - if it
   // is at the front of it.
   //

   KVVAMOSReconNuc* rnuc = (KVVAMOSReconNuc*)nuc;

   // stop the propagation if the current volume is the stopping detector
   // of the nucleus but after the process of this volume
   if (rnuc->GetStoppingDetector()) {
      TGeoVolume* stopVol = (TGeoVolume*)((KVVAMOSDetector*)rnuc->GetStoppingDetector())->GetActiveVolumes()->Last();

      if (GetCurrentVolume() == stopVol) SetStopPropagation();
   }

   if (fDoNothing) return;


   TGeoMaterial* material = GetCurrentVolume()->GetMaterial();
   KVIonRangeTableMaterial* irmat = 0;

   // skip the process if the current material is unkown
   if ((irmat = fRangeTable->GetMaterial(material))) {

      KVString dname;
      Bool_t multi;
      TString absorber_name;
      Bool_t is_active = kFALSE;
      if (GetCurrentDetectorNameAndVolume(dname, multi)) {
         is_active = kTRUE;
         if (multi) {
            absorber_name.Form("%s/%s", dname.Data(), GetCurrentNode()->GetName());
            is_active = absorber_name.Contains("ACTIVE_");
         } else absorber_name = dname;
      } else
         absorber_name = irmat->GetName();

      // Coordinates of the vector between the intersection point at the
      // focal plane and the point at the entrance of the current detector
      Double_t X = GetEntryPoint().X() - fOrigine.X();
      Double_t Y = GetEntryPoint().Y() - fOrigine.Y();
      Double_t Z = GetEntryPoint().Z() - fOrigine.Z();

      // Norm of this vector. The signe gives an infomation about the detector position
      // (1: behind; -1: in front of) with respect to the focal plane.
      Double_t Delta = TMath::Sign(1., Z) * TMath::Sqrt(X * X + Y * Y + Z * Z);

      if ((fCalib & kECalib) || (fCalib & kTCalib)) {
         if (fE > 1e-3) {

            // velocity before material
            Double_t Vi = nuc->GetVelocity().Mag();

            // energy lost in the material
            Double_t DE = irmat->GetLinearDeltaEOfIon(
                             nuc->GetZ(), nuc->GetA(), fE, GetStepSize(), 0.,
                             material->GetTemperature(),
                             material->GetPressure());
            fE -= DE;
            nuc->SetEnergy(fE);

            //set flag to say that particle has been slowed down
            nuc->SetIsDetected();

            // velocity after material
            Double_t Vf = nuc->GetVelocity().Mag();

            if (fCalib & kTCalib) {
               //from current start point to the entrance point
               fTOF += (Delta - fStartPath) / Vi;
               fStartPath = Delta;

               //nuc->GetParameters()->SetValue(Form("TOF:%s",absorber_name.Data()), fTOF);
               if (is_active) nuc->GetParameters()->SetValue(Form("TOF:%s", dname.Data()), fTOF);
               else if ((fCalib & kFullTCalib) == kFullTCalib) nuc->GetParameters()->SetValue(Form("TOF:%s", absorber_name.Data()), fTOF);


               // from the entrance to the exit of the material
               Double_t step = GetStepSize();
               fTOF += CalculateLinearDeltaT(Vi, Vf, step);
               fStartPath += step;
            }

            if (fCalib & kECalib) {
               if (is_active) nuc->GetParameters()->SetValue(Form("DE:%s", dname.Data()), DE);
               else if ((fCalib & kFullECalib) == kFullECalib) nuc->GetParameters()->SetValue(Form("DE:%s", absorber_name.Data()), DE);
            }
         }
      }

      if (is_active)  nuc->GetParameters()->SetValue(Form("DPATH:%s", dname.Data()), Delta);
      else if ((fCalib & kFullTCalib) == kFullTCalib) nuc->GetParameters()->SetValue(Form("DPATH:%s", absorber_name.Data()), Delta);
      nuc->GetParameters()->SetValue(Form("STEP:%s", absorber_name.Data()), GetStepSize());

   }
}