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

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

Ajout de la classe DataTableRow , modifs/ajout interface BaseDataTable - Reza 21/11/2005

File size: 10.4 KB
Line 
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
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
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
21 Copy constructor and equal operator shares the data.
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.
25
26 \sa SOPHYA::MuTyV
27 \sa SOPHYA::DataTableRow
28 \sa SOPHYA::DataTable
29 \sa SOPHYA::SwSegDataBlock SOPHYA::PPFDataSwapper
30
31 \code
32 #include "swppfdtable.h"
33 // ...
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
40 dt.AddFloatColumn("X0_f");
41 dt.AddFloatColumn("X1_f");
42 dt.AddDoubleColumn("X0X0pX1X1_d");
43 // Fill the table
44 MuTyV x[5];
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];
47 dt.AddLine(x);
48 }
49 // Printing table info
50 cout << dt ;
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 }
63 \endcode
64*/
65//! Default constructor with optional specification of block (or segment) size
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) ,
76 mSwOut(&os), mSwIn(NULL),
77 mISwapper(os), mLSwapper(os), mFSwapper(os), mDSwapper(os),
78 mYSwapper(os), mZSwapper(os), mSSwapper(os)
79{
80}
81//! Protected constructor for creation from a swap stream
82SwPPFDataTable::SwPPFDataTable(PInPersist & is, sa_size_t segsz)
83 : BaseDataTable(segsz) ,
84 mSwOut(NULL), mSwIn(NULL)
85{
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);
93 mYSwapper.SetInStream(*pis);
94 mZSwapper.SetInStream(*pis);
95 mSSwapper.SetInStream(*pis);
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}
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}
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;
125 mYSwapper = a.mYSwapper;
126 mZSwapper = a.mZSwapper;
127 mSSwapper = a.mSSwapper;
128
129 mSwOut = a.mSwOut;
130 mSwIn = a.mSwIn;
131 if (mSwIn) mSwIn->refcnt++; // comptage de reference pour le stream input
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 :
166 case DateTimeField :
167 mDCols[sk] = a.mDCols[ska];
168 break;
169 case ComplexField :
170 mYCols[sk] = a.mYCols[ska];
171 break;
172 case DoubleComplexField :
173 mZCols[sk] = a.mZCols[ska];
174 break;
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 :
200 case DateTimeField :
201 mDCols[sk].SwapOutBuffer();
202 break;
203 case ComplexField :
204 mYCols[sk].SwapOutBuffer();
205 break;
206 case DoubleComplexField :
207 mZCols[sk].SwapOutBuffer();
208 break;
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();
238 mYColsP.clear();
239 mZColsP.clear();
240 mSColsP.clear();
241
242 mIColIdx.clear();
243 mLColIdx.clear();
244 mFColIdx.clear();
245 mDColIdx.clear();
246 mYColIdx.clear();
247 mZColIdx.clear();
248 mSColIdx.clear();
249
250 mICols.clear();
251 mLCols.clear();
252 mFCols.clear();
253 mDCols.clear();
254 mYCols.clear();
255 mZCols.clear();
256 mSCols.clear();
257}
258
259
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*/
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 :
298 case DateTimeField :
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;
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;
322 case StringField :
323 ser = mSCols.size();
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
341 mMin.push_back(9.E39);
342 mMax.push_back(-9.E39);
343 mMinMaxNEnt.push_back(0);
344
345 return NVar();
346}
347
348//! Adds a line (or row to the table) with r_8* input data.
349/*!
350 The min/max values for each column is updated, in addition
351 to the actions performed by the base class AddLine()
352*/
353sa_size_t SwPPFDataTable::AddLine(const r_8* data)
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 }
363 return BaseDataTable::AddLine(data);
364}
365
366//! Adds a line (or row to the table) with input data as an array of MuTyV
367/*!
368 The min/max values for each column is updated, in addition
369 to the actions performed by the base class AddLine()
370*/
371sa_size_t SwPPFDataTable::AddLine(const MuTyV * data)
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 }
381 return BaseDataTable::AddLine(data);
382}
383
Note: See TracBrowser for help on using the repository browser.