source: Sophya/trunk/SophyaLib/HiStats/datatable.cc@ 2688

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

1/ Ajout de la classe DataTable (les nouveaux super-ntuple) - La classe
DataTable est l'implementation memoire de la classe de base
BaseDataTable qui sera decline bientot en version swap PPF et FITS
2/ Initialisation PPF I/O de DataTable ds histinit
3/ Ajout fichier datatable.h ds histats.h , MAJ Makefile

Reza 25 Avril 2005

File size: 9.3 KB
Line 
1#include "datatable.h"
2#include "sopnamsp.h"
3#include "strutil.h"
4#include "pexceptions.h"
5#include "fiosegdb.h"
6
7
8/*!
9 \class SOPHYA::DataTable
10 \ingroup HiStats
11 This class can be used to organize data in table (row-column) form.
12 Each column holds homogeneous data (same data type), while different
13 columns can be used for different data types (integer, float, string ...)
14 \sa SOPHYA::MuTyV
15 \sa SOPHYA::BaseDataTable
16 \sa SOPHYA::ObjFileIO<DataTable>
17
18 \code
19 #include "datatable.h"
20 // ...
21 DataTable dt(64);
22 dt.AddFloatColumn("X0_f");
23 dt.AddFloatColumn("X1_f");
24 dt.AddDoubleColumn("X0X0pX1X1_d");
25 double x[5];
26 for(int i=0; i<63; i++) {
27 x[0] = (i%9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1];
28 dt.AddLine(x);
29 }
30 // Printing table info
31 cout << dt ;
32 // Saving object into a PPF file
33 POutPersist po("dtable.ppf");
34 po << dt ;
35 \endcode
36*/
37
38
39//! Default constructor - optional specification of block (or segment) size
40DataTable::DataTable(sa_size_t segsz)
41 : BaseDataTable(segsz)
42{
43}
44
45//! copy constructor - shares the data
46DataTable::DataTable(DataTable const & a, bool share)
47 : BaseDataTable(a.SegmentSize())
48{
49 if (share) Share(a);
50 else Clone(a);
51 mNEnt = a.mNEnt;
52 mNSeg = a.mNSeg;
53 if (a.mInfo) mInfo = new DVList(*(a.mInfo));
54}
55
56void DataTable::Share(DataTable const & a)
57{
58 // On copie la structure de table
59 CopyStructure(a);
60 // Et on partage les donnees des colonnes
61 for (size_t kk=0; kk<mNames.size(); kk++) {
62 sa_size_t sk = mNames[kk].ser;
63 sa_size_t ska = a.mNames[kk].ser;
64 switch (mNames[kk].type) {
65 case IntegerField :
66 mICols[sk].Share(a.mICols[ska]);
67 break;
68 case LongField :
69 mLCols[sk].Share(a.mLCols[ska]);
70 break;
71 case FloatField :
72 mFCols[sk].Share(a.mFCols[ska]);
73 break;
74 case DoubleField :
75 mDCols[sk].Share(a.mDCols[ska]);
76 break;
77 case StringField :
78 mSCols[sk].Share(a.mSCols[ska]);
79 break;
80 default:
81 throw ForbiddenError("DataTable::Share() : unknown column type ");
82 break;
83 }
84 }
85}
86
87void DataTable::Clone(DataTable const & a)
88{
89 // On copie la structure de table
90 CopyStructure(a);
91 // Et on partage les donnees des colonnes
92 for (size_t kk=0; kk<mNames.size(); kk++) {
93 sa_size_t sk = mNames[kk].ser;
94 sa_size_t ska = a.mNames[kk].ser;
95 switch (mNames[kk].type) {
96 case IntegerField :
97 mICols[sk].Clone(a.mICols[ska], true);
98 break;
99 case LongField :
100 mLCols[sk].Clone(a.mLCols[ska], true);
101 break;
102 case FloatField :
103 mFCols[sk].Clone(a.mFCols[ska], true);
104 break;
105 case DoubleField :
106 mDCols[sk].Clone(a.mDCols[ska], true);
107 break;
108 case StringField :
109 mSCols[sk].Clone(a.mSCols[ska], true);
110 break;
111 default:
112 throw ForbiddenError("DataTable::Clone() : unknown column type ");
113 break;
114 }
115 }
116}
117
118void DataTable::Clear()
119{
120 if ( (NVar() == 0) && (NEntry() == 0)) return;
121 mNEnt = 0;
122 mNSeg = 0;
123 if (mVarD) delete[] mVarD;
124 mVarD = NULL;
125 if (mVarMTV) delete[] mVarMTV;
126 mVarMTV = NULL;
127 mNames.clear();
128 if (mInfo) delete mInfo;
129 mInfo = NULL;
130 mMin.clear();
131 mMax.clear();
132 mMinMaxNEnt.clear();
133 mIColsP.clear();
134 mLColsP.clear();
135 mFColsP.clear();
136 mDColsP.clear();
137 mSColsP.clear();
138
139 mIColIdx.clear();
140 mLColIdx.clear();
141 mFColIdx.clear();
142 mDColIdx.clear();
143 mSColIdx.clear();
144
145 mICols.clear();
146 mLCols.clear();
147 mFCols.clear();
148 mDCols.clear();
149 mSCols.clear();
150}
151
152
153sa_size_t DataTable::AddColumn(FieldType ft, string const & cnom)
154{
155 if (NEntry() > 0)
156 throw ParmError("DataTable::AddColumn() Table contains already data ");
157 CheckColName(cnom);
158 sa_size_t ser;
159 sa_size_t idx = NVar();
160 switch (ft) {
161 case IntegerField :
162 ser = mICols.size();
163 mICols.push_back(SegDataBlock<int_4>(mSegSz));
164 mIColIdx.push_back(idx);
165 mIColsP.push_back(NULL);
166 for(sa_size_t kk=0; kk<mICols.size(); kk++)
167 mIColsP[kk] = &(mICols[kk]);
168 break;
169 case LongField :
170 ser = mLCols.size();
171 mLCols.push_back(SegDataBlock<int_8>(mSegSz));
172 mLColIdx.push_back(idx);
173 mLColsP.push_back(NULL);
174 for(sa_size_t kk=0; kk<mLCols.size(); kk++)
175 mLColsP[kk] = &(mLCols[kk]);
176 break;
177 case FloatField :
178 ser = mFCols.size();
179 mFCols.push_back(SegDataBlock<r_4>(mSegSz));
180 mFColIdx.push_back(idx);
181 mFColsP.push_back(NULL);
182 for(sa_size_t kk=0; kk<mFCols.size(); kk++)
183 mFColsP[kk] = &(mFCols[kk]);
184 break;
185 case DoubleField :
186 ser = mDCols.size();
187 mDCols.push_back(SegDataBlock<r_8>(mSegSz));
188 mDColIdx.push_back(idx);
189 mDColsP.push_back(NULL);
190 for(sa_size_t kk=0; kk<mDCols.size(); kk++)
191 mDColsP[kk] = &(mDCols[kk]);
192 break;
193 case StringField :
194 ser = mDCols.size();
195 mSCols.push_back(SegDataBlock<string>(mSegSz));
196 mSColIdx.push_back(idx);
197 mSColsP.push_back(NULL);
198 for(sa_size_t kk=0; kk<mSCols.size(); kk++)
199 mSColsP[kk] = &(mSCols[kk]);
200 break;
201 default:
202 throw ParmError("DataTable::AddColumn() unknown field type ");
203 break;
204 }
205 colst col;
206 col.nom = cnom;
207 col.type = ft;
208 col.ser = ser;
209 mNames.push_back(col);
210 return NVar();
211}
212
213/*!
214 \class SOPHYA::ObjFileIO<DataTable>
215 \ingroup HiStats
216 Persistence (serialisation) handler for class DataTable
217*/
218/* --Methode-- */
219DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
220void ObjFileIO<DataTable>::WriteSelf(POutPersist& s) const
221// Serialisation en ecriture du DataTable sur stream PPF
222{
223 if (dobj == NULL)
224 throw NullPtrError("ObjFileIO<DataTable>::WriteSelf() NULL dobj pointer ");
225 //------- On ecrit 3 uint_4 ....
226 // [0]: Numero de version ;
227 // [1] : bit1 non nul -> has info
228 // [2] : reserve
229 uint_4 itab[3];
230 itab[0] = 1; // Numero de version a 1
231 itab[1] = itab[2] = 0;
232 if (dobj->mInfo) itab[1] = 1;
233 s.Put(itab, 3);
234
235 //-------- Ecriture de segment size, nb de colonnes, nb de lignes ...
236 // [0] : SegmentSize() [1] : NVar()
237 // [2] : NEntry() [3] : NbSegments()
238 uint_8 ltab[5];
239 ltab[0] = dobj->SegmentSize();
240 ltab[1] = dobj->NVar();
241 ltab[2] = dobj->NEntry();
242 ltab[3] = dobj->NbSegments();
243 ltab[4] = 0;
244 s.Put(ltab, 5);
245
246 //------ Ecriture du nom et type des colonnes
247 for(sa_size_t k=0; k<dobj->NVar(); k++) {
248 uint_2 typ = dobj->mNames[k].type;
249 s.Put(typ);
250 s.Put(dobj->mNames[k].nom);
251 }
252 //------- Ecriture du DVList Info() associe, si existant
253 if (dobj->mInfo) s << (*(dobj->mInfo));
254
255 //------- Ecriture des SegDataBlock<T>
256 for (size_t kk=0; kk<dobj->mNames.size(); kk++) {
257 sa_size_t sk = dobj->mNames[kk].ser;
258 switch (dobj->mNames[kk].type) {
259 case BaseDataTable::IntegerField :
260 s << dobj->mICols[sk];
261 break;
262 case BaseDataTable::LongField :
263 s << dobj->mLCols[sk];
264 break;
265 case BaseDataTable::FloatField :
266 s << dobj->mFCols[sk];
267 break;
268 case BaseDataTable::DoubleField :
269 s << dobj->mDCols[sk];
270 break;
271 case BaseDataTable::StringField :
272 s << dobj->mSCols[sk];
273 break;
274 default:
275 throw ForbiddenError("ObjFileIO<DataTable>::WriteSelf() : unknown column type ");
276 break;
277 }
278 }
279 return;
280}
281
282/* --Methode-- */
283DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
284void ObjFileIO<DataTable>::ReadSelf(PInPersist& s)
285// Serialisation en lecture du DataTable sur stream PPF
286{
287 // ------- On lit les 3 premiers uint_4
288 // [0]: Numero de version ;
289 // [1] : bit1 non nul -> has info
290 // [2] : reserve
291 uint_4 itab[3] = {0,0,0};
292 s.Get(itab, 3);
293 bool hadinfo = false;
294 if ((itab[1]&1) == 1) hadinfo = true;
295
296 // -------- Lecture de segment size, nb de colonnes, nb de lignes ...
297 // [0] : SegmentSize() [1] : NVar()
298 // [2] : NEntry() [3] : NbSegments()
299 uint_8 ltab[5] = {0,0,0,0,0};
300 s.Get(ltab, 5);
301 if (dobj == NULL) dobj = new DataTable(ltab[0]);
302 else { dobj->Clear(); dobj->mSegSz = ltab[0]; }
303 // -------- Lecture nom/type colonnes et allocation des colonnes
304 uint_2 typ;
305 string cnom;
306 for(uint_8 k=0; k<ltab[1]; k++) {
307 s.Get(typ);
308 s.Get(cnom);
309 BaseDataTable::FieldType ft = (BaseDataTable::FieldType)typ;
310 dobj->AddColumn(ft, cnom);
311 }
312 // ------- Lecture du DVList Info() associe, si necessaire
313 if (hadinfo) { // Lecture eventuelle du DVList Info
314 if (dobj->mInfo == NULL) dobj->mInfo = new DVList;
315 s >> (*(dobj->mInfo));
316 }
317 // ------- Mise a jour des champs Nb d'entrees, nb segments ...
318 dobj->mNEnt = ltab[2];
319 dobj->mNSeg = ltab[3];
320 // ------- Lecture des SegDataBlock<T>
321 for (size_t kk=0; kk<dobj->mNames.size(); kk++) {
322 sa_size_t sk = dobj->mNames[kk].ser;
323 switch (dobj->mNames[kk].type) {
324 case BaseDataTable::IntegerField :
325 s >> dobj->mICols[sk];
326 break;
327 case BaseDataTable::LongField :
328 s >> dobj->mLCols[sk];
329 break;
330 case BaseDataTable::FloatField :
331 s >> dobj->mFCols[sk];
332 break;
333 case BaseDataTable::DoubleField :
334 s >> dobj->mDCols[sk];
335 break;
336 case BaseDataTable::StringField :
337 s >> dobj->mSCols[sk];
338 break;
339 default:
340 throw ForbiddenError("ObjFileIO<DataTable>::ReadSelf() : unknown column type ");
341 break;
342 }
343 }
344return;
345}
346
347#ifdef __CXX_PRAGMA_TEMPLATES__
348#pragma define_template ObjFileIO<DataTable>
349#endif
350
351#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
352template class ObjFileIO<DataTable>;
353#endif
Note: See TracBrowser for help on using the repository browser.