PCL
APASSDatabaseFile.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/APASSDatabaseFile.h - Released 2024-06-18T15:48:54Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2024 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_APASSDatabaseFile_h
53 #define __PCL_APASSDatabaseFile_h
54 
56 
57 #include <pcl/Defs.h>
58 
59 #include <pcl/Flags.h>
60 #include <pcl/StarDatabaseFile.h>
61 
62 namespace pcl
63 {
64 
65 // ----------------------------------------------------------------------------
66 
85 namespace APASSStarFlag
86 {
87  enum mask_type
88  {
89  NoMag_V = 0x0001,
90  NoMag_B = 0x0002,
91  NoMag_u = 0x0004,
92  NoMag_g = 0x0008,
93  NoMag_r = 0x0010,
94  NoMag_i = 0x0020,
95  NoMag_z_s = 0x0040,
96  NoMag_Y = 0x0080,
97  PosErrorHigh = 0x0100
98  };
99 }
100 
101 // ----------------------------------------------------------------------------
102 
109 struct PCL_CLASS APASSStarData
110 {
111  double ra = 0;
112  double dec = 0;
113  float mag_V = 0;
114  float mag_B = 0;
115  float mag_u = 0;
116  float mag_g = 0;
117  float mag_r = 0;
118  float mag_i = 0;
119  float mag_z_s = 0;
120  float mag_Y = 0;
121  float err_V = 0;
122  float err_B = 0;
123  float err_u = 0;
124  float err_g = 0;
125  float err_r = 0;
126  float err_i = 0;
127  float err_z_s = 0;
128  float err_Y = 0;
129  uint16 flags = 0u;
130 };
131 
132 // ----------------------------------------------------------------------------
133 
141 
142 // ----------------------------------------------------------------------------
143 
179 class PCL_CLASS APASSDatabaseFile : public StarDatabaseFile
180 {
181 public:
182 
189  APASSDatabaseFile() = default;
190 
200  APASSDatabaseFile( const String& filePath )
201  : StarDatabaseFile( filePath )
202  {
203  static_assert( sizeof( EncodedDR9StarData ) == 32, "Invalid sizeof( APASSDatabaseFile::EncodedDR9StarData )" );
204  static_assert( sizeof( EncodedDR10StarData ) == 36, "Invalid sizeof( APASSDatabaseFile::EncodedDR10StarData )" );
205  if ( Metadata().databaseIdentifier == "APASSDR9" )
206  {
207  m_dr = "DR9";
208  m_decoder = &APASSDatabaseFile::GetEncodedDR9Data;
209  }
210  else if ( Metadata().databaseIdentifier == "APASSDR10" )
211  {
212  m_dr = "DR10";
213  m_decoder = &APASSDatabaseFile::GetEncodedDR10Data;
214  }
215  else
216  throw Error( "Invalid or unsupported APASS database file with unknown identifier '"
217  + Metadata().databaseIdentifier + "': " + filePath );
218  }
219 
223  APASSDatabaseFile& operator =( APASSDatabaseFile&& ) = default;
224 
230 
235  APASSDatabaseFile& operator =( const APASSDatabaseFile& ) = delete;
236 
268  void Search( APASSSearchData& data ) const
269  {
270  ElapsedTime T;
271  for ( const XPSD::IndexTree& tree : m_index )
272  tree.Search( data.centerRA, data.centerDec, data.radius, &data );
273  data.timeTotal += T();
274  }
275 
281  const IsoString& DataRelease() const
282  {
283  return m_dr;
284  }
285 
286 private:
287 
288  IsoString m_dr; // data release, one of "DR9", "DR10"
289 
290  using star_decoder = void (APASSDatabaseFile::*)( const ByteArray&, const XPSD::IndexTree&, const XPSD::IndexNode&, void* ) const;
291  star_decoder m_decoder = nullptr;
292 
293 #pragma pack(push, 1)
294 
295  /*
296  * Encoded DR9 star record (32 bytes uncompressed).
297  */
298  struct EncodedDR9StarData
299  {
300  // Projected coordinates relative to the origin of the parent quadtree
301  // node, in mas units.
302  uint32 dx;
303  uint32 dy;
304  // Magnitudes in 0.001 mag units, encoded as (mag + 1.5)*1000.
305  uint16 mag_V;
306  uint16 mag_B;
307  uint16 mag_g;
308  uint16 mag_r;
309  uint16 mag_i;
310  // Magnitude uncertainties in 0.001 mag units.
311  uint16 err_V;
312  uint16 err_B;
313  uint16 err_g;
314  uint16 err_r;
315  uint16 err_i;
316  // Right ascension correction for high declinations, in 0.1 mas units.
317  int16 dra;
318  // Data availability and quality flags.
319  uint16 flags;
320  };
321 
322  /*
323  * Encoded DR10 star record (36 bytes uncompressed).
324  */
325  struct EncodedDR10StarData
326  {
327  // Projected coordinates relative to the origin of the parent quadtree
328  // node, in mas units.
329  uint32 dx;
330  uint32 dy;
331  // Magnitudes in 0.001 mag units, encoded as (mag + 1.5)*1000.
332  uint16 mag_V;
333  uint16 mag_B;
334  // uint16 mag_u;
335  uint16 mag_g;
336  uint16 mag_r;
337  uint16 mag_i;
338  uint16 mag_z_s;
339  // uint16 mag_Y;
340  // Magnitude uncertainties in 0.001 mag units.
341  uint16 err_V;
342  uint16 err_B;
343  // uint16 err_u;
344  uint16 err_g;
345  uint16 err_r;
346  uint16 err_i;
347  uint16 err_z_s;
348  // uint16 err_Y;
349  // Right ascension correction for high declinations, in 0.1 mas units.
350  int16 dra;
351  // Data availability and quality flags.
352  uint16 flags;
353  };
354 
355 #pragma pack(pop)
356 
357  void GetEncodedData( const ByteArray& data, const XPSD::IndexTree& tree, const XPSD::IndexNode& node, void* searchData ) const override
358  {
359  (this->*m_decoder)( data, tree, node, searchData );
360  }
361 
362  void GetEncodedDR9Data( const ByteArray& data, const XPSD::IndexTree& tree, const XPSD::IndexNode& node, void* searchData ) const
363  {
364  ElapsedTime T;
365  APASSSearchData* search = reinterpret_cast<APASSSearchData*>( searchData );
366  double r = Rad( search->radius );
367  const EncodedDR9StarData* S = reinterpret_cast<const EncodedDR9StarData*>( data.Begin() );
368  int count = int( data.Size() / sizeof( EncodedDR9StarData ) );
369  int matched = 0;
370  for ( int i = 0; i < count; ++i, ++S )
371  if ( search->requiredFlags == 0 || (S->flags & search->requiredFlags) == search->requiredFlags )
372  if ( search->inclusionFlags == 0 || (S->flags & search->inclusionFlags) != 0 )
373  if ( search->exclusionFlags == 0 || (S->flags & search->exclusionFlags) == 0 )
374  {
375  float mag_V = 0.001*S->mag_V - 1.5;
376  if ( mag_V >= search->magnitudeLow )
377  if ( mag_V <= search->magnitudeHigh )
378  {
379  APASSStarData star;
380  double x = node.x0 + double( S->dx )/3600/1000;
381  double y = node.y0 + double( S->dy )/3600/1000;
382  tree.Unproject( star.ra, star.dec, x, y );
383  if ( unlikely( S->dra != 0 ) )
384  {
385  star.ra += double( S->dra )/3600/1000/10;
386  if ( star.ra < 0 )
387  star.ra += 360;
388  else if ( star.ra >= 360 )
389  star.ra -= 360;
390  }
391  if ( Distance( search->centerRA, search->centerDec, star.ra, star.dec ) < r )
392  {
393  if ( search->stars.Length() < size_type( search->sourceLimit ) )
394  {
395  star.mag_V = mag_V;
396  star.mag_B = 0.001*S->mag_B - 1.5;
397  star.mag_g = 0.001*S->mag_g - 1.5;
398  star.mag_r = 0.001*S->mag_r - 1.5;
399  star.mag_i = 0.001*S->mag_i - 1.5;
400  star.err_V = 0.001*S->err_V;
401  star.err_B = 0.001*S->err_B;
402  star.err_g = 0.001*S->err_g;
403  star.err_r = 0.001*S->err_r;
404  star.err_i = 0.001*S->err_i;
405  star.flags = S->flags;
406  search->stars << star;
407  }
408  else
409  ++search->excessCount;
410  ++matched;
411  }
412  }
413  }
414 
415  search->rejectCount += count - matched;
416  search->timeDecode += T();
417  }
418 
419  void GetEncodedDR10Data( const ByteArray& data, const XPSD::IndexTree& tree, const XPSD::IndexNode& node, void* searchData ) const
420  {
421  ElapsedTime T;
422  APASSSearchData* search = reinterpret_cast<APASSSearchData*>( searchData );
423  double r = Rad( search->radius );
424  const EncodedDR10StarData* S = reinterpret_cast<const EncodedDR10StarData*>( data.Begin() );
425  int count = int( data.Size() / sizeof( EncodedDR10StarData ) );
426  int matched = 0;
427  for ( int i = 0; i < count; ++i, ++S )
428  if ( search->requiredFlags == 0 || (S->flags & search->requiredFlags) == search->requiredFlags )
429  if ( search->inclusionFlags == 0 || (S->flags & search->inclusionFlags) != 0 )
430  if ( search->exclusionFlags == 0 || (S->flags & search->exclusionFlags) == 0 )
431  {
432  float mag_V = 0.001*S->mag_V - 1.5;
433  if ( mag_V >= search->magnitudeLow )
434  if ( mag_V <= search->magnitudeHigh )
435  {
436  APASSStarData star;
437  double x = node.x0 + double( S->dx )/3600/1000;
438  double y = node.y0 + double( S->dy )/3600/1000;
439  tree.Unproject( star.ra, star.dec, x, y );
440  if ( unlikely( S->dra != 0 ) )
441  {
442  star.ra += double( S->dra )/3600/1000/10;
443  if ( star.ra < 0 )
444  star.ra += 360;
445  else if ( star.ra >= 360 )
446  star.ra -= 360;
447  }
448  if ( Distance( search->centerRA, search->centerDec, star.ra, star.dec ) < r )
449  {
450  if ( search->stars.Length() < size_type( search->sourceLimit ) )
451  {
452  star.mag_V = mag_V;
453  star.mag_B = 0.001*S->mag_B - 1.5;
454  // star.mag_u = 0.001*S->mag_u - 1.5;
455  star.mag_g = 0.001*S->mag_g - 1.5;
456  star.mag_r = 0.001*S->mag_r - 1.5;
457  star.mag_i = 0.001*S->mag_i - 1.5;
458  star.mag_z_s = 0.001*S->mag_z_s - 1.5;
459  // star.mag_Y = 0.001*S->mag_Y - 1.5;
460  star.err_V = 0.001*S->err_V;
461  star.err_B = 0.001*S->err_B;
462  // star.err_u = 0.001*S->err_u;
463  star.err_g = 0.001*S->err_g;
464  star.err_r = 0.001*S->err_r;
465  star.err_i = 0.001*S->err_i;
466  star.err_z_s = 0.001*S->err_z_s;
467  // star.err_Y = 0.001*S->err_Y;
468  star.flags = S->flags;
469  search->stars << star;
470  }
471  else
472  ++search->excessCount;
473  ++matched;
474  }
475  }
476  }
477 
478  search->rejectCount += count - matched;
479  search->timeDecode += T();
480  }
481 
482  friend class APASSDR9DatabaseFileGenerator;
483  friend class APASSDR10DatabaseFileGenerator;
484 };
485 
486 // ----------------------------------------------------------------------------
487 
488 } // pcl
489 
490 #endif // __PCL_APASSDatabaseFile_h
491 
492 // ----------------------------------------------------------------------------
493 // EOF pcl/APASSDatabaseFile.h - Released 2024-06-18T15:48:54Z
APASS catalog star database file (XPSD format).
void Search(APASSSearchData &data) const
APASSDatabaseFile(const String &filePath)
const IsoString & DataRelease() const
APASSDatabaseFile(const APASSDatabaseFile &)=delete
Dynamic array of 8-bit unsigned integers.
High-resolution time stamp.
Definition: ElapsedTime.h:131
A simple exception with an associated error message.
Definition: Exception.h:239
Eight-bit string (ISO/IEC-8859-1 or UTF-8 string)
Definition: String.h:5425
Point source and star catalog database files (XPSD format).
Unicode (UTF-16) string.
Definition: String.h:8113
constexpr T Rad(T x) noexcept
Definition: Math.h:1894
unsigned short uint16
Definition: Defs.h:654
signed short int16
Definition: Defs.h:648
unsigned int uint32
Definition: Defs.h:666
size_t size_type
Definition: Defs.h:609
PCL root namespace.
Definition: AbstractImage.h:77
distance_type Distance(FI i, FI j)
Definition: Iterator.h:161
Data items and parameters for APASS catalog search operations.
Star data structure for APASS catalog search operations.
Metadata items available in point source database files.
double radius
Field radius in degrees (search parameter).
double centerDec
Field center declination coordinate in degrees (search parameter).
double centerRA
Field center right ascension coordinate in degrees (search parameter).
double timeTotal
Total search time in seconds (output data).
Data items and parameters for catalog search operations.