/* * Read an ASCII file as a 2-dimensional array of floating point numbers. * The number of columns is determined by the number of entries on the * first non-comment line. Missing values are set to zero. * Comment lines (preceded with a hash mark) are ignored. * The returned matrix is in row-major order, and as such is * addressed as (*ppData)[iRow*NCols+iCol]. * If the data array is empty, it should be passed with the value ppData = NULL. * * Return IO_GOOD if the file exists, and IO_BAD otherwise. */ int asciifile_read_rowmajor (char pFileName[], int numColsMax, int * pNRows, int * pNCols, float ** ppData) { int fileNum; int iCol; int nValues; int qExist; const int numAddRows = 10; MEMSZ memSize; MEMSZ newMemSize; char * iq; float * pValues; float * pData; char pPrivR[] = "r\0"; *pNCols = 0; *pNRows = 0; qExist = inoutput_open_file(&fileNum, pFileName, pPrivR); if (qExist == IO_GOOD) { /* Allocate a starting block of memory for the data array */ /* Start with enough memory for numAddRows rows */ memSize = numAddRows * sizeof(float) * numColsMax; /* SHOULD BE ABLE TO USE REALLOC BELOW !!!??? */ ccalloc_(&memSize, (void **)ppData); pData = *ppData; /* Allocate the temporary memory for each line of values */ pValues = ccvector_build_(numColsMax); /* Read the first line, which determines the # of cols for all lines */ iq = asciifile_read_line(fileNum, numColsMax, pNCols, pData); /* Read the remaining lines if a first line was read successfully */ if (iq != NULL) { *pNRows=1; while ((iq = asciifile_read_line(fileNum, numColsMax, &nValues, pValues)) != NULL) { /* Allocate more memory for the data array if necessary */ /* Always keep enough memory for at least one more row */ newMemSize = sizeof(float) * (*pNRows + 1) * (*pNCols); if (newMemSize > memSize) { newMemSize = newMemSize + sizeof(float)*(numAddRows); ccalloc_resize_(&memSize, &newMemSize, (void **)ppData); pData = *ppData; memSize = newMemSize; } /* Case where the line contained fewer values than allowed */ if (nValues < *pNCols) { for (iCol=0; iCol<nValues; iCol++) pData[iCol+(*pNCols)*(*pNRows)] = pValues[iCol]; for (iCol=nValues; iCol < *pNCols; iCol++) pData[iCol+(*pNCols)*(*pNRows)] = 0; /* Case where line contained as many or more values than allowed */ } else { for (iCol=0; iCol < *pNCols; iCol++) pData[iCol+(*pNCols)*(*pNRows)] = pValues[iCol]; } (*pNRows)++; } } inoutput_close_file(fileNum); ccvector_free_(pValues); } return qExist; }
void main (int argc, char * ppArgv[], char * ppEnvp[]) { int ic; int qInterp; int qVerbose; int qNoloop; int iGal; int nGal; int nCol; float tmpl; float tmpb; float * pGall = NULL; float * pGalb = NULL; float * pNu = NULL; float * pInu; float * pData; FILE * pFILEout; static char pPrivW[] = "w"; /* Declarations for keyword input values */ int ienv; int nkey; int modelNum; float nuval = 0.0; char * pTemp; char * pKeyname; char * pKeyval; char * pResName; char * pUnitsName; char * pInFile = NULL; char * pOutName = NULL; char * pIPath = NULL; char pString1[13]; char pDefPath[] = "./"; char pDefRes[] = "I4096"; const char pDUST_DIR[] = "DUST_DIR"; const char pEq[] = "="; const char pText_mapdir[] = "/maps/"; /* Declarations for command-line keyword names */ const char pText_ipath[] = "ipath"; const char pText_infile[] = "infile"; const char pText_outfile[] = "outfile"; const char pText_model[] = "model"; const char pText_nu[] = "nu"; const char pText_resolution[] = "resolution"; const char pText_units[] = "units"; const char pText_interp[] = "interp"; const char pText_noloop[] = "noloop"; const char pText_verbose[] = "verbose"; char pText_MJy[] = "MJy"; /* Set defaults */ pIPath = pDefPath; pResName = pDefRes; pUnitsName = pText_MJy; modelNum = 8; /* default to our best-fit model */ qInterp = 0; /* no interpolation */ qVerbose = 0; /* not verbose */ qNoloop = 0; /* do not read entire image into memory */ /* Override default path by value in the environment variable DUST_DIR */ for (ienv=0; ppEnvp[ienv] != 0; ienv++) { if (strcmp(pDUST_DIR,strtok(ppEnvp[ienv],pEq))==0 ) { pIPath = strcat( strtok(NULL,pEq), pText_mapdir ); } } nkey = 0; for (ic=1; ic < argc; ic++) { /* Check if this argument is a keyword */ if ((pTemp=strchr(ppArgv[ic],'=')) != NULL) { nkey++; pKeyname = ppArgv[ic]; pKeyval = pTemp + 1; pTemp[0] = '\0'; /* replace equals with NULL to terminate string */ if (strcmp(pKeyname,pText_nu) == 0) sscanf(pKeyval, "%f", &nuval); if (strcmp(pKeyname,pText_infile) == 0) pInFile = pKeyval; if (strcmp(pKeyname,pText_outfile) == 0) pOutName = pKeyval; if (strcmp(pKeyname,pText_model) == 0) sscanf(pKeyval, "%d", &modelNum); if (strcmp(pKeyname,pText_resolution) == 0) pResName = pKeyval; if (strcmp(pKeyname,pText_units) == 0) pUnitsName = pKeyval; if (strcmp(pKeyname,pText_ipath) == 0) pIPath = pKeyval; if (strcmp(pKeyname,pText_interp) == 0) { if (strchr(pKeyval,'y') != NULL || strchr(pKeyval,'Y') != NULL) qInterp = 1; /* do interpolation */ } if (strcmp(pKeyname,pText_noloop) == 0) { if (strchr(pKeyval,'y') != NULL || strchr(pKeyval,'Y') != NULL) qNoloop=1; /* read entire image into memory */ } if (strcmp(pKeyname,pText_verbose) == 0) { if (strchr(pKeyval,'y') != NULL || strchr(pKeyval,'Y') != NULL) qVerbose = 1; /* do interpolation */ } } } /* If no input coordinate file, then read coordinates from either * the command line or by query */ if (pInFile != NULL) { if (nuval == 0.0) { asciifile_read_colmajor(pInFile, 3, &nGal, &nCol, &pData); pGall = pData; pGalb = pData + nGal; pNu = pData + 2*nGal; if (pNu[0] == 0.0) pNu = NULL; } else { asciifile_read_colmajor(pInFile, 2, &nGal, &nCol, &pData); pGall = pData; pGalb = pData + nGal; } } else { if (argc-nkey > 2) { sscanf(ppArgv[1], "%f", &tmpl); sscanf(ppArgv[2], "%f", &tmpb); } else { printf("Galactic longitude (degrees):\n"); scanf("%f", &tmpl); printf("Galactic latitude (degrees):\n"); scanf("%f", &tmpb); } nGal = 1; pGall = ccvector_build_(nGal); pGalb = ccvector_build_(nGal); pGall[0] = tmpl; pGalb[0] = tmpb; } /* Query for the frequency if not specified on the command line or * in the input file. */ if (nuval == 0.0 && pNu == NULL) { printf("Frequency (GHz):\n"); scanf("%f", &nuval); } /* If "nu" was specified on the command line, then set frequency of all points to this value; this will supersede any in an input file. */ if (nuval != 0.0) { if (pNu == NULL) pNu = ccvector_build_(nGal); for (iGal=0; iGal < nGal; iGal++) pNu[iGal] = nuval; } pInu = predict_thermal(nGal, pGall, pGalb, pNu, pIPath, pResName, pUnitsName, modelNum, qInterp, qNoloop, qVerbose); /* If no output file, then output to screen */ if (pOutName != NULL) pFILEout = fopen(pOutName, pPrivW); else pFILEout = stdout; sprintf(pString1, "Inu(%s)", pUnitsName); fprintf(pFILEout, " l(deg) b(deg) nu(GHz) %-12.12s\n", pString1); fprintf(pFILEout, " ------- ------- ------------ ------------\n"); for (iGal=0; iGal < nGal; iGal++) { fprintf(pFILEout, "%8.3f %7.3f %12.5e %12.5e\n", pGall[iGal], pGalb[iGal], pNu[iGal], pInu[iGal]); } if (pOutName != NULL) fclose(pFILEout); if (pInFile != NULL) { ccfree_((void **)&pData); } else { ccfree_((void **)&pGall); ccfree_((void **)&pGalb); } }
float * predict_thermal (long nGal, float * pGall, float * pGalb, float * pNu, char * pIPath, char * pResName, char * pUnitsName, int modelNum, int qInterp, int qNoloop, int qVerbose) { int ii; int im; int iz1 = -1; /* crash if Zindx not tabulated for alpha1 */ int iz2 = -1; /* crash if Zindx not tabulated for alpha2 */ int imap; int iGal; float * pI100; float * pRmapval; float * pInu; float alpha1; float alpha2; float f1; float q1q2; float RfitA[6]; float lnR; float lnRpow; float T1; float T2; float lnT1; float lnT2; float tcoeff; const float nu100 = 2997.92458; /* Frequency in GHz for 100-microns */ const float h_Pl = 6.6261e-27; /* cm^2 g s^-1 */ const float k_B = 1.3806e-16; /* erg K^-1 */ /* Declarations for command-line keyword names */ char pText_MJy[] = "MJy"; char pText_microK[] = "microK"; char pText_thermo[] = "thermo"; /* Declarations for data file names */ char pFileN[MAX_FILE_NAME_LEN]; char pFileS[MAX_FILE_NAME_LEN]; struct mapParms { char * pName; char * pFile1; char * pFile2; } ppMapAll[] = { { "D1024", "SFD_d100_1024_ngp.fits", "SFD_d100_1024_sgp.fits" }, { "I1024", "SFD_i100_1024_ngp.fits", "SFD_i100_1024_sgp.fits" }, { "I2048", "SFD_i100_2048_ngp.fits", "SFD_i100_2048_sgp.fits" }, { "I4096", "SFD_i100_4096_ngp.fits", "SFD_i100_4096_sgp.fits" } }; const int nmap = sizeof(ppMapAll) / sizeof(ppMapAll[0]); char * ppRmapFile[] = { "FINK_Rmap_ngp.fits" , "FINK_Rmap_sgp.fits" }; /* Set model parameters */ const float alpha1vec[] = {1.50, 1.70, 2.00, 2.20, 1.50, 2.00, 1.50, 1.67}; const float alpha2vec[] = {0.00, 0.00, 0.00, 0.00, 2.60, 2.00, 2.60, 2.70}; const float f1vec[] = {1.00, 1.00, 1.00, 1.00, 0.25, 0.00261, 0.0309, 0.0363}; const float q1q2vec[] = {1.00, 1.00, 1.00, 1.00, 0.61, 2480.0, 11.2, 13.0}; /* const int N_MODEL = sizeof(alpha1vec) / sizeof(alpha1vec[0]); */ /* Rfita contains fit coefficients for T2_of_R */ const float RfitAarr[][6] = {{2.9268E+00, 3.8419E-01, 5.0233E-02, 1.0852E-02, 3.0738E-03, 5.0595E-04}, {2.8483E+00, 3.8044E-01, 4.6584E-02, 9.0938E-03, 2.7038E-03, 5.4664E-04}, {2.7334E+00, 3.7537E-01, 4.1712E-02, 6.8839E-03, 2.0316E-03, 6.0311E-04}, {2.6556E+00, 3.7377E-01, 3.9898E-02, 5.7662E-03, 1.4638E-03, 6.3723E-04}, {2.9206E+00, 2.3254E-01, 2.3506E-02, 4.0781E-03, 1.0048E-03, 1.2004E-04}, {2.9900E+00, 2.5041E-01, 2.9688E-02, 6.5641E-03, 1.5688E-03, 1.6542E-04}, {2.8874E+00, 2.4172E-01, 2.9369E-02, 4.7867E-03, 9.7237E-04, 1.1410E-04}, {2.8723E+00, 2.4071E-01, 2.9625E-02, 4.7196E-03, 9.3207E-04, 1.1099E-04} }; /* Zeta integrals for alpha=[1.50, 1.67, 1.70, 2.00, 2.20, 2.60, 2.70] from equn (15) of Finkbeiner et al. */ const float Zindx[] = {1.50, 1.67, 1.70, 2.00, 2.20, 2.60, 2.70}; const float Zintegral[] = {5.3662E+01, 7.0562E+01, 7.4100E+01, 1.2208E+02, 1.7194E+02, 3.4855E+02, 4.1770E+02}; const int N_ZINDEX = sizeof(Zindx) / sizeof(Zindx[0]); /* Test that inputs are valid */ if (nGal == 0 || pGall == NULL || pGalb == NULL || pNu == NULL) { printf("ERROR: Must specify coordinates and frequencies.\n"); return NULL; } /* Select parameters for this model */ alpha1 = alpha1vec[modelNum-1]; alpha2 = alpha2vec[modelNum-1]; f1 = f1vec[modelNum-1]; q1q2 = q1q2vec[modelNum-1]; for (ii=0; ii < 6; ii++) RfitA[ii] = RfitAarr[modelNum-1][ii]; /* Determine the file names to use */ for (imap=0; imap < nmap; imap++) { if (strcmp(pResName,ppMapAll[imap].pName) == 0) { sprintf(pFileN, "%s/%s", pIPath, ppMapAll[imap].pFile1); sprintf(pFileS, "%s/%s", pIPath, ppMapAll[imap].pFile2); } } /* Read the 100-micron map */ pI100 = lambert_getval(pFileN, pFileS, nGal, pGall, pGalb, qInterp, qNoloop, qVerbose); /* Read the I100/240 ratio map */ sprintf(pFileN, "%s/%s", pIPath, ppRmapFile[0]); sprintf(pFileS, "%s/%s", pIPath, ppRmapFile[1]); pRmapval = lambert_getval(pFileN, pFileS, nGal, pGall, pGalb, qInterp, qNoloop, qVerbose); /* Allocate memory for output array */ pInu = ccvector_build_(nGal); if (modelNum <=4) { /* SINGLE-COMPONENT MODEL: Evaluate equn (1) from Finkbeiner et al */ for (iGal=0; iGal < nGal; iGal++) { /* Compute ln(T1) from ln(Rmap) */ lnR = log(pRmapval[iGal]); lnRpow = 1.0; lnT1 = RfitA[0]; for (ii=1; ii < 6; ii++) { lnRpow *= lnR; lnT1 += RfitA[ii] * lnRpow; } T1 = exp(lnT1); pInu[iGal] = pI100[iGal] * pow(pNu[iGal]/nu100,alpha1) * planck(T1,pNu[iGal]) / ( planck(T1,nu100) * kfactor(alpha1,T1) ); } } else { /* TWO-COMPONENT MODEL: Evaluate equn (6) from Finkbeiner et al */ /* Find Zintegral index for the model values of "alpha" */ for (im=0; im < N_ZINDEX; im++) { if (fabs(Zindx[im] - alpha1) < 1.e-4) iz1 = im; if (fabs(Zindx[im] - alpha2) < 1.e-4) iz2 = im; } tcoeff = pow( (Zintegral[iz2] / (q1q2*Zintegral[iz1])) * pow(h_Pl*nu100*1.e+9/k_B,alpha1-alpha2), 1./(4.+alpha1) ); for (iGal=0; iGal < nGal; iGal++) { /* Compute ln(T2) from ln(Rmap) */ lnR = log(pRmapval[iGal]); lnRpow = 1.0; lnT2 = RfitA[0]; for (ii=1; ii < 6; ii++) { lnRpow *= lnR; lnT2 += RfitA[ii] * lnRpow; } T2 = exp(lnT2); /* Compute T1 as a function of T2; equn (13) of Finkbeiner et al. */ T1 = tcoeff * pow( T2, ((4+alpha2)/(4+alpha1)) ); pInu[iGal] = pI100[iGal] * ( f1 * q1q2 * pow(pNu[iGal]/nu100,alpha1) * planck(T1,pNu[iGal]) + (1-f1) * pow(pNu[iGal]/nu100,alpha2) * planck(T2,pNu[iGal]) ) / ( f1 * q1q2 * planck(T1,nu100) * kfactor(alpha1,T1) + (1-f1) * planck(T2,nu100) * kfactor(alpha2,T2) ); } } /* Convert units */ if (strcmp(pUnitsName,pText_MJy) == 0) { /* MJy/sr */ } else if (strcmp(pUnitsName,pText_microK) == 0) { /* brightness temp micro-K */ for (iGal=0; iGal < nGal; iGal++) pInu[iGal] *= fac_flux2temp(pNu[iGal]); } else if (strcmp(pUnitsName,pText_thermo) == 0) { /* thermodynamic micro-K */ for (iGal=0; iGal < nGal; iGal++) pInu[iGal] *= fac_flux2temp(pNu[iGal]) * planckcorr(pNu[iGal]); } else { printf("ERROR: Invalid units name.\n"); for (iGal=0; iGal < nGal; iGal++) pInu[iGal] = 0.0; } ccvector_free_(pI100); ccvector_free_(pRmapval); return pInu; }
float * predict_sync (long nGal, float * pGall, float * pGalb, float * pNu, char * pIPath, char * pUnitsName, int qInterp, int qNoloop, int qVerbose) { int iGal; float * pAmap; float * pBmap; float * pInu; /* Declarations for command-line keyword names */ char pText_MJy[] = "MJy"; char pText_microK[] = "microK"; char pText_thermo[] = "thermo"; /* Declarations for data file names */ char pFileN[MAX_FILE_NAME_LEN]; char pFileS[MAX_FILE_NAME_LEN]; char * ppHaslamFile[] = { "Haslam_clean_ngp.fits" , "Haslam_clean_sgp.fits" }; char * ppBetaFile[] = { "Synch_Beta_ngp.fits" , "Synch_Beta_sgp.fits" }; /* Test that inputs are valid */ if (nGal == 0 || pGall == NULL || pGalb == NULL || pNu == NULL) { printf("ERROR: Must specify coordinates and frequencies.\n"); return NULL; } /* Read the Haslam map */ sprintf(pFileN, "%s/%s", pIPath, ppHaslamFile[0]); sprintf(pFileS, "%s/%s", pIPath, ppHaslamFile[1]); pAmap = lambert_getval(pFileN, pFileS, nGal, pGall, pGalb, qInterp, qNoloop, qVerbose); /* Read the Beta ratio map */ sprintf(pFileN, "%s/%s", pIPath, ppBetaFile[0]); sprintf(pFileS, "%s/%s", pIPath, ppBetaFile[1]); pBmap = lambert_getval(pFileN, pFileS, nGal, pGall, pGalb, qInterp, qNoloop, qVerbose); /* Allocate memory for output array */ pInu = ccvector_build_(nGal); /* microK brightness temp (Beta map is actually negative of spectral * index, and ranges from roughly 2.5 < beta < 3.0) */ for (iGal=0; iGal < nGal; iGal++) { pInu[iGal] = 1.0e6 * pAmap[iGal] * pow(0.408/pNu[iGal], pBmap[iGal]); } /* Convert units */ if (strcmp(pUnitsName,pText_MJy) == 0) { /* MJy/sr */ for (iGal=0; iGal < nGal; iGal++) pInu[iGal] /= fac_flux2temp(pNu[iGal]); } else if (strcmp(pUnitsName,pText_microK) == 0) { /* brightness temp micro-K */ } else if (strcmp(pUnitsName,pText_thermo) == 0) { /* thermodynamic micro-K */ for (iGal=0; iGal < nGal; iGal++) pInu[iGal] *= planckcorr(pNu[iGal]); } else { printf("ERROR: Invalid units name.\n"); for (iGal=0; iGal < nGal; iGal++) pInu[iGal] = 0.0; } return pInu; }
/* Read one value at a time from NGP+SGP polar projections. * Set qInterp=1 to interpolate, or =0 otherwise. * Set qVerbose=1 to for verbose output, or =0 otherwise. */ float * lambert_getval (char * pFileN, char * pFileS, long nGal, float * pGall, float * pGalb, int qInterp, int qNoloop, int qVerbose) { int iloop; int iGal; int ii; int jj; int * pNS; /* 0 for NGP, 1 for SGP */ int nIndx; int * pIndx; int * pXPix; int * pYPix; int xPix; int yPix; int xsize; DSIZE pStart[2]; DSIZE pEnd[2]; DSIZE nSubimg; float * pSubimg; float dx; float dy; float xr; float yr; float pWeight[4]; float mapval; float * pOutput; float * pDX = NULL; float * pDY = NULL; /* Variables for FITS files */ int qRead; int numAxes; DSIZE * pNaxis; char * pFileIn = NULL; HSIZE nHead; uchar * pHead; /* Allocate output data array */ pNS = ccivector_build_(nGal); pOutput = ccvector_build_(nGal); /* Decide if each point should be read from the NGP or SGP projection */ for (iGal=0; iGal < nGal; iGal++) pNS[iGal] = (pGalb[iGal] >= 0.0) ? 0 : 1; /* ==0 for NGP, ==1 for SGP */ if (qNoloop == 0) { /* LOOP THROUGH ONE POINT AT A TIME */ /* Loop through first NGP then SGP */ for (iloop=0; iloop < 2; iloop++) { qRead = 0; /* Loop through each data point */ for (iGal=0; iGal < nGal; iGal++) { if (pNS[iGal] == iloop) { /* Read FITS header for this projection if not yet read */ if (qRead == 0) { if (iloop == 0) pFileIn = pFileN; else pFileIn = pFileS; fits_read_file_fits_header_only_(pFileIn, &nHead, &pHead); qRead = 1; } if (qInterp == 0) { /* NEAREST PIXELS */ /* Determine the nearest pixel coordinates */ lambert_lb2pix(pGall[iGal], pGalb[iGal], nHead, pHead, &xPix, &yPix); pStart[0] = xPix; pStart[1] = yPix; /* Read one pixel value from data file */ fits_read_point_(pFileIn, nHead, pHead, pStart, &mapval); pOutput[iGal] = mapval; if (qVerbose != 0) printf("%8.3f %7.3f %1d %8d %8d %12.5e\n", pGall[iGal], pGalb[iGal], iloop, xPix, yPix, mapval); } else { /* INTERPOLATE */ fits_compute_axes_(&nHead, &pHead, &numAxes, &pNaxis); /* Determine the fractional pixel coordinates */ lambert_lb2fpix(pGall[iGal], pGalb[iGal], nHead, pHead, &xr, &yr); /* The following 4 lines introduced an erroneous 1/2-pixel shift (DJS 18-Mar-1999). xPix = (int)(xr-0.5); yPix = (int)(yr-0.5); dx = xPix - xr + 1.5; dy = yPix - yr + 1.5; */ xPix = (int)(xr); yPix = (int)(yr); dx = xPix - xr + 1.0; dy = yPix - yr + 1.0; /* Force pixel values to fall within the image boundaries */ if (xPix < 0) { xPix = 0; dx = 1.0; } if (yPix < 0) { yPix = 0; dy = 1.0; } if (xPix >= pNaxis[0]-1) { xPix = pNaxis[0]-2; dx = 0.0; } if (yPix >= pNaxis[1]-1) { yPix = pNaxis[1]-2; dy = 0.0; } pStart[0] = xPix; pStart[1] = yPix; pEnd[0] = xPix + 1; pEnd[1] = yPix + 1; /* Create array of weights */ pWeight[0] = dx * dy ; pWeight[1] = (1-dx) * dy ; pWeight[2] = dx * (1-dy) ; pWeight[3] = (1-dx) * (1-dy) ; /* Read 2x2 array from data file */ fits_read_subimg_(pFileIn, nHead, pHead, pStart, pEnd, &nSubimg, &pSubimg); pOutput[iGal] = 0.0; for (jj=0; jj < 4; jj++) pOutput[iGal] += pWeight[jj] * pSubimg[jj]; fits_free_axes_(&numAxes, &pNaxis); ccfree_((void **)&pSubimg); if (qVerbose != 0) printf("%8.3f %7.3f %1d %9.3f %9.3f %12.5e\n", pGall[iGal], pGalb[iGal], iloop, xr, yr, pOutput[iGal]); } /* -- END NEAREST PIXEL OR INTERPOLATE -- */ } } } } else { /* READ FULL IMAGE */ pIndx = ccivector_build_(nGal); pXPix = ccivector_build_(nGal); pYPix = ccivector_build_(nGal); if (qInterp != 0) { pDX = ccvector_build_(nGal); pDY = ccvector_build_(nGal); } /* Loop through first NGP then SGP */ for (iloop=0; iloop < 2; iloop++) { /* Determine the indices of data points in this hemisphere */ nIndx = 0; for (iGal=0; iGal < nGal; iGal++) { if (pNS[iGal] == iloop) { pIndx[nIndx] = iGal; nIndx++; } } /* Do not continue if no data points in this hemisphere */ if (nIndx > 0) { /* Read FITS header for this projection */ if (iloop == 0) pFileIn = pFileN; else pFileIn = pFileS; fits_read_file_fits_header_only_(pFileIn, &nHead, &pHead); if (qInterp == 0) { /* NEAREST PIXELS */ /* Determine the nearest pixel coordinates */ for (ii=0; ii < nIndx; ii++) { lambert_lb2pix(pGall[pIndx[ii]], pGalb[pIndx[ii]], nHead, pHead, &pXPix[ii], &pYPix[ii]); } pStart[0] = ivector_minimum(nIndx, pXPix); pEnd[0] = ivector_maximum(nIndx, pXPix); pStart[1] = ivector_minimum(nIndx, pYPix); pEnd[1] = ivector_maximum(nIndx, pYPix); /* Read smallest subimage containing all points in this hemi */ fits_read_subimg_(pFileIn, nHead, pHead, pStart, pEnd, &nSubimg, &pSubimg); xsize = pEnd[0] - pStart[0] + 1; /* Determine data values */ for (ii=0; ii < nIndx; ii++) { pOutput[pIndx[ii]] = pSubimg[ pXPix[ii]-pStart[0] + (pYPix[ii]-pStart[1]) * xsize ]; } ccfree_((void **)&pSubimg); } else { /* INTERPOLATE */ fits_compute_axes_(&nHead, &pHead, &numAxes, &pNaxis); /* Determine the fractional pixel coordinates */ for (ii=0; ii < nIndx; ii++) { lambert_lb2fpix(pGall[pIndx[ii]], pGalb[pIndx[ii]], nHead, pHead, &xr, &yr); /* The following 4 lines introduced an erroneous 1/2-pixel shift (DJS 03-Mar-2004). pXPix[ii] = (int)(xr-0.5); pYPix[ii] = (int)(yr-0.5); pDX[ii] = pXPix[ii] - xr + 1.5; pDY[ii] = pYPix[ii] - yr + 1.5; */ pXPix[ii] = (int)(xr); pYPix[ii] = (int)(yr); pDX[ii] = pXPix[ii] - xr + 1.0; pDY[ii] = pYPix[ii] - yr + 1.0; /* Force pixel values to fall within the image boundaries */ if (pXPix[ii] < 0) { pXPix[ii] = 0; pDX[ii] = 1.0; } if (pYPix[ii] < 0) { pYPix[ii] = 0; pDY[ii] = 1.0; } if (pXPix[ii] >= pNaxis[0]-1) { pXPix[ii] = pNaxis[0]-2; pDX[ii] = 0.0; } if (pYPix[ii] >= pNaxis[1]-1) { pYPix[ii] = pNaxis[1]-2; pDY[ii] = 0.0; } } pStart[0] = ivector_minimum(nIndx, pXPix); pEnd[0] = ivector_maximum(nIndx, pXPix) + 1; pStart[1] = ivector_minimum(nIndx, pYPix); pEnd[1] = ivector_maximum(nIndx, pYPix) + 1; /* Read smallest subimage containing all points in this hemi */ fits_read_subimg_(pFileIn, nHead, pHead, pStart, pEnd, &nSubimg, &pSubimg); xsize = pEnd[0] - pStart[0] + 1; /* Determine data values */ for (ii=0; ii < nIndx; ii++) { /* Create array of weights */ pWeight[0] = pDX[ii] * pDY[ii] ; pWeight[1] = (1-pDX[ii]) * pDY[ii] ; pWeight[2] = pDX[ii] * (1-pDY[ii]) ; pWeight[3] = (1-pDX[ii]) * (1-pDY[ii]) ; pOutput[pIndx[ii]] = pWeight[0] * pSubimg[ pXPix[ii]-pStart[0] + (pYPix[ii]-pStart[1] )*xsize ] +pWeight[1] * pSubimg[ pXPix[ii]-pStart[0]+1 + (pYPix[ii]-pStart[1] )*xsize ] +pWeight[2] * pSubimg[ pXPix[ii]-pStart[0] + (pYPix[ii]-pStart[1]+1)*xsize ] +pWeight[3] * pSubimg[ pXPix[ii]-pStart[0]+1 + (pYPix[ii]-pStart[1]+1)*xsize ] ; } fits_free_axes_(&numAxes, &pNaxis); ccfree_((void **)&pSubimg); } /* -- END NEAREST PIXEL OR INTERPOLATE -- */ } } ccivector_free_(pIndx); ccivector_free_(pXPix); ccivector_free_(pYPix); if (qInterp != 0) { ccvector_free_(pDX); ccvector_free_(pDY); } } /* Free the memory allocated for the FITS header (Moved outside previous brace by Chris Stoughton 19-Jan-1999) */ fits_dispose_array_(&pHead); /* Deallocate output data array */ ccivector_free_(pNS); return pOutput; }