This section of the code demonstrates creation of images. Because every fits file must have a PHDU element, all the FITS constructors (ctors) instantiate a PHDU object. In the case of a new file, the default is to establish an empty HDU with BITPIX = 8 (BYTE_IMG). A current limitation of the code is that the data type of the PHDU cannot be replaced after the FITS file is created. Arguments to the FITS ctors allow the specification of the data type and the number of axes and their lengths. An image extension of type float is also written by calls in between the writes to the primary header demonstrating switch between HDUs during writes.
Note that in the example below data of type float is written to an image of type unsigned int, demonstrating both implicit type conversion and the cfitsio extension to unsigned data.
User keywords can be added to the PHDU after successful construction and these will both be accessible as container contents in the in-memory FITS object as well as being written to disk by cfitsio.
Images are represented by the standard library valarray template class which supports vectorized operations on numeric arrays (e.g. taking the square root of an array) and slicing techniques.
The code below also illustrates use of C++ standard library algorithms, and the facilities provided by the std::valarray class.
int writeImage()
{
long naxis = 2;
long naxes[2] = { 300, 200 };
std::auto_ptr<FITS> pFits(0);
try
{
const std::string fileName("!atestfil.fit");
pFits.reset( new FITS(fileName , USHORT_IMG , naxis , naxes ) );
}
catch (FITS::CantCreate)
{
return -1;
}
long& vectorLength = naxes[0];
long& numberOfRows = naxes[1];
long nelements(1);
nelements = std::accumulate(&naxes[0],&naxes[naxis],1,std::multiplies<long>());
std::vector<long> extAx(2,300);
string newName ("NEW-EXTENSION");
ExtHDU* imageExt = pFits->addImage(newName,FLOAT_IMG,extAx);
std::valarray<int> row(vectorLength);
for (long j = 0; j < vectorLength; ++j) row[j] = j;
std::valarray<int> array(nelements);
for (int i = 0; i < numberOfRows; ++i)
{
array[std::slice(vectorLength*static_cast<int>(i),vectorLength,1)] = row + i;
}
long extElements = std::accumulate(extAx.begin(),extAx.end(),1,std::multiplies<long>());
std::valarray<float> ranData(extElements);
const float PIBY (M_PI/150.);
for ( int jj = 0 ; jj < extElements ; ++jj)
{
float arg = PIBY*jj;
ranData[jj] = std::cos(arg);
}
long fpixel(1);
imageExt->write(fpixel,extElements,ranData);
long exposure(1500);
std::complex<float> omega(std::cos(2*M_PI/3.),std::sin(2*M_PI/3));
pFits->pHDU().addKey("EXPOSURE", exposure,"Total Exposure Time");
pFits->pHDU().addKey("OMEGA",omega," Complex cube root of 1 ");
pFits->pHDU().write(fpixel,nelements,array);
std::cout << pFits->pHDU() << std::endl;
return 0;
}