source: Sophya/trunk/SophyaLib/HiStats/swppfdtable.cc@ 2891

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

Corrections AddRow() au lieu de AddLine ds swppfdtable.h .cc - Reza 9/01/2006

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