Program Listing for File CLandscapeMetricsCalculator.h¶
↰ Return to documentation for file (CLandscapeMetricsCalculator.h
)
// This file is part of necsim project which is released under MIT license.
// See file **LICENSE.txt** or visit https://opensource.org/licenses/MIT) for full license details
#ifndef NECSIM_CLANDSCAPEMETRICSCALCULATOR_H
#define NECSIM_CLANDSCAPEMETRICSCALCULATOR_H
#include <Python.h>
#include <vector>
#include <string>
#include <memory>
#include "necsim.h"
#include "LandscapeMetricsCalculator.h"
#include "PyLogging.h"
#include "cpl_custom_handler.h"
#include "PyTemplates.h"
using namespace necsim;
class PyLMC : public PyTemplate<LandscapeMetricsCalculator>
{
public:
unique_ptr<LandscapeMetricsCalculator> landscapeMetricsCalculator;
bool has_imported_map;
};
PyObject* set_map(PyLMC* self, PyObject* args)
{
char* map_file;
// parse arguments
if(!PyArg_ParseTuple(args, "s", &map_file))
{
return nullptr;
}
if(!self->has_imported_map)
{
try
{
getGlobalLogger(self->logger, self->log_function);
string map_path = map_file;
self->landscapeMetricsCalculator->import(map_path);
self->has_imported_map = true;
}
catch(exception &e)
{
removeGlobalLogger();
PyErr_SetString(necsimError, e.what());
return nullptr;
}
}
Py_RETURN_NONE;
}
static PyObject* calculateCLUMPY(PyLMC* self)
{
// parse arguments
try
{
getGlobalLogger(self->logger, self->log_function);
if(!self->has_imported_map)
{
throw runtime_error("Map has not been imported - cannot calculate CLUMPY metric.");
}
double c = self->landscapeMetricsCalculator->calculateClumpiness();
return PyFloat_FromDouble(c);
}
catch(exception &e)
{
removeGlobalLogger();
PyErr_SetString(necsimError, e.what());
return nullptr;
}
}
static PyObject* calculateMNN(PyLMC* self)
{
// parse arguments
try
{
getGlobalLogger(self->logger, self->log_function);
if(!self->has_imported_map)
{
throw runtime_error("Map has not been imported - cannot calculate MNN metric.");
}
double c = self->landscapeMetricsCalculator->calculateMNN();
return PyFloat_FromDouble(c);
}
catch(exception &e)
{
removeGlobalLogger();
PyErr_SetString(necsimError, e.what());
return nullptr;
}
}
static int PyLMC_init(PyLMC* self, PyObject* args, PyObject* kwds)
{
self->landscapeMetricsCalculator = make_unique<LandscapeMetricsCalculator>();
self->has_imported_map = false;
return PyTemplate_init<LandscapeMetricsCalculator>(self, args, kwds);
}
static void PyLMC_dealloc(PyLMC* self)
{
if(self->landscapeMetricsCalculator != nullptr)
{
self->landscapeMetricsCalculator.reset();
self->landscapeMetricsCalculator = nullptr;
}
PyTemplate_dealloc<LandscapeMetricsCalculator>(self);
}
static PyMethodDef PyLMCMethods[] = {{"import_map", (PyCFunction) set_map, METH_VARARGS, "Imports the map file to calculate landscape metrics on. Should only be run once."},
{"calculate_MNN", (PyCFunction) calculateMNN, METH_NOARGS, "Calculates the mean nearest-neighbour for the landscape"},
{"calculate_CLUMPY", (PyCFunction) calculateCLUMPY, METH_NOARGS, "Calculates the CLUMPY metric for the landscape"},
{nullptr, nullptr, 0, nullptr}};
PyTypeObject genLMCType()
{
PyTypeObject ret_Simulation_Type = {PyVarObject_HEAD_INIT(nullptr, 0)};
ret_Simulation_Type.tp_name = (char*) "libnecsim.CLandscapeMetricsCalculator";
ret_Simulation_Type.tp_doc = (char*) "Calculate landscape metrics from a map file.";
ret_Simulation_Type.tp_basicsize = sizeof(PyLMC);
ret_Simulation_Type.tp_itemsize = 0;
ret_Simulation_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC;
ret_Simulation_Type.tp_new = PyTemplate_new<LandscapeMetricsCalculator>;
ret_Simulation_Type.tp_init = (initproc) PyLMC_init;
ret_Simulation_Type.tp_dealloc = (destructor) PyLMC_dealloc;
ret_Simulation_Type.tp_traverse = (traverseproc) PyTemplate_traverse<LandscapeMetricsCalculator>;
// .tp_members = PyTemplate_members<T>,
ret_Simulation_Type.tp_methods = PyLMCMethods;
ret_Simulation_Type.tp_getset = PyTemplate_gen_getsetters<LandscapeMetricsCalculator>();
return ret_Simulation_Type;
}
static PyTypeObject C_LMCType = genLMCType();
#endif // NECSIM_CLANDSCAPEMETRICSCALCULATOR_H