#include "swfitsdtable.h" #include "sopnamsp.h" #include "pexceptions.h" /*! \class SOPHYA::SwFitsDataTable \ingroup FitsIOServer This class can be used to organize data in table (row-column) form. Each column holds homogeneous data (same data type), while different columns can be used for different data types (integer, float, string ...). A Fits file binary table is used as swap space. \warning - When creating a table, the output fits file (FitsInOutFile) must not be closed (destroyed) before the SwFitsDataTable object is destroyed. The destructor writes out any pending buffer to the fits file. - It is not possible to make a complete (deep) copy of a SwFitsDataTable Copy constructor and equal operator shares the data. \sa SOPHYA::MuTyV \sa SOPHYA::DataTableRow \sa SOPHYA::DataTable \sa SOPHYA::SwSegDataBlock SOPHYA::FitsDataSwapper \code #include "swppfdtable.h" // ... { // ---- Creation of the table // Create the swap stream POutPersist so("myswtable.ppf"); SwFitsDataTable dt(so, 64); // define table columns dt.AddFloatColumn("X0_f"); dt.AddFloatColumn("X1_f"); dt.AddDoubleColumn("X0X0pX1X1_d"); // Fill the table MuTyV x[5]; for(int i=0; i<63; i++) { x[0] = (i%9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1]; dt.AddLine(x); } // Printing table info cout << dt ; // Swap out all data and write the table structure to the PPF stream so << dt ; // .... } { // ---- Accessing information from a previously created table SwFitsDataTable dt; PInPersist si("myswtable.ppf"); si >> dt; // Printing table info cout << dt ; } \endcode */ //! Default constructor with optional specification of block (or segment) size SwFitsDataTable::SwFitsDataTable(sa_size_t segsz) : BaseDataTable(segsz) { mFgCreate = false; } /*! Constructor with the specification of the output swap stream - and optional specification of block (or segment) size */ SwFitsDataTable::SwFitsDataTable(FitsInOutFile & os, sa_size_t segsz, bool fgcreate) : BaseDataTable(segsz) , mSwF(os) , mFgCreate(fgcreate) { } //! copy constructor - shares the data SwFitsDataTable::SwFitsDataTable(SwFitsDataTable const & a) : BaseDataTable(a.SegmentSize()), mSwF(a.mSwF) , mFgCreate(a.mFgCreate) { Share(a); } //! Destructor - Deletes / closes the input PPF swap stream SwFitsDataTable::~SwFitsDataTable() { if (mFgCreate) SwapOutAll(); } void SwFitsDataTable::Share(SwFitsDataTable const & a) { // On recopie la taille de segment mSegSz = a.SegmentSize(); if (a.NVar() == 0) return; // Table sans colonne // On copie la structure de table CopyStructure(a); // // Update nombre d'entree, ... mNEnt = a.mNEnt; mNSeg = a.mNSeg; if (a.mInfo) mInfo = new DVList(*(a.mInfo)); // mis a jour des tableax min-max mMin = a.mMin; mMax = a.mMax; mMinMaxNEnt = a.mMinMaxNEnt; // Et on partage les donnees des colonnes for (size_t kk=0; kk with non zero swpos. */ sa_size_t SwFitsDataTable::AddColRd(FieldType ft, string const & cnom, vector const * swpos) { if (NEntry() > 0) throw ParmError("SwFitsDataTable::AddColumn() Table contains already data "); CheckColName(cnom); sa_size_t ser; sa_size_t idx = NVar(); switch (ft) { case IntegerField : { ser = mICols.size(); FITSDataSwapper ISwapper(mSwF, idx+1); if (swpos) mICols.push_back(SwSegDataBlock(ISwapper, *swpos, mSegSz)); else mICols.push_back(SwSegDataBlock(ISwapper, mSegSz)); mIColIdx.push_back(idx); mIColsP.push_back(NULL); for(sa_size_t kk=0; kk LSwapper(mSwF, idx+1); if (swpos) mLCols.push_back(SwSegDataBlock(LSwapper, *swpos, mSegSz)); else mLCols.push_back(SwSegDataBlock(LSwapper, mSegSz)); mLColIdx.push_back(idx); mLColsP.push_back(NULL); for(sa_size_t kk=0; kk FSwapper(mSwF, idx+1); if (swpos) mFCols.push_back(SwSegDataBlock(FSwapper, *swpos, mSegSz)); else mFCols.push_back(SwSegDataBlock(FSwapper, mSegSz)); mFColIdx.push_back(idx); mFColsP.push_back(NULL); for(sa_size_t kk=0; kk DSwapper(mSwF, idx+1); if (swpos) mDCols.push_back(SwSegDataBlock(DSwapper, *swpos, mSegSz)); else mDCols.push_back(SwSegDataBlock(DSwapper, mSegSz)); mDColIdx.push_back(idx); mDColsP.push_back(NULL); for(sa_size_t kk=0; kk > YSwapper(mSwF, idx+1); if (swpos) mYCols.push_back(SwSegDataBlock< complex >(YSwapper, *swpos, mSegSz)); else mYCols.push_back(SwSegDataBlock< complex >(YSwapper, mSegSz)); mYColIdx.push_back(idx); mYColsP.push_back(NULL); for(sa_size_t kk=0; kk > ZSwapper(mSwF, idx+1); if (swpos) mZCols.push_back(SwSegDataBlock< complex >(ZSwapper, *swpos, mSegSz)); else mZCols.push_back(SwSegDataBlock< complex >(ZSwapper, mSegSz)); mZColIdx.push_back(idx); mZColsP.push_back(NULL); for(sa_size_t kk=0; kk SSwapper(mSwF, idx+1); if (swpos) mSCols.push_back(SwSegDataBlock< string >(SSwapper, *swpos, mSegSz)); else mSCols.push_back(SwSegDataBlock< string >(SSwapper, mSegSz)); mSColIdx.push_back(idx); mSColsP.push_back(NULL); for(sa_size_t kk=0; kk mMax[k]) mMax[k] = x; mMinMaxNEnt[k]++; } return BaseDataTable::AddLine(data); } //! Adds a line (or row to the table) with input data as an array of MuTyV /*! The min/max values for each column is updated, in addition to the actions performed by the base class AddLine() */ sa_size_t SwFitsDataTable::AddLine(const MuTyV * data) { // On est oblige de calculer les min-max lors du remplissage // On ne peut pas en effet 'relire' le swap pendant l'ecriture for(sa_size_t k=0; k mMax[k]) mMax[k] = x; mMinMaxNEnt[k]++; } return BaseDataTable::AddLine(data); }