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

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

1/ Prise en charge champ de type DateTimeField ds BaseDataTable , DataTable, SwPPFDataTable
2/ Methodes BaseDataTable completees - en particulier Print/WriteASCII, et
decodage de fichiers ASCII

Reza, 8 Nov 2005

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