13 #include <catch2/catch_test_macros.hpp>
14 #include <catch2/matchers/catch_matchers_floating_point.hpp>
23 double step = (b - a) /
n;
25 for (
int i = 0;
i <
n;
i++) {
36 double segment_length{1.0e-6};
37 double segment_start_val{1.0e-6};
38 std::array<double, 3> segment_start = std::array<double, 3>{0.0, 0.0, segment_start_val};
39 std::array<double, 3> segment_end =
40 paxpy(segment_start, 1.0, std::array<double, 3>{0.0, 0.0, segment_length});
44 std::array<double, 10> vals;
45 double circling_radius{1.0e-6};
46 std::array<double, 3> segment_middle{0.0, 0.0, 1.5e-6};
47 double medium_resistivity_fac{1.0};
48 for (
auto k = 0;
k < 10;
k++) {
49 std::array<double, 3> approaching_elec =
50 paxpy(segment_middle, 1.0, std::array<double, 3>{0.0, 1.0e-5 -
k * 1.0e-6, 0.0});
51 std::array<double, 3> circling_elec =
54 std::array<double, 3>{0.0,
59 approaching_elec, segment_start, segment_end,
floor, medium_resistivity_fac);
61 circling_elec, segment_start, segment_end,
floor, medium_resistivity_fac);
62 double numeric_circling_lfp =
integral(
64 return 1.0 / std::max(
floor,
69 paxpy(segment_start, -1.0, segment_end)))));
75 std::clog <<
"ANALYTIC line source " << analytic_circling_lfp
76 <<
" vs NUMERIC line source LFP " << numeric_circling_lfp <<
"\n";
77 REQUIRE_THAT(analytic_circling_lfp,
78 Catch::Matchers::WithinRel(numeric_circling_lfp,
79 std::numeric_limits<float>::epsilon() * 100.));
81 if (approaching_elec[1] < 0.866e-6) {
82 REQUIRE(analytic_approaching_lfp == 1.0e6);
84 vals[
k] = analytic_circling_lfp;
87 for (
size_t k = 0;
k < 5;
k++) {
88 REQUIRE(std::abs((vals[
k] - vals[
k + 5]) /
89 std::max(std::abs(vals[
k]), std::abs(vals[
k + 5]))) < 1.0e-12);
91 std::vector<std::array<double, 3>> segments_starts = {{0., 0., 1.},
95 std::vector<std::array<double, 3>> segments_ends = {{0., 0., 0.},
99 std::vector<double> radii{0.1, 0.1, 0.1, 0.1};
100 std::vector<std::array<double, 3>> electrodes = {{0.0, 0.3, 0.0}, {0.0, 0.7, 0.8}};
101 std::vector<int> indices = {0, 1, 2, 3};
103 lfp.template lfp<std::vector<double>>({0.0, 1.0, 2.0, 3.0});
104 std::vector<double> res_line_source = lfp.
lfp_values();
106 segments_starts, segments_ends, radii, indices, electrodes, 1.0);
107 lfpp.template lfp<std::vector<double>>({0.0, 1.0, 2.0, 3.0});
108 std::vector<double> res_point_source = lfpp.
lfp_values();
109 REQUIRE_THAT(res_line_source[0], Catch::Matchers::WithinAbs(res_point_source[0], 1.0));
110 REQUIRE_THAT(res_line_source[1], Catch::Matchers::WithinAbs(res_point_source[1], 1.0));
116 #ifdef ENABLE_SONATA_REPORTS
117 #define CATCH_CONFIG_MAIN
120 const std::string report_name =
"compartment_report";
121 const std::vector<uint64_t> gids = {42, 134};
122 const std::vector<int> segment_ids = {0, 1, 2, 3, 4};
123 std::vector<double> curr(segment_ids.size());
129 for (
const auto& gid: gids) {
131 for (
const auto& segment: segment_ids) {
132 std::vector<double> lfp_factors{segment + 1.0, segment + 2.0};
133 mapinfo->mappingvec.back()->add_segment_lfp_factor(segment, lfp_factors);
145 size_t offset_lfp = 0;
146 VarsToReport vars_to_report;
147 for (
const auto& gid: gids) {
148 std::vector<VarWithMapping> to_report;
151 for (
int electrode_id = 0; electrode_id < num_electrodes; electrode_id++) {
152 to_report.emplace_back(VarWithMapping(electrode_id,
mapinfo->_lfp.data() + offset_lfp));
155 if (!to_report.empty()) {
156 vars_to_report[gid] = to_report;
163 for (
const auto& segment_id: segment_ids) {
164 curr[segment_id] = (segment_id + 1) / 10.0;
166 .currents_[segment_id]
167 .push_back(std::make_pair(curr.data() + segment_id, -1));
171 std::vector<double>
currents = {0.2, 0.4, 0.6, 0.8, 1.0};
175 const double dt = 0.025;
176 const double tstart = 0.0;
177 const double report_dt = 0.1;
180 ReportEvent event(
dt, tstart, vars_to_report, report_name.data(), report_dt, report_type);
183 REQUIRE_THAT(
mapinfo->_lfp[0], Catch::Matchers::WithinAbs(5.5, 1.0));
184 REQUIRE_THAT(
mapinfo->_lfp[3], Catch::Matchers::WithinAbs(7.0, 1.0));
Point3D paxpy(const Point3D &p1, const double alpha, const Point3D &p2)
double norm(const Point3D &p1)
double line_source_lfp_factor(const Point3D &e_pos, const Point3D &seg_0, const Point3D &seg_1, const double radius, const double f)
THIS FILE IS AUTO GENERATED DONT MODIFY IT.
NrnMappingInfo mapinfo
mapping information
int const size_t const size_t n
void nrnmpi_init(int nrnmpi_under_nrncontrol, int *pargc, char ***pargv)
CellMapping * get_cell_mapping(int gid)
get cell mapping information for given gid if exist otherwise return NULL.
Compartment mapping information for a cell.
std::unordered_map< int, std::vector< double > > lfp_factors
map containing segment ids an its respective lfp factors
int num_electrodes() const
return the number of electrodes in the lfp_factors map
LFPCalculator allows calculation of LFP given membrane currents.
const std::vector< double > & lfp_values() const noexcept
NrnFastImem * nrn_fast_imem
std::unique_ptr< SummationReportMapping > summation_report_handler_
Compartment mapping information for NrnThread.
double integral(F f, double a, double b, int n)
TEST_CASE("LFP_PointSource_LineSource")