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

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

Modifs code BaseDataTable , DataTable et SwPPFDataTable pour la prise en compte
de colonnes de type complex (complex<r_4> ComplexField et complex<r_8> DoubleComplexField ) Reza , 2 Nov 2005

File size: 10.2 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 call to the SwPPFDataTable object.
20 - It is not possible to make a complete (deep) copy of a table SwPPFDataTable
21 Copy constructor and equal operator shares the data.
22 - Although the destructor DOES NOT save the
23 table object itself to the memory. You have to use the << operator on the
24 output PPF stream being used as swap
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 mDSwapper.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 mDCols[sk] = a.mDCols[ska];
166 break;
167 case ComplexField :
168 mYCols[sk] = a.mYCols[ska];
169 break;
170 case DoubleComplexField :
171 mZCols[sk] = a.mZCols[ska];
172 break;
173 case StringField :
174 mSCols[sk] = a.mSCols[ska];
175 break;
176 default:
177 throw ForbiddenError("SwPPFDataTable::Share() : unknown column type ");
178 break;
179 }
180 }
181}
182void SwPPFDataTable::SwapOutAll() const
183{
184 // Et on vide les buffers de swap
185 for (size_t kk=0; kk<mNames.size(); kk++) {
186 sa_size_t sk = mNames[kk].ser;
187 switch (mNames[kk].type) {
188 case IntegerField :
189 mICols[sk].SwapOutBuffer();
190 break;
191 case LongField :
192 mLCols[sk].SwapOutBuffer();
193 break;
194 case FloatField :
195 mFCols[sk].SwapOutBuffer();
196 break;
197 case DoubleField :
198 mDCols[sk].SwapOutBuffer();
199 break;
200 case ComplexField :
201 mYCols[sk].SwapOutBuffer();
202 break;
203 case DoubleComplexField :
204 mZCols[sk].SwapOutBuffer();
205 break;
206 case StringField :
207 mSCols[sk].SwapOutBuffer();
208 break;
209 default:
210 throw ForbiddenError("SwPPFDataTable::Share() : unknown column type ");
211 break;
212 }
213 }
214}
215
216void SwPPFDataTable::Clear()
217{
218 if ( (NVar() == 0) && (NEntry() == 0)) return;
219 mNEnt = 0;
220 mNSeg = 0;
221 if (mVarD) delete[] mVarD;
222 mVarD = NULL;
223 if (mVarMTV) delete[] mVarMTV;
224 mVarMTV = NULL;
225 mNames.clear();
226 if (mInfo) delete mInfo;
227 mInfo = NULL;
228 mMin.clear();
229 mMax.clear();
230 mMinMaxNEnt.clear();
231 mIColsP.clear();
232 mLColsP.clear();
233 mFColsP.clear();
234 mDColsP.clear();
235 mYColsP.clear();
236 mZColsP.clear();
237 mSColsP.clear();
238
239 mIColIdx.clear();
240 mLColIdx.clear();
241 mFColIdx.clear();
242 mDColIdx.clear();
243 mYColIdx.clear();
244 mZColIdx.clear();
245 mSColIdx.clear();
246
247 mICols.clear();
248 mLCols.clear();
249 mFCols.clear();
250 mDCols.clear();
251 mYCols.clear();
252 mZCols.clear();
253 mSCols.clear();
254}
255
256
257/*!
258 Implements the action defined in the BaseDataTable interface.
259 In the current implementation, throws an exception (ParmError)
260 if the table contains some data already.
261*/
262sa_size_t SwPPFDataTable::AddColumn(FieldType ft, string const & cnom)
263{
264 if (NEntry() > 0)
265 throw ParmError("SwPPFDataTable::AddColumn() Table contains already data ");
266 CheckColName(cnom);
267 sa_size_t ser;
268 sa_size_t idx = NVar();
269 switch (ft) {
270 case IntegerField :
271 ser = mICols.size();
272 mICols.push_back(SwSegDataBlock<int_4>(mISwapper, mSegSz));
273 mIColIdx.push_back(idx);
274 mIColsP.push_back(NULL);
275 for(sa_size_t kk=0; kk<mICols.size(); kk++)
276 mIColsP[kk] = &(mICols[kk]);
277 break;
278 case LongField :
279 ser = mLCols.size();
280 mLCols.push_back(SwSegDataBlock<int_8>(mLSwapper, mSegSz));
281 mLColIdx.push_back(idx);
282 mLColsP.push_back(NULL);
283 for(sa_size_t kk=0; kk<mLCols.size(); kk++)
284 mLColsP[kk] = &(mLCols[kk]);
285 break;
286 case FloatField :
287 ser = mFCols.size();
288 mFCols.push_back(SwSegDataBlock<r_4>(mFSwapper, mSegSz));
289 mFColIdx.push_back(idx);
290 mFColsP.push_back(NULL);
291 for(sa_size_t kk=0; kk<mFCols.size(); kk++)
292 mFColsP[kk] = &(mFCols[kk]);
293 break;
294 case DoubleField :
295 ser = mDCols.size();
296 mDCols.push_back(SwSegDataBlock<r_8>( mDSwapper,mSegSz));
297 mDColIdx.push_back(idx);
298 mDColsP.push_back(NULL);
299 for(sa_size_t kk=0; kk<mDCols.size(); kk++)
300 mDColsP[kk] = &(mDCols[kk]);
301 break;
302 case ComplexField :
303 ser = mYCols.size();
304 mYCols.push_back(SwSegDataBlock< complex<r_4> >(mYSwapper, mSegSz));
305 mYColIdx.push_back(idx);
306 mYColsP.push_back(NULL);
307 for(sa_size_t kk=0; kk<mYCols.size(); kk++)
308 mYColsP[kk] = &(mYCols[kk]);
309 break;
310 case DoubleComplexField :
311 ser = mZCols.size();
312 mZCols.push_back(SwSegDataBlock< complex<r_8> >(mZSwapper, mSegSz));
313 mZColIdx.push_back(idx);
314 mZColsP.push_back(NULL);
315 for(sa_size_t kk=0; kk<mZCols.size(); kk++)
316 mZColsP[kk] = &(mZCols[kk]);
317 break;
318 case StringField :
319 ser = mDCols.size();
320 mSCols.push_back(SwSegDataBlock<string>(mSSwapper, mSegSz));
321 mSColIdx.push_back(idx);
322 mSColsP.push_back(NULL);
323 for(sa_size_t kk=0; kk<mSCols.size(); kk++)
324 mSColsP[kk] = &(mSCols[kk]);
325 break;
326 default:
327 throw ParmError("SwPPFDataTable::AddColumn() unknown field type ");
328 break;
329 }
330 colst col;
331 col.nom = cnom;
332 col.type = ft;
333 col.ser = ser;
334 mNames.push_back(col);
335 // On est oblige de calculer les min-max lors du remplissage
336 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
337 mMin.push_back(0.);
338 mMax.push_back(0.);
339 mMinMaxNEnt.push_back(0);
340
341 return NVar();
342}
343
344//! Adds a line (or row to the table) with r_8* input data.
345/*!
346 The min/max values for each column is updated, in addition
347 to the actions performed by the base class AddLine()
348*/
349sa_size_t SwPPFDataTable::AddLine(const r_8* data)
350{
351 // On est oblige de calculer les min-max lors du remplissage
352 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
353 for(sa_size_t k=0; k<NVar(); k++) {
354 double x = data[k];
355 if (x < mMin[k]) mMin[k] = x;
356 if (x > mMax[k]) mMax[k] = x;
357 mMinMaxNEnt[k]++;
358 }
359 return BaseDataTable::AddLine(data);
360}
361
362//! Adds a line (or row to the table) with input data as an array of MuTyV
363/*!
364 The min/max values for each column is updated, in addition
365 to the actions performed by the base class AddLine()
366*/
367sa_size_t SwPPFDataTable::AddLine(const MuTyV * data)
368{
369 // On est oblige de calculer les min-max lors du remplissage
370 // On ne peut pas en effet 'relire' le swap pendant l'ecriture
371 for(sa_size_t k=0; k<NVar(); k++) {
372 double x = (double)data[k];
373 if (x < mMin[k]) mMin[k] = x;
374 if (x > mMax[k]) mMax[k] = x;
375 mMinMaxNEnt[k]++;
376 }
377 return BaseDataTable::AddLine(data);
378}
379
Note: See TracBrowser for help on using the repository browser.