source: Sophya/trunk/Poubelle/DPC:FitsIOServer/NTools/ntuple.cc@ 658

Last change on this file since 658 was 658, checked in by ansari, 26 years ago

no message

File size: 12.4 KB
Line 
1#include <stdio.h>
2#include <string.h>
3
4#include "strutil.h"
5#include "perrors.h"
6#include "ntuple.h"
7
8
9#define BADVAL -1.e19
10#define LENNAME 8
11#define LENNAME1 (LENNAME+1)
12
13//++
14// Class NTuple
15// Lib Outils++
16// include ntuple.h
17//
18// Classe de ntuples
19//--
20//++
21// Links Parents
22// PPersist
23// NTupleInterface
24//--
25
26/* --Methode-- */
27//++
28NTuple::NTuple()
29//
30// Createur par defaut
31//--
32{
33mNVar = mNEnt = mBlk = mNBlk = 0;
34mVar = NULL;
35mVarD = NULL;
36mNames = NULL;
37mInfo = NULL;
38}
39
40
41//++
42NTuple::NTuple(int nvar, char** noms, int blk)
43//
44// Createur d'un ntuple de `nvar' variables dont les
45// noms sont dans le tableau de cahines de caracteres `noms'
46// avec `blk' d'evenements par blocks.
47//--
48{
49mNVar = mNEnt = mBlk = mNBlk = 0;
50mVar = NULL;
51mVarD = NULL;
52mNames = NULL;
53mInfo = NULL;
54if (nvar <= 0) THROW(sizeMismatchErr);
55mNVar = nvar;
56mVar = new r_4[nvar];
57mVarD = new r_8[nvar];
58if (blk < 10) blk = 10;
59mBlk = blk;
60// On prend des noms de LENNAME char pour le moment
61mNames = new char[nvar*LENNAME1];
62r_4* pt = new r_4[nvar*blk];
63mNBlk = 1;
64mPtr.push_back(pt);
65int i;
66for(i=0; i<nvar; i++)
67 { strncpy(mNames+i*LENNAME1, noms[i], LENNAME);
68 mNames[i*LENNAME1+LENNAME] = '\0'; }
69return;
70}
71
72// cmv 8/10/99
73//++
74NTuple::NTuple(const NTuple& NT)
75//
76// Createur par copie (clone).
77//--
78: mNVar(0), mNEnt(0), mBlk(0), mNBlk(0)
79, mVar(NULL), mVarD(NULL), mNames(NULL), mInfo(NULL)
80{
81if(NT.mNVar<=0) return; // cas ou NT est cree par defaut
82mNVar = NT.mNVar;
83mBlk = NT.mBlk;
84mVar = new r_4[NT.mNVar];
85mVarD = new r_8[NT.mNVar];
86mNames = new char[NT.mNVar*LENNAME1];
87
88int i;
89r_4* pt = new r_4[mNVar*mBlk];
90mNBlk = 1; mPtr.push_back(pt);
91
92for(i=0;i<mNVar;i++) strcpy(mNames+i*LENNAME1,NT.NomIndex(i));
93
94if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
95
96if(NT.mNEnt<=0) return;
97for(i=0;i<NT.mNEnt;i++) {r_4* x=NT.GetVec(i,NULL); Fill(x);}
98
99return;
100}
101
102/* --Methode-- */
103//++
104NTuple::NTuple(char *flnm)
105//
106// Createur lecture fichier ppersist.
107//--
108{
109mNVar = mNEnt = mBlk = mNBlk = 0;
110mVar = NULL;
111mVarD = NULL;
112mNames = NULL;
113mInfo = NULL;
114PInPersist s(flnm);
115ObjFileIO<NTuple> fiont(this);
116fiont.Read(s);
117}
118
119/* --Methode-- */
120NTuple::~NTuple()
121{
122Clean();
123}
124
125/* --Methode-- */
126void NTuple::Clean()
127{
128if (mVar) delete[] mVar;
129if (mVarD) delete[] mVarD;
130if (mNames) delete[] mNames;
131if (mInfo) delete mInfo;
132int i;
133if(mNBlk>0) for(i=0; i<mNBlk; i++) delete[] mPtr[i];
134mPtr.erase(mPtr.begin(), mPtr.end());
135mNVar = mNEnt = mBlk = mNBlk = 0;
136mVar = NULL;
137mVarD = NULL;
138mNames = NULL;
139mInfo = NULL;
140return;
141}
142
143/* --Methode-- cmv 08/10/99 */
144//++
145NTuple& NTuple::operator = (const NTuple& NT)
146//
147// Operateur egal (clone).
148//--
149{
150if(this == &NT) return *this;
151Clean();
152if(NT.mNVar<=0) return *this; // cas ou NT est cree par defaut
153mNVar = NT.mNVar;
154mBlk = NT.mBlk;
155mVar = new r_4[NT.mNVar];
156mVarD = new r_8[NT.mNVar];
157mNames = new char[NT.mNVar*LENNAME1];
158
159int i;
160r_4* pt = new r_4[mNVar*mBlk];
161mNBlk = 1; mPtr.push_back(pt);
162
163for(i=0;i<mNVar;i++) strcpy(mNames+i*LENNAME1,NT.NomIndex(i));
164
165if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
166
167if(NT.mNEnt<=0) return *this;
168for(i=0;i<NT.mNEnt;i++) {r_4* x=NT.GetVec(i,NULL); Fill(x);}
169
170// En fait il faudrait un createur par copie qui partage les donnees
171// quand l'objet est temporaire... trop complique A FAIRE ! cmv.
172return *this;
173}
174
175/* --Methode-- */
176//++
177void NTuple::Fill(r_4* x)
178//
179// Remplit le ntuple avec le tableau cd reels `x'.
180//--
181{
182int numb = mNEnt/mBlk;
183if (numb >= mNBlk) {
184 r_4* pt = new r_4[mNVar*mBlk];
185 mNBlk++;
186 mPtr.push_back(pt);
187}
188int offb = mNEnt-numb*mBlk;
189memcpy((mPtr[numb]+offb*mNVar), x, mNVar*sizeof(r_4));
190mNEnt++;
191return;
192}
193
194
195/* --Methode-- */
196//++
197float NTuple::GetVal(int n, int k) const
198//
199// Retourne la valeur de la variable `k' de l'evenement `n'.
200//--
201{
202if (n >= mNEnt) return(BADVAL);
203if ( (k < 0) || (k >= mNVar) ) return(BADVAL);
204int numb = n/mBlk;
205int offb = n-numb*mBlk;
206return(*(mPtr[numb]+offb*mNVar+k));
207}
208
209
210/* --Methode-- */
211//++
212int NTuple::IndexNom(const char* nom) const
213//
214// Retourne le numero de la variable de nom `nom'.
215//--
216{
217int i;
218for(i=0; i<mNVar; i++)
219 if ( strcmp(nom, mNames+i*LENNAME1) == 0) return(i);
220return(-1);
221}
222
223
224static char nomretour[2*LENNAME1];
225/* --Methode-- */
226//++
227char* NTuple::NomIndex(int k) const
228//
229// Retourne le nom de la variable numero 'k'
230//--
231{
232nomretour[0] = '\0';
233if ((k >= 0) && (k < mNVar)) strcpy(nomretour, mNames+k*LENNAME1);
234return(nomretour);
235}
236
237
238/* --Methode-- */
239//++
240r_4* NTuple::GetVec(int n, r_4* ret) const
241//
242// Retourne l'evenement `n' dans le vecteur `ret'.
243//--
244{
245int i;
246if (ret == NULL) ret = mVar;
247if (n >= mNEnt) {
248 for(i=0; i<mNVar; i++) ret[i] = BADVAL;
249 return(ret);
250}
251
252int numb = n/mBlk;
253int offb = n-numb*mBlk;
254memcpy(ret, (mPtr[numb]+offb*mNVar), mNVar*sizeof(r_4));
255return(ret);
256}
257
258/* --Methode-- */
259//++
260r_8* NTuple::GetVecD(int n, r_8* ret) const
261//
262// Retourne l'evenement `n' dans le vecteur `ret'.
263//--
264{
265int i;
266if (ret == NULL) ret = mVarD;
267float * fr = GetVec(n);
268for(i=0; i<mNVar; i++) ret[i] = fr[i];
269return(ret);
270}
271
272
273
274/* --Methode-- */
275//++
276DVList& NTuple::Info()
277//
278// Renvoie une référence sur l'objet DVList Associé
279//--
280{
281if (mInfo == NULL) mInfo = new DVList;
282return(*mInfo);
283}
284
285/* --Methode-- */
286//++
287void NTuple::Print(int num, int nmax) const
288//
289// Imprime `nmax' evenements a partir du numero `num'.
290//--
291{
292int i,j;
293
294printf("Num ");
295for(i=0; i<mNVar; i++) printf("%8s ", mNames+i*LENNAME1);
296putchar('\n');
297
298if (nmax <= 0) nmax = 1;
299if (num < 0) num = 0;
300nmax += num;
301if (nmax > mNEnt) nmax = mNEnt;
302for(i=num; i<nmax; i++) {
303 GetVec(i, NULL);
304 printf("%6d ", i);
305 for(j=0; j<mNVar; j++) printf("%8g ", (float)mVar[j]);
306 putchar('\n');
307}
308return;
309}
310
311/* --Methode-- */
312//++
313void NTuple::Show(ostream& os) const
314//
315// Imprime l'information generale sur le ntuple.
316//--
317{
318os << "NTuple: NVar= " << mNVar << " NEnt=" << mNEnt
319 << " (Blk Sz,Nb= " << mBlk << " ," << mNBlk << ")\n";
320os << " Variables Min Max \n";
321int i;
322double min, max;
323char buff[128];
324for(i=0; i<mNVar; i++) {
325 GetMinMax(i, min, max);
326 sprintf(buff, "%3d %16s %10lg %10lg \n", i, mNames+i*LENNAME1, min, max);
327 os << (string)buff ;
328 }
329os << endl;
330}
331
332
333/* --Methode-- */
334//++
335int NTuple::FillFromASCIIFile(string const& fn, float defval)
336//
337// Remplit le ntuple a partir d'un fichier ASCII.
338// Renvoie le nombre de lignes ajoutees.
339//--
340{
341if (NbColumns() < 1) {
342 cout << "NTuple::FillFromASCIIFile() Ntuple has " << NbColumns() << " columns" << endl;
343 return(-1);
344 }
345FILE * fip = fopen(fn.c_str(), "r");
346if (fip == NULL) {
347 cout << "NTuple::FillFromASCIIFile() Error opening file " << fn << endl;
348 return(-2);
349 }
350
351char lineb[4096];
352char *line;
353char buff[64];
354char* ccp;
355int i,j,l,kk;
356int postab, posb;
357float* xv = new float[NbColumns()];
358
359int nlread = 0;
360int nvar = NbColumns();
361// On boucle sur toutes les lignes
362while (fgets(lineb,4096,fip) != NULL) {
363 lineb[4095] = '\0';
364 j = 0; line = lineb;
365// On enleve les espaces et tab de debut
366 while ( (line[j] != '\0') && ((line[j] == ' ') || (line[j] == '\t')) ) j++;
367 line = lineb+j;
368// Il faut que le premier caractere non-espace soit un digit, ou + ou - ou .
369 if (!( isdigit(line[0]) || (line[0] == '+') || (line[0] == '-') || (line[0] == '.') )) continue;
370 ccp = line;
371 for(kk=0; kk<nvar; kk++) xv[kk] = defval;
372 for(kk=0; kk<nvar; kk++) {
373// Les mots sont separes par des espaces ou des tab
374 postab = posc(ccp, '\t' );
375 posb = posc(ccp, ' ' );
376 if (postab >= 0) {
377 if (posb < 0) posb = postab;
378 else if (postab < posb) posb = postab;
379 }
380 if (posb >= 0) ccp[posb] = '\0';
381 if ( isdigit(line[0]) || (line[0] == '+') || (line[0] == '-') || (line[0] == '.') )
382 xv[kk] = atof(ccp);
383 if (posb < 0) break;
384 ccp += posb+1; j = 0;
385 while ( (ccp[j] != '\0') && ((ccp[j] == ' ') || (ccp[j] == '\t')) ) j++;
386 ccp += j;
387 }
388 Fill(xv);
389 nlread++;
390 }
391
392delete[] xv;
393cout << "NTuple::FillFromASCIIFile( " << fn << ") " << nlread << " fill from file " << endl;
394return(nlread);
395}
396
397
398// ------- Implementation de l interface NTuple ---------
399
400/* --Methode-- */
401uint_4 NTuple::NbLines() const
402{
403return(NEntry());
404}
405/* --Methode-- */
406uint_4 NTuple::NbColumns() const
407{
408return(NVar());
409}
410
411/* --Methode-- */
412r_8 * NTuple::GetLineD(int n) const
413{
414return(GetVecD(n));
415}
416
417/* --Methode-- */
418r_8 NTuple::GetCell(int n, int k) const
419{
420return(GetVal(n, k));
421}
422
423/* --Methode-- */
424r_8 NTuple::GetCell(int n, string const & nom) const
425{
426return(GetVal(n, nom.c_str()));
427}
428
429/* --Methode-- */
430//++
431void NTuple::GetMinMax(int k, double& min, double& max) const
432//
433// Retourne le minimum et le maximum de la variable `k'.
434//--
435{
436min = 9.e19; max = -9.e19;
437if ( (k < 0) || (k >= mNVar) ) return;
438int jb,ib,i;
439double x;
440i=0;
441for(jb=0; jb< mNBlk; jb++)
442 for(ib=0; ib< mBlk; ib++) {
443 if (i >= mNEnt) break;
444 i++;
445 x = *(mPtr[jb]+ib*mNVar+k);
446 if(i==1) {min = x; max = x;}
447 if (x < min) min = x;
448 if (x > max) max = x;
449 }
450return;
451}
452
453/* --Methode-- */
454void NTuple::GetMinMax(string const & nom, double& min, double& max) const
455{
456GetMinMax(IndexNom(nom.c_str()), min, max);
457}
458
459/* --Methode-- */
460int NTuple::ColumnIndex(string const & nom) const
461{
462return(IndexNom(nom.c_str()));
463}
464
465/* --Methode-- */
466string NTuple::ColumnName(int k) const
467{
468return(NomIndex(k));
469}
470
471/* --Methode-- */
472//++
473string NTuple::VarList_C(const char* nomx) const
474//
475// Retourne une chaine de caracteres avec la declaration des noms de
476// variables. si "nomx!=NULL" , des instructions d'affectation
477// a partir d'un tableau "nomx[i]" sont ajoutees.
478//--
479{
480string rets="";
481int i;
482for(i=0; i<mNVar; i++) {
483 if ( (i%5 == 0) && (i > 0) ) rets += ";";
484 if (i%5 == 0) rets += "\ndouble ";
485 else rets += ",";
486 rets += mNames+i*LENNAME1;
487 }
488rets += "; \n";
489if (nomx) {
490 char buff[256];
491 for(i=0; i<mNVar; i++) {
492 sprintf(buff,"%s=%s[%d]; ", mNames+i*LENNAME1, nomx, i);
493 rets += buff;
494 if ( (i%3 == 0) && (i > 0) ) rets += "\n";
495 }
496 }
497
498return(rets);
499}
500
501
502/* --Methode-- */
503//++
504string NTuple::LineHeaderToString() const
505// Retourne une chaine de caracteres avec la liste des noms de
506// variables, utilisables pour une impression
507//--
508{
509char buff[32];
510string rets=" Num ";
511for(int i=0; i<mNVar; i++) {
512 sprintf(buff, "%8s ", mNames+i*LENNAME1);
513 rets += buff;
514 }
515rets += '\n';
516return(rets);
517}
518
519/* --Methode-- */
520//++
521string NTuple::LineToString(int n) const
522// Retourne une chaine de caracteres avec le contenu de la ligne "n"
523// utilisable pour une impression
524//--
525{
526char buff[32];
527double* val;
528val = GetLineD(n);
529sprintf(buff,"%6d: ",n);
530string rets=buff;
531int i;
532for(i=0; i<mNVar; i++) {
533 sprintf(buff, "%8.3g ", val[i]);
534 rets += buff;
535 }
536rets += '\n';
537return(rets);
538}
539
540
541/* --Methode-- */
542//++
543void ObjFileIO<NTuple>::WriteSelf(POutPersist& s) const
544//
545// Ecriture ppersist du ntuple.
546//--
547{
548char strg[256];
549if (dobj->mInfo) sprintf(strg, "NVar=%6d NEnt=%9d BlkSz=%6d NBlk=%6d HasInfo",
550 (int)dobj->mNVar, (int)dobj->mNEnt, (int)dobj->mBlk, (int)dobj->mNBlk);
551else sprintf(strg, "NVar=%6d NEnt=%9d BlkSz=%6d NBlk=%6d ",
552 (int)dobj->mNVar, (int)dobj->mNEnt, (int)dobj->mBlk, (int)dobj->mNBlk);
553s.PutLine(strg);
554s.PutI4(dobj->mNVar);
555s.PutBytes(dobj->mNames, dobj->mNVar*LENNAME1);
556s.PutI4(dobj->mNEnt);
557s.PutI4(dobj->mBlk);
558s.PutI4(dobj->mNBlk);
559if (dobj->mInfo) s << (*(dobj->mInfo));
560int jb;
561for(jb=0; jb<dobj->mNBlk; jb++)
562 s.PutR4s(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk);
563return;
564}
565
566/* --Methode-- */
567//++
568void ObjFileIO<NTuple>::ReadSelf(PInPersist& s)
569//
570// Lecture ppersist du ntuple.
571//--
572{
573
574dobj->Clean();
575
576char strg[256];
577s.GetLine(strg, 255);
578// Pour savoir s'il y avait un DVList Info associe
579bool hadinfo = false;
580if (strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0) hadinfo = true;
581
582s.GetI4(dobj->mNVar);
583dobj->mNames = new char[dobj->mNVar*LENNAME1];
584dobj->mVar = new r_4[dobj->mNVar];
585dobj->mVarD = new r_8[dobj->mNVar];
586s.GetBytes(dobj->mNames, dobj->mNVar*LENNAME1);
587s.GetI4(dobj->mNEnt);
588s.GetI4(dobj->mBlk);
589s.GetI4(dobj->mNBlk);
590
591if (hadinfo) { // Lecture eventuelle du DVList Info
592 if (dobj->mInfo == NULL) dobj->mInfo = new DVList;
593 s >> (*(dobj->mInfo));
594 }
595
596int jb;
597for(jb=0; jb<dobj->mNBlk; jb++) {
598 r_4* pt = new r_4[dobj->mNVar*dobj->mBlk];
599 dobj->mPtr.push_back(pt);
600 s.GetR4s(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk);
601}
602
603}
604
605#ifdef __CXX_PRAGMA_TEMPLATES__
606#pragma define_template ObjFileIO<NTuple>
607#endif
608
609#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
610template class ObjFileIO<NTuple>;
611#endif
Note: See TracBrowser for help on using the repository browser.