Merge lp:~stellarium/stellarium/catalog-cleanup into lp:stellarium
- catalog-cleanup
- Merge into trunk
Proposed by
Alexander Wolf
Status: | Merged |
---|---|
Merged at revision: | 6355 |
Proposed branch: | lp:~stellarium/stellarium/catalog-cleanup |
Merge into: | lp:stellarium |
Diff against target: |
1865 lines (+1725/-35) 4 files modified
src/core/modules/StarMgr.cpp (+1/-1) stars/default/CMakeLists.txt (+1/-1) stars/default/defaultStarsConfig.json (+33/-33) util/MakeCombinedCatalogue.v2.C (+1690/-0) |
To merge this branch: | bzr merge lp:~stellarium/stellarium/catalog-cleanup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
treaves | Approve | ||
Review via email: mp+196293@code.launchpad.net |
Commit message
Description of the change
This branch contains re-packed stars catalogues without a many artifacts.
I prefer merge it by myself.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/core/modules/StarMgr.cpp' |
2 | --- src/core/modules/StarMgr.cpp 2013-10-18 04:42:17 +0000 |
3 | +++ src/core/modules/StarMgr.cpp 2013-11-22 14:47:49 +0000 |
4 | @@ -68,7 +68,7 @@ |
5 | // This number must be incremented each time the content or file format of the stars catalogs change |
6 | // It can also be incremented when the defaultStarsConfig.json file change. |
7 | // It should always matchs the version field of the defaultStarsConfig.json file |
8 | -static const int StarCatalogFormatVersion = 4; |
9 | +static const int StarCatalogFormatVersion = 5; |
10 | |
11 | // Initialise statics |
12 | bool StarMgr::flagSciNames = true; |
13 | |
14 | === modified file 'stars/default/CMakeLists.txt' |
15 | --- stars/default/CMakeLists.txt 2013-05-08 15:48:03 +0000 |
16 | +++ stars/default/CMakeLists.txt 2013-11-22 14:47:49 +0000 |
17 | @@ -1,5 +1,5 @@ |
18 | |
19 | ########### install files ############### |
20 | |
21 | -INSTALL(FILES defaultStarsConfig.json name.fab stars_0_0v0_3.cat stars_1_0v0_3.cat stars_2_0v0_3.cat stars_3_1v0_2.cat stars_hip_cids_0v0_0.cat stars_hip_sp_0v0_0.cat gcvs_hip_part.dat DESTINATION share/${PACKAGE}/stars/default) |
22 | +INSTALL(FILES defaultStarsConfig.json name.fab stars_0_0v0_4.cat stars_1_0v0_4.cat stars_2_0v0_4.cat stars_3_1v0_3.cat stars_hip_cids_0v0_0.cat stars_hip_sp_0v0_0.cat gcvs_hip_part.dat DESTINATION share/${PACKAGE}/stars/default) |
23 | |
24 | |
25 | === modified file 'stars/default/defaultStarsConfig.json' |
26 | --- stars/default/defaultStarsConfig.json 2013-05-03 17:35:56 +0000 |
27 | +++ stars/default/defaultStarsConfig.json 2013-11-22 14:47:49 +0000 |
28 | @@ -1,93 +1,93 @@ |
29 | { |
30 | - "version": 4, |
31 | + "version": 5, |
32 | "hipSpectralFile": "stars_hip_sp_0v0_0.cat", |
33 | "hipComponentsIdsFile": "stars_hip_cids_0v0_0.cat", |
34 | "catalogs": |
35 | [ |
36 | { |
37 | "id": "stars0", |
38 | - "fileName": "stars_0_0v0_3.cat", |
39 | + "fileName": "stars_0_0v0_4.cat", |
40 | "count": 0.005, |
41 | "magRange": [-2, 6], |
42 | "sizeMb": 0.1, |
43 | - "checksum": "89b6833280270f0846f2c7dae1e310e0", |
44 | + "checksum": "d18dafce604d850efeab79aa8402222c", |
45 | "checked": true |
46 | }, |
47 | { |
48 | "id": "stars1", |
49 | - "fileName": "stars_1_0v0_3.cat", |
50 | + "fileName": "stars_1_0v0_4.cat", |
51 | "count": 0.022, |
52 | "magRange": [6, 7.5], |
53 | "sizeMb": 0.6, |
54 | - "checksum": "59eeeb88a0939930a7ae1042fb542bdd", |
55 | + "checksum": "cdf19a423ed3e129bb5cd6fa0d3a09e2", |
56 | "checked": true |
57 | }, |
58 | { |
59 | "id": "stars2", |
60 | - "fileName": "stars_2_0v0_3.cat", |
61 | + "fileName": "stars_2_0v0_4.cat", |
62 | "count": 0.15, |
63 | "magRange": [7.5, 9], |
64 | "sizeMb": 4.1, |
65 | - "checksum": "43e4a39a7198761e675b0f490de8a9ae", |
66 | + "checksum": "5a4c185f79c31c13b0e27d761e407f97", |
67 | "checked": true |
68 | }, |
69 | { |
70 | "id": "stars3", |
71 | - "fileName": "stars_3_1v0_2.cat", |
72 | + "fileName": "stars_3_1v0_3.cat", |
73 | "count": 0.43, |
74 | "magRange": [9, 10.5], |
75 | - "sizeMb": 4.2, |
76 | - "checksum": "7bfebdea2d6fd7eae8958f36edd82a77", |
77 | + "sizeMb": 4.1, |
78 | + "checksum": "0b2481f67b0af30dbb027d62761cc061", |
79 | "checked": true |
80 | }, |
81 | { |
82 | "id": "stars4", |
83 | - "fileName": "stars_4_1v0_0.cat", |
84 | + "fileName": "stars_4_1v0_1.cat", |
85 | "count": 1.7, |
86 | "magRange": [10.5, 12], |
87 | "sizeMb": 17, |
88 | - "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_4_1v0_0.cat", |
89 | - "checksum": "3abe460ce558418dbdab9a251c173cc4", |
90 | + "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_4_1v0_1.cat", |
91 | + "checksum": "7a3b8b3471a755661b6d3686eb4c7cc2", |
92 | "checked": false |
93 | }, |
94 | { |
95 | "id": "stars5", |
96 | - "fileName": "stars_5_2v0_0.cat", |
97 | - "count": 7.7, |
98 | + "fileName": "stars_5_2v0_1.cat", |
99 | + "count": 7.1, |
100 | "magRange": [12, 13.5], |
101 | - "sizeMb": 44, |
102 | - "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_5_2v0_0.cat", |
103 | - "checksum": "67278f69d584b95710eba3e322e22f2e", |
104 | + "sizeMb": 41, |
105 | + "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_5_2v0_1.cat", |
106 | + "checksum": "50e798428d9402766805da5cf0e8e819", |
107 | "checked": false |
108 | }, |
109 | { |
110 | "id": "stars6", |
111 | - "fileName": "stars_6_2v0_0.cat", |
112 | - "count": 26.6, |
113 | + "fileName": "stars_6_2v0_1.cat", |
114 | + "count": 24.7, |
115 | "magRange": [13.5, 15], |
116 | - "sizeMb": 153, |
117 | - "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_6_2v0_0.cat", |
118 | - "checksum": "2f9a908226a5b7732319b950729b658b", |
119 | + "sizeMb": 142, |
120 | + "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_6_2v0_1.cat", |
121 | + "checksum": "3005959bf7baca36d266def2fecf36d3", |
122 | "checked": false |
123 | }, |
124 | { |
125 | "id": "stars7", |
126 | - "fileName": "stars_7_2v0_0.cat", |
127 | - "count": 57.8, |
128 | + "fileName": "stars_7_2v0_1.cat", |
129 | + "count": 50.8, |
130 | "magRange": [15, 16.5], |
131 | - "sizeMb": 333, |
132 | - "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_7_2v0_0.cat", |
133 | - "checksum": "e05a444abb23232267b10567901b547b", |
134 | + "sizeMb": 292, |
135 | + "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_7_2v0_1.cat", |
136 | + "checksum": "15f856fb4c7830a71cb8d60e1decc387", |
137 | "checked": false |
138 | }, |
139 | { |
140 | "id": "stars8", |
141 | - "fileName": "stars_8_2v0_0.cat", |
142 | - "count": 116.9, |
143 | + "fileName": "stars_8_2v0_1.cat", |
144 | + "count": 92.3, |
145 | "magRange": [16.5, 18], |
146 | - "sizeMb": 674, |
147 | - "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_8_2v0_0.cat", |
148 | - "checksum": "b804136f5c5584e9508f21a1f7aa1a28", |
149 | + "sizeMb": 534, |
150 | + "url": "http://downloads.sourceforge.net/sourceforge/stellarium/stars_8_2v0_1.cat", |
151 | + "checksum": "9e2e362022824c60d7e4d94ef8c3af12", |
152 | "checked": false |
153 | } |
154 | ] |
155 | |
156 | === removed file 'stars/default/stars_0_0v0_3.cat' |
157 | Binary files stars/default/stars_0_0v0_3.cat 2013-05-03 17:35:56 +0000 and stars/default/stars_0_0v0_3.cat 1970-01-01 00:00:00 +0000 differ |
158 | === added file 'stars/default/stars_0_0v0_4.cat' |
159 | Binary files stars/default/stars_0_0v0_4.cat 1970-01-01 00:00:00 +0000 and stars/default/stars_0_0v0_4.cat 2013-11-22 14:47:49 +0000 differ |
160 | === removed file 'stars/default/stars_1_0v0_3.cat' |
161 | Binary files stars/default/stars_1_0v0_3.cat 2013-05-03 17:35:56 +0000 and stars/default/stars_1_0v0_3.cat 1970-01-01 00:00:00 +0000 differ |
162 | === added file 'stars/default/stars_1_0v0_4.cat' |
163 | Binary files stars/default/stars_1_0v0_4.cat 1970-01-01 00:00:00 +0000 and stars/default/stars_1_0v0_4.cat 2013-11-22 14:47:49 +0000 differ |
164 | === removed file 'stars/default/stars_2_0v0_3.cat' |
165 | Binary files stars/default/stars_2_0v0_3.cat 2013-05-03 17:35:56 +0000 and stars/default/stars_2_0v0_3.cat 1970-01-01 00:00:00 +0000 differ |
166 | === added file 'stars/default/stars_2_0v0_4.cat' |
167 | Binary files stars/default/stars_2_0v0_4.cat 1970-01-01 00:00:00 +0000 and stars/default/stars_2_0v0_4.cat 2013-11-22 14:47:49 +0000 differ |
168 | === removed file 'stars/default/stars_3_1v0_2.cat' |
169 | Binary files stars/default/stars_3_1v0_2.cat 2013-05-03 17:35:56 +0000 and stars/default/stars_3_1v0_2.cat 1970-01-01 00:00:00 +0000 differ |
170 | === added file 'stars/default/stars_3_1v0_3.cat' |
171 | Binary files stars/default/stars_3_1v0_3.cat 1970-01-01 00:00:00 +0000 and stars/default/stars_3_1v0_3.cat 2013-11-22 14:47:49 +0000 differ |
172 | === added file 'util/MakeCombinedCatalogue.v2.C' |
173 | --- util/MakeCombinedCatalogue.v2.C 1970-01-01 00:00:00 +0000 |
174 | +++ util/MakeCombinedCatalogue.v2.C 2013-11-22 14:47:49 +0000 |
175 | @@ -0,0 +1,1690 @@ |
176 | +// Author and Copyright: Johannes Gajdosik, 2006 |
177 | +// Modifications: Alexander Wolf, 2013 |
178 | +// License: GPL |
179 | +// g++ -O2 MakeCombinedCatalogue.C -o MakeCombinedCatalogue |
180 | + |
181 | + |
182 | +// change catalogue locations according to your needs: |
183 | + |
184 | +const char *nomad_names[]={ |
185 | + "/storage/1T/nomad.sml/Nomad00.sml", |
186 | + "/storage/1T/nomad.sml/Nomad01.sml", |
187 | + "/storage/1T/nomad.sml/Nomad02.sml", |
188 | + "/storage/1T/nomad.sml/Nomad03.sml", |
189 | + "/storage/1T/nomad.sml/Nomad04.sml", |
190 | + "/storage/1T/nomad.sml/Nomad05.sml", |
191 | + "/storage/1T/nomad.sml/Nomad06.sml", |
192 | + "/storage/1T/nomad.sml/Nomad07.sml", |
193 | + "/storage/1T/nomad.sml/Nomad08.sml", |
194 | + "/storage/1T/nomad.sml/Nomad09.sml", |
195 | + "/storage/1T/nomad.sml/Nomad10.sml", |
196 | + "/storage/1T/nomad.sml/Nomad11.sml", |
197 | + "/storage/1T/nomad.sml/Nomad12.sml", |
198 | + "/storage/1T/nomad.sml/Nomad13.sml", |
199 | + "/storage/1T/nomad.sml/Nomad14.sml", |
200 | + "/storage/1T/nomad.sml/Nomad15.sml", |
201 | + "/storage/1T/nomad.sml/Nomad16.sml", |
202 | + 0 |
203 | +}; |
204 | + |
205 | + |
206 | + |
207 | +#define NR_OF_HIP 120416 |
208 | + |
209 | +#define MAX_HIP_LEVEL 2 |
210 | +#define MAX_TYC_LEVEL 4 |
211 | +#define MAX_LEVEL 9 |
212 | + |
213 | +static |
214 | +const char *output_file_names[MAX_LEVEL+1] = { |
215 | + "stars0.cat", |
216 | + "stars1.cat", |
217 | + "stars2.cat", |
218 | + "stars3.cat", |
219 | + "stars4.cat", |
220 | + "stars5.cat", |
221 | + "stars6.cat", |
222 | + "stars7.cat", |
223 | + "stars8.cat", |
224 | + "stars9.cat" |
225 | +}; |
226 | + |
227 | +static |
228 | +const char *component_ids_filename = "stars_hip_component_ids.cat"; |
229 | + |
230 | +static |
231 | +const char *sp_filename = "stars_hip_sp.cat"; |
232 | + |
233 | +static |
234 | +const double level_mag_limit[MAX_LEVEL+1] = { |
235 | + 6,7.5,9, |
236 | + 10.5,12, |
237 | + 13.5,15,16.5,18,19.5 |
238 | +}; |
239 | + |
240 | + |
241 | + |
242 | + |
243 | + |
244 | + |
245 | + |
246 | + |
247 | + |
248 | +/* |
249 | + |
250 | +Vector (simple 3d-Vector) |
251 | + |
252 | +Author and Copyright: Johannes Gajdosik, 2006 |
253 | + |
254 | +License: GPL |
255 | + |
256 | +*/ |
257 | + |
258 | + |
259 | +#include <math.h> |
260 | + |
261 | +struct Vector { |
262 | + double x[3]; |
263 | + inline double length(void) const; |
264 | + inline void normalize(void); |
265 | + const Vector &operator+=(const Vector &a) { |
266 | + x[0] += a.x[0]; |
267 | + x[1] += a.x[1]; |
268 | + x[2] += a.x[2]; |
269 | + } |
270 | + const Vector &operator-=(const Vector &a) { |
271 | + x[0] -= a.x[0]; |
272 | + x[1] -= a.x[1]; |
273 | + x[2] -= a.x[2]; |
274 | + } |
275 | +}; |
276 | + |
277 | +static inline |
278 | +Vector operator^(const Vector &a,const Vector &b) { |
279 | + Vector c; |
280 | + c.x[0] = a.x[1]*b.x[2] - a.x[2]*b.x[1]; |
281 | + c.x[1] = a.x[2]*b.x[0] - a.x[0]*b.x[2]; |
282 | + c.x[2] = a.x[0]*b.x[1] - a.x[1]*b.x[0]; |
283 | + return c; |
284 | +} |
285 | + |
286 | +static inline |
287 | +Vector operator-(const Vector &a,const Vector &b) { |
288 | + Vector c; |
289 | + c.x[0] = a.x[0]-b.x[0]; |
290 | + c.x[1] = a.x[1]-b.x[1]; |
291 | + c.x[2] = a.x[2]-b.x[2]; |
292 | + return c; |
293 | +} |
294 | + |
295 | +static inline |
296 | +Vector operator+(const Vector &a,const Vector &b) { |
297 | + Vector c; |
298 | + c.x[0] = a.x[0]+b.x[0]; |
299 | + c.x[1] = a.x[1]+b.x[1]; |
300 | + c.x[2] = a.x[2]+b.x[2]; |
301 | + return c; |
302 | +} |
303 | + |
304 | +static inline |
305 | +Vector operator*(double a,const Vector &b) { |
306 | + Vector c; |
307 | + c.x[0] = a*b.x[0]; |
308 | + c.x[1] = a*b.x[1]; |
309 | + c.x[2] = a*b.x[2]; |
310 | + return c; |
311 | +} |
312 | + |
313 | +static inline |
314 | +Vector operator*(const Vector &b,double a) { |
315 | + Vector c; |
316 | + c.x[0] = a*b.x[0]; |
317 | + c.x[1] = a*b.x[1]; |
318 | + c.x[2] = a*b.x[2]; |
319 | + return c; |
320 | +} |
321 | + |
322 | +static inline |
323 | +double operator*(const Vector &a,const Vector &b) { |
324 | + return a.x[0]*b.x[0]+a.x[1]*b.x[1]+a.x[2]*b.x[2]; |
325 | +} |
326 | + |
327 | +double Vector::length(void) const { |
328 | + return sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]); |
329 | +} |
330 | + |
331 | +void Vector::normalize(void) { |
332 | + const double l = 1.0/length(); |
333 | + x[0] *= l; |
334 | + x[1] *= l; |
335 | + x[2] *= l; |
336 | +} |
337 | + |
338 | + |
339 | + |
340 | + |
341 | +void ChangeEpoch(double delta_years, |
342 | + double &ra,double &dec, // degrees |
343 | + double pm_ra,double pm_dec // mas/yr |
344 | + ) { |
345 | + ra *= (M_PI/180); |
346 | + dec *= (M_PI/180); |
347 | + |
348 | + const double cdec = cos(dec); |
349 | + Vector x = {cos(ra)*cdec,sin(ra)*cdec,sin(dec)}; |
350 | + const Vector north = {0.0,0.0,1.0}; |
351 | + |
352 | + Vector axis0 = north ^ x; |
353 | + axis0.normalize(); |
354 | + const Vector axis1 = x ^ axis0; |
355 | + |
356 | + const double f = delta_years*(0.001/3600)*(M_PI/180); |
357 | + |
358 | + x += pm_ra*f*axis1 + pm_dec*f*axis0; |
359 | + |
360 | + ra = atan2(x.x[1],x.x[0]); |
361 | + if (ra < 0.0) ra += 2*M_PI; |
362 | + dec = atan2(x.x[2],sqrt(x.x[0]*x.x[0]+x.x[1]*x.x[1])); |
363 | + |
364 | + ra *= (180/M_PI); |
365 | + dec *= (180/M_PI); |
366 | +} |
367 | + |
368 | + |
369 | + |
370 | + |
371 | + |
372 | + |
373 | +//------------------------------------------------ |
374 | + |
375 | +/* |
376 | + |
377 | +GeodesicGrid: a library for dividing the sphere into triangle zones |
378 | +by subdividing the icosahedron |
379 | + |
380 | +Author and Copyright: Johannes Gajdosik, 2006 |
381 | + |
382 | +This library requires a simple Vector library, |
383 | +which may have different copyright and license. |
384 | + |
385 | +In the moment I choose to distribute the library under the GPL, |
386 | +later I may choose to additionally distribute it under a more |
387 | +relaxed license like the LGPL. If you want to have the library |
388 | +under another license, please ask me. |
389 | + |
390 | + |
391 | + |
392 | +This library is free software; you can redistribute it and/or |
393 | +modify it under the terms of the GNU General Public License |
394 | +as published by the Free Software Foundation; either version 2 |
395 | +of the License, or (at your option) any later version. |
396 | + |
397 | +This library is distributed in the hope that it will be useful, |
398 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
399 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
400 | +GNU General Public License for more details. |
401 | + |
402 | +You should have received a copy of the GNU General Public License |
403 | +along with this library; if not, write to the Free Software |
404 | +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
405 | + |
406 | +*/ |
407 | + |
408 | +using namespace std; |
409 | + |
410 | +struct HalfSpace { |
411 | + // all x with x*n-d >= 0 |
412 | + Vector n; |
413 | + double d; |
414 | + bool inside(const Vector &x) const {return (x*n>=d);} |
415 | +}; |
416 | + |
417 | +class GeodesicGrid { |
418 | + // Grid of triangles (zones) on the sphere with radius 1, |
419 | + // generated by subdividing the icosahedron. |
420 | + // level 0: just the icosahedron, 20 zones |
421 | + // level 1: 80 zones, level 2: 320 zones, ... |
422 | + // Each zone has a unique integer number in the range |
423 | + // [0,getNrOfZones()-1]. |
424 | +public: |
425 | + GeodesicGrid(int max_level); |
426 | + ~GeodesicGrid(void); |
427 | + int getMaxLevel(void) const {return max_level;} |
428 | + static int nrOfZones(int level) |
429 | + {return (20<<(level<<1));} // 20*4^level |
430 | + int getNrOfZones(void) const {return nrOfZones(max_level);} |
431 | + void getTriangleCorners(int lev, int index, Vector& c0, Vector& c1, Vector& c2) const; |
432 | + // Return the position of the 3 corners for the triangle at the given level and index |
433 | + int getPartnerTriangle(int lev, int index) const; |
434 | + // Return the index of the partner triangle with which to form a paralelogram |
435 | + typedef void (VisitFunc)(int lev,int index, |
436 | + const Vector &c0, |
437 | + const Vector &c1, |
438 | + const Vector &c2, |
439 | + void *context); |
440 | + void visitTriangles(int max_visit_level, |
441 | + VisitFunc *func,void *context) const; |
442 | + |
443 | + int searchZone(const Vector &v,int search_level) const; |
444 | + // find the zone number in which a given point lies. |
445 | + // prerequisite: v*v==1 |
446 | + // When the point lies on the border of two or more zones, |
447 | + // one such zone is returned (always the same one, |
448 | + // because the algorithm is deterministic). |
449 | + |
450 | + void searchZones(const HalfSpace *half_spaces,int nr_of_half_spaces, |
451 | + int **inside,int **border,int max_search_level) const; |
452 | + // find all zones that lie fully(inside) or partly(border) |
453 | + // in the intersection of the given half spaces. |
454 | + // The result is accurate when (0,0,0) lies on the border of |
455 | + // each half space. If this is not the case, |
456 | + // the result may be inaccurate, because it is assumed, that |
457 | + // a zone lies in a half space when its 3 corners lie in |
458 | + // this half space. |
459 | + // inside[l] points to the begin of an integer array of size nrOfZones(l), |
460 | + // border[l] points to one after the end of the same integer array. |
461 | + // The array will be filled from the beginning with the inside zone numbers |
462 | + // and from the end with the border zone numbers of the given level l |
463 | + // for 0<=l<=getMaxLevel(). |
464 | + // inside[l] will not contain zones that are already contained |
465 | + // in inside[l1] for some l1 < l. |
466 | + // In order to restrict search depth set max_search_level < max_level, |
467 | + // for full search depth set max_search_level = max_level, |
468 | + |
469 | +private: |
470 | + const Vector& getTriangleCorner(int lev, int index, int cornerNumber) const; |
471 | + void initTriangle(int lev,int index, |
472 | + const Vector &c0, |
473 | + const Vector &c1, |
474 | + const Vector &c2); |
475 | + void visitTriangles(int lev,int index, |
476 | + const Vector &c0, |
477 | + const Vector &c1, |
478 | + const Vector &c2, |
479 | + int max_visit_level, |
480 | + VisitFunc *func, |
481 | + void *context) const; |
482 | + void searchZones(int lev,int index, |
483 | + const HalfSpace *half_spaces, |
484 | + const int nr_of_half_spaces, |
485 | + const int *index_of_used_half_spaces, |
486 | + const int half_spaces_used, |
487 | + const bool *corner0_inside, |
488 | + const bool *corner1_inside, |
489 | + const bool *corner2_inside, |
490 | + int **inside,int **border,int max_search_level) const; |
491 | +private: |
492 | + const int max_level; |
493 | + struct Triangle { |
494 | + Vector e0,e1,e2; // Seitenmittelpunkte |
495 | + }; |
496 | + Triangle **triangles; |
497 | + // 20*(4^0+4^1+...+4^n)=20*(4*(4^n)-1)/3 triangles total |
498 | + // 2+10*4^n corners |
499 | +}; |
500 | + |
501 | +class GeodesicSearchResult { |
502 | +public: |
503 | + GeodesicSearchResult(const GeodesicGrid &grid); |
504 | + ~GeodesicSearchResult(void); |
505 | + void search(const HalfSpace *half_spaces, |
506 | + const int nr_of_half_spaces, |
507 | + int max_search_level); |
508 | + void search(const Vector &e0,const Vector &e1,const Vector &e2,const Vector &e3, |
509 | + int max_search_level); |
510 | + void print(void) const; |
511 | +private: |
512 | + friend class GeodesicSearchInsideIterator; |
513 | + friend class GeodesicSearchBorderIterator; |
514 | + const GeodesicGrid &grid; |
515 | + int **const zones; |
516 | + int **const inside; |
517 | + int **const border; |
518 | +}; |
519 | + |
520 | +class GeodesicSearchBorderIterator { |
521 | +public: |
522 | + GeodesicSearchBorderIterator(const GeodesicSearchResult &r,int level) |
523 | + : r(r),level((level<0)?0:(level>r.grid.getMaxLevel()) |
524 | + ?r.grid.getMaxLevel():level), |
525 | + end(r.zones[GeodesicSearchBorderIterator::level]+ |
526 | + GeodesicGrid::nrOfZones(GeodesicSearchBorderIterator::level)) |
527 | + {reset();} |
528 | + void reset(void) {index = r.border[level];} |
529 | + int next(void) // returns -1 when finished |
530 | + {if (index < end) {return *index++;} return -1;} |
531 | +private: |
532 | + const GeodesicSearchResult &r; |
533 | + const int level; |
534 | + const int *const end; |
535 | + const int *index; |
536 | +}; |
537 | + |
538 | + |
539 | +class GeodesicSearchInsideIterator { |
540 | +public: |
541 | + GeodesicSearchInsideIterator(const GeodesicSearchResult &r,int level) |
542 | + : r(r),max_level((level<0)?0:(level>r.grid.getMaxLevel()) |
543 | + ?r.grid.getMaxLevel():level) |
544 | + {reset();} |
545 | + void reset(void); |
546 | + int next(void); // returns -1 when finished |
547 | +private: |
548 | + const GeodesicSearchResult &r; |
549 | + const int max_level; |
550 | + int level; |
551 | + int max_count; |
552 | + int *index_p; |
553 | + int *end_p; |
554 | + int index; |
555 | + int count; |
556 | +}; |
557 | + |
558 | +#include <stdlib.h> |
559 | +#include <cassert> |
560 | +#include <iostream> |
561 | + |
562 | +using namespace std; |
563 | + |
564 | +static const double icosahedron_G = 0.5*(1.0+sqrt(5.0)); |
565 | +static const double icosahedron_b = 1.0/sqrt(1.0+icosahedron_G*icosahedron_G); |
566 | +static const double icosahedron_a = icosahedron_b*icosahedron_G; |
567 | + |
568 | +static const Vector icosahedron_corners[12] = { |
569 | + { icosahedron_a, -icosahedron_b, 0.0}, |
570 | + { icosahedron_a, icosahedron_b, 0.0}, |
571 | + {-icosahedron_a, icosahedron_b, 0.0}, |
572 | + {-icosahedron_a, -icosahedron_b, 0.0}, |
573 | + { 0.0, icosahedron_a, -icosahedron_b}, |
574 | + { 0.0, icosahedron_a, icosahedron_b}, |
575 | + { 0.0, -icosahedron_a, icosahedron_b}, |
576 | + { 0.0, -icosahedron_a, -icosahedron_b}, |
577 | + {-icosahedron_b, 0.0, icosahedron_a}, |
578 | + { icosahedron_b, 0.0, icosahedron_a}, |
579 | + { icosahedron_b, 0.0, -icosahedron_a}, |
580 | + {-icosahedron_b, 0.0, -icosahedron_a} |
581 | +}; |
582 | + |
583 | +struct TopLevelTriangle { |
584 | + int corners[3]; // index der Ecken |
585 | +}; |
586 | + |
587 | + |
588 | +static const TopLevelTriangle icosahedron_triangles[20] = { |
589 | + { 1, 0,10}, // 1 |
590 | + { 0, 1, 9}, // 0 |
591 | + { 0, 9, 6}, // 12 |
592 | + { 9, 8, 6}, // 9 |
593 | + { 0, 7,10}, // 16 |
594 | + { 6, 7, 0}, // 6 |
595 | + { 7, 6, 3}, // 7 |
596 | + { 6, 8, 3}, // 14 |
597 | + {11,10, 7}, // 11 |
598 | + { 7, 3,11}, // 18 |
599 | + { 3, 2,11}, // 3 |
600 | + { 2, 3, 8}, // 2 |
601 | + {10,11, 4}, // 10 |
602 | + { 2, 4,11}, // 19 |
603 | + { 5, 4, 2}, // 5 |
604 | + { 2, 8, 5}, // 15 |
605 | + { 4, 1,10}, // 17 |
606 | + { 4, 5, 1}, // 4 |
607 | + { 5, 9, 1}, // 13 |
608 | + { 8, 9, 5} // 8 |
609 | +}; |
610 | + |
611 | + |
612 | + |
613 | +GeodesicGrid::GeodesicGrid(const int lev) |
614 | + :max_level(lev<0?0:lev) { |
615 | + if (max_level > 0) { |
616 | + triangles = new Triangle*[max_level]; |
617 | + int nr_of_triangles = 20; |
618 | + for (int i=0;i<max_level;i++) { |
619 | + triangles[i] = new Triangle[nr_of_triangles]; |
620 | + nr_of_triangles *= 4; |
621 | + } |
622 | + for (int i=0;i<20;i++) { |
623 | + const int *const corners = icosahedron_triangles[i].corners; |
624 | + initTriangle(0,i, |
625 | + icosahedron_corners[corners[0]], |
626 | + icosahedron_corners[corners[1]], |
627 | + icosahedron_corners[corners[2]]); |
628 | + } |
629 | + } else { |
630 | + triangles = 0; |
631 | + } |
632 | +} |
633 | + |
634 | +GeodesicGrid::~GeodesicGrid(void) { |
635 | + if (max_level > 0) { |
636 | + for (int i=max_level-1;i>=0;i--) delete[] triangles[i]; |
637 | + delete triangles; |
638 | + } |
639 | +} |
640 | + |
641 | +void GeodesicGrid::getTriangleCorners(int lev,int index, |
642 | + Vector &h0, |
643 | + Vector &h1, |
644 | + Vector &h2) const { |
645 | + if (lev <= 0) { |
646 | + const int *const corners = icosahedron_triangles[index].corners; |
647 | + h0 = icosahedron_corners[corners[0]]; |
648 | + h1 = icosahedron_corners[corners[1]]; |
649 | + h2 = icosahedron_corners[corners[2]]; |
650 | + } else { |
651 | + lev--; |
652 | + const int i = index>>2; |
653 | + Triangle &t(triangles[lev][i]); |
654 | + switch (index&3) { |
655 | + case 0: { |
656 | + Vector c0,c1,c2; |
657 | + getTriangleCorners(lev,i,c0,c1,c2); |
658 | + h0 = c0; |
659 | + h1 = t.e2; |
660 | + h2 = t.e1; |
661 | + } break; |
662 | + case 1: { |
663 | + Vector c0,c1,c2; |
664 | + getTriangleCorners(lev,i,c0,c1,c2); |
665 | + h0 = t.e2; |
666 | + h1 = c1; |
667 | + h2 = t.e0; |
668 | + } break; |
669 | + case 2: { |
670 | + Vector c0,c1,c2; |
671 | + getTriangleCorners(lev,i,c0,c1,c2); |
672 | + h0 = t.e1; |
673 | + h1 = t.e0; |
674 | + h2 = c2; |
675 | + } break; |
676 | + case 3: |
677 | + h0 = t.e0; |
678 | + h1 = t.e1; |
679 | + h2 = t.e2; |
680 | + break; |
681 | + } |
682 | + } |
683 | +} |
684 | + |
685 | +int GeodesicGrid::getPartnerTriangle(int lev, int index) const |
686 | +{ |
687 | + if (lev==0) |
688 | + { |
689 | + assert(index<20); |
690 | + return (index&1) ? index+1 : index-1; |
691 | + } |
692 | + switch(index&7) |
693 | + { |
694 | + case 2: |
695 | + case 6: |
696 | + return index+1; |
697 | + case 3: |
698 | + case 7: |
699 | + return index-1; |
700 | + case 0: |
701 | + return (lev==1) ? index+5 : (getPartnerTriangle(lev-1, index>>2)<<2)+1; |
702 | + case 1: |
703 | + return (lev==1) ? index+3 : (getPartnerTriangle(lev-1, index>>2)<<2)+0; |
704 | + case 4: |
705 | + return (lev==1) ? index-3 : (getPartnerTriangle(lev-1, index>>2)<<2)+1; |
706 | + case 5: |
707 | + return (lev==1) ? index-5 : (getPartnerTriangle(lev-1, index>>2)<<2)+0; |
708 | + default: |
709 | + assert(0); |
710 | + } |
711 | +} |
712 | + |
713 | +void GeodesicGrid::initTriangle(int lev,int index, |
714 | + const Vector &c0, |
715 | + const Vector &c1, |
716 | + const Vector &c2) { |
717 | + Triangle &t(triangles[lev][index]); |
718 | + t.e0 = c1+c2; |
719 | + t.e0.normalize(); |
720 | + t.e1 = c2+c0; |
721 | + t.e1.normalize(); |
722 | + t.e2 = c0+c1; |
723 | + t.e2.normalize(); |
724 | + lev++; |
725 | + if (lev < max_level) { |
726 | + index *= 4; |
727 | + initTriangle(lev,index+0,c0,t.e2,t.e1); |
728 | + initTriangle(lev,index+1,t.e2,c1,t.e0); |
729 | + initTriangle(lev,index+2,t.e1,t.e0,c2); |
730 | + initTriangle(lev,index+3,t.e0,t.e1,t.e2); |
731 | + } |
732 | +} |
733 | + |
734 | + |
735 | +void GeodesicGrid::visitTriangles(int max_visit_level, |
736 | + VisitFunc *func, |
737 | + void *context) const { |
738 | + if (func && max_visit_level >= 0) { |
739 | + if (max_visit_level > max_level) max_visit_level = max_level; |
740 | + for (int i=0;i<20;i++) { |
741 | + const int *const corners = icosahedron_triangles[i].corners; |
742 | + visitTriangles(0,i, |
743 | + icosahedron_corners[corners[0]], |
744 | + icosahedron_corners[corners[1]], |
745 | + icosahedron_corners[corners[2]], |
746 | + max_visit_level,func,context); |
747 | + } |
748 | + } |
749 | +} |
750 | + |
751 | +void GeodesicGrid::visitTriangles(int lev,int index, |
752 | + const Vector &c0, |
753 | + const Vector &c1, |
754 | + const Vector &c2, |
755 | + int max_visit_level, |
756 | + VisitFunc *func, |
757 | + void *context) const { |
758 | + (*func)(lev,index,c0,c1,c2,context); |
759 | + Triangle &t(triangles[lev][index]); |
760 | + lev++; |
761 | + if (lev <= max_visit_level) { |
762 | + index *= 4; |
763 | + visitTriangles(lev,index+0,c0,t.e2,t.e1,max_visit_level,func,context); |
764 | + visitTriangles(lev,index+1,t.e2,c1,t.e0,max_visit_level,func,context); |
765 | + visitTriangles(lev,index+2,t.e1,t.e0,c2,max_visit_level,func,context); |
766 | + visitTriangles(lev,index+3,t.e0,t.e1,t.e2,max_visit_level,func,context); |
767 | + } |
768 | +} |
769 | + |
770 | + |
771 | +int GeodesicGrid::searchZone(const Vector &v,int search_level) const { |
772 | + for (int i=0;i<20;i++) { |
773 | + const int *const corners = icosahedron_triangles[i].corners; |
774 | + const Vector &c0(icosahedron_corners[corners[0]]); |
775 | + const Vector &c1(icosahedron_corners[corners[1]]); |
776 | + const Vector &c2(icosahedron_corners[corners[2]]); |
777 | + if (((c0^c1)*v >= 0.0) && ((c1^c2)*v >= 0.0) && ((c2^c0)*v >= 0.0)) { |
778 | + // v lies inside this icosahedron triangle |
779 | + for (int lev=0;lev<search_level;lev++) { |
780 | + Triangle &t(triangles[lev][i]); |
781 | + i <<= 2; |
782 | + if ((t.e1^t.e2)*v <= 0.0) { |
783 | + // i += 0; |
784 | + } else if ((t.e2^t.e0)*v <= 0.0) { |
785 | + i += 1; |
786 | + } else if ((t.e0^t.e1)*v <= 0.0) { |
787 | + i += 2; |
788 | + } else { |
789 | + i += 3; |
790 | + } |
791 | + } |
792 | + return i; |
793 | + } |
794 | + } |
795 | + cerr << "software error: not found" << endl; |
796 | + exit(-1); |
797 | + // shut up the compiler |
798 | + return -1; |
799 | +} |
800 | + |
801 | +void GeodesicGrid::searchZones(const HalfSpace *half_spaces, |
802 | + const int nr_of_half_spaces, |
803 | + int **inside_list,int **border_list, |
804 | + int max_search_level) const { |
805 | + if (max_search_level < 0) max_search_level = 0; |
806 | + else if (max_search_level > max_level) max_search_level = max_level; |
807 | + int halfs_used[nr_of_half_spaces]; |
808 | + for (int h=0;h<nr_of_half_spaces;h++) {halfs_used[h] = h;} |
809 | + bool corner_inside[12][nr_of_half_spaces]; |
810 | + for (int h=0;h<nr_of_half_spaces;h++) { |
811 | + const HalfSpace &half_space(half_spaces[h]); |
812 | + for (int i=0;i<12;i++) { |
813 | + corner_inside[i][h] = half_space.inside(icosahedron_corners[i]); |
814 | + } |
815 | + } |
816 | + for (int i=0;i<20;i++) { |
817 | + searchZones(0,i, |
818 | + half_spaces,nr_of_half_spaces,halfs_used,nr_of_half_spaces, |
819 | + corner_inside[icosahedron_triangles[i].corners[0]], |
820 | + corner_inside[icosahedron_triangles[i].corners[1]], |
821 | + corner_inside[icosahedron_triangles[i].corners[2]], |
822 | + inside_list,border_list,max_search_level); |
823 | + } |
824 | +} |
825 | + |
826 | +void GeodesicGrid::searchZones(int lev,int index, |
827 | + const HalfSpace *half_spaces, |
828 | + const int nr_of_half_spaces, |
829 | + const int *index_of_used_half_spaces, |
830 | + const int half_spaces_used, |
831 | + const bool *corner0_inside, |
832 | + const bool *corner1_inside, |
833 | + const bool *corner2_inside, |
834 | + int **inside_list,int **border_list, |
835 | + const int max_search_level) const { |
836 | + int halfs_used[half_spaces_used]; |
837 | + int halfs_used_count = 0; |
838 | + for (int h=0;h<half_spaces_used;h++) { |
839 | + const int i = index_of_used_half_spaces[h]; |
840 | + if (!corner0_inside[i] && !corner1_inside[i] && !corner2_inside[i]) { |
841 | + // totally outside this HalfSpace |
842 | + return; |
843 | + } else if (corner0_inside[i] && corner1_inside[i] && corner2_inside[i]) { |
844 | + // totally inside this HalfSpace |
845 | + } else { |
846 | + // on the border of this HalfSpace |
847 | + halfs_used[halfs_used_count++] = i; |
848 | + } |
849 | + } |
850 | + if (halfs_used_count == 0) { |
851 | + // this triangle(lev,index) lies inside all halfspaces |
852 | + **inside_list = index; |
853 | + (*inside_list)++; |
854 | + } else { |
855 | + (*border_list)--; |
856 | + **border_list = index; |
857 | + if (lev < max_search_level) { |
858 | + Triangle &t(triangles[lev][index]); |
859 | + lev++; |
860 | + index <<= 2; |
861 | + inside_list++; |
862 | + border_list++; |
863 | + bool edge0_inside[nr_of_half_spaces]; |
864 | + bool edge1_inside[nr_of_half_spaces]; |
865 | + bool edge2_inside[nr_of_half_spaces]; |
866 | + for (int h=0;h<halfs_used_count;h++) { |
867 | + const int i = halfs_used[h]; |
868 | + const HalfSpace &half_space(half_spaces[i]); |
869 | + edge0_inside[i] = half_space.inside(t.e0); |
870 | + edge1_inside[i] = half_space.inside(t.e1); |
871 | + edge2_inside[i] = half_space.inside(t.e2); |
872 | + } |
873 | + searchZones(lev,index+0, |
874 | + half_spaces,nr_of_half_spaces,halfs_used,halfs_used_count, |
875 | + corner0_inside,edge2_inside,edge1_inside, |
876 | + inside_list,border_list,max_search_level); |
877 | + searchZones(lev,index+1, |
878 | + half_spaces,nr_of_half_spaces,halfs_used,halfs_used_count, |
879 | + edge2_inside,corner1_inside,edge0_inside, |
880 | + inside_list,border_list,max_search_level); |
881 | + searchZones(lev,index+2, |
882 | + half_spaces,nr_of_half_spaces,halfs_used,halfs_used_count, |
883 | + edge1_inside,edge0_inside,corner2_inside, |
884 | + inside_list,border_list,max_search_level); |
885 | + searchZones(lev,index+3, |
886 | + half_spaces,nr_of_half_spaces,halfs_used,halfs_used_count, |
887 | + edge0_inside,edge1_inside,edge2_inside, |
888 | + inside_list,border_list,max_search_level); |
889 | + } |
890 | + } |
891 | +} |
892 | + |
893 | + |
894 | + |
895 | +GeodesicSearchResult::GeodesicSearchResult(const GeodesicGrid &grid) |
896 | + :grid(grid), |
897 | + zones(new int*[grid.getMaxLevel()+1]), |
898 | + inside(new int*[grid.getMaxLevel()+1]), |
899 | + border(new int*[grid.getMaxLevel()+1]) { |
900 | + for (int i=0;i<=grid.getMaxLevel();i++) { |
901 | + zones[i] = new int[GeodesicGrid::nrOfZones(i)]; |
902 | + } |
903 | +} |
904 | + |
905 | +GeodesicSearchResult::~GeodesicSearchResult(void) { |
906 | + for (int i=grid.getMaxLevel();i>=0;i--) { |
907 | + delete zones[i]; |
908 | + } |
909 | + delete border; |
910 | + delete inside; |
911 | + delete zones; |
912 | +} |
913 | + |
914 | +void GeodesicSearchResult::search(const HalfSpace *half_spaces, |
915 | + const int nr_of_half_spaces, |
916 | + int max_search_level) { |
917 | + for (int i=grid.getMaxLevel();i>=0;i--) { |
918 | + inside[i] = zones[i]; |
919 | + border[i] = zones[i]+GeodesicGrid::nrOfZones(i); |
920 | + } |
921 | + grid.searchZones(half_spaces,nr_of_half_spaces,inside,border,max_search_level); |
922 | +} |
923 | + |
924 | +void GeodesicSearchResult::search(const Vector &e0,const Vector &e1, |
925 | + const Vector &e2,const Vector &e3, |
926 | + int max_search_level) { |
927 | + HalfSpace half_spaces[4]; |
928 | + half_spaces[0].d = e0*((e1-e0)^(e2-e0)); |
929 | + if (half_spaces[0].d > 0) { |
930 | + half_spaces[0].n = e0^e1; |
931 | + half_spaces[1].n = e1^e2; |
932 | + half_spaces[2].n = e2^e3; |
933 | + half_spaces[3].n = e3^e0; |
934 | + half_spaces[0].d = 0.0; |
935 | + half_spaces[1].d = 0.0; |
936 | + half_spaces[2].d = 0.0; |
937 | + half_spaces[3].d = 0.0; |
938 | + search(half_spaces,4,max_search_level); |
939 | + } else { |
940 | + half_spaces[0].n = (e1-e0)^(e2-e0); |
941 | + search(half_spaces,1,max_search_level); |
942 | + } |
943 | +} |
944 | + |
945 | + |
946 | + |
947 | +void GeodesicSearchInsideIterator::reset(void) { |
948 | + level = 0; |
949 | + max_count = 1<<(max_level<<1); // 4^max_level |
950 | + index_p = r.zones[0]; |
951 | + end_p = r.inside[0]; |
952 | + index = (*index_p) * max_count; |
953 | + count = (index_p < end_p) ? 0 : max_count; |
954 | +} |
955 | + |
956 | +int GeodesicSearchInsideIterator::next(void) { |
957 | + if (count < max_count) return index+(count++); |
958 | + index_p++; |
959 | + if (index_p < end_p) { |
960 | + index = (*index_p) * max_count; |
961 | + count = 1; |
962 | + return index; |
963 | + } |
964 | + while (level < max_level) { |
965 | + level++; |
966 | + max_count >>= 2; |
967 | + index_p = r.zones[level]; |
968 | + end_p = r.inside[level]; |
969 | + if (index_p < end_p) { |
970 | + index = (*index_p) * max_count; |
971 | + count = 1; |
972 | + return index; |
973 | + } |
974 | + } |
975 | + return -1; |
976 | +} |
977 | + |
978 | +//------------------------------------------------ |
979 | + |
980 | + |
981 | +#include <stdio.h> |
982 | +#include <stdlib.h> |
983 | +#include <string.h> |
984 | +#include <math.h> |
985 | + |
986 | +#include <map> |
987 | +#include <list> |
988 | +#include <string> |
989 | +#include <iostream> |
990 | + |
991 | +using namespace std; |
992 | + |
993 | + |
994 | + |
995 | +static int restrict_output_level_min = 0; |
996 | +static int restrict_output_level_max = MAX_LEVEL; |
997 | + |
998 | + |
999 | + |
1000 | +struct FaintStar { // 6 byte |
1001 | + int x0:18; |
1002 | + int x1:18; |
1003 | + unsigned int b_v:7; |
1004 | + unsigned int mag:5; |
1005 | + bool operator<(const FaintStar &s) const {return (mag < s.mag);} |
1006 | +} __attribute__ ((__packed__)) ; |
1007 | + |
1008 | + |
1009 | +struct TycStar { // 10 byte |
1010 | + int x0:20; |
1011 | + int x1:20; |
1012 | + int dx0:14; |
1013 | + int dx1:14; |
1014 | + unsigned int b_v:7; |
1015 | + unsigned int mag:5; |
1016 | + bool operator<(const TycStar &s) const {return (mag < s.mag);} |
1017 | +} __attribute__ ((__packed__)); |
1018 | + |
1019 | + |
1020 | +struct HipStarCompressed { |
1021 | + int hip:24; // 17 bits needed |
1022 | + unsigned char comp_ids_int; // 5 bits needed |
1023 | + int x0; // 32 bits needed |
1024 | + int x1; // 32 bits needed |
1025 | + unsigned char b_v; // 8 bits needed |
1026 | + unsigned char mag; // 5 bits needed |
1027 | + unsigned short sp_int; // 14 bits needed |
1028 | + int dx0,dx1,plx; |
1029 | +} __attribute__ ((__packed__)); |
1030 | + |
1031 | +struct HipStar : public HipStarCompressed { |
1032 | + string component_ids,sp; |
1033 | + void setPlxSp(double plx,const string &sp) { |
1034 | + HipStar::plx = (int)floor(0.5+100.0*plx); |
1035 | + if (HipStar::plx < 0) HipStar::plx = 0; |
1036 | + HipStar::sp = sp; |
1037 | + } |
1038 | + bool operator<(const HipStar &s) const {return (mag < s.mag);} |
1039 | +}; |
1040 | + |
1041 | + |
1042 | + |
1043 | +struct ZoneData { |
1044 | + virtual ~ZoneData(void) {} |
1045 | + virtual int getArraySize(void) const = 0; |
1046 | + virtual HipStar *add(int level, |
1047 | + int tyc1,int tyc2,int tyc3, |
1048 | + int hip,const char *component_ids, |
1049 | + double x0,double x1,double dx0,double dx1, |
1050 | + double mag,double b_v, |
1051 | + double plx,const char *sp, |
1052 | + bool &does_not_fit) = 0; |
1053 | + void writeInfoToOutput(FILE *f) const; |
1054 | + virtual void writeStarsToOutput(FILE *f) = 0; |
1055 | + Vector center; |
1056 | + Vector axis0; |
1057 | + Vector axis1; |
1058 | +}; |
1059 | + |
1060 | +struct HipZoneData : public ZoneData { |
1061 | + list<HipStar> stars; |
1062 | + int getArraySize(void) const {return stars.size();} |
1063 | + HipStar *add(int level, |
1064 | + int tyc1,int tyc2,int tyc3, |
1065 | + int hip,const char *component_ids, |
1066 | + double x0,double x1,double dx0,double dx1, |
1067 | + double mag,double b_v,double plx,const char *sp, |
1068 | + bool &does_not_fit); |
1069 | + void writeStarsToOutput(FILE *f); |
1070 | +}; |
1071 | + |
1072 | + |
1073 | +static list<HipStar*> hip_index[NR_OF_HIP+1]; |
1074 | + |
1075 | +static void SqueezeHip(void) { |
1076 | + // build lookup maps |
1077 | + map<string,int> component_ids_map,sp_map; |
1078 | + for (int i=0;i<=NR_OF_HIP;i++) { |
1079 | + for (list<HipStar*>::const_iterator it(hip_index[i].begin()); |
1080 | + it!=hip_index[i].end();it++) { |
1081 | + HipStar *h = *it; |
1082 | + component_ids_map[h->component_ids]++; |
1083 | + sp_map[h->sp]++; |
1084 | + } |
1085 | + } |
1086 | + int component_ids_size = 0; |
1087 | + for (map<string,int>::iterator it(component_ids_map.begin()); |
1088 | + it!=component_ids_map.end();it++,component_ids_size++) { |
1089 | + it->second = component_ids_size; |
1090 | + } |
1091 | + if (component_ids_size >= 32) { |
1092 | + cerr << "SqueezeHip: too many component_ids: " |
1093 | + << component_ids_size << endl; |
1094 | + } |
1095 | + int sp_size = 0; |
1096 | + for (map<string,int>::iterator it(sp_map.begin()); |
1097 | + it!=sp_map.end();it++,sp_size++) { |
1098 | + it->second = sp_size; |
1099 | + } |
1100 | + if (sp_size >= 16384) { |
1101 | + cerr << "SqueezeHip: too many sp: " << sp_size << endl; |
1102 | + } |
1103 | + // translate the strings for the hip stars into integers: |
1104 | + for (int i=0;i<=NR_OF_HIP;i++) { |
1105 | + for (list<HipStar*>::const_iterator it(hip_index[i].begin()); |
1106 | + it!=hip_index[i].end();it++) { |
1107 | + HipStar *h = *it; |
1108 | + h->comp_ids_int = component_ids_map[h->component_ids]; |
1109 | + h->sp_int = sp_map[h->sp]; |
1110 | + } |
1111 | + } |
1112 | + // write output files for component_ids and sp |
1113 | + FILE *f = fopen(component_ids_filename,"wb"); |
1114 | + if (f==0) { |
1115 | + cout << "fopen(" << component_ids_filename << ") failed" << endl; |
1116 | + exit(-1); |
1117 | + } |
1118 | + for (map<string,int>::const_iterator it(component_ids_map.begin()); |
1119 | + it!=component_ids_map.end();it++,component_ids_size++) { |
1120 | + fprintf(f,"%s\n",it->first.c_str()); |
1121 | + } |
1122 | + fclose(f); |
1123 | + f = fopen(sp_filename,"wb"); |
1124 | + if (f==0) { |
1125 | + cout << "fopen(" << sp_filename << ") failed" << endl; |
1126 | + exit(-1); |
1127 | + } |
1128 | + for (map<string,int>::const_iterator it(sp_map.begin()); |
1129 | + it!=sp_map.end();it++,sp_size++) { |
1130 | + fprintf(f,"%s\n",it->first.c_str()); |
1131 | + } |
1132 | + fclose(f); |
1133 | +} |
1134 | + |
1135 | +struct TycZoneData : public ZoneData { |
1136 | + list<TycStar> stars; |
1137 | + int getArraySize(void) const {return stars.size();} |
1138 | + HipStar *add(int level, |
1139 | + int tyc1,int tyc2,int tyc3, |
1140 | + int hip,const char *component_ids, |
1141 | + double x0,double x1,double dx0,double dx1, |
1142 | + double mag,double b_v,double plx,const char *sp, |
1143 | + bool &does_not_fit); |
1144 | + void writeStarsToOutput(FILE *f); |
1145 | +}; |
1146 | + |
1147 | +struct FaintZoneData : public ZoneData { |
1148 | + list<FaintStar> stars; |
1149 | + int getArraySize(void) const {return stars.size();} |
1150 | + HipStar *add(int level, |
1151 | + int tyc1,int tyc2,int tyc3, |
1152 | + int hip,const char *component_ids, |
1153 | + double x0,double x1,double dx0,double dx1, |
1154 | + double mag,double b_v,double plx,const char *sp, |
1155 | + bool &does_not_fit); |
1156 | + void writeStarsToOutput(FILE *f); |
1157 | +}; |
1158 | + |
1159 | + |
1160 | +class Accumulator { |
1161 | +public: |
1162 | + Accumulator(void); |
1163 | + ~Accumulator(void); |
1164 | + int addStar(int tyc1,int tyc2,int tyc3,int hip,const char *component_ids, |
1165 | + double ra, // degrees |
1166 | + double dec, // degrees |
1167 | + double pma,double pmd, |
1168 | + double mag,double b_v, |
1169 | + double plx,const char *sp); |
1170 | + void writeOutput(const char *fnames[]); |
1171 | +private: |
1172 | + GeodesicGrid grid; |
1173 | + struct ZoneArray { |
1174 | + ZoneArray(int level,GeodesicGrid &grid) |
1175 | + : level(level),nr_of_zones(GeodesicGrid::nrOfZones(level)),grid(grid) |
1176 | + {scale = 0.0;nr_of_stars = 0;} |
1177 | + virtual ~ZoneArray(void) {} |
1178 | + virtual ZoneData *getZone(int index) const = 0; |
1179 | + virtual void writeHeaderToOutput(FILE *f) const = 0; |
1180 | + const int level; |
1181 | + const int nr_of_zones; |
1182 | + const GeodesicGrid &grid; |
1183 | + double scale; |
1184 | +// int scale_int; |
1185 | + int nr_of_stars; |
1186 | + HipStar *addStar(int tyc1,int tyc2,int tyc3, |
1187 | + int hip,const char *component_ids, |
1188 | + double ra, // degrees |
1189 | + double dec, // degrees |
1190 | + double pma,double pmd, |
1191 | + double mag,double b_v, |
1192 | + double plx,const char *sp, |
1193 | + bool &does_not_fit); |
1194 | + void writeOutput(const char *fname); |
1195 | + }; |
1196 | + struct HipZoneArray : public ZoneArray { |
1197 | + HipZoneArray(int level,GeodesicGrid &grid) |
1198 | + : ZoneArray(level,grid),zones(new HipZoneData[nr_of_zones]) {} |
1199 | + ~HipZoneArray(void) {delete[] zones;} |
1200 | + void writeHeaderToOutput(FILE *f) const; |
1201 | + HipZoneData *const zones; |
1202 | + ZoneData *getZone(int index) const { |
1203 | + if (index<0 || index>=nr_of_zones) { |
1204 | + cerr << "getZone: bad index" << endl; |
1205 | + exit(-1); |
1206 | + } |
1207 | + return zones+index; |
1208 | + } |
1209 | + }; |
1210 | + struct TycZoneArray : public ZoneArray { |
1211 | + TycZoneArray(int level,GeodesicGrid &grid) |
1212 | + : ZoneArray(level,grid),zones(new TycZoneData[nr_of_zones]) {} |
1213 | + ~TycZoneArray(void) {delete[] zones;} |
1214 | + void writeHeaderToOutput(FILE *f) const; |
1215 | + TycZoneData *zones; |
1216 | + ZoneData *getZone(int index) const { |
1217 | + if (index<0 || index>=nr_of_zones) { |
1218 | + cerr << "getZone: bad index" << endl; |
1219 | + exit(-1); |
1220 | + } |
1221 | + return zones+index; |
1222 | + } |
1223 | + }; |
1224 | + struct FaintZoneArray : public ZoneArray { |
1225 | + FaintZoneArray(int level,GeodesicGrid &grid) |
1226 | + : ZoneArray(level,grid),zones(new FaintZoneData[nr_of_zones]) {} |
1227 | + ~FaintZoneArray(void) {delete[] zones;} |
1228 | + void writeHeaderToOutput(FILE *f) const; |
1229 | + FaintZoneData *zones; |
1230 | + ZoneData *getZone(int index) const { |
1231 | + if (index<0 || index>=nr_of_zones) { |
1232 | + cerr << "getZone: bad index" << endl; |
1233 | + exit(-1); |
1234 | + } |
1235 | + return zones+index; |
1236 | + } |
1237 | + }; |
1238 | + ZoneArray *zone_array[MAX_LEVEL+1]; |
1239 | + |
1240 | +private: |
1241 | + static void initTriangleFunc(int lev,int index, |
1242 | + const Vector &c0, |
1243 | + const Vector &c1, |
1244 | + const Vector &c2, |
1245 | + void *user_data) { |
1246 | + reinterpret_cast<Accumulator*>(user_data) |
1247 | + ->initTriangle(lev,index,c0,c1,c2); |
1248 | + } |
1249 | + void initTriangle(int lev,int index, |
1250 | + const Vector &c0, |
1251 | + const Vector &c1, |
1252 | + const Vector &c2); |
1253 | +}; |
1254 | + |
1255 | + |
1256 | + |
1257 | + |
1258 | + |
1259 | + |
1260 | + |
1261 | + |
1262 | + |
1263 | +static |
1264 | +void WriteByte(FILE *f,int x) { |
1265 | + unsigned char c = (unsigned int)x; |
1266 | + if (1!=fwrite(&c,1,1,f)) { |
1267 | + cerr << "WriteByte: fwrite failed" << endl; |
1268 | + exit(-1); |
1269 | + } |
1270 | +} |
1271 | + |
1272 | +static |
1273 | +void WriteInt(FILE *f,int x) { |
1274 | + if (4!=fwrite(&x,1,4,f)) { |
1275 | + cerr << "WriteInt: fwrite failed" << endl; |
1276 | + exit(-1); |
1277 | + } |
1278 | +} |
1279 | + |
1280 | +//static |
1281 | +//int DoubleToInt(double x) { |
1282 | +// return (int)floor(0.5+x*0x7FFFFFFF); |
1283 | +//} |
1284 | + |
1285 | +//static |
1286 | +//double IntToDouble(int x) { |
1287 | +// double rval = x; |
1288 | +// rval /= 0x7FFFFFFF; |
1289 | +// return rval; |
1290 | +//} |
1291 | + |
1292 | +void ZoneData::writeInfoToOutput(FILE *f) const { |
1293 | +// WriteInt(f,DoubleToInt(center.x[0])); |
1294 | +// WriteInt(f,DoubleToInt(center.x[1])); |
1295 | +// WriteInt(f,DoubleToInt(center.x[2])); |
1296 | + WriteInt(f,getArraySize()); |
1297 | +} |
1298 | + |
1299 | +void HipZoneData::writeStarsToOutput(FILE *f) { |
1300 | + stars.sort(); |
1301 | + for (list<HipStar>::const_iterator it(stars.begin()); |
1302 | + it!=stars.end();it++) { |
1303 | + if (sizeof(HipStarCompressed)!= |
1304 | + fwrite(&(*it),1,sizeof(HipStarCompressed),f)) { |
1305 | + cerr << "HipZoneData::writeStarsToOutput: fwrite failed" << endl; |
1306 | + exit(-1); |
1307 | + } |
1308 | + } |
1309 | +} |
1310 | + |
1311 | +void TycZoneData::writeStarsToOutput(FILE *f) { |
1312 | + stars.sort(); |
1313 | + for (list<TycStar>::const_iterator it(stars.begin()); |
1314 | + it!=stars.end();it++) { |
1315 | + if (sizeof(TycStar)!=fwrite(&(*it),1,sizeof(TycStar),f)) { |
1316 | + cerr << "TycZoneData::writeStarsToOutput: fwrite failed" << endl; |
1317 | + exit(-1); |
1318 | + } |
1319 | + } |
1320 | +} |
1321 | + |
1322 | + |
1323 | +void FaintZoneData::writeStarsToOutput(FILE *f) { |
1324 | + stars.sort(); |
1325 | + for (list<FaintStar>::const_iterator it(stars.begin()); |
1326 | + it!=stars.end();it++) { |
1327 | + if (sizeof(FaintStar)!=fwrite(&(*it),1,sizeof(FaintStar),f)) { |
1328 | + cerr << "FaintZoneData::writeStarsToOutput: fwrite failed" << endl; |
1329 | + exit(-1); |
1330 | + } |
1331 | + } |
1332 | +} |
1333 | + |
1334 | + |
1335 | + |
1336 | + |
1337 | + |
1338 | + |
1339 | + |
1340 | + |
1341 | + |
1342 | + |
1343 | + |
1344 | + |
1345 | + |
1346 | + |
1347 | + |
1348 | + |
1349 | + |
1350 | + |
1351 | + |
1352 | +Accumulator::Accumulator(void) |
1353 | + :grid(MAX_LEVEL) { |
1354 | + int l=0; |
1355 | + for (;l<=MAX_HIP_LEVEL;l++) { |
1356 | + zone_array[l] = new HipZoneArray(l,grid); |
1357 | + } |
1358 | + for (;l<=MAX_TYC_LEVEL;l++) { |
1359 | + zone_array[l] = new TycZoneArray(l,grid); |
1360 | + } |
1361 | + for (;l<=MAX_LEVEL;l++) { |
1362 | + zone_array[l] = new FaintZoneArray(l,grid); |
1363 | + } |
1364 | + grid.visitTriangles(MAX_LEVEL,initTriangleFunc,this); |
1365 | + for (int l=0;l<=MAX_LEVEL;l++) { |
1366 | +// zone_array[l]->scale_int = DoubleToInt(zone_array[l]->scale); |
1367 | +// while (IntToDouble(zone_array[l]->scale_int) > zone_array[l]->scale) { |
1368 | +// zone_array[l]->scale_int--; |
1369 | +// } |
1370 | +// zone_array[l]->scale = IntToDouble(zone_array[l]->scale_int); |
1371 | + cout << "Accumulator::Accumulator: level " << zone_array[l]->level |
1372 | + << ", scale: " << zone_array[l]->scale << endl; |
1373 | + } |
1374 | +} |
1375 | + |
1376 | +Accumulator::~Accumulator(void) { |
1377 | + for (int l=0;l<=MAX_LEVEL;l++) { |
1378 | + delete zone_array[l]; |
1379 | + } |
1380 | +} |
1381 | + |
1382 | +static const Vector north = {0.0,0.0,1.0}; |
1383 | + |
1384 | +void Accumulator::initTriangle(int lev,int index, |
1385 | + const Vector &c0, |
1386 | + const Vector &c1, |
1387 | + const Vector &c2) { |
1388 | + ZoneData &z(*zone_array[lev]->getZone(index)); |
1389 | + double &scale(zone_array[lev]->scale); |
1390 | + z.center = c0+c1+c2; |
1391 | + z.center.normalize(); |
1392 | + z.axis0 = north ^ z.center; |
1393 | + z.axis0.normalize(); |
1394 | + z.axis1 = z.center ^ z.axis0; |
1395 | + |
1396 | + double mu0,mu1,f,h; |
1397 | + |
1398 | + mu0 = (c0-z.center)*z.axis0; |
1399 | + mu1 = (c0-z.center)*z.axis1; |
1400 | + f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1); |
1401 | + h = fabs(mu0)*f; |
1402 | + if (scale < h) scale = h; |
1403 | + h = fabs(mu1)*f; |
1404 | + if (scale < h) scale = h; |
1405 | + |
1406 | + mu0 = (c1-z.center)*z.axis0; |
1407 | + mu1 = (c1-z.center)*z.axis1; |
1408 | + f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1); |
1409 | + h = fabs(mu0)*f; |
1410 | + if (scale < h) scale = h; |
1411 | + h = fabs(mu1)*f; |
1412 | + if (scale < h) scale = h; |
1413 | + |
1414 | + mu0 = (c2-z.center)*z.axis0; |
1415 | + mu1 = (c2-z.center)*z.axis1; |
1416 | + f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1); |
1417 | + h = fabs(mu0)*f; |
1418 | + if (scale < h) scale = h; |
1419 | + h = fabs(mu1)*f; |
1420 | + if (scale < h) scale = h; |
1421 | +} |
1422 | + |
1423 | +static |
1424 | +unsigned char BvToColorIndex(double b_v) { |
1425 | + b_v *= 1000.0; |
1426 | + if (b_v < -500) { |
1427 | + b_v = -500; |
1428 | + } else if (b_v > 3499) { |
1429 | + b_v = 3499; |
1430 | + } |
1431 | + return (unsigned int)floor(0.5+127.0*((500.0+b_v)/4000.0)); |
1432 | +} |
1433 | + |
1434 | +HipStar *FaintZoneData::add(int level, |
1435 | + int tyc1,int tyc2,int tyc3, |
1436 | + int hip,const char *component_ids, |
1437 | + double x0,double x1,double dx0,double dx1, |
1438 | + double mag,double b_v,double plx,const char *sp, |
1439 | + bool &does_not_fit) { |
1440 | + if (mag>=level_mag_limit[level]) { |
1441 | + cout << "too faint" << endl; |
1442 | + exit(-1); |
1443 | + } |
1444 | + FaintStar s; |
1445 | + s.x0 = ((int)floor(0.5+x0*((1<<17)-1))); // 18 bit signed |
1446 | + s.b_v = BvToColorIndex(b_v); // 0..127: 7 Bit unsigned |
1447 | + s.x1 = ((int)floor(0.5+x1*((1<<17)-1))); // 18 bit signed |
1448 | + s.mag = (unsigned int)floor(30*(mag-level_mag_limit[level-1])/ |
1449 | + (level_mag_limit[level]-level_mag_limit[level-1])); |
1450 | + // steps(accuracy) of 0.05mag, 5 bit unsigned |
1451 | + stars.push_back(s); |
1452 | + does_not_fit = false; |
1453 | + return 0; |
1454 | +} |
1455 | + |
1456 | +HipStar *TycZoneData::add(int level, |
1457 | + int tyc1,int tyc2,int tyc3, |
1458 | + int hip,const char *component_ids, |
1459 | + double x0,double x1,double dx0,double dx1, |
1460 | + double mag,double b_v,double plx,const char *sp, |
1461 | + bool &does_not_fit) { |
1462 | + TycStar s; |
1463 | + s.x0 = ((int)floor(0.5+x0*((1<<19)-1))); // 20 bit signed |
1464 | + s.b_v = BvToColorIndex(b_v); // 0..127: 7 Bit unsigned |
1465 | + s.x1 = ((int)floor(0.5+x1*((1<<19)-1))); // 20 bit signed |
1466 | + s.mag = (unsigned int)floor(30*(mag-level_mag_limit[level-1])/ |
1467 | + (level_mag_limit[level]-level_mag_limit[level-1])); |
1468 | + // steps(accuracy) of 0.05mag, 5 bit unsigned |
1469 | + const int dx0_int = (int)floor(0.5+dx0*10.0); // 14 bit signed |
1470 | + const int dx1_int = (int)floor(0.5+dx1*10.0); // 14 bit signed |
1471 | + if (dx0_int >= 8192 || dx0_int<-8192 || |
1472 | + dx1_int >= 8192 || dx1_int<-8192) { |
1473 | + // does not fit, must store in Hip format |
1474 | + does_not_fit = true; |
1475 | + return 0; |
1476 | + } |
1477 | + s.dx0 = dx0_int; |
1478 | + s.dx1 = dx1_int; |
1479 | + stars.push_back(s); |
1480 | + does_not_fit = false; |
1481 | + return 0; |
1482 | +} |
1483 | + |
1484 | + |
1485 | +HipStar *HipZoneData::add(int level, |
1486 | + int tyc1,int tyc2,int tyc3, |
1487 | + int hip,const char *component_ids, |
1488 | + double x0,double x1,double dx0,double dx1, |
1489 | + double mag,double b_v,double plx,const char *sp, |
1490 | + bool &does_not_fit) { |
1491 | + HipStar s; |
1492 | + s.x0 = ((int)floor(0.5+x0*((1<<31)-1))); // 32 bit signed |
1493 | + s.b_v = BvToColorIndex(b_v); // 0..127: 7 Bit unsigned |
1494 | + s.x1 = ((int)floor(0.5+x1*((1<<31)-1))); // 32 bit signed |
1495 | + const int mag_int = (int)floor(20* |
1496 | + (mag-((level==0)?-2.0:level_mag_limit[level-1]))); |
1497 | + if (mag_int < 0 || mag_int > 255) { |
1498 | + cerr << "HipZoneData(" << level << ")::add: bad mag: " << mag << endl; |
1499 | + exit(-1); |
1500 | + } |
1501 | + s.mag = mag_int; |
1502 | + s.dx0 = (int)floor(0.5+dx0*10.0); |
1503 | + s.dx1 = (int)floor(0.5+dx1*10.0); |
1504 | + s.hip = hip; |
1505 | + s.component_ids = component_ids; |
1506 | + s.comp_ids_int = 0; |
1507 | + s.sp_int = 0; |
1508 | + s.plx = (int)floor(0.5+100.0*plx); |
1509 | + s.sp = sp; |
1510 | + stars.push_back(s); |
1511 | + does_not_fit = false; |
1512 | + return &(stars.back()); |
1513 | +} |
1514 | + |
1515 | + |
1516 | +HipStar *Accumulator::ZoneArray::addStar( |
1517 | + int tyc1,int tyc2,int tyc3,int hip,const char *component_ids, |
1518 | + double ra,double dec,double pma,double pmd, |
1519 | + double mag,double b_v,double plx,const char *sp, |
1520 | + bool &does_not_fit) { |
1521 | + ra *= (M_PI/180.0); |
1522 | + dec *= (M_PI/180.0); |
1523 | + if (ra < 0 || ra >= 2*M_PI || dec < -0.5*M_PI || dec > 0.5*M_PI) { |
1524 | + cerr << "ZoneArray(l=" << level << ")::addStar: " |
1525 | + "bad ra/dec: " << ra << ',' << dec << endl; |
1526 | + exit (-1); |
1527 | + } |
1528 | + const double cdec = cos(dec); |
1529 | + Vector pos; |
1530 | + pos.x[0] = cos(ra)*cdec; |
1531 | + pos.x[1] = sin(ra)*cdec; |
1532 | + pos.x[2] = sin(dec); |
1533 | + const int zone = grid.searchZone(pos,level); |
1534 | + |
1535 | + ZoneData &z(*getZone(zone)); |
1536 | + const double mu0 = (pos-z.center) * z.axis0; |
1537 | + const double mu1 = (pos-z.center) * z.axis1; |
1538 | + const double d = 1.0 - mu0*mu0 - mu1*mu1; |
1539 | + const double sd = sqrt(d); |
1540 | + const double x0 = mu0/(sd*scale); |
1541 | + const double x1 = mu1/(sd*scale); |
1542 | + const double h = mu0*pma + mu1*pmd; |
1543 | + const double dx0 = (pma*d + mu0*h) / (sd*d); |
1544 | + const double dx1 = (pmd*d + mu1*h) / (sd*d); |
1545 | + |
1546 | +//cout << "Accumulator::ZoneArray(l=" << level << ")::addStar: " << zone << endl; |
1547 | + HipStar *rval = z.add(level,tyc1,tyc2,tyc3,hip,component_ids, |
1548 | + x0,x1,dx0,dx1,mag,b_v,plx,sp,does_not_fit); |
1549 | + if (!does_not_fit) nr_of_stars++; |
1550 | +//cout << "Accumulator::ZoneArray(l=" << level << ")::addStar: 999"; |
1551 | + return rval; |
1552 | +} |
1553 | + |
1554 | +int Accumulator::addStar(int tyc1,int tyc2,int tyc3,int hip,const char *component_ids, |
1555 | + double ra,double dec,double pma,double pmd, |
1556 | + double mag,double b_v,double plx,const char *sp) { |
1557 | +// const int packed_hip = PackHip(hip,component_ids); |
1558 | +// const int packed_tyc = PackTyc(tyc1,tyc2,tyc3); |
1559 | + |
1560 | + int l=0; |
1561 | + while (l<MAX_LEVEL && mag>=level_mag_limit[l]) l++; |
1562 | + if (hip>0 && l>MAX_HIP_LEVEL) l = MAX_HIP_LEVEL; |
1563 | +// store the faint tyc2 stars as faint stars |
1564 | +// else if (tyc1>0 && l>MAX_TYC_LEVEL) l = MAX_TYC_LEVEL; |
1565 | + |
1566 | + |
1567 | + if (restrict_output_level_max < l || |
1568 | + restrict_output_level_min > l) { |
1569 | + // you may want to restrict the output |
1570 | + // in order to restrict the amount of main memory used. |
1571 | + // Calling the program twice may be faster than calling once |
1572 | + // without enough main memory (avoid swapping). |
1573 | + return 0; |
1574 | + } |
1575 | + |
1576 | + bool does_not_fit; |
1577 | + HipStar *s = zone_array[l]->addStar(tyc1,tyc2,tyc3,hip,component_ids, |
1578 | + ra,dec,pma,pmd, |
1579 | + mag,b_v,plx,sp,does_not_fit); |
1580 | + if (does_not_fit) s = zone_array[MAX_HIP_LEVEL] |
1581 | + ->addStar(tyc1,tyc2,tyc3,hip,component_ids, |
1582 | + ra,dec,pma,pmd, |
1583 | + mag,b_v,plx,sp,does_not_fit); |
1584 | + if (s) hip_index[hip].push_back(s); |
1585 | + return 0; |
1586 | +} |
1587 | + |
1588 | + |
1589 | + |
1590 | + |
1591 | + |
1592 | + |
1593 | + |
1594 | + |
1595 | + |
1596 | + |
1597 | + |
1598 | + |
1599 | + |
1600 | + |
1601 | +#define FILE_MAGIC 0x835f040a |
1602 | + |
1603 | +void Accumulator::HipZoneArray::writeHeaderToOutput(FILE *f) const { |
1604 | + cout << "Accumulator::HipZoneArray(" << level << ")::writeHeaderToOutput: " |
1605 | + << nr_of_stars << endl; |
1606 | + WriteInt(f,FILE_MAGIC); |
1607 | + WriteInt(f,0); // type |
1608 | + WriteInt(f,0); // major version |
1609 | + WriteInt(f,4); // minor version |
1610 | + WriteInt(f,level); |
1611 | +// WriteInt(f,scale_int); |
1612 | + if (level == 0) { |
1613 | + WriteInt(f,-2000); // min_mag |
1614 | + } else { |
1615 | + WriteInt(f,(int)floor(0.5+1000.0*level_mag_limit[level-1])); // min_mag |
1616 | + } |
1617 | + WriteInt(f,12800); // mag_range |
1618 | + WriteInt(f,256); // mag_steps |
1619 | +} |
1620 | + |
1621 | +void Accumulator::TycZoneArray::writeHeaderToOutput(FILE *f) const { |
1622 | + cout << "Accumulator::TycZoneArray(" << level << ")::writeHeaderToOutput: " |
1623 | + << nr_of_stars << endl; |
1624 | + WriteInt(f,FILE_MAGIC); |
1625 | + WriteInt(f,1); // type |
1626 | + WriteInt(f,0); // major version |
1627 | + WriteInt(f,3); // minor version |
1628 | + WriteInt(f,level); |
1629 | +// WriteInt(f,scale_int); |
1630 | + WriteInt(f,(int)floor(0.5+1000.0*level_mag_limit[level-1])); // min_mag |
1631 | + WriteInt(f,(int)floor(0.5+1000.0*(level_mag_limit[level] |
1632 | + -level_mag_limit[level-1]))); // mag_range |
1633 | + WriteInt(f,30); // mag_steps |
1634 | +} |
1635 | + |
1636 | +void Accumulator::FaintZoneArray::writeHeaderToOutput(FILE *f) const { |
1637 | + cout << "Accumulator::FaintZoneArray(" << level << ")::writeHeaderToOutput: " |
1638 | + << nr_of_stars << endl; |
1639 | + WriteInt(f,FILE_MAGIC); |
1640 | + WriteInt(f,2); // type |
1641 | + WriteInt(f,0); // major version |
1642 | + WriteInt(f,1); // minor version |
1643 | + WriteInt(f,level); |
1644 | +// WriteInt(f,scale_int); |
1645 | + WriteInt(f,(int)floor(0.5+1000.0*level_mag_limit[level-1])); // min_mag |
1646 | + WriteInt(f,(int)floor(0.5+1000.0*(level_mag_limit[level] |
1647 | + -level_mag_limit[level-1]))); // mag_range |
1648 | + WriteInt(f,30); // mag_steps |
1649 | +} |
1650 | + |
1651 | + |
1652 | +void Accumulator::ZoneArray::writeOutput(const char *fname) { |
1653 | + if (nr_of_stars <= 0) return; |
1654 | + FILE *f = fopen(fname,"wb"); |
1655 | + if (f==0) { |
1656 | + cerr << "Accumulator::writeOutput(" << fname << "): " |
1657 | + "fopen failed" << endl; |
1658 | + return; |
1659 | + } |
1660 | + writeHeaderToOutput(f); |
1661 | + for (int zone=0;zone<nr_of_zones;zone++) { |
1662 | + getZone(zone)->writeInfoToOutput(f); |
1663 | + } |
1664 | + int permille = 0; |
1665 | + for (int zone=0;zone<nr_of_zones;zone++) { |
1666 | + getZone(zone)->writeStarsToOutput(f); |
1667 | + int p = (1000*zone)/nr_of_zones; |
1668 | + if (p != permille) { |
1669 | + permille = p; |
1670 | + cout << "\rAccumulator::writeOutput(" << fname << "): " |
1671 | + << permille << "permille written" << flush; |
1672 | + } |
1673 | + } |
1674 | + cout << endl; |
1675 | + fclose(f); |
1676 | +} |
1677 | + |
1678 | +void Accumulator::writeOutput(const char *fnames[]) { |
1679 | + for (int l=0;l<=MAX_LEVEL;l++) { |
1680 | + zone_array[l]->writeOutput(fnames[l]); |
1681 | + } |
1682 | +} |
1683 | + |
1684 | + |
1685 | + |
1686 | + |
1687 | + |
1688 | + |
1689 | + |
1690 | + |
1691 | + |
1692 | + |
1693 | + |
1694 | + |
1695 | + |
1696 | + |
1697 | + |
1698 | +int ReadHipTycFile(Accumulator &accu) { |
1699 | + int count = 0; |
1700 | + FILE *f; |
1701 | + const char *fname = "HipTyc"; |
1702 | + f = fopen(fname,"r"); |
1703 | + if (f == 0) { |
1704 | + fprintf(stderr,"Could not open file \"%s\".\n",fname); |
1705 | + exit(-1); |
1706 | + } |
1707 | + |
1708 | + int hip,tyc1,tyc2,tyc3; |
1709 | + char cids[32]; |
1710 | + char sp[256]; |
1711 | + int mag,b_v,VarFlag; |
1712 | + double ra,dec,Plx,pm_ra,pm_dec; |
1713 | + while (14==fscanf(f,"%d%d%d%d%s%d%lf%lf%lf%lf%lf%d%d%s", |
1714 | + &hip,&tyc1,&tyc2,&tyc3,cids,&VarFlag, |
1715 | + &ra,&dec,&Plx,&pm_ra,&pm_dec,&mag,&b_v,sp)) { |
1716 | + if (b_v>-500 && b_v<3450) { |
1717 | + const int rc = accu.addStar(tyc1,tyc2,tyc3,hip, |
1718 | + cids[0]=='?'?"":cids, |
1719 | + ra, // degrees |
1720 | + dec, // degrees |
1721 | + pm_ra,pm_dec,0.001*mag,0.001*b_v, |
1722 | + Plx,sp[0]=='?'?"":sp); |
1723 | + if (rc < 0) { |
1724 | + // never mind: propably no magnitude for Hiparcos star |
1725 | +// fprintf(stderr,"File \"%s\", record %d: Error 13 %d %d \"%s\"\n", |
1726 | +// fname,count,rc,hip,sp); |
1727 | +// exit(-1); |
1728 | + } |
1729 | + count++; |
1730 | + } |
1731 | + } |
1732 | + fclose(f); |
1733 | + return count; |
1734 | +} |
1735 | + |
1736 | + |
1737 | +const unsigned short int SHORT_ASTSRCBIT0 = 0x0001; // Astrometry source bit 0 |
1738 | +const unsigned short int SHORT_ASTSRCBIT1 = 0x0002; // Astrometry source bit 1 |
1739 | +const unsigned short int SHORT_ASTSRCBIT2 = 0x0004; // Astrometry source bit 2 |
1740 | +const unsigned short int SHORT_UBBIT = 0x0008; |
1741 | +const unsigned short int SHORT_TMBIT = 0x0010; |
1742 | +const unsigned short int SHORT_XRBIT = 0x0020; |
1743 | +const unsigned short int SHORT_IUCBIT = 0x0040; |
1744 | +const unsigned short int SHORT_ITYBIT = 0x0080; |
1745 | +const unsigned short int SHORT_OMAGBIT = 0x0100; |
1746 | +const unsigned short int SHORT_EMAGBIT = 0x0200; |
1747 | +const unsigned short int SHORT_TMONLY = 0x0400; |
1748 | +const unsigned short int SHORT_SPIKE = 0x0800; |
1749 | +const unsigned short int SHORT_TYCONF = 0x1000; |
1750 | +const unsigned short int SHORT_BSCONF = 0x2000; |
1751 | +const unsigned short int SHORT_BSART = 0x4000; |
1752 | +const unsigned short int SHORT_USEME = 0x8000; |
1753 | + |
1754 | +struct Short_NOMAD_Record { |
1755 | + int ra,spd,pm_ra,pm_spd; |
1756 | + short int b,v,r; |
1757 | + unsigned short int flags; |
1758 | +}; |
1759 | + |
1760 | + |
1761 | + |
1762 | +#define READ_SIZE 10000 |
1763 | +static Short_NOMAD_Record buff[READ_SIZE]; |
1764 | + |
1765 | +void ReadNOMADFile(const char *fname,Accumulator &accu) { |
1766 | + int count; |
1767 | + FILE *f; |
1768 | + f = fopen(fname,"r"); |
1769 | + if (f == 0) { |
1770 | + fprintf(stderr,"Could not open file \"%s\".\n",fname); |
1771 | + exit(-1); |
1772 | + } |
1773 | + int total = 0; |
1774 | + do { |
1775 | + count = fread(buff,sizeof(Short_NOMAD_Record),READ_SIZE,f); |
1776 | + total += count; |
1777 | + printf("\rfread(%s,...) returned %6d, total = %8d", |
1778 | + fname,count,total); |
1779 | + fflush(stdout); |
1780 | + int i; |
1781 | + for (i=0;i<count;i++) { |
1782 | + int mag = 30000; |
1783 | + int b_v; |
1784 | + if (buff[i].v >= 30000) { |
1785 | + if (buff[i].b >= 30000) { |
1786 | + if (buff[i].r >= 30000) { |
1787 | +// cerr << "no magnitude at all" << endl; |
1788 | + } else { |
1789 | + mag = buff[i].r + 3499; // just an assumption |
1790 | + b_v = 3499; |
1791 | + } |
1792 | + } else { |
1793 | + mag = buff[i].b + 500; // just an assumption |
1794 | + b_v = -500; |
1795 | + } |
1796 | + } else { |
1797 | + mag = buff[i].v; |
1798 | + if (buff[i].b >= 30000) { |
1799 | + if (buff[i].r >= 30000) { |
1800 | + b_v = 0; |
1801 | + } else { |
1802 | + b_v = buff[i].v-buff[i].r; // desperate |
1803 | + } |
1804 | + } else { |
1805 | + b_v = buff[i].b-buff[i].v; |
1806 | + } |
1807 | + } |
1808 | + |
1809 | + int nr_of_measurements = 0; |
1810 | + if (buff[i].b < 30000) nr_of_measurements++; |
1811 | + if (buff[i].v < 30000) nr_of_measurements++; |
1812 | + if (buff[i].r < 30000) nr_of_measurements++; |
1813 | + |
1814 | + if (mag < 19500 && b_v>-500 && b_v<3450 && |
1815 | + ((buff[i].flags&SHORT_USEME) || |
1816 | + ( |
1817 | + ((buff[i].flags&(SHORT_ASTSRCBIT0|SHORT_ASTSRCBIT1|SHORT_ASTSRCBIT2))!=1 || |
1818 | + (((buff[i].flags&SHORT_UBBIT)==0) |
1819 | + && |
1820 | + (mag>14000 || nr_of_measurements>1) && |
1821 | + (mag>13000 || nr_of_measurements>2) |
1822 | + )) && |
1823 | + ((buff[i].flags&SHORT_SPIKE)==0) && |
1824 | + ((buff[i].flags&SHORT_BSART)==0) && |
1825 | + ((buff[i].flags&SHORT_TMONLY)==0)))) { |
1826 | + if (accu.addStar(0,0,0,0,"", |
1827 | + buff[i].ra/(3600.0*1000.0), // degrees |
1828 | + (buff[i].spd-90*3600*1000)/(3600.0*1000.0), // degrees |
1829 | + 0.1*buff[i].pm_ra,0.1*buff[i].pm_spd, |
1830 | + 0.001*mag,0.001*b_v, |
1831 | + 0,"") < 0) { |
1832 | + fprintf(stderr,"File \"%s\", record %d: Error 16\n",fname,count); |
1833 | + exit(-1); |
1834 | + } |
1835 | + } |
1836 | + } |
1837 | + } while (count == READ_SIZE); |
1838 | + printf("\n"); |
1839 | + fclose(f); |
1840 | +} |
1841 | + |
1842 | + |
1843 | +int main(int argc,char *argv[]) { |
1844 | + if (argc != 3 || |
1845 | + 1 != sscanf(argv[1],"%d",&restrict_output_level_min) || |
1846 | + 1 != sscanf(argv[2],"%d",&restrict_output_level_max)) { |
1847 | + cerr << "Usage: " << argv[0] << " level_min level_max" << endl |
1848 | + << " (like " << argv[0] << " 0 6)" << endl << endl; |
1849 | + return -1; |
1850 | + } |
1851 | + |
1852 | + Accumulator accu; |
1853 | + int n=0; |
1854 | + n = ReadHipTycFile(accu); |
1855 | + printf("HipTyc: %d records processed.\n",n); |
1856 | + SqueezeHip(); |
1857 | + |
1858 | + for (int c=0;nomad_names[c];c++) { |
1859 | + ReadNOMADFile(nomad_names[c],accu); |
1860 | + } |
1861 | + |
1862 | + accu.writeOutput(output_file_names); |
1863 | + |
1864 | + return 0; |
1865 | +} |
Looks O.K.
I t would be nice to wrap this in a gui at some point.