release_site.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2020 by
  4. * The Salk Institute for Biological Studies
  5. *
  6. * Use of this source code is governed by an MIT-style
  7. * license that can be found in the LICENSE file or at
  8. * https://opensource.org/licenses/MIT.
  9. *
  10. ******************************************************************************/
  11. #ifndef API_RELEASE_SITE_H
  12. #define API_RELEASE_SITE_H
  13. #include "generated/gen_release_site.h"
  14. #include "api/molecule_release_info.h"
  15. #include "api/api_common.h"
  16. #include "api/complex.h"
  17. #include "bng/bng_defines.h"
  18. namespace MCell {
  19. namespace API {
  20. class ReleaseSite: public GenReleaseSite {
  21. public:
  22. RELEASE_SITE_CTOR()
  23. void postprocess_in_ctor() override {
  24. if (is_set(region) && shape != Shape::REGION_EXPR) {
  25. if (shape != Shape::UNSET) {
  26. throw ValueError(S("When ") + NAME_REGION + " is set, "
  27. "shape must be either unset or set to " + NAME_ENUM_SHAPE + "." + NAME_EV_REGION_EXPR + ".");
  28. }
  29. shape = Shape::REGION_EXPR;
  30. }
  31. if (is_set(complex) && is_set(complex->get_primary_compartment_name()) &&
  32. shape != Shape::COMPARTMENT && shape != Shape::REGION_EXPR) {
  33. if (shape != Shape::UNSET) {
  34. throw ValueError(S("When ") + NAME_COMPARTMENT_NAME + " is set, "
  35. "shape must be either unset or set to " + NAME_ENUM_SHAPE + "." + NAME_EV_COMPARTMENT + " or " +
  36. NAME_ENUM_SHAPE + "." + NAME_EV_REGION_EXPR + ".");
  37. }
  38. shape = Shape::COMPARTMENT;
  39. }
  40. if (is_set(molecule_list) && shape != Shape::LIST) {
  41. if (shape != Shape::UNSET) {
  42. throw ValueError(S("When ") + NAME_MOLECULE_LIST + " is set, "
  43. "shape must be either unset or set to " + NAME_ENUM_SHAPE + "." + NAME_EV_LIST + ".");
  44. }
  45. shape = Shape::LIST;
  46. }
  47. if (is_set(location) && shape != Shape::SPHERICAL) {
  48. if (shape != Shape::UNSET) {
  49. throw ValueError(S("When ") + NAME_LOCATION + " is set, "
  50. "shape must be either unset or set to " + NAME_ENUM_SHAPE + "." + NAME_EV_SPHERICAL + ".");
  51. }
  52. shape = Shape::SPHERICAL;
  53. }
  54. if (release_probability < 0 || release_probability > 1) {
  55. throw ValueError(S("Parameter ") + NAME_RELEASE_PROBABILITY + " must be >= 0 and <= 1.");
  56. }
  57. }
  58. void check_semantics() const override {
  59. // TODO: add additional checks, e.g. that site_diameter must can be set only for SPHERICAL, etc.
  60. GenReleaseSite::check_semantics();
  61. if (release_time < 0) {
  62. throw ValueError(S("Value of ") + NAME_RELEASE_TIME + " must not be smaller than 0.");
  63. }
  64. if (get_num_set(site_diameter, site_radius) > 1) {
  65. throw ValueError(S("Only either ") + NAME_SITE_DIAMETER + " or " + NAME_SITE_RADIUS + " can be set.");
  66. }
  67. if (get_num_set(number_to_release, density, concentration, molecule_list) != 1) {
  68. throw ValueError(
  69. S("Exactly one of ") + NAME_NUMBER_TO_RELEASE + ", " + NAME_DENSITY + ", " + NAME_CONCENTRATION +
  70. " or " + NAME_MOLECULE_LIST + " must be set.");
  71. }
  72. if (shape != Shape::REGION_EXPR && get_num_set(number_to_release, density, concentration) == 1 &&
  73. (number_to_release < 0 || density < 0 || concentration < 0)) {
  74. const char* attribute_name;
  75. if (is_set(number_to_release)) {
  76. attribute_name = NAME_NUMBER_TO_RELEASE;
  77. }
  78. else if (is_set(density)) {
  79. attribute_name = NAME_DENSITY;
  80. }
  81. else if (is_set(concentration)) {
  82. attribute_name = NAME_CONCENTRATION;
  83. }
  84. else {
  85. release_assert(false);
  86. }
  87. throw ValueError(
  88. S("Negative release value of ") + attribute_name + " may be set only when " + NAME_REGION + " is set.");
  89. }
  90. if (get_num_set(complex, molecule_list) != 1) {
  91. throw ValueError(
  92. S("Exactly one of ") + NAME_COMPLEX + " or " + NAME_MOLECULE_LIST + " must be set.");
  93. }
  94. if (shape == Shape::COMPARTMENT &&
  95. BNG::get_in_or_out_compartment_id(complex->compartment_name) != BNG::COMPARTMENT_ID_INVALID) {
  96. throw ValueError(
  97. S(NAME_CLASS_RELEASE_SITE) + " must not use compartment class name " + complex->compartment_name + ".");
  98. }
  99. if ( (shape == Shape::COMPARTMENT && get_num_set(region, molecule_list, location) != 0) &&
  100. (shape != Shape::COMPARTMENT && get_num_set(region, molecule_list, location) != 1)
  101. ) {
  102. throw ValueError(
  103. S("Either compartment or exactly one of ") + NAME_REGION + ", " + NAME_MOLECULE_LIST +
  104. " or " + NAME_LOCATION + " must be set.");
  105. }
  106. if (shape == Shape::SPHERICAL && !is_set(location)) {
  107. throw ValueError(
  108. S("When ") + NAME_SHAPE + " is set to " + NAME_ENUM_SHAPE + "." + NAME_EV_LIST +
  109. " " + NAME_LOCATION + " must be set.");
  110. }
  111. if (is_set(location) && location.size() != 3) {
  112. throw ValueError(S("Argument ") + NAME_LOCATION + " must be a list containing 3 floats.");
  113. }
  114. }
  115. };
  116. } // namespace API
  117. } // namespace MCell
  118. #endif // API_RELEASE_SITE_H