Kstars

pykstars.cpp
1/*
2 SPDX-FileCopyrightText: 2021 Valentin Boettcher <hiro at protagon.space; @hiro98:tchncs.de>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include <pybind11/pybind11.h>
8#include <pybind11/chrono.h>
9#include "skyobjects/skypoint.h"
10#include "skymesh.h"
11#include "cachingdms.h"
12#include "sqlstatements.cpp"
13#include "catalogobject.h"
14#include "catalogsdb.h"
15#include <iostream>
16
17using namespace pybind11::literals;
18namespace py = pybind11;
19namespace pybind11
20{
21namespace detail
22{
23template <>
24struct type_caster<QString>
25{
26 public:
27 PYBIND11_TYPE_CASTER(QString, _("QString"));
28
29 bool load(handle src, bool)
30 {
31 try
32 {
33 value = QString::fromStdString(src.cast<std::string>());
34 }
35 catch (const py::cast_error &)
36 {
37 return false;
38 }
39
40 return !PyErr_Occurred();
41 }
42
43 static handle cast(QString src, return_value_policy /* policy */, handle /* parent */)
44 {
45 const handle *obj = new py::object(py::cast(src.toUtf8().constData()));
46 return *obj;
47 }
48};
49
50template <>
52{
53 public:
54 PYBIND11_TYPE_CASTER(QDateTime, _("QDateTime"));
55
56 bool load(handle src, bool)
57 {
58 try
59 {
61 std::chrono::duration_cast<std::chrono::milliseconds>(
62 src.cast<std::chrono::system_clock::time_point>().time_since_epoch())
63 .count());
64 }
65 catch (const py::cast_error &)
66 {
67 return false;
68 }
69
70 return !PyErr_Occurred();
71 }
72
73 static handle cast(QDateTime src, return_value_policy /* policy */,
74 handle /* parent */)
75 {
76 const handle *obj = new py::object(py::cast(std::chrono::system_clock::time_point(
77 std::chrono::milliseconds(src.currentMSecsSinceEpoch()))));
78 return *obj;
79 }
80};
81} // namespace detail
82} // namespace pybind11
83
84/**
85 * @struct Indexer
86 * Provides a simple wrapper to generate trixel ids from python code.
87 */
88struct Indexer
89{
90 Indexer(int level) : m_mesh{ SkyMesh::Create(level) } {};
91
92 int getLevel() const { return m_mesh->level(); };
93 void setLevel(int level) { m_mesh = SkyMesh::Create(level); };
94
95 int getTrixel(double ra, double dec, bool convert_epoch = false) const
96 {
97 SkyPoint p{ dms(ra), dms(dec) };
98 if (convert_epoch)
99 {
100 p.B1950ToJ2000();
101 p = SkyPoint{ p.ra(), p.dec() }; // resetting ra0, dec0
102 }
103
104 return m_mesh->index(&p);
105 };
106
107 SkyMesh *m_mesh;
108};
109
110///////////////////////////////////////////////////////////////////////////////
111// PYBIND //
112///////////////////////////////////////////////////////////////////////////////
113
114const CatalogObject DEFAULT_CATALOG_OBJECT{};
115
116template <typename T>
117T cast_default(const py::object &value, const T &default_value)
118{
119 try
120 {
121 return py::cast<T>(value);
122 }
123 catch (const py::cast_error &)
124 {
125 return default_value;
126 }
127}
128
129PYBIND11_MODULE(pykstars, m)
130{
131 m.doc() = "Thin bindings for KStars to facilitate trixel indexation from python.";
132
133 py::class_<Indexer>(m, "Indexer")
134 .def(py::init<int>(), "level"_a,
135 "Initializes an `Indexer` with the given `level`.\n"
136 "If the level is greater then approx. 10 the initialization can take some "
137 "time.")
138 .def_property("level", &Indexer::getLevel, &Indexer::setLevel,
139 "Sets the level of the HTMesh/SkyMesh used to index points.")
140 .def(
141 "get_trixel", &Indexer::getTrixel, "ra"_a, "dec"_a, "convert_epoch"_a = false,
142 "Calculates the trixel number from the right ascention and the declination.\n"
143 "The epoch of coordinates is assumed to be J2000.\n\n"
144 "If the epoch is B1950, `convert_epoch` has to be set to `True`.")
145 .def("__repr__", [](const Indexer &indexer) {
146 std::ostringstream lvl;
147 lvl << indexer.getLevel();
148 return "<Indexer level=" + lvl.str() + ">";
149 });
150
151 {
152 using namespace CatalogsDB;
153 py::class_<DBManager>(m, "DBManager")
154 .def(py::init([](const std::string &filename) {
155 return new DBManager(QString::fromStdString(filename));
156 }),
157 "filename"_a)
158 .def(
159 "register_catalog",
160 [](DBManager &self, const py::dict &cat) {
161 return self.register_catalog(
162 py::cast<int>(cat["id"]), py::cast<QString>(cat["name"]),
163 py::cast<bool>(cat["mut"]), py::cast<bool>(cat["enabled"]),
164 py::cast<double>(cat["precedence"]),
165 py::cast<QString>(cat["author"]),
166 py::cast<QString>(cat["source"]),
167 py::cast<QString>(cat["description"]),
168 py::cast<int>(cat["version"]), py::cast<QString>(cat["color"]),
169 py::cast<QString>(cat["license"]),
170 py::cast<QString>(cat["maintainer"]),
171 py::cast<QDateTime>(cat["timestamp"]));
172 },
173 "catalog"_a)
174 .def(
175 "update_catalog_meta",
176 [](DBManager &self, const py::dict &cat) {
177 return self.update_catalog_meta(
178 { py::cast<int>(cat["id"]), py::cast<QString>(cat["name"]),
179 py::cast<double>(cat["precedence"]),
180 py::cast<QString>(cat["author"]),
181 py::cast<QString>(cat["source"]),
182 py::cast<QString>(cat["description"]),
183 py::cast<bool>(cat["mut"]), py::cast<bool>(cat["enabled"]),
184 py::cast<int>(cat["version"]), py::cast<QString>(cat["color"]),
185 py::cast<QString>(cat["license"]),
186 py::cast<QString>(cat["maintainer"]),
187 py::cast<QDateTime>(cat["timestamp"]) });
188 },
189 "catalog"_a)
190 .def("__repr__",
191 [](const DBManager &manager) {
192 return QString("<DBManager filename=\"" + manager.db_file_name() +
193 "\">");
194 })
195 .def("update_catalog_views", &DBManager::update_catalog_views)
196 .def("compile_master_catalog", &DBManager::compile_master_catalog)
197 .def("dump_catalog", &DBManager::dump_catalog, "catalog_id"_a, "file_path"_a)
198 .def("import_catalog", &DBManager::import_catalog, "file_path"_a,
199 "overwrite"_a)
200 .def("remove_catalog", &DBManager::remove_catalog, "catalog_id"_a);
201
202 py::register_exception<DatabaseError>(m, "DatabaseError");
203 }
204
205 py::enum_<SkyObject::TYPE>(m, "ObjectType", "The types of CatalogObjects",
206 py::arithmetic())
207 .value("STAR", SkyObject::STAR)
208 .value("CATALOG_STAR", SkyObject::CATALOG_STAR)
209 .value("PLANET", SkyObject::TYPE::PLANET)
210 .value("OPEN_CLUSTER", SkyObject::TYPE::OPEN_CLUSTER)
211 .value("GLOBULAR_CLUSTER", SkyObject::TYPE::GLOBULAR_CLUSTER)
212 .value("GASEOUS_NEBULA", SkyObject::TYPE::GASEOUS_NEBULA)
213 .value("PLANETARY_NEBULA", SkyObject::TYPE::PLANETARY_NEBULA)
214 .value("SUPERNOVA_REMNANT", SkyObject::TYPE::SUPERNOVA_REMNANT)
215 .value("GALAXY", SkyObject::TYPE::GALAXY)
216 .value("COMET", SkyObject::TYPE::COMET)
217 .value("ASTEROID", SkyObject::TYPE::ASTEROID)
218 .value("CONSTELLATION", SkyObject::TYPE::CONSTELLATION)
219 .value("MOON", SkyObject::TYPE::MOON)
220 .value("ASTERISM", SkyObject::TYPE::ASTERISM)
221 .value("GALAXY_CLUSTER", SkyObject::TYPE::GALAXY_CLUSTER)
222 .value("DARK_NEBULA", SkyObject::TYPE::DARK_NEBULA)
223 .value("QUASAR", SkyObject::TYPE::QUASAR)
224 .value("MULT_STAR", SkyObject::TYPE::MULT_STAR)
225 .value("RADIO_SOURCE", SkyObject::TYPE::RADIO_SOURCE)
226 .value("SATELLITE", SkyObject::TYPE::SATELLITE)
227 .value("SUPERNOVA", SkyObject::TYPE::SUPERNOVA)
228 .value("NUMBER_OF_KNOWN_TYPES", SkyObject::TYPE::NUMBER_OF_KNOWN_TYPES)
229 .value("TYPE_UNKNOWN", SkyObject::TYPE::TYPE_UNKNOWN)
230 .export_values();
231
232 m.def(
233 "get_id",
234 [](const py::dict &obj) -> py::bytes {
236 static_cast<SkyObject::TYPE>(py::cast<int>(obj["type"])),
237 py::cast<double>(obj["ra"]), py::cast<double>(obj["dec"]),
238 py::cast<QString>(obj["name"]),
239 py::cast<QString>(obj["catalog_identifier"]))
240 .toStdString();
241 },
242 "object"_a,
243 R"(
244 Calculate the id of an object.
245
246 Parameters
247 ----------)");
248
249 ///////////////////////////////////////////////////////////////////////////
250 // Sql Statements //
251 ///////////////////////////////////////////////////////////////////////////
252 auto s = m.def_submodule("sqlstatements");
253 {
254 using namespace CatalogsDB::SqlStatements;
255
256 s.doc() = "Assorted sql statements to modify the catalog database.";
257
258 s.def("insert_dso", &insert_dso, "catalog_id"_a);
259 s.def("create_catalog_table", &create_catalog_table, "catalog_id"_a);
260
261#define ATTR(name) \
262 { \
263 s.attr(#name) = name; \
264 }
265 ATTR(create_catalog_list_table);
266 ATTR(insert_catalog);
267 ATTR(get_catalog_by_id);
268 ATTR(all_catalog_view);
269 ATTR(master_catalog);
270 ATTR(dso_by_name);
271#undef ATTR
272 }
273}
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
const oid getId() const
Manages the catalog database and provides an interface to provide an interface to query and modify th...
Definition catalogsdb.h:183
const QString & db_file_name() const
Definition catalogsdb.h:227
std::pair< bool, QString > update_catalog_meta(const Catalog &cat)
Update the metatadata `catalog`.
std::pair< bool, QString > register_catalog(const int id, const QString &name, const bool mut, const bool enabled, const double precedence, const QString &author=cat_defaults.author, const QString &source=cat_defaults.source, const QString &description=cat_defaults.description, const int version=cat_defaults.version, const QString &color=cat_defaults.color, const QString &license=cat_defaults.license, const QString &maintainer=cat_defaults.maintainer, const QDateTime &timestamp=cat_defaults.timestamp)
Registers a new catalog in the database.
int level() const
returns the mesh level.
Definition HTMesh.h:122
Provides an interface to the Hierarchical Triangular Mesh (HTM) library written by A.
Definition skymesh.h:74
static SkyMesh * Create(int level)
creates the single instance of SkyMesh.
Definition skymesh.cpp:25
Trixel index(const SkyPoint *p)
returns the index of the trixel containing p.
Definition skymesh.cpp:74
TYPE
The type classification of the SkyObject.
Definition skyobject.h:112
The sky coordinates of a point in the sky.
Definition skypoint.h:45
const CachingDms & ra() const
Definition skypoint.h:263
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
Holds a collection of hardcoded sql statements.
QAction * load(const QObject *recvr, const char *slot, QObject *parent)
QStringView level(QStringView ifopt)
const char * constData() const const
qint64 currentMSecsSinceEpoch()
QDateTime fromMSecsSinceEpoch(qint64 msecs)
QString fromStdString(const std::string &str)
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:03 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.