/* * 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 COLUMN-MAJOR order, and as such is * addressed as (*ppData)[iCol*NRows+iRow]. * This is the Fortran storage scheme, but it is useful in addressing * a column as a vector that is contiguous in memory. * If the data array is empty, it should be passed with the value ppData = NULL. * * Return IO_GOOD if the file exists, and IO_FALSE otherwise. */ int asciifile_read_colmajor (char pFileName[], int numColsMax, int * pNRows, int * pNCols, float ** ppData) { int iCol; int iRow; int qExist; MEMSZ memSize; float * pNewData; qExist = asciifile_read_rowmajor(pFileName, numColsMax, pNRows, pNCols, ppData); if (qExist == IO_GOOD) { /* Create a new array of the same dimensions */ memSize = sizeof(float) * (*pNRows)*(*pNCols); ccalloc_(&memSize, (void **)&pNewData); /* Copy the data into this array in column-major order */ for (iCol=0; iCol < (*pNCols); iCol++) { for (iRow=0; iRow < (*pNRows); iRow ++) { pNewData[iCol*(*pNRows)+iRow] = (*ppData)[iRow*(*pNCols)+iCol]; } } /* Toss out the old array */ ccfree_((void **)ppData); *ppData = pNewData; } return qExist; }
/* 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; }
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); } }
/* Transform from galactic (l,b) coordinates to fractional (x,y) pixel location. * Latitude runs clockwise from X-axis for NGP, counterclockwise for SGP. * This function returns the ZERO-INDEXED pixel position. * Updated 04-Mar-1999 to allow ZEA coordinate convention for the same * projection. */ void lambert_lb2fpix (float gall, /* Galactic longitude */ float galb, /* Galactic latitude */ HSIZE nHead, uchar * pHead, float * pX, /* X position in pixels from the center */ float * pY) /* Y position in pixels from the center */ { int q1; int q2; int nsgp; float scale; float crval1; float crval2; float crpix1; float crpix2; float cdelt1; float cdelt2; float cd1_1; float cd1_2; float cd2_1; float cd2_2; float lonpole; float xr; float yr; float theta; float phi; float Rtheta; float denom; static double dradeg = 180 / 3.1415926534; char * pCtype1; char * pCtype2; fits_get_card_string_(&pCtype1, label_ctype1, &nHead, &pHead); fits_get_card_string_(&pCtype2, label_ctype2, &nHead, &pHead); fits_get_card_rval_(&crval1, label_crval1, &nHead, &pHead); fits_get_card_rval_(&crval2, label_crval2, &nHead, &pHead); fits_get_card_rval_(&crpix1, label_crpix1, &nHead, &pHead); fits_get_card_rval_(&crpix2, label_crpix2, &nHead, &pHead); if (strcmp(pCtype1, "LAMBERT--X") == 0 && strcmp(pCtype2, "LAMBERT--Y") == 0) { fits_get_card_ival_(&nsgp, label_lam_nsgp, &nHead, &pHead); fits_get_card_rval_(&scale, label_lam_scal, &nHead, &pHead); lambert_lb2xy(gall, galb, nsgp, scale, &xr, &yr); *pX = xr + crpix1 - crval1 - 1.0; *pY = yr + crpix2 - crval2 - 1.0; } else if (strcmp(pCtype1, "GLON-ZEA") == 0 && strcmp(pCtype2, "GLAT-ZEA") == 0) { q1 = fits_get_card_rval_(&cdelt1, label_cdelt1, &nHead, &pHead); q2 = fits_get_card_rval_(&cdelt2, label_cdelt2, &nHead, &pHead); if (q1 == TRUE && q2 == TRUE) { cd1_1 = cdelt1; cd1_2 = 0.0; cd2_1 = 0.0; cd2_2 = cdelt2; } else { fits_get_card_rval_(&cd1_1, label_cd1_1, &nHead, &pHead); fits_get_card_rval_(&cd1_2, label_cd1_2, &nHead, &pHead); fits_get_card_rval_(&cd2_1, label_cd2_1, &nHead, &pHead); fits_get_card_rval_(&cd2_2, label_cd2_2, &nHead, &pHead); } q1 = fits_get_card_rval_(&lonpole, label_lonpole, &nHead, &pHead); if (q1 == FALSE) lonpole = 180.0; /* default value */ /* ROTATION */ /* Equn (4) - degenerate case */ if (crval2 > 89.9999) { theta = galb; phi = gall + 180.0 + lonpole - crval1; } else if (crval2 < -89.9999) { theta = -galb; phi = lonpole + crval1 - gall; } else { printf("ERROR: Unsupported projection!!!\n"); /* Assume it's an NGP projection ... */ theta = galb; phi = gall + 180.0 + lonpole - crval1; } /* Put phi in the range [0,360) degrees */ phi = phi - 360.0 * floor(phi/360.0); /* FORWARD MAP PROJECTION */ /* Equn (26) */ Rtheta = 2.0 * dradeg * sin((0.5 / dradeg) * (90.0 - theta)); /* Equns (10), (11) */ xr = Rtheta * sin(phi / dradeg); yr = - Rtheta * cos(phi / dradeg); /* SCALE FROM PHYSICAL UNITS */ /* Equn (3) after inverting the matrix */ denom = cd1_1 * cd2_2 - cd1_2 * cd2_1; *pX = (cd2_2 * xr - cd1_2 * yr) / denom + (crpix1 - 1.0); *pY = (cd1_1 * yr - cd2_1 * xr) / denom + (crpix2 - 1.0); } else { *pX = -99.0; *pY = -99.0; } ccfree_((void **)&pCtype1); ccfree_((void **)&pCtype2); }