void TestOdeSolverForFox2002WithRegularStimulus(void) throw (Exception) { clock_t ck_start, ck_end; // Set stimulus double magnitude = -80.0; double duration = 1.0 ; // ms double start = 50.0; // ms double period = 500; // ms boost::shared_ptr<RegularStimulus> p_stimulus(new RegularStimulus(magnitude, duration, period, start)); double end_time = 1000.0; //One second in milliseconds HeartConfig::Instance()->SetOdeTimeStep(0.002); // 0.005 leads to NaNs. boost::shared_ptr<EulerIvpOdeSolver> p_solver(new EulerIvpOdeSolver); CellFoxModel2002FromCellML fox_ode_system(p_solver, p_stimulus); // Solve and write to file ck_start = clock(); RunOdeSolverWithIonicModel(&fox_ode_system, end_time, "FoxRegularStimLong", 500); ck_end = clock(); double forward = (double)(ck_end - ck_start)/CLOCKS_PER_SEC; CheckCellModelResults("FoxRegularStimLong"); // Solve using Backward Euler HeartConfig::Instance()->SetOdeTimeStep(0.01); CellFoxModel2002FromCellMLBackwardEuler backward_system(p_solver, p_stimulus); ck_start = clock(); RunOdeSolverWithIonicModel(&backward_system, end_time, "BackwardFoxRegularStimLong", 100); ck_end = clock(); double backward = (double)(ck_end - ck_start)/CLOCKS_PER_SEC; CompareCellModelResults("FoxRegularStimLong", "BackwardFoxRegularStimLong", 0.15); // Mainly for coverage, and to test consistency of GetIIonic TS_ASSERT_DELTA(fox_ode_system.GetIIonic(), backward_system.GetIIonic(), 1e-6); std::cout << "Run times:\n\tForward: " << forward << "\n\tBackward: " << backward << std::endl; }
/** * Here we test that the scale factors for the TT model do what they are expected to * We check that they modify APD in a way that is expected. */ void TestScaleFactorsForTT06(void) { double simulation_end=500;/*end time, in milliseconds for this model*/ // Set the stimulus, the following values are appropriate for single cell simulations of this model. double magnitude = -38.0; // pA/pF double duration = 1.0; // ms double start = 100; // ms boost::shared_ptr<SimpleStimulus> p_stimulus(new SimpleStimulus(magnitude, duration, start)); boost::shared_ptr<EulerIvpOdeSolver> p_solver(new EulerIvpOdeSolver); //define the solver HeartConfig::Instance()->SetOdeTimeStep(0.001);// with Forward Euler, this must be as small as 0.001. const std::string control_file = "TT_epi"; const std::string mid_file = "TT_mid"; const std::string endo_file = "TT_endo"; const std::string LQT_file = "TT_LQT"; CellTenTusscher2006EpiFromCellML TT_model_epi(p_solver, p_stimulus); TT_model_epi.SetParameter("ScaleFactorIto", 1.0); TT_model_epi.SetParameter("ScaleFactorGkr", 1.0); TT_model_epi.SetParameter("ScaleFactorGks", 1.0); //run the model RunOdeSolverWithIonicModel(&TT_model_epi, simulation_end, control_file, 100, false); CellTenTusscher2006EpiFromCellML TT_model_mid(p_solver, p_stimulus); TT_model_mid.SetParameter("ScaleFactorIto", 1.0); TT_model_mid.SetParameter("ScaleFactorGkr", 1.0); TT_model_mid.SetParameter("ScaleFactorGks", 0.25); RunOdeSolverWithIonicModel(&TT_model_mid, simulation_end, mid_file, 100, false); CellTenTusscher2006EpiFromCellML TT_model_endo(p_solver, p_stimulus); TT_model_endo.SetParameter("ScaleFactorIto", 0.165); TT_model_endo.SetParameter("ScaleFactorGkr", 1.0); TT_model_endo.SetParameter("ScaleFactorGks", 0.66); RunOdeSolverWithIonicModel(&TT_model_endo, simulation_end, endo_file, 100, false); CellTenTusscher2006EpiFromCellML TT_model_LQT(p_solver, p_stimulus); TT_model_LQT.SetParameter("ScaleFactorIto", 1.0); TT_model_LQT.SetParameter("ScaleFactorGkr", 0.0); TT_model_LQT.SetParameter("ScaleFactorGks", 1.0); RunOdeSolverWithIonicModel(&TT_model_LQT, simulation_end, LQT_file, 100, false); ColumnDataReader data_reader1("TestIonicModels", control_file); std::vector<double> voltages1 = GetVoltages(data_reader1); ColumnDataReader data_reader2("TestIonicModels", mid_file); std::vector<double> voltages2 = GetVoltages(data_reader2); ColumnDataReader data_reader3("TestIonicModels", endo_file); std::vector<double> voltages3 = GetVoltages(data_reader3); ColumnDataReader data_reader4("TestIonicModels", LQT_file); std::vector<double> voltages4 = GetVoltages(data_reader4); TS_ASSERT_EQUALS(voltages1.size(), voltages2.size()); TS_ASSERT_EQUALS(voltages2.size(), voltages3.size()); TS_ASSERT_EQUALS(voltages3.size(), voltages4.size()); //create the times vector std::vector<double> times; double k =0; for (unsigned i=0; i<voltages2.size(); i++) { times.push_back(k); k=k+0.1; } CellProperties cell_properties_control(voltages1, times); CellProperties cell_properties_mid(voltages2, times); CellProperties cell_properties_endo(voltages3, times); CellProperties cell_properties_LQT(voltages4, times); double control_APD = cell_properties_control.GetLastActionPotentialDuration(90); double mid_APD = cell_properties_mid.GetLastActionPotentialDuration(90); double endo_APD = cell_properties_endo.GetLastActionPotentialDuration(90); double LQT_APD = cell_properties_LQT.GetLastActionPotentialDuration(90); TS_ASSERT_DELTA(control_APD, 300.4789, 0.1); TS_ASSERT_DELTA(mid_APD, 392.1871, 0.1); TS_ASSERT_DELTA(endo_APD, 329.2048, 0.1); TS_ASSERT_DELTA(LQT_APD , 347.8374, 0.1); }
void TestSMCmodelModified(void) throw (Exception) { // Set stimulus (no stimulus in this case) double magnitude_stimulus = 0.0; // dimensionless double duration_stimulus = 0.05; // ms double start_stimulus = 0.01; // ms double period=1;// boost::shared_ptr<RegularStimulus> stimulus(new RegularStimulus(magnitude_stimulus, duration_stimulus, period, start_stimulus)); boost::shared_ptr<EulerIvpOdeSolver> solver(new EulerIvpOdeSolver); //define the solver HeartConfig::Instance()->SetOdePdeAndPrintingTimeSteps(0.1,0.1,1); CorriasBuistSMCModified smc_ode_system(solver, stimulus); TS_ASSERT_EQUALS(smc_ode_system.GetCarbonMonoxideScaleFactor(), 1.0); //coverage smc_ode_system.SetCarbonMonoxideScaleFactor(1.0);//coverage // Solve and write to file RunOdeSolverWithIonicModel(&smc_ode_system, 60000,/*end time, in milliseconds*/ "SMCmodel_modified", 1000); // Calculate APDs and compare with hardcoded values ColumnDataReader data_reader1("TestIonicModels", "SMCmodel_modified"); std::vector<double> voltages = data_reader1.GetValues("Vm_SM"); //create the times vector double k =0; std::vector<double> times; for (unsigned i=0; i<voltages.size(); i++) { times.push_back(k); k=k+100; } CellProperties cell_properties(voltages, times, -45.0);//note the lower threshold for SMC calculation of 'AP'); TS_ASSERT_DELTA(cell_properties.GetLastActionPotentialDuration(50), 8331.3835, 0.1); TS_ASSERT_DELTA(cell_properties.GetLastActionPotentialDuration(70), 8571.1671, 0.1); TS_ASSERT_DELTA(cell_properties.GetLastActionPotentialDuration(80), 8722.6543, 0.1); TS_ASSERT_DELTA(cell_properties.GetLastActionPotentialDuration(90), 8955.8126, 0.1); CorriasBuistSMCModified smc_ode_system_no_stim(solver, stimulus); //check the default value of the presence of ICC stimulus TS_ASSERT_EQUALS(smc_ode_system_no_stim.GetFakeIccStimulusPresent(), true); //Switch off ICC stimulus and check the voltage is almost flat smc_ode_system_no_stim.SetFakeIccStimulusPresent(false); //check member variable was switched correctly TS_ASSERT_EQUALS(smc_ode_system_no_stim.GetFakeIccStimulusPresent(), false); // Solve and write to file RunOdeSolverWithIonicModel(&smc_ode_system_no_stim, 60000,/*end time, in milliseconds*/ "SMCmodel_modified_nostim", 1000); // Calculate APDs and compare with hardcoded values ColumnDataReader data_reader2("TestIonicModels", "SMCmodel_modified_nostim"); std::vector<double> voltages_flat = data_reader2.GetValues("Vm_SM"); CellProperties cell_properties_2(voltages_flat, times, -45.0); //it should be flat now, no AP and cell properties should throw TS_ASSERT_THROWS_THIS(cell_properties_2.GetLastActionPotentialDuration(90), "AP did not occur, never exceeded threshold voltage."); }