source: Sophya/trunk/SophyaExt/FitsIOServer/swfitsdtable.cc@ 2865

Last change on this file since 2865 was 2865, checked in by ansari, 20 years ago

Ajout fichiers swfitsdtable.h .cc - classe SwFitsDataTable , Reza 2 Jan 2006

File size: 10.7 KB
Line 
1#include "swfitsdtable.h"
2#include "sopnamsp.h"
3#include "pexceptions.h"
4
5
6/*!
7 \class SOPHYA::SwFitsDataTable
8 \ingroup FitsIOServer
9 This class can be used to organize data in table (row-column) form.
10 Each column holds homogeneous data (same data type), while different
11 columns can be used for different data types
12 (integer, float, string ...).
13 A Fits file binary table is used as swap space.
14
15 \warning
16 - When creating a table, the output fits file (FitsInOutFile) must not be closed
17 (destroyed) before the SwFitsDataTable object is destroyed. The destructor writes
18 out any pending buffer to the fits file.
19 - It is not possible to make a complete (deep) copy of a SwFitsDataTable
20 Copy constructor and equal operator shares the data.
21
22 \sa SOPHYA::MuTyV
23 \sa SOPHYA::DataTableRow
24 \sa SOPHYA::DataTable
25 \sa SOPHYA::SwSegDataBlock SOPHYA::FitsDataSwapper
26
27 \code
28 #include "swppfdtable.h"
29 // ...
30 {
31 // ---- Creation of the table
32 // Create the swap stream
33 POutPersist so("myswtable.ppf");
34 SwFitsDataTable dt(so, 64);
35 // define table columns
36 dt.AddFloatColumn("X0_f");
37 dt.AddFloatColumn("X1_f");
38 dt.AddDoubleColumn("X0X0pX1X1_d");
39 // Fill the table
40 MuTyV x[5];
41 for(int i=0; i<63; i++) {
42 x[0] = (i%9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1];
43 dt.AddLine(x);
44 }
45 // Printing table info
46 cout << dt ;
47 // Swap out all data and write the table structure to the PPF stream
48 so << dt ;
49 // ....
50 }
51 {
52 // ---- Accessing information from a previously created table
53 SwFitsDataTable dt;
54 PInPersist si("myswtable.ppf");
55 si >> dt;
56 // Printing table info
57 cout << dt ;
58 }
59 \endcode
60*/
61//! Default constructor with optional specification of block (or segment) size
62SwFitsDataTable::SwFitsDataTable(sa_size_t segsz)
63 : BaseDataTable(segsz)
64{
65 mFgCreate = false;
66}
67/*! Constructor with the specification of the output swap stream -
68 and optional specification of block (or segment) size
69*/
70SwFitsDataTable::SwFitsDataTable(FitsInOutFile & os, sa_size_t segsz, bool fgcreate)
71 : BaseDataTable(segsz) ,
72 mSwF(os) , mFgCreate(fgcreate)
73{
74}
75//! copy constructor - shares the data
76SwFitsDataTable::SwFitsDataTable(SwFitsDataTable const & a)
77 : BaseDataTable(a.SegmentSize()),
78 mSwF(a.mSwF) , mFgCreate(a.mFgCreate)
79{
80 Share(a);
81}
82//! Destructor - Deletes / closes the input PPF swap stream
83SwFitsDataTable::~SwFitsDataTable()
84{
85 if (mFgCreate) SwapOutAll();
86}
87
88void SwFitsDataTable::Share(SwFitsDataTable const & a)
89{
90 // On recopie la taille de segment
91 mSegSz = a.SegmentSize();
92 if (a.NVar() == 0) return; // Table sans colonne
93
94 // On copie la structure de table
95 CopyStructure(a);
96
97 //
98 // Update nombre d'entree, ...
99 mNEnt = a.mNEnt;
100 mNSeg = a.mNSeg;
101 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
102
103 // mis a jour des tableax min-max
104 mMin = a.mMin;
105 mMax = a.mMax;
106 mMinMaxNEnt = a.mMinMaxNEnt;
107
108 // Et on partage les donnees des colonnes
109 for (size_t kk=0; kk<mNames.size(); kk++) {
110 sa_size_t sk = mNames[kk].ser;
111 sa_size_t ska = a.mNames[kk].ser;
112 switch (mNames[kk].type) {
113 case IntegerField :
114 mICols[sk] = a.mICols[ska];
115 break;
116 case LongField :
117 mLCols[sk] = a.mLCols[ska];
118 break;
119 case FloatField :
120 mFCols[sk] = a.mFCols[ska];
121 break;
122 case DoubleField :
123 case DateTimeField :
124 mDCols[sk] = a.mDCols[ska];
125 break;
126 case ComplexField :
127 mYCols[sk] = a.mYCols[ska];
128 break;
129 case DoubleComplexField :
130 mZCols[sk] = a.mZCols[ska];
131 break;
132 case StringField :
133 mSCols[sk] = a.mSCols[ska];
134 break;
135 default:
136 throw ForbiddenError("SwFitsDataTable::Share() : unknown column type ");
137 break;
138 }
139 }
140}
141void SwFitsDataTable::SwapOutAll() const
142{
143 // Et on vide les buffers de swap
144 for (size_t kk=0; kk<mNames.size(); kk++) {
145 sa_size_t sk = mNames[kk].ser;
146 switch (mNames[kk].type) {
147 case IntegerField :
148 mICols[sk].SwapOutBuffer();
149 break;
150 case LongField :
151 mLCols[sk].SwapOutBuffer();
152 break;
153 case FloatField :
154 mFCols[sk].SwapOutBuffer();
155 break;
156 case DoubleField :
157 case DateTimeField :
158 mDCols[sk].SwapOutBuffer();
159 break;
160 case ComplexField :
161 mYCols[sk].SwapOutBuffer();
162 break;
163 case DoubleComplexField :
164 mZCols[sk].SwapOutBuffer();
165 break;
166 case StringField :
167 mSCols[sk].SwapOutBuffer();
168 break;
169 default:
170 throw ForbiddenError("SwFitsDataTable::Share() : unknown column type ");
171 break;
172 }
173 }
174}
175
176void SwFitsDataTable::Clear()
177{
178 if ( (NVar() == 0) && (NEntry() == 0)) return;
179 mNEnt = 0;
180 mNSeg = 0;
181 if (mVarD) delete[] mVarD;
182 mVarD = NULL;
183 if (mVarMTV) delete[] mVarMTV;
184 mVarMTV = NULL;
185 mNames.clear();
186 if (mInfo) delete mInfo;
187 mInfo = NULL;
188 mMin.clear();
189 mMax.clear();
190 mMinMaxNEnt.clear();
191 mIColsP.clear();
192 mLColsP.clear();
193 mFColsP.clear();
194 mDColsP.clear();
195 mYColsP.clear();
196 mZColsP.clear();
197 mSColsP.clear();
198
199 mIColIdx.clear();
200 mLColIdx.clear();
201 mFColIdx.clear();
202 mDColIdx.clear();
203 mYColIdx.clear();
204 mZColIdx.clear();
205 mSColIdx.clear();
206
207 mICols.clear();
208 mLCols.clear();
209 mFCols.clear();
210 mDCols.clear();
211 mYCols.clear();
212 mZCols.clear();
213 mSCols.clear();
214
215 /*
216 mISwapper.clear();
217 mLSwapper.clear();
218 mFSwapper.clear();
219 mDSwapper.clear();
220 mYSwapper.clear();
221 mZSwapper.clear();
222 mSSwapper.clear();
223 */
224}
225
226
227/*!
228 Implements the action defined in the BaseDataTable interface.
229 In the current implementation, throws an exception (ParmError)
230 if the table contains some data already.
231*/
232sa_size_t SwFitsDataTable::AddColumn(FieldType ft, string const & cnom)
233{
234 return AddColRd(ft, cnom, NULL);
235}
236/*!
237 Adds a column to the table. If swpos != NULL, the swapper is initialized
238 for reading data from the fits file. This method can be called
239 by FitsHandler<BaseDataTable> with non zero swpos.
240*/
241sa_size_t SwFitsDataTable::AddColRd(FieldType ft, string const & cnom,
242 vector<int_8> const * swpos)
243{
244 if (NEntry() > 0)
245 throw ParmError("SwFitsDataTable::AddColumn() Table contains already data ");
246 CheckColName(cnom);
247 sa_size_t ser;
248 sa_size_t idx = NVar();
249 switch (ft) {
250 case IntegerField :
251 {
252 ser = mICols.size();
253 FITSDataSwapper<int_4> ISwapper(mSwF, idx+1);
254 if (swpos)
255 mICols.push_back(SwSegDataBlock<int_4>(ISwapper, *swpos, mSegSz));
256 else
257 mICols.push_back(SwSegDataBlock<int_4>(ISwapper, mSegSz));
258 mIColIdx.push_back(idx);
259 mIColsP.push_back(NULL);
260 for(sa_size_t kk=0; kk<mICols.size(); kk++)
261 mIColsP[kk] = &(mICols[kk]);
262 break;
263 }
264 case LongField :
265 {
266 ser = mLCols.size();
267 FITSDataSwapper<int_8> LSwapper(mSwF, idx+1);
268 if (swpos)
269 mLCols.push_back(SwSegDataBlock<int_8>(LSwapper, *swpos, mSegSz));
270 else
271 mLCols.push_back(SwSegDataBlock<int_8>(LSwapper, mSegSz));
272 mLColIdx.push_back(idx);
273 mLColsP.push_back(NULL);
274 for(sa_size_t kk=0; kk<mLCols.size(); kk++)
275 mLColsP[kk] = &(mLCols[kk]);
276 break;
277 }
278 case FloatField :
279 {
280 ser = mFCols.size();
281 FITSDataSwapper<r_4> FSwapper(mSwF, idx+1);
282 if (swpos)
283 mFCols.push_back(SwSegDataBlock<r_4>(FSwapper, *swpos, mSegSz));
284 else
285 mFCols.push_back(SwSegDataBlock<r_4>(FSwapper, mSegSz));
286 mFColIdx.push_back(idx);
287 mFColsP.push_back(NULL);
288 for(sa_size_t kk=0; kk<mFCols.size(); kk++)
289 mFColsP[kk] = &(mFCols[kk]);
290 break;
291 }
292 case DoubleField :
293 case DateTimeField :
294 {
295 ser = mDCols.size();
296 FITSDataSwapper<r_8> DSwapper(mSwF, idx+1);
297 if (swpos)
298 mDCols.push_back(SwSegDataBlock<r_8>(DSwapper, *swpos, mSegSz));
299 else
300 mDCols.push_back(SwSegDataBlock<r_8>(DSwapper, mSegSz));
301 mDColIdx.push_back(idx);
302 mDColsP.push_back(NULL);
303 for(sa_size_t kk=0; kk<mDCols.size(); kk++)
304 mDColsP[kk] = &(mDCols[kk]);
305 break;
306 }
307 case ComplexField :
308 {
309 ser = mYCols.size();
310 FITSDataSwapper< complex<r_4> > YSwapper(mSwF, idx+1);
311 if (swpos)
312 mYCols.push_back(SwSegDataBlock< complex<r_4> >(YSwapper, *swpos, mSegSz));
313 else
314 mYCols.push_back(SwSegDataBlock< complex<r_4> >(YSwapper, mSegSz));
315 mYColIdx.push_back(idx);
316 mYColsP.push_back(NULL);
317 for(sa_size_t kk=0; kk<mYCols.size(); kk++)
318 mYColsP[kk] = &(mYCols[kk]);
319 break;
320 }
321 case DoubleComplexField :
322 {
323 ser = mZCols.size();
324 FITSDataSwapper< complex<r_8> > ZSwapper(mSwF, idx+1);
325 if (swpos)
326 mZCols.push_back(SwSegDataBlock< complex<r_8> >(ZSwapper, *swpos, mSegSz));
327 else
328 mZCols.push_back(SwSegDataBlock< complex<r_8> >(ZSwapper, mSegSz));
329 mZColIdx.push_back(idx);
330 mZColsP.push_back(NULL);
331 for(sa_size_t kk=0; kk<mZCols.size(); kk++)
332 mZColsP[kk] = &(mZCols[kk]);
333 break;
334 }
335 case StringField :
336 {
337 ser = mSCols.size();
338 FITSDataSwapper< string > SSwapper(mSwF, idx+1);
339 if (swpos)
340 mSCols.push_back(SwSegDataBlock< string >(SSwapper, *swpos, mSegSz));
341 else
342 mSCols.push_back(SwSegDataBlock< string >(SSwapper, mSegSz));
343 mSColIdx.push_back(idx);
344 mSColsP.push_back(NULL);
345 for(sa_size_t kk=0; kk<mSCols.size(); kk++)
346 mSColsP[kk] = &(mSCols[kk]);
347 break;
348 }
349 default:
350 throw ParmError("SwFitsDataTable::AddColumn() unknown field type ");
351 break;
352 }
353 colst col;
354 col.nom = cnom;
355 col.type = ft;
356 col.ser = ser;
357 mNames.push_back(col);
358 // On est oblige de calculer les min-max lors du remplissage
359 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
360 mMin.push_back(9.E39);
361 mMax.push_back(-9.E39);
362 mMinMaxNEnt.push_back(0);
363
364 return NVar();
365}
366
367//! Adds a line (or row to the table) with r_8* input data.
368/*!
369 The min/max values for each column is updated, in addition
370 to the actions performed by the base class AddLine()
371*/
372sa_size_t SwFitsDataTable::AddLine(const r_8* data)
373{
374 // On est oblige de calculer les min-max lors du remplissage
375 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
376 for(sa_size_t k=0; k<NVar(); k++) {
377 double x = data[k];
378 if (x < mMin[k]) mMin[k] = x;
379 if (x > mMax[k]) mMax[k] = x;
380 mMinMaxNEnt[k]++;
381 }
382 return BaseDataTable::AddLine(data);
383}
384
385//! Adds a line (or row to the table) with input data as an array of MuTyV
386/*!
387 The min/max values for each column is updated, in addition
388 to the actions performed by the base class AddLine()
389*/
390sa_size_t SwFitsDataTable::AddLine(const MuTyV * data)
391{
392 // On est oblige de calculer les min-max lors du remplissage
393 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
394 for(sa_size_t k=0; k<NVar(); k++) {
395 double x = (double)data[k];
396 if (x < mMin[k]) mMin[k] = x;
397 if (x > mMax[k]) mMax[k] = x;
398 mMinMaxNEnt[k]++;
399 }
400 return BaseDataTable::AddLine(data);
401}
402
Note: See TracBrowser for help on using the repository browser.