diff --git a/src/include/Configuration.h b/src/include/Configuration.h
index 2efd8b2df9e8b1fd1c14777433e5adf6e7627c1e..dbebc7117190524d2df160f56f30b75941dd542c 100644
--- a/src/include/Configuration.h
+++ b/src/include/Configuration.h
@@ -59,13 +59,13 @@ class GeometryConfiguration {
 protected:
   //! \brief Number of spherical components.
   int number_of_spheres;
-  //! \brief Maximum expansion order of angular momentum.
+  //! \brief Maximum field expansion order.
   int l_max;
-  //! \brief QUESTION: definition?
+  //! \brief Maximum internal field expansion order.
   int li;
-  //! \brief QUESTION: definition?
+  //! \brief Maximum external field expansion order.
   int le;
-  //! \brief QUESTION: definition?
+  //! \brief Maximum dimension of allocated matrix allowance (deprecated).
   int mxndm;
   //! \brief QUESTION: definition?
   int iavm;
@@ -157,7 +157,7 @@ public:
    *
    * \param rhs: `GeometryConfiguration` preexisting object to copy from.
    */
-  GeometryConfiguration(const  GeometryConfiguration& rhs);
+  GeometryConfiguration(const GeometryConfiguration& rhs);
 
   /*! \brief Destroy a GeometryConfiguration instance.
    */
@@ -175,6 +175,50 @@ public:
    * configuration data.
    */
   static GeometryConfiguration *from_legacy(std::string file_name);
+
+  /*! \brief Get the value of a parameter by name.
+   *
+   * The proper way to access read-only parameters from outside a class is to define
+   * public methods that return their values. For configuration operations, whose
+   * optimization is not critical, it is possible to define a single function that
+   * returns simple scalar values called by name. Access to more complicated data
+   * structures, on the other hand, require specialized methods which avoid the
+   * burden of searching the necessary value across the whole array every time.
+   *
+   * \param param_name: `string` Name of the parameter to be retrieved.
+   * \return value: `double` Value of the requested parameter.
+   */
+  double get_param(std::string param_name);
+  
+  /*! \brief Get the X coordinate of a sphere by its index.
+   *
+   * This is a specialized function to access the X coordinate of a sphere through
+   * its index.
+   *
+   * \param index: `int` Index of the scale to be retrieved.
+   * \return scale: `double` The X coordinate of the requested sphere.
+   */
+  double get_sph_x(int index) { return sph_x[index]; }
+  
+  /*! \brief Get the Y coordinate of a sphere by its index.
+   *
+   * This is a specialized function to access the Y coordinate of a sphere through
+   * its index.
+   *
+   * \param index: `int` Index of the scale to be retrieved.
+   * \return scale: `double` The Y coordinate of the requested sphere.
+   */
+  double get_sph_y(int index) { return sph_y[index]; }
+  
+  /*! \brief Get the Z coordinate of a sphere by its index.
+   *
+   * This is a specialized function to access the Z coordinate of a sphere through
+   * its index.
+   *
+   * \param index: `int` Index of the scale to be retrieved.
+   * \return scale: `double` The Z coordinate of the requested sphere.
+   */
+  double get_sph_z(int index) { return sph_z[index]; }
 };
 
 /**
@@ -363,12 +407,10 @@ public:
    */
   static ScattererConfiguration* from_dedfb(std::string file_name);
 
-  /*! \brief Get the ID of a sphere by its index.
+  /*! \brief Get the ID of the configuration of a sphere by the sphere's index.
    *
-   * The proper way to access read-only parameters from outside a class is to define
-   * public methods that return their values. For arrays, particularly those that
-   * are accessed multiple times, it is convenient to have specialized methods that
-   * return the required values based on their index in the array.
+   * This is a specialized function to access the ID of the configuration group a
+   * sphere belongs to, through the index of the sphere.
    *
    * \param index: `int` Index of the ID to be retrieved.
    * \return id: `int` The desired identifier.
@@ -382,19 +424,27 @@ public:
    * optimization is not critical, it is possible to define a single function that
    * returns simple scalar values called by name. Access to more complicated data
    * structures, on the other hand, require specialized methods which avoid the
-   * burden of searching the necessary value across the whole arrya every time.
+   * burden of searching the necessary value across the whole array every time.
    *
    * \param param_name: `string` Name of the parameter to be retrieved.
    * \return value: `double` Value of the requested parameter.
    */
   double get_param(std::string param_name);
   
+  /*! \brief Get the ID of a sphere by its index.
+   *
+   * This is a specialized function to get the name of the reference variable as a
+   * string.
+   *
+   * \param index: `int` Index of the ID to be retrieved.
+   * \return id: `int` The desired identifier.
+   */
+  std::string get_reference() { return reference_variable_name; }
+  
   /*! \brief Get the value of a scale by its index.
    *
-   * The proper way to access read-only parameters from outside a class is to define
-   * public methods that return their values. For arrays, particularly those that
-   * are accessed multiple times, it is convenient to have specialized methods that
-   * return the required values based on their index in the array.
+   * This is a specialized function to access a scale (generally a wavelength),
+   * through its index.
    *
    * \param index: `int` Index of the scale to be retrieved.
    * \return scale: `double` The desired scale.
diff --git a/src/libnptm/Configuration.cpp b/src/libnptm/Configuration.cpp
index 80fb5ecd92f49faa4b17d6febd2d155d65db5ee9..8cde1b7e7c47d049fdb122467d5b830c59b4258c 100644
--- a/src/libnptm/Configuration.cpp
+++ b/src/libnptm/Configuration.cpp
@@ -76,6 +76,7 @@ GeometryConfiguration::GeometryConfiguration(
   sph_y = y;
   sph_z = z;
 }
+
 GeometryConfiguration::GeometryConfiguration(const  GeometryConfiguration& rhs)
 {
   number_of_spheres = rhs.number_of_spheres;
@@ -232,6 +233,39 @@ GeometryConfiguration* GeometryConfiguration::from_legacy(string file_name) {
   return conf;
 }
 
+GeometryConfiguration::get_param(std::string param_name) {
+  double value;
+  if (param_name.compare("number_of_spheres") == 0) value = (double)number_of_spheres;
+  else if (param_name.compare("nsph") == 0) value = (double)number_of_spheres;
+  else if (param_name.compare("l_max") == 0) value = (double)l_max;
+  else if (param_name.compare("li") == 0) value = (double)li;
+  else if (param_name.compare("le") == 0) value = (double)le;
+  else if (param_name.compare("mxndm") == 0) value = (double)mxndm;
+  else if (param_name.compare("iavm") == 0) value = (double)iavm;
+  else if (param_name.compare("in_pol") == 0) value = (double)in_pol;
+  else if (param_name.compare("npnt") == 0) value = (double)npnt;
+  else if (param_name.compare("npntts") == 0) value = (double)npntts;
+  else if (param_name.compare("meridional_type") == 0) value = (double)meridional_type;
+  else if (param_name.compare("jwtm") == 0) value = (double)jwtm;
+  else if (param_name.compare("in_theta_start") == 0) value = in_theta_start;
+  else if (param_name.compare("in_theta_step") == 0) value = in_theta_step;
+  else if (param_name.compare("in_theta_end") == 0) value = in_theta_end;
+  else if (param_name.compare("sc_theta_start") == 0) value = sc_theta_start;
+  else if (param_name.compare("sc_theta_step") == 0) value = sc_theta_step;
+  else if (param_name.compare("sc_theta_end") == 0) value = sc_theta_end;
+  else if (param_name.compare("in_phi_start") == 0) value = in_phi_start;
+  else if (param_name.compare("in_phi_step") == 0) value = in_phi_step;
+  else if (param_name.compare("in_phi_end") == 0) value = in_phi_end;
+  else if (param_name.compare("sc_phi_start") == 0) value = sc_phi_start;
+  else if (param_name.compare("sc_phi_step") == 0) value = sc_phi_step;
+  else if (param_name.compare("sc_phi_end") == 0) value = sc_phi_end;
+  else {
+    string message = "unrecognized parameter \"" + param_name + "\"";
+    throw UnrecognizedParameterException(message);
+  }
+  return value;
+}
+
 ScattererConfiguration::ScattererConfiguration(
 					       int nsph,
 					       int configs, 
@@ -797,17 +831,18 @@ ScattererConfiguration* ScattererConfiguration::from_legacy(string file_name) {
 
 double ScattererConfiguration::get_param(string param_name) {
   double value;
-  if (param_name.compare("number_of_spheres") == 0) value = 1.0 * number_of_spheres;
-  else if (param_name.compare("nsph") == 0) value = 1.0 * number_of_spheres;
-  else if (param_name.compare("number_of_scales") == 0) value = 1.0 * number_of_scales;
-  else if (param_name.compare("nxi") == 0) value = 1.0 * number_of_scales;
-  else if (param_name.compare("idfc") == 0) value = 1.0 * idfc;
+  if (param_name.compare("number_of_spheres") == 0) value = (double)number_of_spheres;
+  else if (param_name.compare("nsph") == 0) value = (double)number_of_spheres;
+  else if (param_name.compare("configurations") == 0) value = (double)configurations;
+  else if (param_name.compare("number_of_scales") == 0) value = (double)number_of_scales;
+  else if (param_name.compare("nxi") == 0) value = (double)number_of_scales;
+  else if (param_name.compare("idfc") == 0) value = (double)idfc;
   else if (param_name.compare("exdc") == 0) value = exdc;
   else if (param_name.compare("wp") == 0) value = wp;
   else if (param_name.compare("xip") == 0) value = xip;
   else {
-    // TODO: add exception code for unknown parameter.
-    return 0.0;
+    string message = "unrecognized parameter \"" + param_name + "\"";
+    throw UnrecognizedParameterException(message);
   }
   return value;
 }
diff --git a/src/libnptm/logging.cpp b/src/libnptm/logging.cpp
index 67a586e467d4c0a5aa8f19a0197e4209dbe1355d..fbf96725e621c856a9937855ced71a8268fc848b 100644
--- a/src/libnptm/logging.cpp
+++ b/src/libnptm/logging.cpp
@@ -26,44 +26,56 @@ Logger::~Logger() {
 }
 
 void Logger::err(std::string message) {
-  fprintf(err_output, "%s", message.c_str());
-  fflush(err_output);
+#pragma omp critical
+  {
+    fprintf(err_output, "%s", message.c_str());
+    fflush(err_output);
+  }
 }
 
 void Logger::flush(int level) {
-  string summary = "\"" + *last_message + "\" issued " + to_string(repetitions);
-  if (repetitions == 1) summary += " time.\n";
-  else summary += " times.\n";
-  if (level == LOG_ERRO) err(summary);
-  else {
-    if (level >= log_threshold) {
-      fprintf(log_output, "%s", summary.c_str());
-      fflush(log_output);
+#pragma omp critical
+  {
+    string summary = "\"" + *last_message + "\" issued " + to_string(repetitions);
+    if (repetitions == 1) summary += " time.\n";
+    else summary += " times.\n";
+    if (level == LOG_ERRO) err(summary);
+    else {
+      if (level >= log_threshold) {
+	fprintf(log_output, "%s", summary.c_str());
+	fflush(log_output);
+      }
     }
+    delete last_message;
+    last_message = new string("");
+    repetitions = 0;
   }
-  delete last_message;
-  last_message = new string("");
-  repetitions = 0;
 }
 
 void Logger::log(std::string message, int level) {
-  if (level == LOG_ERRO) err(message);
-  else {
-    if (level >= log_threshold) {
-      fprintf(log_output, "%s", message.c_str());
-      fflush(log_output);
+#pragma omp critical
+  {
+    if (level == LOG_ERRO) err(message);
+    else {
+      if (level >= log_threshold) {
+	fprintf(log_output, "%s", message.c_str());
+	fflush(log_output);
+      }
     }
   }
 }
 
 void Logger::push(std::string message) {
-  if (repetitions > 0) {
-    if (message.compare(*last_message) != 0) {
-      flush(LOG_DEBG);
+#pragma omp critical
+  {
+    if (repetitions > 0) {
+      if (message.compare(*last_message) != 0) {
+	flush(LOG_DEBG);
+      }
     }
+    log(message, LOG_DEBG);
+    delete last_message;
+    last_message = new string(message);
+    repetitions++;
   }
-  log(message, LOG_DEBG);
-  delete last_message;
-  last_message = new string(message);
-  repetitions++;
 }