// ADD POINT void ICoDF_HTM::HTM::AddPoint(const double& ra, const double& dec) { PointInfo_t* info = new PointInfo_t; info->_ra = ra; info->_dec = dec; info->_position = Vector3d{0, 0, 0}; if (IsCorrectRA(ra) && IsCorrectDEC(dec)) { if (info->_position == Vector3d{0, 0, 0}) { double rProjection = sin(90 - abs(dec)); double x = rProjection * cos(ra); double y = rProjection * sin(ra); double z = cos(90 - abs(dec)); info->_position = Vector3d{x, y, z}; } } if (this->SelectRootTrixel(info)) { this->_pointList.push(info); this->_pointsToCompute.push_back(info); } else delete info; }
// -------------------------------------------------------------------- // GETINDEX (PointInfo version) unsigned short int ICoDF_HTM::GetIndex(trixel_t* trixel, PointInfo_t* pointInfo) { double ra = pointInfo->_ra; double dec = pointInfo->_dec; if (IsCorrectRA(ra) && IsCorrectDEC(dec)) { unsigned short int index = GetIndex(trixel, pointInfo->_position); return index; } else { std::stringstream tmp; tmp << "Given <ra> [" << ra << "] or <dec> [" << dec << "] is out of bounds"; LS_ADDMSG(LogService::WARNING, "ICoDF_HTM", tmp.str()); } return (unsigned short int)~0; }
// --------------------------------------------------------------------- // GETINDEX (astral coordinates version) unsigned short int GetIndex(trixel* trixel, double& ra, double& dec) { if (IsCorrectRA(ra) && IsCorrectDEC(dec)) { double rProjection = sin(90 - abs(dec)); double x = rProjection * cos(ra); double y = rProjection * sin(ra); double z = cos(90 - abs(dec)); Eigen::Vector3d p(x, y, z); unsigned short int ret = GetIndex(trixel, p); if (ret == max<unsigned short>()) // Is it not good ..? { // Did nothing in the first place... } return ret; } else { llog::warn["HTM"] << "Given <ra> [" << ra << "] or <dec> [" << dec << "] is out of bounds" << std::endl; } return max<unsigned short>(); }
/// TwoPointsCorrelation unsigned int ICoDF_HTM::HTM::TwoPointsCorrelation(double& radius, double& delta) { unsigned int * nbPair = new unsigned int [this->_pointsToCompute.size()]; double infLimit = radius - delta; if (infLimit < 0) infLimit = 0; double supLimit = radius + delta; for (unsigned int i = 0; i < this->_pointsToCompute.size(); ++i) { PointInfo_t const * pt = this->_pointsToCompute[i]; nbPair[i] = 0; if (IsCorrectRA(pt->_ra) && IsCorrectDEC(pt->_dec)) { Vector3d p = pt->_position; double pNorm = p.norm(); double pDot = p.dot(Vector3d{1,0,0}); double phi2 = acos(pDot / pNorm); std::queue<trixel_t*> workingList; for (unsigned int i = 0; i < 4; ++i) workingList.push(this->_octahedron->_rootTrixels[i]); while (workingList.size() > 0) { trixel_t* tmp = workingList.front(); workingList.pop(); double dist[3] = { p.dot(tmp->_vertices[0]), p.dot(tmp->_vertices[1]), p.dot(tmp->_vertices[2]) }; unsigned int infInside = (dist[0] > infLimit) + (dist[1] > infLimit) + (dist[2] > infLimit); unsigned int supInside = (dist[0] > supLimit) + (dist[1] > supLimit) + (dist[2] > supLimit); if (supInside == 3 && infInside == 0) nbPair[i] += tmp->_nbChildObject; else if ((supInside == 3 && infInside > 0) || supInside > 0) { if (tmp->_children != NULL) { for (unsigned int i = 0; i < 4; ++i) if (tmp->_children[i] != NULL) workingList.push(tmp->_children[i]); } else nbPair[i] += 1; } else { if (tmp->_phi == 0) { Vector3d tmpVec1 = tmp->_vertices[1] - tmp->_vertices[0]; Vector3d tmpVec2 = tmp->_vertices[2] - tmp->_vertices[1]; Vector3d tmpVec3 = tmpVec1.cross(tmpVec2); tmp->_trixelBoundary = tmpVec3 / tmpVec3.norm(); tmp->_phi = acos(tmp->_trixelBoundary.dot(Vector3d{1,0,0}) / (tmp->_trixelBoundary.norm())); tmp->_cross01 = tmp->_vertices[0].cross(tmp->_vertices[1]); tmp->_cross12 = tmp->_vertices[1].cross(tmp->_vertices[2]); tmp->_cross20 = tmp->_vertices[2].cross(tmp->_vertices[0]); } double theta = tmp->_trixelBoundary.dot(p) / tmp->_trixelBoundary.norm(); if (acos(theta * pNorm) < tmp->_phi + phi2) { if (!(tmp->_cross01.dot(p) < 0 && tmp->_cross12.dot(p) < 0 && tmp->_cross20.dot(p))) { nbPair[i] += 1; } } } } } } delete nbPair; return std::accumulate(nbPair, nbPair + this->_pointsToCompute.size(), 0); }
/// TwoPointsCorrelation unsigned int ICoDF_HTM::HTM::TwoPointsCorrelation(double& radius, double& delta) { unsigned int nbPairs = 0; std::map<std::string, PointInfo_t*>::iterator it; double infLimit = radius - delta; if (infLimit < 0) infLimit = 0; double supLimit = radius + delta; HTMConstraint_t *constraint = new HTMConstraint_t; for (it = this->_points.begin(); it != this->_points.end(); ++it) { PointInfo_t* pt = (*it).second; if (IsCorrectRA(pt->_ra) && IsCorrectDEC(pt->_dec)) { double rProjection = sin(90 - abs(pt->_dec)); double x = rProjection * cos(pt->_ra); double y = rProjection * sin(pt->_ra); double z = cos(90 - abs(pt->_dec)); Eigen::Vector3d p(x, y, z); static std::queue<trixel_t*> workingList; std::queue<trixel_t*>().swap(workingList); for (unsigned int i = 0; i < 4; ++i) { unsigned short int infInside = 0; unsigned short int supInside = 0; if (this->_octahedron->_rootTrixels[i] != NULL) { if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[0]) > infLimit) ++infInside; if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[1]) > infLimit) ++infInside; if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[2]) > infLimit) infInside++; if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[0]) > supLimit) ++supInside; if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[1]) > supLimit) ++supInside; if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[2]) > supLimit) supInside++; } if (supInside == 3 && infInside == 0) constraint->_inside.push_back(this->_octahedron->_rootTrixels[i]); if ((supInside == 3 && infInside > 0) || supInside > 0) workingList.push(this->_octahedron->_rootTrixels[i]); else { Eigen::Vector3d tmpVec1 = _octahedron->_rootTrixels[i]->_vertices[1] - _octahedron->_rootTrixels[i]->_vertices[0]; Eigen::Vector3d tmpVec2 = _octahedron->_rootTrixels[i]->_vertices[2] - _octahedron->_rootTrixels[i]->_vertices[1]; Eigen::Vector3d tmpVec3 = tmpVec1.cross(tmpVec2); Eigen::Vector3d trixelBoundary = tmpVec3 / tmpVec3.norm(); double theta = acos(trixelBoundary.dot(p) / (trixelBoundary.norm() * p.norm())); double phi1 = acos(trixelBoundary.dot(Eigen::Vector3d(1,0,0)) / (trixelBoundary.norm())); double phi2 = acos(p.dot(Eigen::Vector3d(1,0,0)) / p.norm()); if (theta < phi1 + phi2) { if (!(_octahedron->_rootTrixels[i]->_vertices[0].cross(_octahedron->_rootTrixels[i]->_vertices[1]).dot(p) < 0 && _octahedron->_rootTrixels[i]->_vertices[1].cross(_octahedron->_rootTrixels[i]->_vertices[2]).dot(p) < 0 && _octahedron->_rootTrixels[i]->_vertices[2].cross(_octahedron->_rootTrixels[i]->_vertices[0]).dot(p))) { constraint->_partial.push_back(_octahedron->_rootTrixels[i]); } } } } while (workingList.size() > 0) { trixel_t* tmp = workingList.front(); workingList.pop(); unsigned short int infInside = 0; unsigned short int supInside = 0; if (p.dot(tmp->_vertices[0]) > infLimit) ++infInside; if (p.dot(tmp->_vertices[2]) > infLimit) ++infInside; if (p.dot(tmp->_vertices[1]) > infLimit) ++infInside; if (p.dot(tmp->_vertices[0]) > supLimit) ++supInside; if (p.dot(tmp->_vertices[2]) > supLimit) ++supInside; if (p.dot(tmp->_vertices[1]) > supLimit) ++supInside; if (supInside == 3 && infInside == 0) constraint->_inside.push_back(tmp); else if ((supInside == 3 && infInside > 0) || supInside > 0) { if (tmp->_children != NULL) { for (unsigned int i = 0; i < 4; ++i) if (tmp->_children[i] != NULL) workingList.push(tmp->_children[i]); } else constraint->_partial.push_back(tmp); } else { Eigen::Vector3d tmpVec1 = tmp->_vertices[1] - tmp->_vertices[0]; Eigen::Vector3d tmpVec2 = tmp->_vertices[2] - tmp->_vertices[1]; Eigen::Vector3d tmpVec3 = tmpVec1.cross(tmpVec2); Eigen::Vector3d trixelBoundary = tmpVec3 / tmpVec3.norm(); double theta = acos(trixelBoundary.dot(p) / (trixelBoundary.norm() * p.norm())); double phi1 = acos(trixelBoundary.dot(Eigen::Vector3d(1,0,0)) / (trixelBoundary.norm())); double phi2 = acos(p.dot(Eigen::Vector3d(1,0,0)) / p.norm()); if (theta < phi1 + phi2) { if (!(tmp->_vertices[0].cross(tmp->_vertices[1]).dot(p) < 0 && tmp->_vertices[1].cross(tmp->_vertices[2]).dot(p) < 0 && tmp->_vertices[2].cross(tmp->_vertices[0]).dot(p))) { constraint->_partial.push_back(tmp); } } } } } } for (auto it2 = constraint->_inside.begin(); it2 != constraint->_inside.end(); ++it2) { nbPairs += (*it2)->_nbChildObject; } for (auto it2 = constraint->_partial.begin(); it2 != constraint->_partial.end(); ++it2) { nbPairs += 1; } delete constraint; return nbPairs; }
HTMConstraint_t* ICoDF_HTM::HTM::SetConstraint(PointInfo_t* pt, double& radius) { HTMConstraint_t* constraint = NULL; if (pt != NULL) { if (IsCorrectRA(pt->_ra) && IsCorrectDEC(pt->_dec)) { double rProjection = sin(90 - abs(pt->_dec)); double x = rProjection * cos(pt->_ra); double y = rProjection * sin(pt->_ra); double z = cos(90 - abs(pt->_dec)); Eigen::Vector3d p(x, y, z); constraint = new HTMConstraint_t; static std::queue<trixel_t*> workingList; std::queue<trixel_t*>().swap(workingList); for(unsigned int i = 0; i < 4; ++i) { unsigned short int inside = 0; if (this->_octahedron->_rootTrixels[i] != NULL) { if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[0]) > radius) ++inside; if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[1]) > radius) ++inside; if (p.dot(this->_octahedron->_rootTrixels[i]->_vertices[2]) > radius) inside++; } if (inside == 3) constraint->_inside.push_back(this->_octahedron->_rootTrixels[i]); else if (inside > 0) workingList.push(this->_octahedron->_rootTrixels[i]); else { Eigen::Vector3d tmpVec1 = _octahedron->_rootTrixels[i]->_vertices[1] - _octahedron->_rootTrixels[i]->_vertices[0]; Eigen::Vector3d tmpVec2 = _octahedron->_rootTrixels[i]->_vertices[2] - _octahedron->_rootTrixels[i]->_vertices[1]; Eigen::Vector3d tmpVec3 = tmpVec1.cross(tmpVec2); Eigen::Vector3d trixelBoundary = tmpVec3 / tmpVec3.norm(); double theta = acos(trixelBoundary.dot(p) / (trixelBoundary.norm() * p.norm())); double phi1 = acos(trixelBoundary.dot(Eigen::Vector3d(1,0,0)) / (trixelBoundary.norm())); double phi2 = acos(p.dot(Eigen::Vector3d(1,0,0)) / p.norm()); if (theta < phi1 + phi2) { if (!(_octahedron->_rootTrixels[i]->_vertices[0].cross(_octahedron->_rootTrixels[i]->_vertices[1]).dot(p) < 0 && _octahedron->_rootTrixels[i]->_vertices[1].cross(_octahedron->_rootTrixels[i]->_vertices[2]).dot(p) < 0 && _octahedron->_rootTrixels[i]->_vertices[2].cross(_octahedron->_rootTrixels[i]->_vertices[0]).dot(p))) { constraint->_partial.push_back(_octahedron->_rootTrixels[i]); } } } } while (workingList.size() > 0) { trixel_t* tmp = workingList.front(); workingList.pop(); unsigned short int inside = 0; if (p.dot(tmp->_vertices[0]) > radius) ++inside; if (p.dot(tmp->_vertices[2]) > radius) ++inside; if (p.dot(tmp->_vertices[1]) > radius) ++inside; if (inside == 3) constraint->_inside.push_back(tmp); else if (inside > 0) { if (tmp->_children != NULL) { for (unsigned int i = 0; i < 4; ++i) if (tmp->_children[i] != NULL) workingList.push(tmp->_children[i]); } else constraint->_partial.push_back(tmp); } else { Eigen::Vector3d tmpVec1 = tmp->_vertices[1] - tmp->_vertices[0]; Eigen::Vector3d tmpVec2 = tmp->_vertices[2] - tmp->_vertices[1]; Eigen::Vector3d tmpVec3 = tmpVec1.cross(tmpVec2); Eigen::Vector3d trixelBoundary = tmpVec3 / tmpVec3.norm(); double theta = acos(trixelBoundary.dot(p) / (trixelBoundary.norm() * p.norm())); double phi1 = acos(trixelBoundary.dot(Eigen::Vector3d(1,0,0)) / (trixelBoundary.norm())); double phi2 = acos(p.dot(Eigen::Vector3d(1,0,0)) / p.norm()); if (theta < phi1 + phi2) { if (!(tmp->_vertices[0].cross(tmp->_vertices[1]).dot(p) < 0 && tmp->_vertices[1].cross(tmp->_vertices[2]).dot(p) < 0 && tmp->_vertices[2].cross(tmp->_vertices[0]).dot(p))) { constraint->_partial.push_back(tmp); } } } } } else { LS_ADDMSG(LogService::WARNING, "ICoDF_HTM::HTM::SetConstraint", "Given right ascension and/or declination has incorrect value"); return NULL; } } else { LS_ADDMSG(LogService::NOTICE, "HTM::SetConstraint", "Given <pt> has a NULL value"); } return constraint; }