home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume16 / sao / part01 next >
Text File  |  1988-12-06  |  34KB  |  1,047 lines

  1. Subject:  v16i090:  Smithsonian Astronomical Observatory, Part01/49
  2. Newsgroups: comp.sources.unix,sci.astro,sci.space
  3. Approved: rsalz@uunet.UU.NET
  4.  
  5. Submitted-by: Alan Wm Paeth <awpaeth@watcgl.waterloo.edu>
  6. Posting-number: Volume 16, Issue 90
  7. Archive-name: sao/part01
  8.  
  9. # This is a shell archive.  Remove anything before this line,
  10. # then unpack it by saving it in a file and typing "sh file".
  11. # Contents:  NOTES-SAO README build compile decode decodeall encode encodeall
  12. #    makeshar saoconv.c saoextract stardouble stardust.c starsplit.c
  13.  
  14. echo x - NOTES-SAO
  15. sed 's/^@//' > "NOTES-SAO" <<'@//E*O*F NOTES-SAO//'
  16. -------------------------------------------------------------------------------
  17.                              REDUCED SAO
  18.  
  19.                             Alan Wm Paeth
  20.                      Computer Graphic Laboratory
  21.                         University of Waterloo
  22.                         Ontario, Canada N2L 3G1
  23.  
  24. -------------------------------------------------------------------------------
  25.  
  26.  
  27. The following describes the SAO (Smithsonian Astronomical Observatory) dataset,
  28. reduced to RA/DECL/MAG records and posted in ASCII format in 48 parts.
  29.  
  30. The SAO dataset was furnished c/o Nasa Goddard for non-commercial use. It is
  31. probably the most comprehensive electronic stellar database having both full
  32. sky coverage and general availability. Containing 258,997 records to magnitude
  33. 11.6, it is popularly considered to have a limiting magnitude (that point at
  34. which omissions equals inclusions) of 9.5. The original 40 megabyte dataset
  35. is distributed on tape. Its records contain detailed information on proper
  36. motion, photometry and other information.
  37.  
  38. This reduced dataset provides about 1.4M of excerpted information, encoded to
  39. minimized overall transmission costs. Decoding requires a UNIX software system
  40. and C compiler. All data may be redistributed for non-commercial private use.
  41. (This is encouraged to save unnecessary repeated postings from any one site).
  42.  
  43. The remainder of this document is in two sections. The first is a functional
  44. description of how to decode the postings to form the canonical set of 48 files
  45. which form the reduced SAO. The final section details the steps used to reduce
  46. and distribute the dataset.
  47.  
  48.  
  49. [1] UNPACKING INSTRUCTIONS
  50.  
  51. Summary
  52.  
  53. The SAO distribution is a suite 48 files, normally distributed on the net with
  54. one file enclosure per posting (the largest file is intentionally just under
  55. 50K bytes). Each file is a free-standing entity describing the location, class
  56. (single, double, variable) and magnitude of all stars within one spatial area,
  57. sorted by increasing magnitude. The area represented is implicit in the file
  58. name; no file extension is used. This arrangement by spatial region simplifies
  59. both distribution and use of the dataset. A typical file from the distribution
  60. suite is named "SAO22+60"
  61.  
  62. In a nutshell, decoding of any one file begins by stripping out unnecessary
  63. message header information (if present) leaving a characteristic "uuencoded"
  64. ASCII file of sixty-four character lines. Next, a specialized program (called
  65. "stardust", but invoked implicitly during decoding) is compiled to assist the
  66. decoding. A final script decodes the file. An example of the three steps is:
  67.  
  68.     #strip header from posting and save data as "SAO22+60.dzu"
  69.     ./compile                         # make up the stardust program
  70.     ./decode SAO22+60                 # decode the one file "SAO22+60"
  71.  
  72. Similarly, once all 48 source files have been retrieved from each posting and
  73. saved as .dzu files, then the entire dataset may be created (with the program
  74. compilation performed implicitly) be executing one shell command:
  75.  
  76.     ./decodeall                       # decodes entire dataset
  77.     
  78. For those more interested in the specifics of how coding takes place, the
  79. operation of these files is described below.
  80.  
  81. Nuts and Bolts
  82.  
  83. Encoded SAO files stripped of message header information are stored with the
  84. extension ".dzu".  This designation indicates that the data has been
  85. "starDusted", "lempel-Zif compressed" and "Uuencoded", in that order. In nested
  86. fashion, the reverse set of operations must then be performed to reconstruct
  87. the original file. Each decoding step removes the final character of the file
  88. extension (each character represents a successive coding step) until no file
  89. extension remains, at which time the required SAO file will be rebuilt. Of
  90. these three steps, two are common to Unix systems. The third step called
  91. "stardust" is a C program written specifically to compress each SAO file. It
  92. is distributed as part of the reduced SAO suite.
  93.  
  94. As an example, we wish to reconstruct the SAO file "SAO18-30" (the "teapot" of
  95. Sagittarius) from a posting. We first strip off extraneous message detail and
  96. form the file "SAO18-30.dzu". Assuming we have only the source for stardust.c,
  97. we then perform:
  98.  
  99.     cc stardust.c -o stardust          # generate "stardust" tool
  100.     uudecode SAO18-30.dzu              # map uuencoded ASCII to binary
  101.     uncompress SAO18-30.dz             # uncompress binary to "dusted" ASCII
  102.     ./stardust <SAO18-30.d >SAO18-30   # reintegrated stardusted file to SAO 
  103.  
  104. This entire operation (without the C compile) is present in the shell script
  105. "decode". The parent "decodeall" runs this operation on all 48 files.
  106. Similarly, the scripts "encode" and "encodeall" perform the reverse operation.
  107.  
  108. An additional software tool "starsplit.c" is also provided in the distribution
  109. to split the entire dataset into its 48 constituent files (certain operations
  110. are best performed on the entire data "en masse", but the datset is always
  111. presented as 48 separate spatial entities for the sake of distribution and
  112. convention). For additional details read the source code.
  113.  
  114.  
  115. [2] CONVERSION DETAILS
  116.  
  117. Reduction
  118.  
  119. The SAO reduction is to a file format compatible with the "StarChart" software
  120. suite published by Alan Paeth (awpaeth.waterloo.edu) on net.sources.unix (then
  121. "net.sources") in 1987 and  now under active development by Craig Counterman
  122. (ccount@royal.mit.edu). Because of the shear enormity of the dataset and the
  123. cost of distribution, notable omissions in the reduction include SAO numbers
  124. and spectral classes, leaving merely Ra/Decl/Mag and a star designator.
  125.  
  126. We do not consider the SAO reduction a replacement to the Yale Bright Star
  127. Catalog reduction previously posted (the latter includes spectral classes plus
  128. common names and designations), but a means to supplement Yale with additional
  129. information for the express purpose of making detailed finder charts at a very
  130. large scale. The SAO data is inappropriate for most wide-field or low power
  131. charts and would provide needlessly cluttered output.
  132.  
  133. Conversion
  134.  
  135. The conversion moved stellar locations (through proper motion) from 1950.0 to
  136. 2000.0 positions. An epoch change to 2000.0 (owing to the precession of the
  137. equinoxes) was then performed. Visual magnitudes were used, photographic
  138. magnitudes were substituted when the former was absent. Missing records were
  139. deleted (there are 230 SAO numbers no longer having a unique associated star).
  140. These conversions all took place at the original precision of the dataset of
  141. about 0.01", which was then rounded into standard Right Ascension and
  142. Declination numeric values in the format used by the StarChart software suite.
  143.  
  144. The "raw" SAO data at the reduced resolution was then sorted by location and
  145. magnitude and run through a simple awk (Unix record processor) script to merge
  146. stars of identical location at the new positional resolution into unique stars.
  147. A composite magnitude was computed by proper application of logarithms. Any
  148. star designation of "single" was promoted to "double" and a new composite
  149. magnitude computed. Multiple systems are similarly grouped and composited but
  150. also show a "double" designation, which should be taken to mean "non-single".
  151. Variable stars are much more rare and this designation is kept to represent
  152. the aggregation on the whole should any one component be variable. This reduces
  153. SAO by 560 records to a final value of 258,277 fixed length ASCII records,
  154. which should not change.
  155.  
  156. File Splitting
  157.  
  158. The data (still sorted by magnitude) was then split into 48 files based on
  159. spatial location. This simplifies both distribution and program use. Because a
  160. detailed chart will rarely require more than a few of the forty eight files
  161. simultaneously, this provides a simple means to limit the volume of data which
  162. any program must process. The split boundaries lie on even hours of Right
  163. Ascension (twelve splits) at the Celestial Equator and at +-30 degrees in
  164. Declination. This conveniently allows the Ecliptic to lie within the inner set
  165. of charts, with one chart representing roughly one constellation of the zodiac.
  166. The equatorial charts are also (roughly) square, being 30 degrees on each side.
  167. The polar charts span sixty degrees in Declination, but cover an identical
  168. spatial area, as a consequence of the Equal Area Cylindrical projection (and
  169. the fact that sin(30deg) = 0.5 exactly).
  170.  
  171. The 48 sorted, split files constitute the reduced SAO dataset, and they are
  172. distributed as 48 separate postings. Sites are free to merge and sort the
  173. datasets into single files, but in the interests of compatibility, the
  174. "starsplit" C program is also distributed to allow spatial fragmentation back
  175. into "canonical" pieces.
  176.  
  177. File Names and Format
  178.  
  179. File names are eight characters and of the form SAOhhsDD where "hh" is the Ra
  180. designator taken from the set (00 02 04 06 08 10 12 14 16 18 20 22) and "sDD"
  181. is the De designator taken from the set (-90 -30 +00 +30 +60). The designators
  182. give the minimum values for Ra and De occurring in the file, bounded at the
  183. high end by the next larger designator (with and implicit limit of 24 hours and
  184. +90 degrees for Ra and De). For instance, SA002-60 contains stars with RA and
  185. DE such that (02 hours <= RA < 04 hours) and (-60 deg <= DE < 0 deg).
  186.  
  187. Each fixed length record consists of sixteen ASCII characters (digits, +, -, S,
  188. V, D are the only values which occur) followed by a carriage return. The format
  189. is HHMMSS+DDMMmmmCC where "HH" is HHMMSS give hours, minutes and seconds in
  190. Right Ascension, +DDMM give signed degrees and minutes in Declination, mmm give
  191. magnitude*100 for positive values and magnitude*10 for negative and CC is one
  192. of "SS", "SD" or "SV" signifying "star, single", "star, double [multiple] or
  193. "star variable", respectively. This format cannot record magnitudes below 9.99.
  194. However, because only 3719 records or 1.4% of the reduced SAO records are this
  195. dim, they are retained at magnitude "9.99", while records of magnitude "10.0"
  196. are recorded as "9.98" to provide unambiguity. The latter is an insignificant
  197. change in magnitude, as the original SAO data records magnitude to the first
  198. decimal point.
  199.  
  200. The four brightest stars in the reduced SAO are listed as a format example.
  201.  
  202. 064510-1643-16SD
  203. 062358-5242-09SS
  204. 143937-6050010SD
  205. 183657+3847010SS
  206.  
  207. The dimmest stars in the original dataset were (here precessed to E2000.0):
  208.  
  209.     ra      decl   mag
  210.  -------  ------  ----
  211.  1h06m26s -31o01' 11.6
  212.  6h52m42s -52o16' 11.6
  213.  9h57m24s -42o26' 11.6 (now grouped with a star of mag 9.3)
  214. 11h39m55s -38o30' 11.6
  215. 21h41m10s -34o57' 11.6
  216.  2h37m47s -41o54' 11.8
  217. 23h18m44s -34o56' 11.8
  218.  7h55m39s -43o47' 11.9 (now grouped with a star of mag 7.5)
  219.  
  220. Being below the limiting magnitude of the dataset, these most often represent
  221. faint companions to brighter stars.
  222.  
  223. Coding and Distribution
  224.  
  225. A three step coding process is used to reduce the size of each file prior
  226. to distribution. The heart of this process is the second step: the Unix
  227. "compress" program. A large increase in overall compression can be achieved by
  228. preprocessing the data to compress into a form which is more regular, possibly
  229. by coding patterns which "compress" has not taken advantage of.
  230.  
  231. The program which accomplishes this is called "stardust". Because the fixed
  232. length records tend to have very similar characters in each card column
  233. (especially considering that they lie in similar spatial areas and are sorted
  234. by magnitude), we perform a differencing operation across adjacent scanlines,
  235. in which a "0" indicates that no change has occurred and more generally, digits
  236. will change modulo ten from previous digits (the exact details are implicit in
  237. the source code). This regularity is normally missed by compress, because such
  238. "runs" occur every record length of seventeen characters, not in adjacent
  239. columns. The differencing operation makes for a much higher density of ASCII
  240. zeros in the file, which compress happily encodes.
  241.  
  242. The final step is "uuencode" which remaps the 8-bit binary output of compress
  243. into ASCII characters for subsequent transmission, thereby increasing the
  244. overall file size by about 4/3. Following this step, the largest file is
  245. still under 50K in size, a valuable consideration for many mail systems.
  246. Unfortunately, a "full" version of compress is required for this compaction;
  247. the "-b12" twelve-bit reduced coding table compress variant (the only version
  248. available on some smaller systems) cannot achieve packing below 50K, despite
  249. a compression difference of only a few percent.
  250.  
  251. Present and Future Plans
  252.  
  253. A modest extension to SAO would include the last three digits of each star's
  254. SAO number and a spectral class indication. However, it is estimated that this
  255. would increase the size of the entire dataset by 50% and will probably not be
  256. done. Instead, astronomical sites may wish to obtain the original dataset and
  257. reconvert as per their specific needs.
  258.  
  259. Present work involves identifying those stars within SAO which are already
  260. present within the posted Yale data. By publishing a simple omissions list,
  261. the file SAO' may then be formed. The superset of both Yale and SAO may then
  262. be constructed simply by concatenating Yale with this SAO' and then sorting
  263. (as appropriate). This would yield a master dataset with proper names, stellar
  264. class and other detailed information for the first ~9000 stars, with the
  265. SAO data providing detail for stars dimmer than about magnitude 6.5.
  266.  
  267. All software used to map from the tape dataset into the final distribution
  268. files has been included or the sake of professional sites wishing to perform
  269. custom, private reductions. Questions and comments should be directed to:
  270. Alan Paeth (awpaeth@waterloo.edu, awpaeth@watcgl@waterloo.csnet).
  271. @//E*O*F NOTES-SAO//
  272. chmod u=rw,g=r,o=r NOTES-SAO
  273.  
  274. echo x - README
  275. sed 's/^@//' > "README" <<'@//E*O*F README//'
  276. Name          Description
  277. ----          -----------
  278. NOTES-SAO     description of unpacking instructions and the conversion process
  279. README        this file
  280. SAO?????      canonical SAO files in dataset (48)
  281. SAO?????.dzu  above in encoded format
  282. build         convert raw tape data to final 48 (coded) files for distribution
  283. compile       compile "stardust" program for decoding.
  284. decode        decode one SAOxxxxx.dzu into an SAOxxxxx file
  285. decodeall     decode all 48 SAO*.dzu files into the canonical dataset
  286. encode        encode one SAOxxxxx file into a SAOxxxxx.dzu file
  287. encodeall     encode all canonical SAO files into .dzu files
  288. makeshar      file to shar the non-data portions of the SAO suite
  289. saoconv.c     (used to convert the SAO tape into the raw dataset)
  290. saoextract    runs saoconv; converts SAO tape into raw dataset
  291. stardouble    awk script to remove duplicate spatial entries from raw sao 
  292. stardust.c    source for stardust.c -- used to ready sao for (de)compression
  293. starsplit.c   split raw sao into 48 constituent parts
  294. @//E*O*F README//
  295. chmod u=rw,g=r,o=r README
  296.  
  297. echo x - build
  298. sed 's/^@//' > "build" <<'@//E*O*F build//'
  299. #!/bin/csh -f
  300. #
  301. # This script converts the master (40M) tape dataset "sao" into 48 encoded
  302. # canonical reduced SAO files for distribution. Site use requires access to
  303. # the original SAO data as distributed by NASA.
  304. #
  305. # compile specialized tools as needed
  306. #
  307. cc saoconv.c -lm -o saoconv
  308. cc starsplit.c -o starsplit
  309. #
  310. # run it
  311. #
  312. @./saoextract sao
  313. @./starsplit  <sao.star
  314. @./encodeall
  315. @//E*O*F build//
  316. chmod u=rwx,g=rx,o=rx build
  317.  
  318. echo x - compile
  319. sed 's/^@//' > "compile" <<'@//E*O*F compile//'
  320. #!/bin/csh -f
  321. #
  322. # compile custom program necessary for decoding (and encoding).
  323. cc stardust.c -o stardust
  324. @//E*O*F compile//
  325. chmod u=rwx,g=rx,o=rx compile
  326.  
  327. echo x - decode
  328. sed 's/^@//' > "decode" <<'@//E*O*F decode//'
  329. #!/bin/csh -f
  330. #
  331. # decode - convert one SAO encoded file (with implicit .dzu extension) into
  332. #          unencoded output. Note: no encoded files are deleted by this script.
  333. #
  334. # example "./decode SAO12+30"
  335. #
  336. uudecode $1.dzu
  337. chmod +rw $1.dz
  338. uncompress -c <$1.dz >$1.d
  339. @./stardust <$1.d >$1
  340. rm $1.dz $1.d
  341. #rm $1.dzu
  342. @//E*O*F decode//
  343. chmod u=rwx,g=rx,o=rx decode
  344.  
  345. echo x - decodeall
  346. sed 's/^@//' > "decodeall" <<'@//E*O*F decodeall//'
  347. #!/bin/csh -f
  348. #
  349. # Run "decode" on all .dzu files (48) to form canonical dataset
  350. #
  351. @./compile
  352. #
  353. @./decode SAO00+00
  354. @./decode SAO00+30
  355. @./decode SAO00-30
  356. @./decode SAO00-90
  357. @./decode SAO02+00
  358. @./decode SAO02+30
  359. @./decode SAO02-30
  360. @./decode SAO02-90
  361. @./decode SAO04+00
  362. @./decode SAO04+30
  363. @./decode SAO04-30
  364. @./decode SAO04-90
  365. @./decode SAO06+00
  366. @./decode SAO06+30
  367. @./decode SAO06-30
  368. @./decode SAO06-90
  369. @./decode SAO08+00
  370. @./decode SAO08+30
  371. @./decode SAO08-30
  372. @./decode SAO08-90
  373. @./decode SAO10+00
  374. @./decode SAO10+30
  375. @./decode SAO10-30
  376. @./decode SAO10-90
  377. @./decode SAO12+00
  378. @./decode SAO12+30
  379. @./decode SAO12-30
  380. @./decode SAO12-90
  381. @./decode SAO14+00
  382. @./decode SAO14+30
  383. @./decode SAO14-30
  384. @./decode SAO14-90
  385. @./decode SAO16+00
  386. @./decode SAO16+30
  387. @./decode SAO16-30
  388. @./decode SAO16-90
  389. @./decode SAO18+00
  390. @./decode SAO18+30
  391. @./decode SAO18-30
  392. @./decode SAO18-90
  393. @./decode SAO20+00
  394. @./decode SAO20+30
  395. @./decode SAO20-30
  396. @./decode SAO20-90
  397. @./decode SAO22+00
  398. @./decode SAO22+30
  399. @./decode SAO22-30
  400. @./decode SAO22-90
  401. @//E*O*F decodeall//
  402. chmod u=rwx,g=rx,o=rx decodeall
  403.  
  404. echo x - encode
  405. sed 's/^@//' > "encode" <<'@//E*O*F encode//'
  406. #!/bin/csh -f
  407. #
  408. # encode - convert one good SAO file into an encoded .dzu file.
  409. #
  410. # example: "./encode SAO12+30"
  411. #
  412. #./stardust <$1 -e | compress -c -b12 | uuencode $1.dz >$1.dzu # we wish!
  413. @./stardust  <$1 -e | compress -c      | uuencode $1.dz >$1.dzu
  414. @//E*O*F encode//
  415. chmod u=rwx,g=rx,o=rx encode
  416.  
  417. echo x - encodeall
  418. sed 's/^@//' > "encodeall" <<'@//E*O*F encodeall//'
  419. #!/bin/csh -f
  420. #
  421. # encode all 48 canonical SAO files to form encoded .dzu set.
  422. #
  423. @./compile
  424. #
  425. @./encode SAO00+00
  426. @./encode SAO00+30
  427. @./encode SAO00-30
  428. @./encode SAO00-90
  429. @./encode SAO02+00
  430. @./encode SAO02+30
  431. @./encode SAO02-30
  432. @./encode SAO02-90
  433. @./encode SAO04+00
  434. @./encode SAO04+30
  435. @./encode SAO04-30
  436. @./encode SAO04-90
  437. @./encode SAO06+00
  438. @./encode SAO06+30
  439. @./encode SAO06-30
  440. @./encode SAO06-90
  441. @./encode SAO08+00
  442. @./encode SAO08+30
  443. @./encode SAO08-30
  444. @./encode SAO08-90
  445. @./encode SAO10+00
  446. @./encode SAO10+30
  447. @./encode SAO10-30
  448. @./encode SAO10-90
  449. @./encode SAO12+00
  450. @./encode SAO12+30
  451. @./encode SAO12-30
  452. @./encode SAO12-90
  453. @./encode SAO14+00
  454. @./encode SAO14+30
  455. @./encode SAO14-30
  456. @./encode SAO14-90
  457. @./encode SAO16+00
  458. @./encode SAO16+30
  459. @./encode SAO16-30
  460. @./encode SAO16-90
  461. @./encode SAO18+00
  462. @./encode SAO18+30
  463. @./encode SAO18-30
  464. @./encode SAO18-90
  465. @./encode SAO20+00
  466. @./encode SAO20+30
  467. @./encode SAO20-30
  468. @./encode SAO20-90
  469. @./encode SAO22+00
  470. @./encode SAO22+30
  471. @./encode SAO22-30
  472. @./encode SAO22-90
  473. @//E*O*F encodeall//
  474. chmod u=rwx,g=rx,o=rx encodeall
  475.  
  476. echo x - makeshar
  477. sed 's/^@//' > "makeshar" <<'@//E*O*F makeshar//'
  478. #!/bin/csh -f
  479. public shar -c NOTES-SAO README build compile decode decodeall encode encodeall makeshar saoconv.c saoextract stardouble stardust.c starsplit.c >SaoMaster.shar
  480. @//E*O*F makeshar//
  481. chmod u=rwx,g=rwx,o=rwx makeshar
  482.  
  483. echo x - saoconv.c
  484. sed 's/^@//' > "saoconv.c" <<'@//E*O*F saoconv.c//'
  485. /*
  486.  * saoconv.c -- convert sao data into starchart format
  487.  *
  488.  * copyright (c) 1988 by Alan Wm Paeth. All rights reserved.
  489.  *
  490.  * SAO input is taken as the raw 150 character ASCII records as appearing
  491.  * in the tape distribution. The output is in the form of StarChart style
  492.  * records. This version includes facilities to clip to a limiting magnitude
  493.  * of 10, and to record the number of dim (or missing) stars. Four command
  494.  * line parameters may be provided to give limiting RA and DECL values, but
  495.  * for current purposes the mapping into spatial regions is done later.
  496.  * 
  497.  */
  498.  
  499. #include <stdio.h>
  500. #include <math.h>
  501.  
  502. /*
  503.  * the following give the input and output proper motion locations and epochs
  504.  */
  505.  
  506. #define EPIN   1950.0
  507. #define EPOUT  2000.0
  508. #define POSIN  1950.0
  509. #define POSOUT 2000.0
  510.  
  511. #define STDIN 0
  512. #define STDOUT 1
  513. #define ISIZE 150
  514. #define OSIZE   5
  515.  
  516. #define LR 0.0
  517. #define HR 360.0
  518. #define LD -90.0
  519. #define HD 90.0
  520.  
  521. #define DLDEGSEC 3600.0
  522. #define DLMINSEC 60.0
  523. #define RAHRSSEC 54000.0
  524. #define RAMINSEC 900.0
  525. #define RASECSEC 15.0
  526. #define RADTODEG (180.0/3.14159265358979324)
  527. #define DEGTORAD (3.14159265358979324/180.0)
  528.  
  529. #define R90 (90.0*DEGTORAD)
  530. #define R360 (360.0*DEGTORAD)
  531.  
  532. #define DSIN(x) sin((x)*DEGTORAD)
  533. #define DCOS(x) cos((x)*DEGTORAD)
  534. #define DTAN(x) tan((x)*DEGTORAD)
  535.  
  536. #define F(col1, col2) (in[col2] = '\0', atof(&in[col1-1]))
  537. #define I(col1, col2) (in[col2] = '\0', atoi(&in[col1-1]))
  538.  
  539. double atof();
  540. char in[ISIZE+1], out[OSIZE+2];
  541. int nomag, dimmag;
  542.  
  543. main(argc, argv)
  544.     char *argv[];
  545.     {
  546.     int rval;
  547.     double ra, dl, ra2, dl2, mg;
  548.     char tp;
  549.     double lr, hr, ld, hd;
  550. /*
  551.  * arg checking
  552.  */
  553.     if (argc == 1)
  554.     {
  555.     lr = LR;
  556.     hr = HR;
  557.     ld = LD;
  558.     hd = HD;
  559.     }
  560.     else if (argc == 5)
  561.     {
  562.     lr = atof(argv[1]);
  563.     hr = atof(argv[2]);
  564.     ld = atof(argv[3]);
  565.     hd = atof(argv[4]);
  566.     }
  567.     else err("use: saoconv {ralow rahi declow dechi {flt degs}}\n");
  568.     if (lr < LR) err("ra too low");
  569.     if (hr > HR) err("ra too high");
  570.     if (ld < LD) err("dcl too low");
  571.     if (hd > HD) err("decl too high");
  572.     if (lr >= hr) err("ra overlap");
  573.     if (ld >= hd) err("decl overlap");
  574.     lr *= DEGTORAD;
  575.     hr *= DEGTORAD;
  576.     ld *= DEGTORAD;
  577.     hd *= DEGTORAD;
  578. /*
  579.  * the stuff
  580.  */
  581.      while (rval = saoread(&ra, &dl, &mg, &tp, POSIN, POSOUT))
  582.     {
  583.     if ((rval > 0) && (ra >= lr) && (ra < hr) && (dl >= ld) && (dl < hd) )
  584.         {
  585.         xform(ra, dl, &ra2, &dl2, EPIN, EPOUT);
  586.         saowrite(ra2, dl2, mg, tp);
  587.         }
  588.     }
  589.     fprintf(stderr, "nomag: %d, dimmag: %d\n", nomag,dimmag);
  590.     exit(0);
  591.     }
  592.  
  593. saoread(r, d, m, t, ein, eout)
  594.     double *r, *d, *m, ein, eout;
  595.     char *t;
  596.     {
  597.     int len;
  598.     double dec, ras, mag, vis, pho;
  599.     double mua, mud;
  600.     int hdc, dup;
  601.     char tp;
  602.     len = read(STDIN, in, ISIZE);
  603.     if (len == 0) return(0);
  604.     if (len < 0)
  605.     {
  606.     fprintf(stderr, "read error; code = %d\n", len);
  607.     fflush(stderr);
  608.     return(0);
  609.     }
  610.     if (len != ISIZE)
  611.     {
  612.     fprintf(stderr, "runt record: %d-of-%d bytes \n", len, ISIZE);
  613.     fflush(stderr);
  614.     return(0);
  615.     }
  616.     if (in[6] == 'D') return(-1);
  617. /*
  618.  * warning: reads must be from successively lower numbered columns.
  619.  */
  620.     dec = F(140,150);
  621.     ras = F(130,139);
  622.     hdc = I(124, 124);
  623.     dup = I( 95, 95);
  624.     vis = F( 81, 84);
  625.     pho = F( 77, 80);
  626.     mud = F( 52, 57);
  627.     mua = F( 18, 24);
  628. /*
  629.  * get brighter of visual/photographic magnitudes
  630.  */
  631.     mag = (vis < 20.0) ? vis : pho;
  632.     if (mag > 12.0)
  633.     {
  634.     nomag++;
  635.     return(-1);
  636.     }
  637. /*
  638.  * CLIP DIM STARS TO MAG 9.99, (stars of mag 10.0 become 9.98 to disambiguate)
  639.  */
  640.     else if (mag > 10.0)
  641.     {
  642.     dimmag++;
  643.     mag = 9.99;
  644.     }
  645.     else if (mag == 10.0) mag = 9.98;
  646.     tp = 'S';
  647.     if (dup > 4) tp = 'V';
  648.     else if ((dup > 0) || hdc) tp = 'D';
  649.     *r = ras + ( (eout-ein)*mua*RASECSEC/DLDEGSEC*DEGTORAD);
  650.     *d = dec + ( (eout-ein)*mud         /DLDEGSEC*DEGTORAD);
  651.     if (*r > R360) *r -= R360;
  652.     if (*r < 0) *r += R360;
  653.     if ((*d > R90) || (*d < -R90)) err("proper motion beyond +-90 decl");
  654.     *m = mag;
  655.     *t = tp;
  656.     return(1);
  657.     }
  658.  
  659. saowrite(r, d, m, t)
  660.     double r, d, m;
  661.     char t;
  662.     {
  663.     int rah, ram, ras, dld, dlm, sign, mag;
  664. /*
  665.  * convert ra to base 60
  666.  */
  667.     r *= RADTODEG;
  668.     d *= RADTODEG;
  669.     r *= DLDEGSEC;
  670.     rah = r/RAHRSSEC;
  671.     r -= rah*RAHRSSEC;
  672.     ram = r/RAMINSEC;
  673.     r -= ram*RAMINSEC;
  674.     ras = r/RASECSEC + 0.5;
  675. /*
  676.  * round and propagate ra in seconds and minutes
  677.  */
  678.     if (ras >= 60)
  679.     {
  680.     ras -= 60;
  681.     ram++;
  682.     }
  683.     if (ram >= 60)
  684.     {
  685.     ram -= 60;
  686.     rah++;
  687.     }
  688. /*
  689.  * convert de to base 60
  690.  */
  691.     sign = (d < 0.0);
  692.     if (sign) d = -d;
  693.     dld = d;
  694.     d -= dld;
  695.     dlm = d * DLMINSEC + 0.5;
  696. /*
  697.  * round and propage de in minutes
  698.  */
  699.     if (dlm >= 60)
  700.     {
  701.     dlm -= 60;
  702.     dld++;
  703.     }
  704. /*
  705.  * error check new output values (propagation/range errors)
  706.  */
  707.     if (rah >= 24)
  708.     fprintf(stderr, "int. ra error %02d%02d%02d%s%02d%02d%03dS%c\n",
  709.     rah, ram, ras, sign ? "-":"+", dld, dlm, mag, t);
  710.     if (dld >= 90)
  711.     fprintf(stderr, "int. decl. error %02d%02d%02d%s%02d%02d%03dS%c\n",
  712.     rah, ram, ras, sign ? "-":"+", dld, dlm, mag, t);
  713. /*
  714.  * compute rounded magnitudes, print in three digits
  715.  */
  716.     mag = (m < 0.0) ? m*10 : m*100;
  717.     if (mag > 999)
  718.     {
  719.     fprintf(stdout, "%02d%02d%02d%s%02d%02d%04dS%c\n",
  720.     rah, ram, ras, sign ? "-":"+", dld, dlm, mag, t);
  721.     fprintf(stderr, "mag too low\n");
  722.     }
  723.     else
  724.     fprintf(stdout, "%02d%02d%02d%s%02d%02d%03dS%c\n",
  725.     rah, ram, ras, sign ? "-":"+", dld, dlm, mag, t);
  726.     }
  727.  
  728. xform(rin, din, rout, dout, ein, eout)
  729.     double rin, din, *rout, *dout, ein, eout;
  730.     {
  731.     double t, t2, x, y, z, w, d;
  732. /*
  733.  * update
  734.  */
  735.     rin *= RADTODEG;
  736.     din *= RADTODEG;
  737. /* */
  738.     t2 = ( (ein+eout)/2.0 - 1900.0 ) / 100.0;
  739.     x = 3.07234 + (.00186 * t2);
  740.     y = 20.0468 - (.0085 * t2);
  741.     z = y/15;
  742.     t = eout-ein;
  743.     w = .0042 * t * (x + (z * DSIN(rin) * DTAN(din)) );
  744.     d = .00028 * t * y * DCOS(rin);
  745.     *rout = rin + w;
  746.     if (*rout >= 360.0) *rout -= 360.0;
  747.     if (*rout < 0.0) *rout += 360.0;
  748.     *dout = din + d;
  749. /*
  750.  * update
  751.  */
  752.     *rout /= RADTODEG;
  753.     *dout /= RADTODEG;
  754.     }
  755.  
  756. err(s)
  757.     char *s;
  758.     {
  759.     fprintf(stderr, "%s\n", s);
  760.     fflush(stderr);
  761.     exit(1);
  762.     }
  763. @//E*O*F saoconv.c//
  764. chmod u=rw,g=r,o=r saoconv.c
  765.  
  766. echo x - saoextract
  767. sed 's/^@//' > "saoextract" <<'@//E*O*F saoextract//'
  768. #!/bin/csh -f
  769. #
  770. # This script runs "saoconv" with appropriate sorting and merging to convert
  771. # the 40M SAO tape dataset (the standard input) into the master "StarChart"
  772. # format SAO dataset "sao.star". Errors and summary detail logged in "saoerr".
  773. #
  774. # We don't use the "-n" sort flag because this buys about 1.2% in overall
  775. # compression, which is valuable in reducing the largest dataset from a
  776. # critical size (in terms of transport by e-mail) of 49.5kbytes to 48.9kbytes.
  777. # The penalty incurred is in reversing the sorted order of the two brightest
  778. # stars (Sirius and Alpha Centaurii alone possess negative magnitudes) which
  779. # is unimportant. The favorable alphabetic sorting on ra/decl fields for
  780. # records having like magnitudes (runs) produces more compressable output.
  781. #
  782. (./saoconv <$1 |\
  783.    sort +0.0 |\
  784.    ./stardouble - |\
  785.    sort +0.11 -0.16 +0.0 -0.10 >sao.star ) >& saoerr
  786. @//E*O*F saoextract//
  787. chmod u=rwx,g=rx,o=rx saoextract
  788.  
  789. echo x - stardouble
  790. sed 's/^@//' > "stardouble" <<'@//E*O*F stardouble//'
  791. #!/bin/awk -f
  792.   {
  793.   id =  substr($0, 1,11);
  794.   mag = substr($0,12, 3);
  795.   des = substr($0,15, 2);
  796.   tail= substr($0,17,99);
  797.   if( id == oid )
  798.       {
  799.       mag = log(exp(-0.00921034*mag) + exp(-0.00921034*omag)) * (-100/.921034); 
  800.       if (des != "SV") des = "SD";
  801.       if (length(otail) > length(tail)) tail = otail;
  802.       }
  803.   else if( oid != 0 ) printf "%s%03d%s%s\n", oid, omag, odes, otail
  804.   oid = id;
  805.   omag = mag;
  806.   odes = des;
  807.   otail= tail;
  808.   }
  809. END { printf "%s%03d%s%s\n", oid, omag, odes, otail }
  810. @//E*O*F stardouble//
  811. chmod u=rwx,g=rx,o=rx stardouble
  812.  
  813. echo x - stardust.c
  814. sed 's/^@//' > "stardust.c" <<'@//E*O*F stardust.c//'
  815. /*
  816.  * stardust.c -- (un)pulverize files into dust more digestable by compress
  817.  *
  818.  * stardust -e <file.star | compress >small # encode for better compression
  819.  * uncompress small | stardust >file.star   # decode after decompress
  820.  *
  821.  * copyright (c) 1988 by Alan Paeth (awpaeth@watcgl)
  822.  */
  823.  
  824. #include <stdio.h>
  825.  
  826. #define BS 17
  827. #define STDIN 0
  828. #define STDOUT 1
  829. #define CD 15    /* buf offset to (S,V,D) star code; (0,1,2) if encoded */
  830.  
  831. int ln, en;
  832.  
  833. main(argc, argv)
  834.     char *argv[];
  835.     {
  836.     char b1[BS], b2[BS], b3[BS], *cur, *lst, *t;
  837.     if (argc > 2) err("too many cmd parms");
  838.     if (argc == 2)
  839.     {
  840.     if (argv[1][0] != '-') err("switch expected");
  841.     if (argv[1][1] != 'e') err("only '-e' {encode} allowed");
  842.     en = 1;
  843.     }
  844.     cur = b3;
  845.     lst = b2;
  846.     if (!rline(lst)) err("input file is empty");
  847.     wline(lst);
  848.     while (rline(cur))
  849.     {
  850.     cline(b1, (!en && (ln>2)) ? b1 : lst, cur);
  851.     wline(b1);
  852.     t = cur; cur = lst; lst = t;
  853.     }
  854.     }
  855.  
  856. cline(bo, ba, bb)
  857.     char *bo, *ba, *bb;
  858.     {
  859.     int i;
  860.     for (i=0; i<BS; i++)
  861.     {
  862.     char c, t;
  863.     c = *ba++ - (t=*bb++);
  864.     if (t != '0')
  865.         {
  866.         if (c < 0) c += 10;
  867.         if (en && ((c < 0) || (c > 9))) err("non-digit or non-match");
  868.         }
  869.     *bo++ = c + '0';
  870.     }
  871.     }
  872.  
  873. rline(b)
  874.     char *b;
  875.     {
  876.     int l, cd;
  877.     char *c;
  878.     l = read(STDIN, b, BS);
  879.     if (l == 0) return(0);
  880.     ln++;
  881.     if (l != BS) err( (l<0) ? "read error" : "runt record");
  882.     c = &b[CD];            /* map star code to digits */
  883.     cd = (*c >= '0') && (*c <= '9');
  884.     if (!cd && !en) err("!you meant to encode!");
  885.     if ( cd &&  en) err("!you meant to decode!");
  886.     if (en)
  887.     {
  888.     if (*c == 'S') *c = '0'; else if (*c == 'D') *c = '1'; else *c = '2';
  889.     }
  890.     return(1);
  891.     }
  892.     
  893. wline(b)
  894.     char *b;
  895.     {
  896.     char t, *c = &b[CD];
  897.     t = *c;
  898.     if (!en)
  899.     {
  900.     if (*c == '0') *c = 'S'; else if (*c == '1') *c = 'D'; else *c = 'V';
  901.     }
  902.     write(STDOUT, b, BS);
  903.     *c = t;
  904.     }
  905.  
  906. err(s)
  907.     char *s;
  908.     {
  909.     fprintf(stderr, "stardust error (line %d) -- %s\n", ln, s);
  910.     exit(1);
  911.     }
  912. @//E*O*F stardust.c//
  913. chmod u=rw,g=r,o=r stardust.c
  914.  
  915. echo x - starsplit.c
  916. sed 's/^@//' > "starsplit.c" <<'@//E*O*F starsplit.c//'
  917. /*
  918.  * starsplit.c -- spatially scatter Starchart data into output files.
  919.  *
  920.  * copyright (c) 1988 by Alan Wm Paeth. All rights reserved.
  921.  * 
  922.  * This program operates on StarChart style datasets to "multiplex" data into
  923.  * a number of output files. Code changes and multiple data runs will be
  924.  * required on Unix systems which do not support 48 simultaneous files open
  925.  * for output. The split points in the arrays rabreak and debreak are the
  926.  * canonical splits for the reduced SAO distribution and should not be changed. 
  927.  * When changed for non/custom SAO applications, read on.
  928.  * 
  929.  * The compile time arrays rabreak and debreak define N+1 and M+1 boundaries
  930.  * which enclose the NxM area grid for output, written to files with names
  931.  * formed from the "HEAD" constant and the smaller ra/de boundaries. Data not
  932.  * fitting into any cell (as when ra or de don't span 0..24 or -90..90) are
  933.  * written to stderr.
  934.  *
  935.  * NOTE: a "0" should appear in "debreak" to represent the celestial equator,
  936.  * to deal with a code contrivance which assures that negative decl values
  937.  * round in the right direction (the zero assures symmetry in the split).
  938.  * This code exists to deal with the imprecision in decl (minutes are not
  939.  * used to in splitting) which may move a boundary by 1 degree less epsilon.
  940.  * Fortunately, the code always writes the input record to exactly one output
  941.  * file, so that no data is lost
  942.  */
  943.  
  944. int rabreak[] = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24 };
  945. int debreak[] = { -90, -30, 0, 30, 90 };
  946.  
  947. #include <stdio.h>
  948. #include <strings.h>    /* for strlen, can probably be omitted */
  949.  
  950. #define HEAD "SAO"    /* beginning of file name */
  951.  
  952. #define ARLEN(a) (sizeof(a)/sizeof(*a))
  953. #define RA (ARLEN(rabreak)-1)
  954. #define DE (ARLEN(debreak)-1)
  955. #define FILES (RA*DE)
  956.  
  957. #define RAPOS 0
  958. #define DEPOS 7
  959. #define DESGN 6
  960.  
  961. main()
  962.     {
  963.     FILE *f[FILES];
  964.     char buf[200], n[20];
  965.     int r, d, i, ra, de, deneg;
  966.     int monot, zerof, badra, cruft;
  967.     monot = zerof = badra = 0;
  968.     for (r = 0; r<RA; r++)
  969.     {
  970.     monot |= (rabreak[r] >= rabreak[r+1]);
  971.     badra |= (ra < 0);
  972.     for (d=0; d<DE; d++)
  973.         {
  974.         zerof |= (debreak[d] == 0);
  975.         monot |= (debreak[d] >= debreak[d+1]);
  976.         sprintf(n, "%s%02d%+03d", HEAD, rabreak[r], debreak[d]);
  977.         f[DE*r+d] = fopen(n, "w");
  978.         }
  979.     }
  980.     if (monot || !zerof || badra)
  981.     {
  982.     if (badra) fprintf(stderr, "negative ra value found\n");
  983.     if (monot) fprintf(stderr, "coded ra/de tables non-monotonic\n");
  984.     if (zerof) fprintf(stderr, "no zero (celstial equ.) in decl table\n");
  985.     exit(1);
  986.     }
  987.     while (1)
  988.     {
  989.     fgets(buf, sizeof(buf), stdin);
  990.         if (feof(stdin)) break;
  991.     ra = (buf[RAPOS]-'0')*10 + buf[RAPOS+1]-'0';
  992.     de = (buf[DEPOS]-'0')*10 + buf[DEPOS+1]-'0';
  993.     deneg =(buf[DESGN] != '+');    /* note: -0 (+eps) decl. case */
  994.     if (deneg) de = -de;
  995.     for (r=0; r<RA; r++)
  996.         {
  997.         if ((rabreak[r] <= ra) && (ra < rabreak[r+1])) break;
  998.         }
  999.     cruft = (ra >= rabreak[RA+1]);
  1000.     for (d=0; d<DE; d++)
  1001.         {
  1002.         if ((!deneg) && (debreak[d] <= de) && (de <  debreak[d+1])) break;
  1003.         if (( deneg) && (debreak[d] <  de) && (de <= debreak[d+1])) break;
  1004.         }
  1005.     cruft |= (de >= debreak[DE+1]);
  1006.     i = DE*r + d;
  1007.     if ((i<0) || (i > FILES))
  1008.         {
  1009.         fprintf(stderr, "bad file index. bogus input line?:\n%s\n", buf);
  1010.         exit(1);
  1011.         }
  1012.     fwrite(buf, 1, strlen(buf), cruft ? f[i] : stderr);
  1013.     }
  1014.     for (i=0; i<FILES; i++) fclose(f[i]);
  1015.     exit(0);
  1016.     }
  1017. @//E*O*F starsplit.c//
  1018. chmod u=rw,g=r,o=r starsplit.c
  1019.  
  1020. echo Inspecting for damage in transit...
  1021. temp=/tmp/shar$$; dtemp=/tmp/.shar$$
  1022. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  1023. cat > $temp <<\!!!
  1024.      254    2084   13675 NOTES-SAO
  1025.       18     143    1033 README
  1026.       16      64     378 build
  1027.        4      16     106 compile
  1028.       13      51     311 decode
  1029.       54     114     958 decodeall
  1030.        8      46     252 encode
  1031.       54     114     956 encodeall
  1032.        2      20     174 makeshar
  1033.      278    1020    6104 saoconv.c
  1034.       18     146     887 saoextract
  1035.       19      78     507 stardouble
  1036.       97     359    1994 stardust.c
  1037.      100     550    3384 starsplit.c
  1038.      935    4805   30719 total
  1039. !!!
  1040. wc  NOTES-SAO README build compile decode decodeall encode encodeall makeshar saoconv.c saoextract stardouble stardust.c starsplit.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  1041. if [ -s $dtemp ]
  1042. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  1043. else echo "No problems found."
  1044. fi
  1045. exit 0
  1046.  
  1047.