11 NNGC=7840, /* number of NGC numbers [1..NNGC] */
12 NIC = 5386, /* number of IC numbers */
13 NNGCrec=NNGC+NIC, /* number of records in the NGC catalog (including IC's, starting at NNGC */
14 NMrec=122, /* number of M records */
15 NM=110, /* number of M numbers */
16 NAbell=2712, /* number of records in the Abell catalog */
17 NName=1000, /* number of prose names; estimated maximum (read from editable text file) */
18 NBayer=1517, /* number of bayer entries */
19 NSAO=258998, /* number of SAO stars */
20 MAXcon=1932, /* maximum number of patches in a constellation */
21 Ncon=88, /* number of constellations */
22 Npatch=92053, /* highest patch number */
25 char ngctype[NNGCrec];
26 Mindexrec mindex[NMrec];
28 Bayerec bayer[NBayer];
30 ushort conindex[Ncon+1];
31 long patchaddr[Npatch+1];
57 main(int argc, char *argv[])
61 Binit(&bin, 0, OREAD);
62 Binit(&bout, 1, OWRITE);
66 while(line = Brdline(&bin, '\n')){
67 line[Blinelen(&bin)-1] = 0;
72 closedisplay(display);
73 /* automatic refresh of rio window is triggered by mouse */
74 close(open("/dev/mouse", OREAD));
92 rec = realloc(rec, nreca*sizeof(Record));
94 fprint(2, "scat: realloc fails\n");
106 orec = realloc(orec, nreca*sizeof(Record));
108 fprint(2, "scat: realloc fails\n");
112 memmove(orec, rec, nrec*sizeof(Record));
122 sprint(buf, "%s/%s.scat", dir, s);
125 fprint(2, "scat: can't open %s\n", buf);
133 Eread(int f, char *name, void *addr, long n)
135 if(read(f, addr, n) != n){ /* BUG! */
136 fprint(2, "scat: read error on %s\n", name);
144 while(*s!=0 && (*s==' ' || *s=='\t'))
150 skipstr(char *s, char *t)
157 /* produce little-endian long at address l */
164 return (long)p[0]|((long)p[1]<<8)|((long)p[2]<<16)|((long)p[3]<<24);
167 /* produce little-endian long at address l */
174 return p[0]|(p[1]<<8);
185 namedb = eopen("name");
186 Binit(&b, namedb, OREAD);
187 for(i=0; i<NName; i++){
188 l = Brdline(&b, '\n');
194 Bprint(&bout, "warning: name.scat bad format; line %d\n", i+1);
198 strcpy(name[i].name, l);
199 if(strncmp(p, "ngc", 3) == 0)
200 name[i].ngc = atoi(p+3);
201 else if(strncmp(p, "ic", 2) == 0)
202 name[i].ngc = atoi(p+2)+NNGC;
203 else if(strncmp(p, "sao", 3) == 0)
204 name[i].sao = atoi(p+3);
205 else if(strncmp(p, "abell", 5) == 0)
206 name[i].abell = atoi(p+5);
211 Bprint(&bout, "warning: too many names in name.scat (max %d); extra ignored\n", NName);
214 bayerdb = eopen("bayer");
215 Eread(bayerdb, "bayer", bayer, sizeof bayer);
217 for(i=0; i<NBayer; i++)
218 bayer[i].sao = Long(&bayer[i].sao);
227 saodb = eopen("sao");
236 ngcdb = eopen("ngc2000");
237 ngctypedb = eopen("ngc2000type");
238 Eread(ngctypedb, "ngctype", ngctype, sizeof ngctype);
246 /* nothing extra to do with abell: it's directly indexed by number */
248 abelldb = eopen("abell");
259 patchdb = eopen("patch");
260 sprint(buf, "%s/patchindex.scat", dir);
261 b = Bopen(buf, OREAD);
263 fprint(2, "can't open %s\n", buf);
266 for(m=0,l=0; l<=Npatch; l++)
267 patchaddr[l] = m += Bgetc(b)*4;
278 mindexdb = eopen("mindex");
279 Eread(mindexdb, "mindex", mindex, sizeof mindex);
281 for(i=0; i<NMrec; i++)
282 mindex[i].ngc = Short(&mindex[i].ngc);
292 condb = eopen("con");
293 conindexdb = eopen("conindex");
294 Eread(conindexdb, "conindex", conindex, sizeof conindex);
296 for(i=0; i<Ncon+1; i++)
297 conindex[i] = Short((short*)&conindex[i]);
305 if('A'<=*s && *s<='Z')
316 j = (index-1)*sizeof(NGCrec);
321 /* special case: NGC data may not be available */
322 if(read(ngcdb, &cur->ngc, sizeof(NGCrec)) != sizeof(NGCrec)){
324 fprint(2, "scat: NGC database not available\n");
335 cur->ngc.ngc = Short(&cur->ngc.ngc);
336 cur->ngc.ra = Long(&cur->ngc.ra);
337 cur->ngc.dec = Long(&cur->ngc.dec);
338 cur->ngc.diam = Long(&cur->ngc.diam);
339 cur->ngc.mag = Short(&cur->ngc.mag);
344 loadabell(long index)
353 seek(abelldb, j*sizeof(Abellrec), 0);
354 Eread(abelldb, "abell", &cur->abell, sizeof(Abellrec));
355 cur->abell.abell = Short(&cur->abell.abell);
356 if(cur->abell.abell != index){
357 fprint(2, "bad format in abell catalog\n");
360 cur->abell.ra = Long(&cur->abell.ra);
361 cur->abell.dec = Long(&cur->abell.dec);
362 cur->abell.glat = Long(&cur->abell.glat);
363 cur->abell.glong = Long(&cur->abell.glong);
364 cur->abell.rad = Long(&cur->abell.rad);
365 cur->abell.mag10 = Short(&cur->abell.mag10);
366 cur->abell.pop = Short(&cur->abell.pop);
367 cur->abell.dist = Short(&cur->abell.dist);
374 if(index<=0 || index>NSAO)
380 seek(saodb, (index-1)*sizeof(SAOrec), 0);
381 Eread(saodb, "sao", &cur->sao, sizeof(SAOrec));
382 cur->sao.ra = Long(&cur->sao.ra);
383 cur->sao.dec = Long(&cur->sao.dec);
384 cur->sao.dra = Long(&cur->sao.dra);
385 cur->sao.ddec = Long(&cur->sao.ddec);
386 cur->sao.mag = Short(&cur->sao.mag);
387 cur->sao.mpg = Short(&cur->sao.mpg);
388 cur->sao.hd = Long(&cur->sao.hd);
393 loadplanet(int index, Record *r)
395 if(index<0 || index>NPlanet || planet[index].name[0]=='\0')
400 /* check whether to take new or existing record */
402 memmove(&cur->planet, &planet[index], sizeof(Planetrec));
404 memmove(&cur->planet, &r->planet, sizeof(Planetrec));
409 loadpatch(long index)
414 if(index<=0 || index>Npatch)
419 seek(patchdb, patchaddr[index-1], 0);
420 cur->patch.nkey = (patchaddr[index]-patchaddr[index-1])/4;
421 Eread(patchdb, "patch", cur->patch.key, cur->patch.nkey*4);
422 for(i=0; i<cur->patch.nkey; i++)
423 cur->patch.key[i] = Long(&cur->patch.key[i]);
433 for(i=0; i<NNGCrec; i++)
434 if(t == (ngctype[i])){
453 for(i=0,or=orec; i<norec; i++,or++){
456 fprint(2, "bad type %d in flatten\n", or->type);
467 memmove(cur, or, sizeof(Record));
471 if(loadngc(or->index))
481 if(loadngc(or->index))
486 loadabell(or->index);
491 loadpatch(or->index);
496 for(j=1; j<or->patch.nkey; j++){
497 key = or->patch.key[j];
498 if((key&0x3F) == SAO)
499 loadsao((key>>8)&0xFFFFFF);
500 else if((key&0x3F) == Abell)
501 loadabell((key>>8)&0xFFFFFF);
503 loadngc((key>>16)&0xFFFF);
517 for(i=0; i<NMrec; i++)
518 if(mindex[i].ngc == index)
524 alpha(char *s, char *t)
529 if(strncmp(s, t, n)==0 && (s[n]<'a' || 'z'<s[n]))
536 text(char *s, char *t)
541 if(strncmp(s, t, n)==0 && (s[n]==0 || s[n]==' ' || s[n]=='\t'))
548 cull(char *s, int keep, int dobbox)
550 int i, j, nobj, keepthis;
553 int dogrtr, doless, dom, dosao, dongc, doabell;
557 memset(obj, 0, sizeof(obj));
571 mgrtr = 10 * strtod(s+1, &t);
572 if(mgrtr==0 && t==s+1){
573 fprint(2, "bad magnitude\n");
581 mless = 10 * strtod(s+1, &t);
582 if(mless==0 && t==s+1){
583 fprint(2, "bad magnitude\n");
589 if(t = text(s, "m")){
594 if(t = text(s, "sao")){
599 if(t = text(s, "ngc")){
604 if(t = text(s, "abell")){
609 for(i=0; names[i].name; i++)
610 if(t = alpha(s, names[i].name)){
612 fprint(2, "too many object types\n");
615 obj[nobj++] = names[i].type;
623 fprint(2, "syntax error in object list\n");
639 for(i=0,or=orec; i<norec; i++,or++){
641 if(dobbox && inbbox(or->ngc.ra, or->ngc.dec))
643 if(doless && or->ngc.mag <= mless)
645 if(dogrtr && or->ngc.mag >= mgrtr)
647 if(dom && (or->type==NGC && ism(or->ngc.ngc)))
649 if(dongc && or->type==NGC)
651 if(doabell && or->type==Abell)
653 if(dosao && or->type==SAO)
655 for(j=0; j<nobj; j++)
656 if(or->type==NGC && or->ngc.type==obj[j])
660 memmove(cur, or, sizeof(Record));
667 compar(void *va, void *vb)
671 if(a->type == b->type)
672 return a->index - b->index;
673 return a->type - b->type;
684 qsort(rec, nrec, sizeof(Record), compar);
687 for(i=1; i<nrec; i++,r++){
688 /* may have multiple instances of a planet in the scene */
689 if(r->type==s->type && r->index==s->index && r->type!=Planet)
691 memmove(++s, r, sizeof(Record));
707 for(i=1; i<=24; i++){
708 n = strlen(greek[i]);
709 if(strncmp(s, greek[i], n)==0 && (s[n]==' ' || s[n]=='\t')){
711 t += runetochar(t, &greeklet[i]);
715 n = chartorune(&r, s);
733 n = chartorune(&r, s);
734 for(i=1; i<=24; i++){
735 if(r == greeklet[i]){
737 t += strlen(greek[i]);
760 long dec, ra, ndec, nra;
767 for(i=0,or=orec; i<norec; i++,or++){
768 if(or->type == Planet) /* must keep it here */
769 loadplanet(or->index, or);
770 dec = or->ngc.dec/MILLIARCSEC;
771 ra = or->ngc.ra/MILLIARCSEC;
772 rdeg = deg/cos((dec*PI)/180);
773 for(y=-deg; y<=+deg; y++){
775 if(ndec/2>=90 || ndec/2<=-90)
777 /* fp errors hurt here, so we round 1' to the pole */
779 ndec = ndec*500*60*60 + 60000;
781 ndec = ndec*500*60*60 - 60000;
782 for(x=-rdeg; x<=+rdeg; x++){
788 /* fp errors hurt here, so we round up 1' */
789 nra = nra/2*MILLIARCSEC + 60000;
790 loadpatch(patcha(angle(nra), angle(ndec)));
800 * New version attempts to match the boundaries of the plot better.
812 circle = 360*MILLIARCSEC;
819 factor = cos(angle((decmax+decmin)/2));
822 factor = floor(1/factor);
824 bbox(factor*deg, deg, 1);
825 Bprint(&bout, "%s to ", hms(angle(ramin)));
826 Bprint(&bout, "%s\n", hms(angle(ramax)));
827 Bprint(&bout, "%s to ", dms(angle(decmin)));
828 Bprint(&bout, "%s\n", dms(angle(decmax)));
831 for(i=0,or=orec; i<norec; i++,or++)
832 if(or->type == Planet) /* must keep it here */
833 loadplanet(or->index, or);
837 for(x=min; x<=ramax; x+=250*60*60){
841 for(y=decmin; y<=decmax; y+=250*60*60)
842 if(-circle/4 < y && y < circle/4)
843 loadpatch(patcha(angle(xx), angle(y)));
855 int na, rah, ram, d1, d2;
858 long ramin, ramax, decmin, decmax; /* all in degrees */
861 Angle racenter, deccenter, rasize, decsize, a[4];
870 if(('0'<=*flags && *flags<='9') || *flags=='+' || *flags=='-'){
873 a[na++] = getra(flags);
874 while(*flags && *flags!=' ')
880 Bprint(&bout, "syntax error in plate\n");
905 if(rasize<0.0 || decsize<0.0){
906 Bprint(&bout, "negative sizes\n");
912 /* convert to milliarcsec */
916 Bprint(&bout, "empty\n");
922 decmax = -0x7FFFFFFF;
923 for(r=rec,i=0; i<nrec; i++,r++){
924 if(r->type == Patch){
925 radec(r->index, &rah, &ram, &dec);
927 r0 = c/cos(RAD(dec));
936 }else if(r->type==SAO || r->type==NGC || r->type==Abell){
939 d1 = 0, d2 = 0, r0 = 0;
940 }else if(r->type==NGCN){
943 }else if(r->type==NamedSAO){
946 }else if(r->type==NamedNGC){
949 }else if(r->type==NamedAbell){
968 if(!folded && ramax-ramin>270*c){
972 racenter = angle(ramin+(ramax-ramin)/2);
973 deccenter = angle(decmin+(decmax-decmin)/2);
974 if(rasize<0 || decsize<0){
975 rasize = angle(ramax-ramin)*cos(deccenter);
976 decsize = angle(decmax-decmin);
979 if(DEG(rasize)>1.1 || DEG(decsize)>1.1){
980 Bprint(&bout, "plate too big: %s", ms(rasize));
981 Bprint(&bout, " x %s\n", ms(decsize));
982 Bprint(&bout, "trimming to 30'x30'\n");
986 Bprint(&bout, "%s %s ", hms(racenter), dms(deccenter));
987 Bprint(&bout, "%s", ms(rasize));
988 Bprint(&bout, " x %s\n", ms(decsize));
991 pic = image(racenter, deccenter, rasize, decsize);
994 Bprint(&bout, "plate %s locn %d %d %d %d\n", pic->name, pic->minx, pic->miny, pic->maxx, pic->maxy);
1000 lookup(char *s, int doreset)
1004 char *starts, *inputline=s, *t, *u;
1016 if(t = alpha(s, "flat")){
1018 fprint(2, "flat takes no arguments\n");
1022 fprint(2, "no records\n");
1029 if(t = alpha(s, "print")){
1031 fprint(2, "print takes no arguments\n");
1034 for(i=0,r=rec; i<nrec; i++,r++)
1039 if(t = alpha(s, "add")){
1044 if(t = alpha(s, "sao")){
1045 n = strtoul(t, &u, 10);
1050 fprint(2, "syntax error in sao\n");
1060 if(t = alpha(s, "ngc")){
1061 n = strtoul(t, &u, 10);
1066 fprint(2, "syntax error in ngc\n");
1076 if(t = alpha(s, "ic")){
1077 n = strtoul(t, &u, 10);
1082 fprint(2, "syntax error in ic\n");
1087 if(!loadngc(n+NNGC))
1092 if(t = alpha(s, "abell")){
1093 n = strtoul(t, &u, 10);
1094 if(n<=0 || n>NAbell)
1103 if(t = alpha(s, "m")){
1104 n = strtoul(t, &u, 10);
1108 for(j=n-1; mindex[j].m<n; j++)
1112 while(mindex[j].m == n){
1116 cur->index = mindex[j].ngc;
1123 for(i=1; i<=Ncon; i++)
1124 if(t = alpha(s, constel[i])){
1126 fprint(2, "syntax error in constellation\n");
1130 seek(condb, 4L*conindex[i-1], 0);
1131 j = conindex[i]-conindex[i-1];
1132 Eread(condb, "con", con, 4*j);
1138 cur->index = Long(&con[k]);
1143 if(t = alpha(s, "expand")){
1146 if(*t<'0' && '9'<*t){
1148 fprint(2, "syntax error in expand\n");
1151 n = strtoul(t, &u, 10);
1160 if(t = alpha(s, "plot")){
1162 Bprint(&bout, "empty\n");
1169 if(t = alpha(s, "astro")){
1174 if(t = alpha(s, "plate")){
1179 if(t = alpha(s, "gamma")){
1186 Bprint(&bout, "%.2f\n", gam.gamma);
1190 if(t = alpha(s, "keep")){
1196 if(t = alpha(s, "drop")){
1202 for(i=0; planet[i].name[0]; i++){
1203 if(t = alpha(s, planet[i].name)){
1211 for(i=0; names[i].name; i++){
1212 if(t = alpha(s, names[i].name)){
1214 fprint(2, "syntax error in type\n");
1219 loadtype(names[i].type);
1229 fprint(2, "bad star name\n");
1237 starts = fromgreek(starts);
1238 for(i=0; i<NName; i++)
1239 if(equal(starts, name[i].name)){
1242 rec[j].type = NamedSAO;
1243 rec[j].index = name[i].sao;
1246 rec[j].type = NamedNGC;
1247 rec[j].index = name[i].ngc;
1250 rec[j].type = NamedAbell;
1251 rec[j].index = name[i].abell;
1253 strcpy(rec[j].named.name, name[i].name);
1256 if(parsename(starts))
1257 for(i=0; i<NBayer; i++)
1258 if(bayer[i].name[0]==parsed[0] &&
1259 (bayer[i].name[1]==parsed[1] || parsed[1]==0) &&
1260 bayer[i].name[2]==parsed[2]){
1262 rec[j].type = NamedSAO;
1263 rec[j].index = bayer[i].sao;
1264 strncpy(rec[j].named.name, starts, sizeof(rec[j].named.name));
1273 case '0': case '1': case '2': case '3': case '4':
1274 case '5': case '6': case '7': case '8': case '9':
1278 fprint(2, "bad coordinates %s\n", inputline);
1282 while(*s && *s!=' ' && *s!='\t')
1287 deg = strtol(s, &t, 10);
1290 /* degree sign etc. is optional */
1291 if((uchar)*t == L'°')
1292 deg = DEG(getra(s));
1295 if(abs(deg)>=90 || rah>=24)
1297 if(!loadpatch(patch(rah, ram, deg)))
1302 fprint(2, "unknown command %s\n", inputline);
1308 Bprint(&bout, "empty\n");
1310 for(i=0; i<nrec; i++)
1313 Bprint(&bout, "%ld items\n", nrec);
1317 fprint(2, "%s not found\n", inputline);
1343 if(d<Galaxy || d>PlateDefect)
1344 return "can't happen";
1348 short descindex[NINDEX];
1351 printnames(Record *r)
1356 for(i=0; i<NName; i++){ /* stupid linear search! */
1358 if(r->type==SAO && r->index==name[i].sao)
1360 if(r->type==NGC && r->ngc.ngc==name[i].ngc)
1362 if(r->type==Abell && r->abell.abell==name[i].abell)
1366 Bprint(&bout, "\t");
1367 Bprint(&bout, " \"%s\"", togreek(name[i].name));
1371 Bprint(&bout, "\n");
1375 equal(char *s1, char *s2)
1388 if('A'<=*s2 && *s2<='Z')
1403 blank = strchr(s, ' ');
1404 if(blank==0 || strchr(blank+1, ' ') || strlen(blank+1)!=3)
1407 parsed[0] = parsed[1] = parsed[2] = 0;
1408 if('0'<=s[0] && s[0]<='9'){
1414 for(i=1; i<=24; i++)
1415 if(strncmp(greek[i], s, strlen(greek[i]))==0){
1421 if('0'<=s[strlen(greek[i])] && s[strlen(greek[i])]<='9')
1422 parsed[1]=s[strlen(greek[i])]-'0';
1424 for(i=1; i<=88; i++)
1425 if(strcmp(constel[i], blank)==0){
1482 static char buf[128];
1492 if(s->name[0] >= 100){
1493 i = snprint(buf, sizeof buf, "%C", greeklet[s->name[0]-100]);
1495 i += snprint(buf+i, sizeof buf-i, "%d", s->name[1]);
1497 i = snprint(buf, sizeof buf, " %d", s->name[0]);
1498 snprint(buf+i, sizeof buf-i, " %s", constel[s->name[2]]);
1502 if(n->type >= Uncertain)
1505 snprint(buf, sizeof buf, "NGC%4d ", n->ngc);
1507 snprint(buf, sizeof buf, "IC%4d ", n->ngc-NNGC);
1511 snprint(buf, sizeof buf, "Abell%4d", a->abell);
1524 int i, rah, ram, dec, nn;
1527 if(r) switch(r->type){
1529 fprint(2, "can't prrec type %d\n", r->type);
1534 Bprint(&bout, "%s", p->name);
1535 Bprint(&bout, "\t%s %s",
1537 dms(angle(p->dec)));
1538 Bprint(&bout, " %3.2f° %3.2f°",
1539 p->az/(double)MILLIARCSEC, p->alt/(double)MILLIARCSEC);
1540 Bprint(&bout, " %s",
1541 ms(angle(p->semidiam)));
1543 Bprint(&bout, " %g", p->phase);
1544 Bprint(&bout, "\n");
1550 Bprint(&bout, "NGC%4d ", n->ngc);
1552 Bprint(&bout, "IC%4d ", n->ngc-NNGC);
1553 Bprint(&bout, "%s ", ngcstring(n->type));
1554 if(n->mag == UNKNOWNMAG)
1555 Bprint(&bout, "----");
1557 Bprint(&bout, "%.1f%c", n->mag/10.0, n->magtype);
1558 Bprint(&bout, "\t%s %s\t%c%.1f'\n",
1562 DEG(angle(n->diam))*60.);
1563 prdesc(n->desc, desctab, descindex);
1569 Bprint(&bout, "Abell%4d %.1f %.2f° %dMpc", a->abell, a->mag10/10.0,
1570 DEG(angle(a->rad)), a->dist);
1571 Bprint(&bout, "\t%s %s\t%.2f %.2f\n",
1574 DEG(angle(a->glat)),
1575 DEG(angle(a->glong)));
1576 Bprint(&bout, "\tdist grp: %s rich grp: %s %d galaxies/°²\n",
1577 dist_grp(a->distgrp),
1578 rich_grp(a->richgrp),
1585 Bprint(&bout, "SAO%6ld ", r->index);
1586 if(s->mag==UNKNOWNMAG)
1587 Bprint(&bout, "---");
1589 Bprint(&bout, "%.1f", s->mag/10.0);
1590 if(s->mpg==UNKNOWNMAG)
1591 Bprint(&bout, ",---");
1593 Bprint(&bout, ",%.1f", s->mpg/10.0);
1594 Bprint(&bout, " %s %s %.4fs %.3f\"",
1597 DEG(angle(s->dra))*(4*60),
1598 DEG(angle(s->ddec))*(60*60));
1599 Bprint(&bout, " %.3s %c %.2s %ld %d",
1600 s->spec, s->code, s->compid, s->hd, s->hdcode);
1602 Bprint(&bout, " \"%s\"", nameof(r));
1603 Bprint(&bout, "\n");
1608 radec(r->index, &rah, &ram, &dec);
1609 Bprint(&bout, "%dh%dm %d°", rah, ram, dec);
1610 key = r->patch.key[0];
1611 Bprint(&bout, " %s", constel[key&0xFF]);
1612 if((key>>=8) & 0xFF)
1613 Bprint(&bout, " %s", constel[key&0xFF]);
1614 if((key>>=8) & 0xFF)
1615 Bprint(&bout, " %s", constel[key&0xFF]);
1616 if((key>>=8) & 0xFF)
1617 Bprint(&bout, " %s", constel[key&0xFF]);
1618 for(i=1; i<r->patch.nkey; i++){
1619 key = r->patch.key[i];
1622 Bprint(&bout, " SAO%ld", (key>>8)&0xFFFFFF);
1625 Bprint(&bout, " Abell%ld", (key>>8)&0xFFFFFF);
1628 nn = (key>>16)&0xFFFF;
1630 Bprint(&bout, " IC%d", nn-NNGC);
1632 Bprint(&bout, " NGC%d", nn);
1633 Bprint(&bout, "(%s)", ngcstring(key&0x3F));
1637 Bprint(&bout, "\n");
1641 if(r->index <= NNGC)
1642 Bprint(&bout, "NGC%ld\n", r->index);
1644 Bprint(&bout, "IC%ld\n", r->index-NNGC);
1648 Bprint(&bout, "SAO%ld \"%s\"\n", r->index, togreek(r->named.name));
1652 if(r->index <= NNGC)
1653 Bprint(&bout, "NGC%ld \"%s\"\n", r->index, togreek(r->named.name));
1655 Bprint(&bout, "IC%ld \"%s\"\n", r->index-NNGC, togreek(r->named.name));
1659 Bprint(&bout, "Abell%ld \"%s\"\n", r->index, togreek(r->named.name));
1663 radec(r->index, &rah, &ram, &dec);
1664 Bprint(&bout, "%dh%dm %d\n", rah, ram, dec);