The interface supports writing to vector tables the following data structures: C-arrays (T*), std::vector<T> objects, std::valarray<T> objects, and std::vector<valarray<T> >. The last of these is the internal representation of the data.
The function below exercises the following functionality:
int writeBinary () //********************************************************************* // Create a BINARY table extension and write and manipulate vector rows //********************************************************************* { std::auto_ptr<FITS> pFits(0); try { const std::string fileName("atestfil.fit"); pFits.reset( new FITS(fileName,Write) ); } catch (CCfits::FITS::CantOpen) { return -1; } unsigned long rows(3); string hduName("TABLE_BINARY"); std::vector<string> colName(7,""); std::vector<string> colForm(7,""); std::vector<string> colUnit(7,""); colName[0] = "numbers"; colName[1] = "sequences"; colName[2] = "powers"; colName[3] = "big-integers"; colName[4] = "dcomplex-roots"; colName[5] = "fcomplex-roots"; colName[6] = "scalar-complex"; colForm[0] = "8A"; colForm[1] = "20J"; colForm[2] = "20D"; colForm[3] = "20V"; colForm[4] = "20M"; colForm[5] = "20C"; colForm[6] = "1M"; colUnit[0] = "magnets"; colUnit[1] = "bulbs"; colUnit[2] = "batteries"; colUnit[3] = "mulberries"; colUnit[4] = ""; colUnit[5] = ""; colUnit[6] = "pico boo"; std::vector<string> numbers(rows); const string num("NUMBER-"); for (size_t j = 0; j < rows; ++j) { #ifdef HAVE_STRSTREAM std::ostrstream pStr; #else std::ostringstream pStr; #endif pStr << num << j+1; numbers[j] = string(pStr.str()); } const size_t OFFSET(20); // write operations take in data as valarray<T>, vector<T> , and // vector<valarray<T> >, and T* C-arrays. Create arrays to exercise the C++ // containers. Check complex I/O for both float and double complex types. std::valarray<long> sequence(60); std::vector<long> sequenceVector(60); std::vector<std::valarray<long> > sequenceVV(3); for (size_t j = 0; j < rows; ++j) { sequence[OFFSET*j] = 1 + j; sequence[OFFSET*j+1] = 1 + j; sequenceVector[OFFSET*j] = sequence[OFFSET*j]; sequenceVector[OFFSET*j+1] = sequence[OFFSET*j+1]; // generate Fibonacci numbers. for (size_t i = 2; i < OFFSET; ++i) { size_t elt (OFFSET*j +i); sequence[elt] = sequence[elt-1] + sequence[elt - 2]; sequenceVector[elt] = sequence[elt] ; } sequenceVV[j].resize(OFFSET); sequenceVV[j] = sequence[std::slice(OFFSET*j,OFFSET,1)]; } std::valarray<unsigned long> unsignedData(60); unsigned long base (1 << 31); std::valarray<double> powers(60); std::vector<double> powerVector(60); std::vector<std::valarray<double> > powerVV(3); std::valarray<std::complex<double> > croots(60); std::valarray<std::complex<float> > fcroots(60); std::vector<std::complex<float> > fcroots_vector(60); std::vector<std::valarray<std::complex<float> > > fcrootv(3); // create complex data as 60th roots of unity. double PIBY = M_PI/30.; for (size_t j = 0; j < rows; ++j) { for (size_t i = 0; i < OFFSET; ++i) { size_t elt (OFFSET*j+i); unsignedData[elt] = sequence[elt]; croots[elt] = std::complex<double>(std::cos(PIBY*elt),std::sin(PIBY*elt)); fcroots[elt] = std::complex<float>(croots[elt].real(),croots[elt].imag()); double x = i+1; powers[elt] = pow(x,j+1); powerVector[elt] = powers[elt]; } powerVV[j].resize(OFFSET); powerVV[j] = powers[std::slice(OFFSET*j,OFFSET,1)]; } FITSUtil::fill(fcroots_vector,fcroots[std::slice(0,20,1)]); unsignedData += base; // syntax identical to Binary Table Table* newTable = pFits->addTable(hduName,rows,colName,colForm,colUnit); // numbers is a scalar column newTable->column(colName[0]).write(numbers,1); // write valarrays to vector column: note signature change newTable->column(colName[1]).write(sequence,rows,1); newTable->column(colName[2]).write(powers,rows,1); newTable->column(colName[3]).write(unsignedData,rows,1); newTable->column(colName[4]).write(croots,rows,1); newTable->column(colName[5]).write(fcroots,rows,3); newTable->column(colName[6]).write(fcroots_vector,1); // write vectors to column: note signature change newTable->column(colName[1]).write(sequenceVector,rows,4); newTable->column(colName[2]).write(powerVector,rows,4); std::cout << *newTable << std::endl; for (size_t j = 0; j < 3 ; ++j) { fcrootv[j].resize(20); fcrootv[j] = fcroots[std::slice(20*j,20,1)]; } // write vector<valarray> object to column. newTable->column(colName[1]).writeArrays(sequenceVV,7); newTable->column(colName[2]).writeArrays(powerVV,7); // create a new vector column in the Table newTable->addColumn(Tfloat,"powerSeq",20,"none"); // add data entries to it. newTable->column("powerSeq").writeArrays(powerVV,1); newTable->column("powerSeq").write(powerVector,rows,4); newTable->column("dcomplex-roots").write(croots,rows,4); newTable->column("powerSeq").write(sequenceVector,rows,7); std::cout << *newTable << std::endl; // delete one of the original columns. newTable->deleteColumn(colName[2]); // add a new set of rows starting after row 3. So we'll have 14 with // rows 4,5,6,7,8 blank newTable->insertRows(3,5); // now, in the new column, write 3 rows (sequenceVV.size() = 3). This // will place data in rows 3,4,5 of this column,overwriting them. newTable->column("powerSeq").writeArrays(sequenceVV,3); newTable->column("fcomplex-roots").writeArrays(fcrootv,3); // delete 3 rows starting with row 2. A Table:: method, so the same // code is called for all Table objects. We should now have 11 rows. newTable->deleteRows(2,3); //add a history string. This function call is in HDU:: so is identical //for all HDUs string hist("This file was created for testing CCfits write functionality"); hist += " it serves no other useful purpose. This particular part of the file was "; hist += " constructed to test the writeHistory() and writeComment() functionality" ; newTable->writeHistory(hist); // add a comment string. Use std::string method to change the text in the message // and write the previous junk as a comment. hist.insert(0, " COMMENT TEST "); newTable->writeComment(hist); // ... print the result. std::cout << *newTable << std::endl; return 0; }