11#ifndef FIMS_COMMON_INFORMATION_HPP
12#define FIMS_COMMON_INFORMATION_HPP
39template <
typename Type>
45 static std::shared_ptr<Information<Type>>
54 std::vector<std::string>
59 std::map<uint32_t, std::shared_ptr<fims_data_object::DataObject<Type>>>
61 typedef typename std::map<
62 uint32_t, std::shared_ptr<fims_data_object::DataObject<Type>>>::iterator
66 std::map<uint32_t, std::shared_ptr<fims_popdy::RecruitmentBase<Type>>>
69 typedef typename std::map<
70 uint32_t, std::shared_ptr<fims_popdy::RecruitmentBase<Type>>>::iterator
74 std::map<uint32_t, std::shared_ptr<fims_popdy::RecruitmentBase<Type>>>
77 typedef typename std::map<
78 uint32_t, std::shared_ptr<fims_popdy::RecruitmentBase<Type>>>::iterator
82 std::map<uint32_t, std::shared_ptr<fims_popdy::SelectivityBase<Type>>>
85 typedef typename std::map<
86 uint32_t, std::shared_ptr<fims_popdy::SelectivityBase<Type>>>::iterator
90 std::map<uint32_t, std::shared_ptr<fims_popdy::GrowthBase<Type>>>
94 typename std::map<uint32_t,
95 std::shared_ptr<fims_popdy::GrowthBase<Type>>>::iterator
99 std::map<uint32_t, std::shared_ptr<fims_popdy::MaturityBase<Type>>>
102 typedef typename std::map<
103 uint32_t, std::shared_ptr<fims_popdy::MaturityBase<Type>>>::iterator
108 std::map<uint32_t, std::shared_ptr<fims_popdy::Fleet<Type>>>
111 typedef typename std::map<uint32_t,
112 std::shared_ptr<fims_popdy::Fleet<Type>>>::iterator
117 std::map<uint32_t, std::shared_ptr<fims_popdy::Population<Type>>>
121 typename std::map<uint32_t,
122 std::shared_ptr<fims_popdy::Population<Type>>>::iterator
128 std::shared_ptr<fims_distributions::DensityComponentBase<Type>>>
131 typedef typename std::map<
133 std::shared_ptr<fims_distributions::DensityComponentBase<Type>>>::iterator
137 std::unordered_map<uint32_t,
138 std::shared_ptr<fims_popdy::FisheryModelBase<Type>>>
141 typedef typename std::unordered_map<
142 uint32_t, std::shared_ptr<fims_popdy::FisheryModelBase<Type>>>::iterator
145 std::unordered_map<uint32_t, fims::Vector<Type>*>
148 typedef typename std::unordered_map<uint32_t, fims::Vector<Type>*>::iterator
163 void ResetRecruitmentLinks() noexcept {
164 auto detach = [](
auto& models) {
165 for (
auto& entry : models) {
166 const auto& recruitment = entry.second;
168 recruitment->process.reset();
169 recruitment->recruitment.reset();
189 this->parameter_names.clear();
190 this->parameters.clear();
198 ResetRecruitmentLinks();
204 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
206 if ((d->priors)[0]) {
209 if (d->data_observed_values) {
210 d->data_observed_values.reset();
212 if (d->data_expected_values) {
213 d->data_expected_values->clear();
218 if (d->re_expected_values) {
219 d->re_expected_values->clear();
235 std::stringstream ss;
236 ss <<
"Information object State:\n";
238 ss <<
"populations: " << this->
populations.size() << std::endl;
241 ss <<
"fleets: " << this->
fleets.size() << std::endl;
242 ss <<
"growth_models: " << this->
growth_models.size() << std::endl;
243 ss <<
"maturity_models: " << this->
maturity_models.size() << std::endl;
244 ss <<
"parameter_names: " << this->parameter_names.size() << std::endl;
245 ss <<
"parameters: " << this->parameters.size() << std::endl;
248 ss <<
"random_effects_parameters: "
252 ss <<
"recruitment_process_models: "
256 ss <<
"models_map: " << this->
models_map.size() << std::endl;
257 ss <<
"n_years: " << this->n_years << std::endl;
258 ss <<
"n_ages: " << this->n_ages << std::endl;
272 std::make_shared<fims_info::Information<Type>>();
301 this->parameter_names.push_back(p_name);
320 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
322 if (d->input_type ==
"prior") {
323 FIMS_INFO_LOG(
"Setup prior for distribution " + fims::to_string(d->id));
325 FIMS_INFO_LOG(
"Link prior from distribution " + fims::to_string(d->id) +
326 " to parameter " + fims::to_string(d->key[0]));
327 d->priors.resize(d->key.size());
328 for (
size_t i = 0; i < d->key.size(); i++) {
330 fims::to_string(d->id) +
" to parameter " +
331 fims::to_string(d->key[0]));
333 d->priors[i] = (*vmit).second;
335 FIMS_INFO_LOG(
"Prior size for distribution " + fims::to_string(d->id) +
336 "is: " + fims::to_string(d->observed_values.size()));
348 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
350 if (d->input_type ==
"random_effects") {
352 fims::to_string(d->id));
355 fims::to_string(d->id) +
" to derived value " +
356 fims::to_string(d->key[0]));
358 d->re = (*vmit).second;
359 if (d->key.size() == 2) {
361 d->re_expected_values = (*vmit).second;
363 d->re_expected_values = &d->expected_values;
366 fims::to_string(d->id) +
367 " is: " + fims::to_string(d->observed_values.size()));
379 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
381 if (d->input_type ==
"data") {
382 FIMS_INFO_LOG(
"Setup expected value for data distribution " +
383 fims::to_string(d->id));
386 fims::to_string(d->id) +
" to derived value " +
387 fims::to_string(d->key[0]));
389 d->data_expected_values = (*vmit).second;
391 "Expected value size for distribution " + fims::to_string(d->id) +
392 " is: " + fims::to_string((*d->data_expected_values).size()));
406 if (f->fleet_observed_catch_data_id_m !=
static_cast<Type
>(-999)) {
407 uint32_t observed_catch_id =
408 static_cast<uint32_t
>(f->fleet_observed_catch_data_id_m);
411 f->observed_catch_data = (*it).second;
412 FIMS_INFO_LOG(
"Catch data for fleet " + fims::to_string(f->id) +
413 " successfully set to " +
414 fims::to_string(f->observed_catch_data->at(1)));
418 fims::to_string(f->id) +
", index " +
419 fims::to_string(observed_catch_id));
433 if (f->fleet_observed_index_data_id_m !=
static_cast<Type
>(-999)) {
434 uint32_t observed_index_id =
435 static_cast<uint32_t
>(f->fleet_observed_index_data_id_m);
438 f->observed_index_data = (*it).second;
439 FIMS_INFO_LOG(
"Index data for fleet " + fims::to_string(f->id) +
440 " successfully set to " +
441 fims::to_string(f->observed_index_data->at(1)));
445 fims::to_string(f->id) +
", index " +
446 fims::to_string(observed_index_id));
460 if (f->fleet_observed_agecomp_data_id_m !=
static_cast<Type
>(-999)) {
461 uint32_t observed_agecomp_id =
462 static_cast<uint32_t
>(f->fleet_observed_agecomp_data_id_m);
465 f->observed_agecomp_data = (*it).second;
466 FIMS_INFO_LOG(
"Observed input age-composition data for fleet " +
467 fims::to_string(f->id) +
" successfully set to " +
468 fims::to_string(f->observed_agecomp_data->at(1)));
472 "Expected age-composition observations not defined for fleet " +
473 fims::to_string(f->id));
487 if (f->fleet_observed_lengthcomp_data_id_m !=
static_cast<Type
>(-999)) {
488 uint32_t observed_lengthcomp_id =
489 static_cast<uint32_t
>(f->fleet_observed_lengthcomp_data_id_m);
492 f->observed_lengthcomp_data = (*it).second;
493 FIMS_INFO_LOG(
"Observed input length-composition data for fleet " +
494 fims::to_string(f->id) +
" successfully set to " +
495 fims::to_string(f->observed_lengthcomp_data->at(1)));
499 "Expected length-composition observations not defined for fleet " +
500 fims::to_string(f->id));
515 if (f->fleet_selectivity_id_m !=
static_cast<Type
>(-999)) {
516 uint32_t sel_id =
static_cast<uint32_t
>(
517 f->fleet_selectivity_id_m);
522 f->selectivity = (*it).second;
524 fims::to_string(f->fleet_selectivity_id_m) +
525 " successfully set to fleet " + fims::to_string(f->id));
528 FIMS_ERROR_LOG(
"Expected selectivity pattern not defined for fleet " +
529 fims::to_string(f->id) +
", selectivity pattern " +
530 fims::to_string(sel_id));
534 fims::to_string(f->id) +
535 ". FIMS requires selectivity be defined for all fleets "
536 "when running a catch at age model.");
552 if (p ==
nullptr || f ==
nullptr) {
555 "Unable to set fleet age-to-length conversion because the population "
557 "pointer was null.");
561 f->age_to_length_conversion_model =
564 if (f->age_to_length_conversion_model !=
nullptr &&
565 f->age_to_length_conversion_model->IsActive()) {
569 if (!f->requires_age_length_mapping) {
573 if (f->n_lengths == 0) {
576 " requires age-to-length conversion but has no fleet "
577 "length observation bins. Provide length_bin rows or "
578 "length_comp rows with length values.");
584 "Fleet " + fims::to_string(f->id) +
585 " has fleet length observation bins but no usable "
586 "age-to-length conversion path. Provide fixed "
587 "age-to-length conversion of size " +
588 fims::to_string(f->n_ages * f->n_lengths) +
589 " or use a supported growth-derived age-to-length conversion path.");
602 if (p->recruitment_id !=
static_cast<Type
>(-999)) {
603 uint32_t recruitment_uint =
static_cast<uint32_t
>(p->recruitment_id);
609 p->recruitment = (*it).second;
610 FIMS_INFO_LOG(
"Recruitment model " + fims::to_string(recruitment_uint) +
611 " successfully set to population " +
612 fims::to_string(p->id));
616 "Expected recruitment function not defined for "
618 fims::to_string(p->id) +
", recruitment function " +
619 fims::to_string(recruitment_uint));
623 "No recruitment function defined for population " +
624 fims::to_string(p->id) +
625 ". FIMS requires recruitment functions be defined for all "
626 "populations when running a catch at age model.");
640 std::shared_ptr<fims_popdy::RecruitmentBase<Type>> r = p->recruitment;
643 if (r->process_id !=
static_cast<Type
>(-999)) {
644 uint32_t process_uint =
static_cast<uint32_t
>(r->process_id);
649 r->process = (*it).second;
651 "Recruitment Process model " + fims::to_string(process_uint) +
652 " successfully set to population " + fims::to_string(p->id));
653 (*it).second->recruitment = r;
657 "Expected recruitment process function not defined for "
659 fims::to_string(p->id) +
", recruitment process function " +
660 fims::to_string(process_uint));
664 "No recruitment process function defined for population " +
665 fims::to_string(p->id) +
666 ". FIMS requires recruitment process functions be defined for all "
667 "recruitments when running a catch at age model.");
683 for (std::size_t fleet_index = 0; fleet_index < p->fleets.size();
685 const std::shared_ptr<fims_popdy::Fleet<Type>>& fleet =
686 p->fleets[fleet_index];
688 if (fleet ==
nullptr) {
692 if (!fleet->requires_age_length_mapping || fleet->n_lengths == 0) {
697 if (fleet->lengths.size() != fleet->n_lengths) {
698 throw std::runtime_error(
699 "Fleet length_bin centers are not consistent with n_lengths");
702 fleet->length_bin_edges =
729 fleet_edges.size() == 0) {
733 for (std::size_t population_bin_index = 0;
734 population_bin_index < size_grid.
n_bins; ++population_bin_index) {
735 const double population_left = size_grid.
edges[population_bin_index];
736 const double population_right = size_grid.
edges[population_bin_index + 1];
737 const double population_bin_width = population_right - population_left;
738 const double population_tolerance =
739 1e-12 * (population_bin_width > 1.0 ? population_bin_width : 1.0);
741 for (std::size_t fleet_index = 0; fleet_index < fleet_edges.size();
745 for (std::size_t fleet_bin_index = 1; fleet_bin_index < edges.
size();
747 const double fleet_left = edges[fleet_bin_index - 1];
748 const double fleet_right = edges[fleet_bin_index];
749 const double overlap_left = std::max(population_left, fleet_left);
750 const double overlap_right = std::min(population_right, fleet_right);
752 if (!(overlap_right > overlap_left)) {
756 const double fleet_bin_width = fleet_right - fleet_left;
757 if (population_bin_width > fleet_bin_width + population_tolerance) {
758 throw std::runtime_error(
759 "Population biological size grid contains at least one bin "
760 "that is coarser than an overlapping active fleet observation "
761 "bin. Provide a finer biological size-grid override or correct "
762 "the fleet bin setup.");
792 }
catch (
const std::exception& e) {
795 "Failed to prepare fleet observation-bin geometry for population " +
796 fims::to_string(p->id) +
": " + e.what());
800 if (p->size_grid.IsConsistent() && p->size_grid.n_bins > 0) {
803 }
catch (
const std::exception& e) {
806 "Population " + fims::to_string(p->id) +
807 " has a biological size grid that is incompatible with active "
808 "fleet observation bins: " +
814 const bool size_grid_missing = p->size_grid.n_bins == 0 &&
815 p->size_grid.edges.size() == 0 &&
816 p->size_grid.centers.size() == 0;
818 if (size_grid_missing) {
820 if (fleet_edges.
size() == 0) {
821 throw std::runtime_error(
822 "No resolvable fleet observation-bin geometry was available "
823 "to build the default biological size grid");
830 const std::size_t regular_bin_count =
831 p->size_grid.n_bins > 0 ? p->size_grid.n_bins - 1 : 0;
833 if (regular_bin_count > 200) {
835 "Built-in default biological size grid created more than 200 "
836 "regular bins for population " +
837 fims::to_string(p->id) +
838 ". This may slow model evaluation. Consider providing a "
839 "biological size-grid override if needed.");
842 }
catch (
const std::exception& e) {
845 "Failed to initialize default population size grid for "
847 fims::to_string(p->id) +
": " + e.what());
854 "Population " + fims::to_string(p->id) +
855 " has an invalid biological size grid. Provide a consistent override "
856 "or leave the grid empty so FIMS can build the default.");
869 growth_observation) {
870 std::shared_ptr<fims_popdy::GrowthDerivedSizeProvider<Type>> size_provider =
871 std::make_shared<fims_popdy::GrowthDerivedSizeProvider<Type>>();
873 size_provider->SetGrowth(growth_observation);
874 size_provider->SetPopulationDimensions(p->n_years, p->n_ages);
875 size_provider->SetPopulationSizeGrid(&(p->size_grid));
877 p->size_distribution_provider = size_provider;
890 if (p->growth_id !=
static_cast<Type
>(-999)) {
891 uint32_t growth_uint =
static_cast<uint32_t
>(p->growth_id);
902 growth_observation = std::dynamic_pointer_cast<
905 growth_observation->Initialize(p->n_years, p->n_ages, 1);
907 if (p->ages.size() > 0) {
908 double min_age = p->ages[0];
909 for (
size_t i = 1; i < p->ages.size(); ++i) {
910 if (p->ages[i] < min_age) {
911 min_age = p->ages[i];
914 growth_observation->SetAgeOffset(
static_cast<double>(min_age));
917 const bool population_has_size_grid_input =
918 p->size_grid.n_bins > 0 || p->size_grid.edges.size() > 0 ||
919 p->size_grid.centers.size() > 0;
921 bool any_length_based_fleet =
false;
922 for (std::size_t i = 0; i < p->fleets.size(); ++i) {
923 if (p->fleets[i] !=
nullptr &&
924 p->fleets[i]->requires_age_length_mapping &&
925 p->fleets[i]->n_lengths > 0) {
926 any_length_based_fleet =
true;
931 if (population_has_size_grid_input || any_length_based_fleet) {
939 FIMS_INFO_LOG(
"Growth model " + fims::to_string(growth_uint) +
940 " successfully set to population " +
941 fims::to_string(p->id));
944 FIMS_ERROR_LOG(
"Expected growth function not defined for population " +
945 fims::to_string(p->id) +
", growth function " +
946 fims::to_string(growth_uint));
950 fims::to_string(p->id) +
951 ". FIMS requires growth functions be defined for all "
952 "populations when running a catch at age model.");
966 if (p->maturity_id !=
static_cast<Type
>(-999)) {
967 uint32_t maturity_uint =
static_cast<uint32_t
>(p->maturity_id);
972 p->maturity = (*it).second;
973 FIMS_INFO_LOG(
"Maturity model " + fims::to_string(maturity_uint) +
974 " successfully set to population " +
975 fims::to_string(p->id));
979 "Expected maturity function not defined for population " +
980 fims::to_string(p->id) +
", maturity function " +
981 fims::to_string(maturity_uint));
985 fims::to_string(p->id) +
986 ". FIMS requires maturity functions be defined for all "
987 "populations when running a catch at age model.");
1000 std::shared_ptr<fims_popdy::Fleet<Type>> f = (*it).second;
1001 FIMS_INFO_LOG(
"Initializing fleet " + fims::to_string(f->id));
1024 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
1028 if (d->input_type ==
"data") {
1029 if (d->observed_data_id_m !=
static_cast<Type
>(-999)) {
1030 uint32_t observed_data_id =
1031 static_cast<uint32_t
>(d->observed_data_id_m);
1035 d->data_observed_values = (*it).second;
1036 FIMS_INFO_LOG(
"Observed data " + fims::to_string(observed_data_id) +
1037 " successfully set to density component " +
1038 fims::to_string(d->id));
1040 valid_model =
false;
1042 "Expected data observations not defined for density "
1044 fims::to_string(d->id) +
", observed data " +
1045 fims::to_string(observed_data_id));
1048 valid_model =
false;
1050 fims::to_string(d->id));
1065 std::shared_ptr<fims_popdy::Population<Type>> p = (*it).second;
1067 FIMS_INFO_LOG(
"Initializing population " + fims::to_string(p->id));
1069 typename std::set<uint32_t>::iterator fleet_ids_it;
1071 for (fleet_ids_it = p->fleet_ids.begin();
1072 fleet_ids_it != p->fleet_ids.end(); ++fleet_ids_it) {
1081 if (it != this->
fleets.end()) {
1083 std::shared_ptr<fims_popdy::Fleet<Type>> f = (*it).second;
1087 p->fleets.push_back(f);
1089 valid_model =
false;
1091 "\" undefined, not found for Population \"" +
1092 fims::to_string(p->id) +
"\". ");
1097 this->n_years = std::max(this->n_years, p->n_years);
1098 this->n_ages = std::max(this->n_ages, p->n_ages);
1105 for (
size_t i = 0; i < p->fleets.size(); ++i) {
1119 std::shared_ptr<fims_popdy::FisheryModelBase<Type>>& model = (*it).second;
1120 std::set<uint32_t>::iterator jt;
1122 for (jt = model->population_ids.begin();
1123 jt != model->population_ids.end(); ++jt) {
1127 std::shared_ptr<fims_popdy::Population<Type>> p = (*pt).second;
1128 model->populations.push_back(p);
1129 for (
size_t i = 0; i < p->fleets.size(); i++) {
1130 uint32_t local_fleet_id = p->fleets[i]->GetId();
1131 model->fleets[local_fleet_id] = p->fleets[i];
1133 fims::to_string(local_fleet_id) +
1134 std::string(
" into model id ") +
1135 fims::to_string(model->GetId()));
1138 valid_model =
false;
1140 fims::to_string(model->GetId()));
1143 model->Initialize();
1158 FIMS_INFO_LOG(
"Creating model and checking for required components...");
1159 bool valid_model =
true;
1244 bool valid_model =
true;
1247 std::shared_ptr<fims_popdy::FisheryModelBase<Type>>& model = (*it).second;
1248 std::set<uint32_t>::iterator jt;
1250 for (jt = model->population_ids.begin();
1251 jt != model->population_ids.end(); ++jt) {
1255 std::shared_ptr<fims_popdy::Population<Type>> p = (*pt).second;
1257 if (model->model_type_m ==
"caa") {
1258 typename std::set<uint32_t>::iterator fleet_ids_it;
1259 for (fleet_ids_it = p->fleet_ids.begin();
1260 fleet_ids_it != p->fleet_ids.end(); ++fleet_ids_it) {
1263 if (it != this->
fleets.end()) {
1265 std::shared_ptr<fims_popdy::Fleet<Type>> f = (*it).second;
1267 if (f->fleet_selectivity_id_m ==
static_cast<Type
>(-999)) {
1268 valid_model =
false;
1270 "No selectivity pattern defined for fleet " +
1271 fims::to_string(f->id) +
1272 ". FIMS requires selectivity be defined for all fleets "
1273 "when running a catch at age model.");
1278 if (p->recruitment_id ==
static_cast<Type
>(-999)) {
1279 valid_model =
false;
1281 "No recruitment function defined for population " +
1282 fims::to_string(p->id) +
1283 ". FIMS requires recruitment functions be defined for all "
1284 "populations when running a catch at age model.");
1287 std::shared_ptr<fims_popdy::RecruitmentBase<Type>> r =
1290 if (r->process_id ==
static_cast<Type
>(-999)) {
1291 valid_model =
false;
1293 "No recruitment process function defined for population " +
1294 fims::to_string(p->id) +
1295 ". FIMS requires recruitment process functions be defined "
1297 "recruitments when running a catch at age model.");
1300 if (p->growth_id ==
static_cast<Type
>(-999)) {
1301 valid_model =
false;
1303 "No growth function defined for population " +
1304 fims::to_string(p->id) +
1305 ". FIMS requires growth functions be defined for all "
1306 "populations when running a catch at age model.");
1309 if (p->maturity_id ==
static_cast<Type
>(-999)) {
1310 valid_model =
false;
1313 "No maturity function defined for population " +
1314 fims::to_string(p->id) +
1315 ". FIMS requires maturity functions be defined for all "
1316 "populations when running a catch at age model.");
1326template <
typename Type>
Definition fims_vector.hpp:27
void emplace_back(Args &&...args)
Constructs an element in-place at the end.
Definition fims_vector.hpp:389
size_type size() const
Returns the number of elements.
Definition fims_vector.hpp:299
Generic capability interface for growth models that can feed the growth-derived age-to-length convers...
Definition growth_model_adapter.hpp:26
Platform macros and the core FIMS logging system.
#define FIMS_WARNING_LOG(MESSAGE)
Definition def.hpp:648
#define FIMS_INFO_LOG(MESSAGE)
Record an info-log entry with metadata.
Definition def.hpp:636
#define FIMS_ERROR_LOG(MESSAGE)
Definition def.hpp:664
This distributions module includes any .hpp files within the subfolders so that only this file needs ...
Establishes the FIMS Vector class.
Defines the base class for all fishery models within the FIMS framework.
Declare the fleet functor class which is the base class for all fleet functors.
Includes any .hpp files within the subfolders so that only this file needs to included in include sta...
Defines a size provider that reads mean growth outputs and prepares population-level size probabiliti...
Definition of the FIMSObject structure.
std::shared_ptr< AgeToLengthConversionBase< Type > > BuildAgeToLengthConversionFleet(const std::shared_ptr< Population< Type > > &population, const std::shared_ptr< Fleet< Type > > &fleet)
Build the active age-to-length conversion for a fleet from the current population and fleet state.
Definition runtime.hpp:44
Defines the Population class and its fields and methods.
Includes any .hpp files within the subfolders so that only this file needs to included in include sta...
Shared runtime helpers for constructing and validating fleet age-to-length conversions.
Includes any .hpp files within the subfolders so that only this file needs to included in include sta...
Defines helpers for constructing population-level biological size grids.
Base class for all fleets.
Definition fleet.hpp:26
Population class. Contains subpopulations that are divided into generic partitions (e....
Definition population.hpp:27
static fims::Vector< double > BuildObservationEdgesFromCenters(const fims::Vector< double > ¢ers)
Build one fleet observation-bin edge vector from stored bin centers.
Definition size_grid_builder.hpp:107
static SizeGrid BuildDefaultFromFleetEdges(const fims::Vector< fims::Vector< double > > &fleet_edges)
Build the default population biological size grid from resolved fleet observation-bin edges.
Definition size_grid_builder.hpp:160
Population-level biological size grid.
Definition size_grid.hpp:26
bool IsConsistent() const
Return whether the grid dimensions and geometry are internally consistent.
Definition size_grid.hpp:80
fims::Vector< double > edges
Definition size_grid.hpp:28
std::size_t n_bins
Definition size_grid.hpp:27