File indexing completed on 2024-12-22 04:17:05

0001 /***************************************************************************
0002                   healpix_tools.cpp  -  tools for healpix datasource
0003                              -------------------
0004     begin                : Wed June 01 2005
0005     copyright            : (C) 2005 Ted Kisner
0006     email                : tskisner.public@gmail.com
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "healpix_tools.h"
0019 
0020 /* FITS keys */
0021 
0022 healpix_keys *healpix_keys_alloc()
0023 {
0024   healpix_keys *keys;
0025   keys = (healpix_keys *) calloc(1, sizeof(healpix_keys));
0026   keys->nskeys = 0;
0027   keys->nikeys = 0;
0028   keys->nfkeys = 0;
0029   keys->skeynames = NULL;
0030   keys->skeyvals = NULL;
0031   keys->skeycoms = NULL;
0032   keys->ikeynames = NULL;
0033   keys->ikeyvals = NULL;
0034   keys->ikeycoms = NULL;
0035   keys->fkeynames = NULL;
0036   keys->fkeyvals = NULL;
0037   keys->fkeycoms = NULL;
0038   return keys;
0039 }
0040 
0041 int healpix_keys_free(healpix_keys * keys)
0042 {
0043   size_t i;
0044   if (keys) {
0045     for (i = 0; i < (keys->nskeys); i++) {
0046       free(keys->skeynames[i]);
0047       free(keys->skeyvals[i]);
0048       free(keys->skeycoms[i]);
0049     }
0050     if (keys->nskeys != 0) {
0051       free(keys->skeynames);
0052       free(keys->skeyvals);
0053       free(keys->skeycoms);
0054     }
0055     for (i = 0; i < (keys->nikeys); i++) {
0056       free(keys->ikeynames[i]);
0057       free(keys->ikeycoms[i]);
0058     }
0059     if (keys->nikeys != 0) {
0060       free(keys->ikeynames);
0061       free(keys->ikeyvals);
0062       free(keys->ikeycoms);
0063     }
0064     for (i = 0; i < (keys->nfkeys); i++) {
0065       free(keys->fkeynames[i]);
0066       free(keys->fkeycoms[i]);
0067     }
0068     if (keys->nfkeys != 0) {
0069       free(keys->fkeynames);
0070       free(keys->fkeyvals);
0071       free(keys->fkeycoms);
0072     }
0073     free(keys);
0074   }
0075   return 0;
0076 }
0077 
0078 int healpix_keys_clear(healpix_keys * keys)
0079 {
0080   size_t i;
0081   if (keys) {
0082     for (i = 0; i < (keys->nskeys); i++) {
0083       free(keys->skeynames[i]);
0084       free(keys->skeyvals[i]);
0085       free(keys->skeycoms[i]);
0086     }
0087     if (keys->nskeys != 0) {
0088       free(keys->skeynames);
0089       free(keys->skeyvals);
0090       free(keys->skeycoms);
0091     }
0092     for (i = 0; i < (keys->nikeys); i++) {
0093       free(keys->ikeynames[i]);
0094       free(keys->ikeycoms[i]);
0095     }
0096     if (keys->nikeys != 0) {
0097       free(keys->ikeynames);
0098       free(keys->ikeyvals);
0099       free(keys->ikeycoms);
0100     }
0101     for (i = 0; i < (keys->nfkeys); i++) {
0102       free(keys->fkeynames[i]);
0103       free(keys->fkeycoms[i]);
0104     }
0105     if (keys->nfkeys != 0) {
0106       free(keys->fkeynames);
0107       free(keys->fkeyvals);
0108       free(keys->fkeycoms);
0109     }
0110     keys->nskeys = 0;
0111     keys->nikeys = 0;
0112     keys->nfkeys = 0;
0113     keys->skeynames = NULL;
0114     keys->skeyvals = NULL;
0115     keys->skeycoms = NULL;
0116     keys->ikeynames = NULL;
0117     keys->ikeyvals = NULL;
0118     keys->ikeycoms = NULL;
0119     keys->fkeynames = NULL;
0120     keys->fkeyvals = NULL;
0121     keys->fkeycoms = NULL;
0122   }
0123   return 0;
0124 }
0125 
0126 /* add keys */
0127 
0128 int healpix_keys_sadd(healpix_keys * keys, char *keyname, char *keyval, char *keycom)
0129 {
0130   if (keys) {
0131     
0132     (keys->skeynames) =
0133         (char **)realloc(keys->skeynames,
0134     ((keys->nskeys) + 1) * sizeof(char *));
0135     (keys->skeynames[keys->nskeys]) =
0136         (char *)calloc(HEALPIX_STRNL, sizeof(char));
0137     
0138     (keys->skeyvals) = (char **)realloc(keys->skeyvals, ((keys->nskeys) + 1) * sizeof(char *));
0139     (keys->skeyvals[keys->nskeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char));
0140     
0141     (keys->skeycoms) = (char **)realloc(keys->skeycoms, ((keys->nskeys) + 1) * sizeof(char *));
0142     (keys->skeycoms[keys->nskeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char));
0143     
0144     strncpy(keys->skeynames[keys->nskeys], keyname, HEALPIX_STRNL);
0145     strncpy(keys->skeyvals[keys->nskeys], keyval, HEALPIX_STRNL);
0146     strncpy(keys->skeycoms[keys->nskeys], keycom, HEALPIX_STRNL);
0147     (keys->nskeys)++;
0148   }
0149   return 0;
0150 }
0151 
0152 int healpix_keys_iadd(healpix_keys * keys, char *keyname, int keyval, char *keycom)
0153 {
0154   if (keys) {
0155     (keys->ikeynames) =
0156         (char **)realloc(keys->ikeynames,
0157     ((keys->nikeys) + 1) * sizeof(char *));
0158     (keys->ikeynames[keys->nikeys]) =
0159         (char *)calloc(HEALPIX_STRNL, sizeof(char));
0160     
0161     (keys->ikeyvals) =
0162         (int *)realloc(keys->ikeyvals, ((keys->nikeys) + 1) * sizeof(int));
0163     
0164     (keys->ikeycoms) =
0165         (char **)realloc(keys->ikeycoms, ((keys->nikeys) + 1) * sizeof(char *));
0166     (keys->ikeycoms[keys->nikeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char));
0167     
0168     strncpy(keys->ikeynames[keys->nikeys], keyname, HEALPIX_STRNL);
0169     keys->ikeyvals[keys->nikeys] = keyval;
0170     strncpy(keys->ikeycoms[keys->nikeys], keycom, HEALPIX_STRNL);
0171     (keys->nikeys)++;
0172   }
0173   return 0;
0174 }
0175 
0176 int healpix_keys_fadd(healpix_keys * keys, char *keyname, float keyval, char *keycom)
0177 {
0178   if (keys) {
0179     (keys->fkeynames) =
0180         (char **)realloc(keys->fkeynames,
0181     ((keys->nfkeys) + 1) * sizeof(char *));
0182     (keys->fkeynames[keys->nfkeys]) =
0183         (char *)calloc(HEALPIX_STRNL, sizeof(char));
0184     
0185     (keys->fkeyvals) =
0186         (float *)realloc(keys->fkeyvals, ((keys->nfkeys) + 1) * sizeof(float));
0187     
0188     (keys->fkeycoms) =
0189         (char **)realloc(keys->fkeycoms, ((keys->nfkeys) + 1) * sizeof(char *));
0190     (keys->fkeycoms[keys->nfkeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char));
0191     
0192     strncpy(keys->fkeynames[keys->nfkeys], keyname, HEALPIX_STRNL);
0193     keys->fkeyvals[keys->nfkeys] = keyval;
0194     strncpy(keys->fkeycoms[keys->nfkeys], keycom, HEALPIX_STRNL);
0195     (keys->nfkeys)++;
0196   }
0197   return 0;  
0198 }
0199 
0200 /* read keys */
0201 
0202 int healpix_keys_read(healpix_keys * keys, fitsfile * fp, int *ret)
0203 {
0204   int nread = 0;
0205   int rec = 0;
0206   size_t nexc = 21;
0207   char **exclist;
0208   char **inclist;
0209   char card[HEALPIX_STRNL];
0210   char keyval[HEALPIX_STRNL];
0211   char keycom[HEALPIX_STRNL];
0212   char keytype;
0213   char keyname[HEALPIX_STRNL];
0214   int keylen;
0215 
0216   exclist = healpix_strarr_alloc(nexc);
0217   inclist = healpix_strarr_alloc(1);
0218 
0219   /*exclude required keywords */
0220   strcpy(exclist[0], "XTENSION");
0221   strcpy(exclist[1], "BITPIX");
0222   strcpy(exclist[2], "NAXIS*");
0223   strcpy(exclist[3], "PCOUNT");
0224   strcpy(exclist[4], "GCOUNT");
0225   strcpy(exclist[5], "TFIELDS");
0226   strcpy(exclist[6], "TTYPE*");
0227   strcpy(exclist[7], "TFORM*");
0228   strcpy(exclist[8], "TUNIT*");
0229   strcpy(exclist[9], "EXTNAME");
0230   strcpy(exclist[10], "PIXTYPE");
0231   strcpy(exclist[11], "ORDERING");
0232   strcpy(exclist[12], "NSIDE");
0233   strcpy(exclist[13], "COORDSYS");
0234   strcpy(exclist[14], "INDXSCHM");
0235   strcpy(exclist[15], "GRAIN");
0236   strcpy(exclist[16], "COMMENT");
0237   strcpy(exclist[17], "TBCOL*");
0238   strcpy(exclist[18], "SIMPLE");
0239   strcpy(exclist[19], "EXTEND");
0240   strcpy(exclist[19], "CREATOR");
0241   strcpy(inclist[0], "*");
0242 
0243   (*ret) = 0;
0244   if (fits_read_record(fp, rec, card, ret)) {
0245     return 0;
0246   }
0247   while (!fits_find_nextkey(fp, inclist, 1, exclist, (int)nexc, card, ret)) {
0248     fits_get_keyname(card, keyname, &keylen, ret);
0249     fits_parse_value(card, keyval, keycom, ret);
0250     fits_get_keytype(keyval, &keytype, ret);
0251     switch (keytype) {
0252       case 'I':
0253         healpix_keys_iadd(keys, keyname, atoi(keyval), keycom);
0254         break;
0255       case 'F':
0256         healpix_keys_fadd(keys, keyname, (float)atof(keyval), keycom);
0257         break;
0258       default:
0259         healpix_keys_sadd(keys, keyname, keyval, keycom);
0260         break;
0261     }
0262     nread++;
0263   }
0264   (*ret = 0);
0265 
0266   healpix_strarr_free(exclist, nexc);
0267   healpix_strarr_free(inclist, 1);
0268 
0269   return nread;
0270 }
0271 
0272 /* FITS file tests */
0273 
0274 int healpix_fits_map_test(char *filename, size_t * nside, int *order, int *coord, int *type, size_t * nmaps)
0275 {
0276   fitsfile *fp;
0277   int ret = 0;
0278   int ttype;
0279   int inside;
0280   long nrows;
0281   long pcount;
0282   int tfields;
0283   int grain;
0284   char pixtype[HEALPIX_STRNL];
0285   char coordstr[HEALPIX_STRNL];
0286   char orderstr[HEALPIX_STRNL];
0287   char indxstr[HEALPIX_STRNL];
0288   char comment[HEALPIX_STRNL];
0289   char extname[HEALPIX_STRNL];
0290   float nullval = HEALPIX_NULL;
0291   int nnull;
0292   float testval;
0293   long keynpix;
0294   long keyfirst;
0295   int ischunk = 0;
0296   int lastcol;
0297 
0298   /* open file */
0299   if (fits_open_file(&fp, filename, READONLY, &ret)) {
0300     return 0;
0301   }
0302 
0303   /* make sure extension is a binary table */
0304   if (fits_movabs_hdu(fp, 2, &ttype, &ret)) {
0305     ret = 0;
0306     fits_close_file(fp, &ret);
0307     return 0;
0308   }
0309   if (ttype != BINARY_TBL) {
0310     ret = 0;
0311     fits_close_file(fp, &ret);
0312     return 0;
0313   }
0314 
0315   /* determine the number of maps */
0316   if (fits_read_btblhdr(fp, HEALPIX_FITS_MAXCOL, &nrows, &tfields, NULL, NULL, NULL, extname, &pcount, &ret)) {
0317     ret = 0;
0318     fits_close_file(fp, &ret);
0319     return 0;
0320   }
0321 
0322   /* make sure this is a HEALPIX file */
0323   char charPixType[] = "PIXTYPE";
0324   if (fits_read_key(fp, TSTRING, charPixType, pixtype, comment, &ret)) {
0325     ret = 0;
0326     fits_close_file(fp, &ret);
0327     return 0;
0328   }
0329   if (strncmp(pixtype, "HEALPIX", HEALPIX_STRNL) != 0) {
0330     ret = 0;
0331     fits_close_file(fp, &ret);
0332     return 0;
0333   }
0334 
0335   /* check required keywords (NSIDE, ORDERING, COORDSYS) */
0336   char charNSide[] = "NSIDE";
0337   char charOrdering[] = "ORDERING";
0338   char charCoordSys[] = "COORDSYS";
0339   if (fits_read_key(fp, TINT, charNSide, &inside, comment, &ret)) {
0340     ret = 0;
0341     fits_close_file(fp, &ret);
0342     return 0;
0343   }
0344   (*nside) = (size_t) inside;
0345   if (healpix_nsidecheck(*nside)) {
0346     ret = 0;
0347     fits_close_file(fp, &ret);
0348     return 0;
0349   }
0350   if (fits_read_key(fp, TSTRING, charOrdering, orderstr, comment, &ret)) {
0351     ret = 0;
0352     fits_close_file(fp, &ret);
0353     return 0;
0354   }
0355   if (strncmp(orderstr, "RING", HEALPIX_STRNL) == 0) {
0356     (*order) = HEALPIX_RING;
0357   } else if (strncmp(orderstr, "NESTED", HEALPIX_STRNL) == 0) {
0358     (*order) = HEALPIX_NEST;
0359   } else {
0360     ret = 0;
0361     fits_close_file(fp, &ret);
0362     return 0;
0363   }
0364   if (fits_read_key(fp, TSTRING, charCoordSys, coordstr, comment, &ret)) {
0365     ret = 0;
0366     (*coord) = HEALPIX_COORD_C;
0367   } else {
0368     if (strncmp(coordstr, "C", HEALPIX_STRNL) == 0) {
0369       (*coord) = HEALPIX_COORD_C;
0370     } else if (strncmp(coordstr, "G", HEALPIX_STRNL) == 0) {
0371       (*coord) = HEALPIX_COORD_G;
0372     } else if (strncmp(coordstr, "E", HEALPIX_STRNL) == 0) {
0373       (*coord) = HEALPIX_COORD_E;
0374     } else {
0375       (*coord) = HEALPIX_COORD_O;
0376     }
0377   }
0378 
0379   /* check for INDXSCHM and GRAIN.  if not found, assume implicit */
0380   char charObject[] = "OBJECT";
0381   char charIndxSchm[] = "INDXSCHM";
0382   char charGrain[] = "GRAIN";
0383   strcpy(indxstr,"");
0384   if (fits_read_key(fp, TSTRING, charObject, indxstr, comment, &ret)) {
0385     ret = 0;
0386     if (fits_read_key(fp, TSTRING, charIndxSchm, indxstr, comment, &ret)) {
0387       ret = 0;
0388       (*type) = HEALPIX_FITS_FULL;
0389     } else {
0390       if (strncmp(indxstr, "EXPLICIT", HEALPIX_STRNL) == 0) {
0391         (*type) = HEALPIX_FITS_CUT;
0392       } else {
0393         (*type) = HEALPIX_FITS_FULL;
0394       }
0395     }
0396     if (fits_read_key(fp, TINT, charGrain, &grain, comment, &ret)) {
0397       ret = 0;
0398       grain = 0;
0399     }
0400     if (((grain == 0) && ((*type) == HEALPIX_FITS_CUT)) ||
0401         ((grain != 0) && ((*type) == HEALPIX_FITS_FULL))) {
0402       ret = 0;
0403       fits_close_file(fp, &ret);
0404       return 0;
0405     }
0406   } else {
0407     if (strncmp(indxstr, "PARTIAL", HEALPIX_STRNL) == 0) {
0408       (*type) = HEALPIX_FITS_CUT;
0409     } else {
0410       if (strncmp(indxstr, "FULLSKY", HEALPIX_STRNL) == 0) {
0411         (*type) = HEALPIX_FITS_FULL;
0412       } else {
0413         if (fits_read_key(fp, TSTRING, charIndxSchm, indxstr, comment, &ret)) {
0414           ret = 0;
0415           (*type) = HEALPIX_FITS_FULL;
0416         } else {
0417           if (strncmp(indxstr, "EXPLICIT", HEALPIX_STRNL) == 0) {
0418             (*type) = HEALPIX_FITS_CUT;
0419           } else {
0420             (*type) = HEALPIX_FITS_FULL;
0421           }
0422         }
0423         if (fits_read_key(fp, TINT, charGrain, &grain, comment, &ret)) {
0424           ret = 0;
0425           grain = 0;
0426         }
0427         if (((grain == 0) && ((*type) == HEALPIX_FITS_CUT)) ||
0428             ((grain != 0) && ((*type) == HEALPIX_FITS_FULL))) {
0429           ret = 0;
0430           fits_close_file(fp, &ret);
0431           return 0;
0432         } 
0433       } 
0434     }
0435   }
0436 
0437   /* check for chunk file and truncation */
0438   char charFirstPix[] = "FIRSTPIX";
0439   char charNPix[] = "NPIX";
0440   char charLastPix[] = "LASTPIX";
0441   if ((*type) == HEALPIX_FITS_FULL) {
0442     (*nmaps) = tfields;
0443     if ((nrows != (long)(12*inside*inside))&&(1024*nrows != (long)(12*inside*inside))) {
0444       /*is this a chunk file?*/
0445       if (fits_read_key(fp, TLONG, charFirstPix, &keyfirst, comment, &ret)) {
0446         /*must at least have FIRSTPIX key*/
0447         ret = 0;
0448         ischunk = 0;
0449       } else {
0450         if (fits_read_key(fp, TLONG, charNPix, &keynpix, comment, &ret)) {
0451           ret = 0;
0452           /*might be using LASTPIX instead*/
0453           if (fits_read_key(fp, TLONG, charLastPix, &keynpix, comment, &ret)) {
0454             ret = 0;
0455             ischunk = 0;
0456           } else {
0457             keynpix = keynpix - keyfirst + 1;
0458             if ((keyfirst < 0)||(keynpix < 0)||(keynpix+keyfirst > (long)(12*inside*inside))) {
0459               ischunk = 0;
0460             } else {
0461               ischunk = 1;
0462             }
0463           }
0464         } else {
0465           if ((keyfirst < 0)||(keynpix < 0)||(keynpix+keyfirst > (long)(12*inside*inside))) {
0466             ischunk = 0;
0467           } else {
0468             ischunk = 1;
0469           }
0470         }
0471       }
0472     } else {
0473       /*header doesn't matter, since we have entire map*/
0474       if (nrows == (long)(12*inside*inside)) {
0475         lastcol = 1;
0476       } else {
0477         lastcol = 1024;
0478       }
0479     }
0480     if (ischunk) {
0481       if (nrows == keynpix) {
0482         lastcol = 1;
0483       } else {
0484         lastcol = keynpix % 1024;
0485         if (lastcol == 0) {
0486           lastcol = 1024;
0487         }
0488       }
0489     }
0490     if (fits_read_col(fp, TFLOAT, 1, nrows, lastcol, 1, &nullval, &testval, &nnull, &ret)) {
0491       ret = 0;
0492       fits_close_file(fp, &ret);
0493       return 0;
0494     }
0495   } else {
0496     (*nmaps) = tfields - 3;
0497     if (fits_read_col(fp, TFLOAT, 2, nrows, 1, 1, &nullval, &testval, &nnull, &ret)) {
0498       ret = 0;
0499       fits_close_file(fp, &ret);
0500       return 0;
0501     }
0502   }
0503 
0504   fits_close_file(fp, &ret);
0505   return 1;
0506 }
0507 
0508 int healpix_fits_map_info(char *filename, size_t * nside, int *order, int *coord, int *type, size_t * nmaps, char *creator, char *extname, char **names, char **units, healpix_keys *keys)
0509 {
0510   fitsfile *fp;
0511   int ret = 0;
0512   int ttype;
0513   int inside;
0514   long nrows;
0515   long pcount;
0516   int tfields;
0517   int grain;
0518   char pixtype[HEALPIX_STRNL];
0519   char coordstr[HEALPIX_STRNL];
0520   char orderstr[HEALPIX_STRNL];
0521   char indxstr[HEALPIX_STRNL];
0522   char comment[HEALPIX_STRNL];
0523   float nullval = HEALPIX_NULL;
0524   int nnull;
0525   float testval;
0526   long keynpix;
0527   long keyfirst;
0528   int ischunk = 0;
0529   int lastcol;
0530 
0531   /* open file */
0532   if (fits_open_file(&fp, filename, READONLY, &ret)) {
0533     return 0;
0534   }
0535 
0536   /* read header info */
0537   char charCreator[] = "CREATOR";
0538   fits_read_key(fp, TSTRING, charCreator, creator, comment, &ret);
0539   ret = 0;
0540 
0541   /* make sure extension is a binary table */
0542   if (fits_movabs_hdu(fp, 2, &ttype, &ret)) {
0543     ret = 0;
0544     fits_close_file(fp, &ret);
0545     return 0;
0546   }
0547   if (ttype != BINARY_TBL) {
0548     ret = 0;
0549     fits_close_file(fp, &ret);
0550     return 0;
0551   }
0552 
0553   /* determine the number of maps */
0554   if (fits_read_btblhdr(fp, HEALPIX_FITS_MAXCOL, &nrows, &tfields, names, NULL, units, extname, &pcount, &ret)) {
0555     ret = 0;
0556     fits_close_file(fp, &ret);
0557     return 0;
0558   }
0559 
0560   /* make sure this is a HEALPIX file */
0561   char charPixtype[] = "PIXTYPE";
0562   if (fits_read_key(fp, TSTRING, charPixtype, pixtype, comment, &ret)) {
0563     ret = 0;
0564     fits_close_file(fp, &ret);
0565     return 0;
0566   }
0567   if (strncmp(pixtype, "HEALPIX", HEALPIX_STRNL) != 0) {
0568     ret = 0;
0569     fits_close_file(fp, &ret);
0570     return 0;
0571   }
0572 
0573   /* check required keywords (NSIDE, ORDERING, COORDSYS) */
0574   char charNSide[] = "NSIDE";
0575   char charOrdering[] = "ORDERING";
0576   char charCoordSys[] = "COORDSYS";
0577   if (fits_read_key(fp, TINT, charNSide, &inside, comment, &ret)) {
0578     ret = 0;
0579     fits_close_file(fp, &ret);
0580     return 0;
0581   }
0582   (*nside) = (size_t) inside;
0583   if (healpix_nsidecheck(*nside)) {
0584     ret = 0;
0585     fits_close_file(fp, &ret);
0586     return 0;
0587   }
0588   if (fits_read_key(fp, TSTRING, charOrdering, orderstr, comment, &ret)) {
0589     ret = 0;
0590     fits_close_file(fp, &ret);
0591     return 0;
0592   }
0593   if (strncmp(orderstr, "RING", HEALPIX_STRNL) == 0) {
0594     (*order) = HEALPIX_RING;
0595   } else if (strncmp(orderstr, "NESTED", HEALPIX_STRNL) == 0) {
0596     (*order) = HEALPIX_NEST;
0597   } else {
0598     ret = 0;
0599     fits_close_file(fp, &ret);
0600     return 0;
0601   }
0602   if (fits_read_key(fp, TSTRING, charCoordSys, coordstr, comment, &ret)) {
0603     ret = 0;
0604     (*coord) = HEALPIX_COORD_C;
0605   } else {
0606     if (strncmp(coordstr, "C", HEALPIX_STRNL) == 0) {
0607       (*coord) = HEALPIX_COORD_C;
0608     } else if (strncmp(coordstr, "G", HEALPIX_STRNL) == 0) {
0609       (*coord) = HEALPIX_COORD_G;
0610     } else if (strncmp(coordstr, "E", HEALPIX_STRNL) == 0) {
0611       (*coord) = HEALPIX_COORD_E;
0612     } else {
0613       (*coord) = HEALPIX_COORD_O;
0614     }
0615   }
0616 
0617   /* check for INDXSCHM and GRAIN.  if not found, assume implicit */
0618   char charObject[] = "OBJECT";
0619   char charIndxSchm[] = "INDXSCHM";
0620   char charGrain[] = "GRAIN";
0621   strcpy(indxstr,"");
0622   if (fits_read_key(fp, TSTRING, charObject, indxstr, comment, &ret)) {
0623     ret = 0;
0624     if (fits_read_key(fp, TSTRING, charIndxSchm, indxstr, comment, &ret)) {
0625       ret = 0;
0626       (*type) = HEALPIX_FITS_FULL;
0627     } else {
0628       if (strncmp(indxstr, "EXPLICIT", HEALPIX_STRNL) == 0) {
0629         (*type) = HEALPIX_FITS_CUT;
0630       } else {
0631         (*type) = HEALPIX_FITS_FULL;
0632       }
0633     }
0634     if (fits_read_key(fp, TINT, charGrain, &grain, comment, &ret)) {
0635       ret = 0;
0636       grain = 0;
0637     }
0638     if (((grain == 0) && ((*type) == HEALPIX_FITS_CUT)) ||
0639         ((grain != 0) && ((*type) == HEALPIX_FITS_FULL))) {
0640       ret = 0;
0641       fits_close_file(fp, &ret);
0642       return 0;
0643     }
0644   } else {
0645     if (strncmp(indxstr, "PARTIAL", HEALPIX_STRNL) == 0) {
0646       (*type) = HEALPIX_FITS_CUT;
0647     } else {
0648       if (strncmp(indxstr, "FULLSKY", HEALPIX_STRNL) == 0) {
0649         (*type) = HEALPIX_FITS_FULL;
0650       } else {
0651         if (fits_read_key(fp, TSTRING, charIndxSchm, indxstr, comment, &ret)) {
0652           ret = 0;
0653           (*type) = HEALPIX_FITS_FULL;
0654         } else {
0655           if (strncmp(indxstr, "EXPLICIT", HEALPIX_STRNL) == 0) {
0656             (*type) = HEALPIX_FITS_CUT;
0657           } else {
0658             (*type) = HEALPIX_FITS_FULL;
0659           }
0660         }
0661         if (fits_read_key(fp, TINT, charGrain, &grain, comment, &ret)) {
0662           ret = 0;
0663           grain = 0;
0664         }
0665         if (((grain == 0) && ((*type) == HEALPIX_FITS_CUT)) ||
0666             ((grain != 0) && ((*type) == HEALPIX_FITS_FULL))) {
0667           ret = 0;
0668           fits_close_file(fp, &ret);
0669           return 0;
0670         }
0671       }
0672     }
0673   }
0674 
0675   /* read extension keys */
0676   healpix_keys_read(keys, fp, &ret);
0677 
0678   /* check for chunk file and truncation */
0679   char charFirstPix[] = "FIRSTPIX";
0680   char charNPix[] = "NPIX";
0681   char charLastPix[] = "LASTPIX";
0682 
0683   if ((*type) == HEALPIX_FITS_FULL) {
0684     (*nmaps) = tfields;
0685     if ((nrows != (long)(12*inside*inside))&&(1024*nrows != (long)(12*inside*inside))) {
0686       /*is this a chunk file?*/
0687       if (fits_read_key(fp, TLONG, charFirstPix, &keyfirst, comment, &ret)) {
0688         /*must at least have FIRSTPIX key*/
0689         ret = 0;
0690         ischunk = 0;
0691       } else {
0692         if (fits_read_key(fp, TLONG, charNPix, &keynpix, comment, &ret)) {
0693           ret = 0;
0694           /*might be using LASTPIX instead*/
0695           if (fits_read_key(fp, TLONG, charLastPix, &keynpix, comment, &ret)) {
0696             ret = 0;
0697             ischunk = 0;
0698           } else {
0699             keynpix = keynpix - keyfirst + 1;
0700             if ((keyfirst < 0)||(keynpix < 0)||(keynpix+keyfirst > (long)(12*inside*inside))) {
0701               ischunk = 0;
0702             } else {
0703               ischunk = 1;
0704             }
0705           }
0706         } else {
0707           if ((keyfirst < 0)||(keynpix < 0)||(keynpix+keyfirst > (long)(12*inside*inside))) {
0708             ischunk = 0;
0709           } else {
0710             ischunk = 1;
0711           }
0712         }
0713       }
0714     } else {
0715       /*header doesn't matter, since we have entire map*/
0716       if (nrows == (long)(12*inside*inside)) {
0717         lastcol = 1;
0718       } else {
0719         lastcol = 1024;
0720       }
0721     }
0722     if (ischunk) {
0723       if (nrows == keynpix) {
0724         lastcol = 1;
0725       } else {
0726         lastcol = keynpix % 1024;
0727         if (lastcol == 0) {
0728           lastcol = 1024;
0729         }
0730       }
0731     }
0732     if (fits_read_col(fp, TFLOAT, 1, nrows, lastcol, 1, &nullval, &testval, &nnull, &ret)) {
0733       ret = 0;
0734       fits_close_file(fp, &ret);
0735       return 0;
0736     }
0737   } else {
0738     (*nmaps) = tfields - 3;
0739     if (fits_read_col(fp, TFLOAT, 2, nrows, 1, 1, &nullval, &testval, &nnull, &ret)) {
0740       ret = 0;
0741       fits_close_file(fp, &ret);
0742       return 0;
0743     }
0744   }
0745 
0746   fits_close_file(fp, &ret);
0747   return 1;
0748 }
0749