diff --git a/src/databases.cpp b/src/databases.cpp index 1c0ab7a1..748c5c42 100644 --- a/src/databases.cpp +++ b/src/databases.cpp @@ -21,6 +21,7 @@ namespace lost { const int32_t PairDistanceKVectorDatabase::kMagicValue = 0x2536f009; +const int32_t TetraDatabase::kMagicValue = 0x26683787; struct KVectorPair { int16_t index1; @@ -344,27 +345,23 @@ std::pair, std::vector> TetraPreparePattCat(cons } TetraDatabase::TetraDatabase(DeserializeContext *des) { - // maxAngle_ = *(float*)buffer; - // buffer += sizeof(float); - // catalogSize_ = *(int32_t *)buffer; maxAngle_ = DeserializePrimitive(des); - catalogSize_ = DeserializePrimitive(des); + pattCatSize_ = DeserializePrimitive(des); + tetraStarCatSize_ = DeserializePrimitive(des); + pattCats_ = DeserializeArray(des, 4 * pattCatSize_); + starCatInds_ = DeserializeArray(des, tetraStarCatSize_); } TetraPatt TetraDatabase::GetPattern(int index) const { - std::vector res; - const unsigned char *p = buffer_ + headerSize; + TetraPatt res; for (int i = 0; i < 4; i++) { - res.push_back(*((uint16_t *)p + 4 * index + i)); + res.push_back(pattCats_[4*index + i]); } - return res; } uint16_t TetraDatabase::GetTrueCatInd(int tetraInd) const { - // TODO: don't harcode this 4 - const unsigned char *p = buffer_ + headerSize + PattCatSize() * 4 * sizeof(uint16_t); - return *((uint16_t *)p + tetraInd); + return starCatInds_[tetraInd]; } std::vector TetraDatabase::GetPatternMatches(int index) const { @@ -471,7 +468,7 @@ std::vector PairDistanceKVectorDatabase::StarDistances(int16_t star, ///////////////////// Tetra database ////////////////////// -void SerializeTetraDatabase(SerializeContext *ser, Catalog &catalog, float maxFovDeg, +void SerializeTetraDatabase(SerializeContext *ser, const Catalog &catalog, float maxFovDeg, const std::vector &pattStarIndices, const std::vector &catIndices) { const float maxFovRad = DegToRad(maxFovDeg); @@ -631,6 +628,7 @@ void SerializeTetraDatabase(SerializeContext *ser, Catalog &catalog, float maxFo } SerializePrimitive(ser, maxFovDeg); SerializePrimitive(ser, pattCatalog.size()); + SerializePrimitive(ser, catIndices.size()); for (Pattern patt : pattCatalog) { for (int i = 0; i < pattSize; i++) { SerializePrimitive(ser, patt[i]); diff --git a/src/databases.hpp b/src/databases.hpp index ffb9d981..375d31c1 100644 --- a/src/databases.hpp +++ b/src/databases.hpp @@ -85,12 +85,12 @@ Pre-processing for Tetra star-id algorithm std::pair, std::vector> TetraPreparePattCat(const Catalog &, const float maxFovDeg); -void SerializeTetraDatabase(SerializeContext *, Catalog &, float maxFovDeg, - const std::vector& pattStarIndices, - const std::vector& catIndices); +void SerializeTetraDatabase(SerializeContext *, const Catalog &, float maxFovDeg, + const std::vector &pattStarIndices, + const std::vector &catIndices); /// Tetra star pattern = vector of 4 star IDs -using TetraPatt = std::vector; +using TetraPatt = std::vector; /** * A database storing Tetra star patterns @@ -98,13 +98,15 @@ using TetraPatt = std::vector; * (or guarantee load factor < 0.5) * * Layout: - * | size (bytes) | name | description | - * |-----------------+--------------+-------------------------------------------------------------| | - * | sizeof float | maxFov | max angle (degrees) allowed between any 2 stars | - * | | | in the same pattern | - * | 8 | pattCatSize | number of rows in pattern catalog | - * | 4*pattCatSize*2 | pattCat | hash table for Tetra star patternss | - * | 2*tetraCatSize | tetraStarCat | list of catalog indices to use for Tetra star-id algo | + * | size (bytes) | name | description | + * |----------------------------------+--------------+-------------------------------------------------------------| | + * | sizeof float | maxFov | max angle (degrees) allowed between any 2 stars | + * | | | in the same pattern | + * | sizeof(uint64_t) | pattCatSize | number of rows in pattern catalog | + * | sizeof(uint64_t) | tetraCatSize | number of Tetra catalog indices | + * | 4*pattCatSize * sizeof(uint16_t) | pattCat | hash table for Tetra star patternss | + * | tetraCatSize * sizeof(uint16_t) | tetraStarCat | list of catalog indices to use for Tetra star-id algo | + * |----------------------------------+--------------+-------------------------------------------------------------| */ class TetraDatabase { public: @@ -115,7 +117,7 @@ class TetraDatabase { /// Number of rows in pattern catalog // With load factor of just under 0.5, size = numPatterns*2 + 1 - int PattCatSize() const {return catalogSize_;} + uint64_t PattCatSize() const {return pattCatSize_;} /// Get the 4-tuple pattern at row=index, 0-based TetraPatt GetPattern(int index) const; @@ -129,13 +131,15 @@ class TetraDatabase { // TODO: should probably have a field describing number of indices for future updates to db /// Magic value to use when storing inside a MultiDatabase - static const int32_t kMagicValue = 0xDEADBEEF; - static const int headerSize = sizeof(float) + sizeof(uint64_t); + static const int32_t kMagicValue; + // static const int headerSize = sizeof(float) + sizeof(uint64_t); private: - // const unsigned char *buffer_; float maxAngle_; - uint32_t catalogSize_; + uint64_t pattCatSize_; + uint16_t tetraStarCatSize_; + const uint16_t* pattCats_; + const uint16_t* starCatInds_; }; // /** diff --git a/src/io.cpp b/src/io.cpp index 2b505746..06af8984 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -299,14 +299,36 @@ MultiDatabaseDescriptor GenerateDatabases(const Catalog &catalog, const Database SerializeCatalog(&catalogSer, catalog, false, true); dbEntries.emplace_back(kCatalogMagicValue, catalogSer.buffer); + bool dbProvided = false; + if (values.kvector) { + dbProvided = true; float minDistance = DegToRad(values.kvectorMinDistance); float maxDistance = DegToRad(values.kvectorMaxDistance); long numBins = values.kvectorNumDistanceBins; SerializeContext ser = serFromDbValues(values); SerializePairDistanceKVector(&ser, catalog, minDistance, maxDistance, numBins); dbEntries.emplace_back(PairDistanceKVectorDatabase::kMagicValue, ser.buffer); - } else { + } + + if (values.tetra) { + dbProvided = true; + float maxAngleDeg = values.tetraMaxAngle; + std::cerr << "Tetra max angle: " << maxAngleDeg << std::endl; + + auto tetraPrepRes = TetraPreparePattCat(catalog, maxAngleDeg); + std::vector catIndices = tetraPrepRes.first; + std::vector pattStarsInds = tetraPrepRes.second; + + std::cerr << "Tetra processed catalog has " << catIndices.size() << " stars." << std::endl; + std::cerr << "Number of pattern stars: " << pattStarsInds.size() << std::endl; + + SerializeContext ser = serFromDbValues(values); + SerializeTetraDatabase(&ser, catalog, maxAngleDeg, pattStarsInds, catIndices); + dbEntries.emplace_back(TetraDatabase::kMagicValue, ser.buffer); + } + + if (!dbProvided) { std::cerr << "No database builder selected -- no database generated." << std::endl; exit(1); } diff --git a/src/io.hpp b/src/io.hpp index 29852d37..c78454d3 100644 --- a/src/io.hpp +++ b/src/io.hpp @@ -295,10 +295,10 @@ SerializeContext serFromDbValues(const DatabaseOptions &values); /// @sa SerializeMultiDatabase MultiDatabaseDescriptor GenerateDatabases(const Catalog &, const DatabaseOptions &values); -// TODO: can we avoid the split? -void GenerateTetraDatabases(MultiDatabaseBuilder *, const Catalog &, const DatabaseOptions &values, - const std::vector &pattStars, - const std::vector &catIndices); +// // TODO: can we avoid the split? +// void GenerateTetraDatabases(MultiDatabaseBuilder *, const Catalog &, const DatabaseOptions &values, +// const std::vector &pattStars, +// const std::vector &catIndices); ///////////////////// // INSPECT CATALOG // diff --git a/src/star-id.cpp b/src/star-id.cpp index b08aaadc..ed08afee 100644 --- a/src/star-id.cpp +++ b/src/star-id.cpp @@ -114,7 +114,8 @@ StarIdentifiers TetraStarIdAlgorithm::Go(const unsigned char *database, const St std::cerr << "Could not get to Tetra database" << std::endl; return result; } - TetraDatabase tetraDatabase(databaseBuffer); + DeserializeContext des(databaseBuffer); + TetraDatabase tetraDatabase(&des); const long long catLength = tetraDatabase.PattCatSize(); const float maxFov = tetraDatabase.MaxAngle(); @@ -219,7 +220,7 @@ StarIdentifiers TetraStarIdAlgorithm::Go(const unsigned char *database, const St int hashIndex = KeyToIndex(code, numPattBins, catLength); // Get a list of Pattern Catalog rows with hash code == hashIndex // One of these Patterns in the database could be a match to our constructed Pattern - std::vector matches = tetraDatabase.GetPatternMatches(hashIndex); + std::vector matches = tetraDatabase.GetPatternMatches(hashIndex); if ((int)matches.size() == 0) { // std::cerr << "Alert: matches size = 0, continuing" << std::endl; @@ -228,7 +229,7 @@ StarIdentifiers TetraStarIdAlgorithm::Go(const unsigned char *database, const St bool alrFoundMatch = false; int numMatches = 0; - for (std::vector matchRow : matches) { + for (TetraPatt matchRow : matches) { // Construct the pattern we found in the Pattern Catalog std::vector catStarInds; std::vector catStarVecs; @@ -573,7 +574,7 @@ std::vector ConsumeInvolvingIterator(PairDistanceInvolvingIterator it) /** * Given the result of a pair-distance kvector query, build a hashmultimap of stars to other stars * that appeared with it in the query. - * + * * The resulting map is "symmetrical" in the sense that if a star B is in the map for star A, then * star A is also in the map for star B. */ diff --git a/src/star-utils.cpp b/src/star-utils.cpp index 304347f9..f513eaf5 100644 --- a/src/star-utils.cpp +++ b/src/star-utils.cpp @@ -84,17 +84,8 @@ Catalog::const_iterator FindNamedStar(const Catalog &catalog, int name) { * @param inclName Whether to include the (numerical) name of the star. * @param buffer[out] Where the serialized star is stored. */ -<<<<<<< HEAD -// TODO: make inclusion of name/magnitude true by default? -// Actually why give the option in the first place, algos like Tetra need this to work -void SerializeCatalogStar(const CatalogStar &catalogStar, bool inclMagnitude, bool inclName, - unsigned char *buffer) { - SerializeVec3(catalogStar.spatial, buffer); - buffer += SerializeLengthVec3(); -======= void SerializeCatalogStar(SerializeContext *ser, const CatalogStar &catalogStar, bool inclMagnitude, bool inclName) { SerializeVec3(ser, catalogStar.spatial); ->>>>>>> master if (inclMagnitude) { SerializePrimitive(ser, catalogStar.magnitude); }