GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
EGConverter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2004-2006 by Olivier Stezowski & Christophe Theisen *
3  * stezow(AT)ipnl.in2p3.fr, christophe.theisen(AT)cea.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
23 #ifndef GW_EGCONVERTER_H
24 #include "EGConverter.h"
25 #endif
26 
27 #ifndef ROOT_TRegexp
28 #include <TRegexp.h>
29 #endif
30 
31 #ifndef ROOT_TSystem
32 #include <TSystem.h>
33 #endif
34 
35 #ifndef ROOT_TSystemDirectory
36 #include <TSystemDirectory.h>
37 #endif
38 
39 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
40 #include "TList.h"
41 #endif
42 
43 #include <iostream>
44 using namespace std;
45 
46 namespace { EGConverter gEGConverter; } // prototype ONLY use to create a new DB system
47 
48 //_________________________________________________________________
49 EGConverter::EGConverter(const char *name) : HistoConverter(name)
50 {
51  // default type for gpsi
52  fType = "eg";
53  CheckDirectory(name);
54  fStreamIN.clear(); fCycle = '_'; // because ; is not supported by all file systems
55  fLog.GetProcessName() = "EGConverter";
56 }
57 
58 //_________________________________________________________________
60 {
61  // default type for gpsi
62  fType = "eg";
63  fFileExt = ".eg";
64  fOptions = "";
65  // add this interface to the DB service
66  AddPrototype(GetType(),this);
67 }
68 
69 //_________________________________________________________________
71 {
72  CloseEG();
73 }
74 
75 //_________________________________________________________________
76 HistoConverter *EGConverter::NewDB(const char *name) const
77 {
78  return new EGConverter(name);
79 }
80 
81 //_________________________________________________________________
82 void EGConverter::PrintHeader() const
83 {
84  cout << "magic number : " << fHeader.magic_number << endl;
85  cout << "spectrum name : " << fHeader.spectrum_name << endl;
86  cout << "creation date : " << fHeader.creation_date << endl;
87  cout << "modifi. date : " << fHeader.modification_date << endl;
88  cout << "fold : " << fHeader.fold << endl;
89  cout << "size : " << fHeader.count_free_space << endl;
90 
91  unsigned long i;
92  for(i=0; i < fHeader.fold; i++){
93  printf("dim %d : init = %4d range = %4d \n",
94  (int)i,(int)fHeader.base_info[i],(int)fHeader.range[i]);
95  }
96 
97  printf("layout = %1d type = %1d pointer %d \n",
98  (int)fHeader.data_array_descriptor1[0],
99  (int)fHeader.data_array_descriptor1[1],
100  (int)fHeader.data_array_descriptor1[4]);
101 
102  /*
103  printf("FIP : ");
104  for(i=0; i<32; i++)
105  printf("%2d : %d \n",i,fHeader.fip[i]);
106 
107  printf("Anotation pointer : \n");
108  for(i=0; i<8; i++)
109  printf("%d : %d \n",i,fHeader.anotation_pointer[i]);
110 
111  printf("Calibration pointer : \n");
112  for(i=0; i<8; i++)
113  printf("%d : %d \n",i,fHeader.calibration_pointer[i]);
114 
115  printf("Efficiency pointer : \n");
116  for(i=0; i<8; i++)
117  printf("%d : %d \n",i,fHeader.efficiency_pointer[i]);
118 
119  printf("Data array desciptor 1: \n");
120  for(i=0; i<5 ; i++)
121  printf("%1d : %d \n",i,fHeader.data_array_descriptor1[i]);
122  printf("Data array desciptor 2: \n");
123  for(i=0; i<5 ; i++)
124  printf("%1d : %d \n",i,fHeader.data_array_descriptor2[i]);
125 
126 
127 
128  printf("base_address_string_space = %d \n",
129  fHeader.base_address_string_space);
130  printf("string_free_space = %d \n",
131  fHeader.string_free_space);
132  printf("top_string_space = %d \n",
133  fHeader.top_string_space);
134  printf("base_address_count_space = %d \n",
135  fHeader.base_address_count_space);
136  printf("count_free_space = %d \n",
137  fHeader.count_free_space);
138  printf("top_count_space = %d \n",
139  fHeader.top_count_space);
140 
141 
142  printf("Unused : \n");
143  for(i=0; i<20; i++)
144  printf("%2d : %d \n",i,fHeader.unused[i]);
145  */
146 }
147 
148 //_________________________________________________________________
149 void EGConverter::InitHeader(int dimx, int dimy, HeaderEG &header, const char *name, int type)
150 {
151  time_t cl;
152  char str[27];
153  int i;
154 
155  header.magic_number = 0x189c5e39;
156  header.magic_number = ULong((char*)&header.magic_number);
157  header.version = 1;
158  header.version = ULong((char*)&header.version);
159  strncpy(header.spectrum_name,name,31);
160  header.spectrum_name[31] = 0;
161 
162  if (dimy == 1)
163  header.fold = 1;
164  else
165  header.fold = 2;
166 
167  header.fold = ULong((char*)&header.fold);
168 
169  time(&cl);
170  strcpy(str, ctime(&cl));
171  if (str[8] == ' ')
172  header.creation_date[0] = header.modification_date[0] = '0';
173  else
174  header.creation_date[0] = header.modification_date[0] = str[8];
175  header.creation_date[1] = header.modification_date[1] = str[9];
176  header.creation_date[2] = header.modification_date[2] = '-';
177  for (i = 3; i < 6; ++i)
178  header.creation_date[i] = header.modification_date[i] = str[i+1];
179  header.creation_date[6] = header.modification_date[6] = '-';
180  for (i = 7; i < 11; ++i)
181  header.creation_date[i] = header.modification_date[i] = str[i+13];
182  header.creation_date[11] = header.modification_date[11] = ' ';
183  for (i = 12; i < 20; ++i)
184  header.creation_date[i] = header.modification_date[i] = str[i-1];
185 
186  for(i=0; i<8; i++){
187  header.base_info[i] = 0xFFFFFFFF;
188  header.base_info[i] = ULong((char*)&header.base_info[i]);
189  header.range[i] = 0xFFFFFFFF;
190  header.range[i] = ULong((char*)&header.range[i]);
191  }
192 
193  switch(dimy){
194  case 1:
195  header.base_info[0] = 0;
196  header.base_info[0] = ULong((char*)&header.base_info[0]);
197  header.range[0] = dimx;
198  header.range[0] = ULong((char*)&header.range[0]);
199  break;
200  default:
201  header.base_info[0] = 0;
202  header.base_info[0] = ULong((char*)&header.base_info[0]);
203  header.range[0] = dimx;
204  header.range[0] = ULong((char*)&header.range[0]);
205  header.base_info[1] = 0;
206  header.base_info[1] = ULong((char*)&header.base_info[1]);
207  header.range[1] = dimy;
208  header.range[1] = ULong((char*)&header.range[1]);
209  }
210 
211  for(i=0; i<32; i++)
212  header.fip[i] = 0xFFFFFFFF;
213 
214  header.fip[0] = 0;
215  for(i=0; i<32; i++)
216  header.fip[i] = ULong((char*)&header.fip[i]);
217 
218  for(i=0; i<8; i++){
219  header.anotation_pointer[i] = -1;
220  header.anotation_pointer[i] = Long((char*)&header.anotation_pointer[i]);
221  header.calibration_pointer[i] = -1;
222  header.calibration_pointer[i] = Long((char*)&header.calibration_pointer[i]);
223  header.efficiency_pointer[i] = -1;
224  header.efficiency_pointer[i] = Long((char*)&header.efficiency_pointer[i]);
225  }
226 
227  header.data_array_descriptor1[0] = 0;
228  header.data_array_descriptor1[0] = ULong((char*)&header.data_array_descriptor1[0]);
229  header.data_array_descriptor1[1] = type;
230  header.data_array_descriptor1[1] = ULong((char*)&header.data_array_descriptor1[1]);
231  header.data_array_descriptor2[1] = type;
232  header.data_array_descriptor2[1] = ULong((char*)&header.data_array_descriptor2[1]);
233  header.data_array_descriptor2[4] = 0xFFFFFFFF;
234  header.data_array_descriptor2[4] = ULong((char*)&header.data_array_descriptor2[5]);
235 
236  switch(type){
237  case 0: // unsigned char
238  case 1: // char
239  header.count_free_space = dimx*dimy;
240  header.top_count_space = dimx*dimy -1;
241  header.base_address_string_space = dimx*dimy + 512;
242  break;
243  case 2: // unsigned short
244  case 3: // short
245  header.count_free_space = dimx*dimy*2;
246  header.top_count_space = dimx*dimy*2 -1;
247  header.base_address_string_space = dimx*dimy*2 + 512;
248  break;
249  case 4: // unsigned int
250  case 5: // int
251  case 6: // float
252  header.count_free_space = dimx*dimy*4;
253  header.top_count_space = dimx*dimy*4 -1;
254  header.base_address_string_space = dimx*dimy*4 + 512;
255  break;
256  }
257 
258  header.count_free_space = ULong((char*)&header.count_free_space);
259  header.top_count_space = ULong((char*)&header.top_count_space);
260  header.base_address_string_space = Long((char*)&header.base_address_string_space);
261 
262  header.base_address_count_space = 512;
263  header.base_address_count_space = ULong((char*)&header.base_address_count_space);
264  header.top_string_space = 1023;
265  header.top_string_space = ULong((char*)&header.top_string_space);
266  header.string_free_space = 256;
267  header.string_free_space = Long((char*)&header.string_free_space);
268 
269 }
270 
271 //_________________________________________________________________
272 void EGConverter::ReadHeader(char *buffer, HeaderEG &header)
273 {
274 
275  int offset, i;
276 
277  offset = 0;
278  header.magic_number = ULong(buffer+offset);
279 
280  offset = 4;
281  header.version = ULong(buffer+offset);
282 
283  offset = 8;
284  for ( i = 0; i < 32; i++ )
285  header.spectrum_name[i] = buffer[offset+i];
286 
287  offset = 40;
288  header.fold = ULong(buffer+offset);
289 
290  offset = 44;
291  for ( i = 0; i < 20; i++ )
292  header.creation_date[i] = buffer[offset+i];
293 
294  offset = 64;
295  for ( i = 0; i < 20; i++ )
296  header.modification_date[i] = buffer[offset+i];
297 
298  offset = 84;
299  for ( i = 0; i < 8; i++ )
300  header.base_info[i] = ULong(buffer+offset+sizeof(unsigned long)*i);
301 
302  offset = 116;
303  for ( i = 0; i < 8; i++ )
304  header.range[i] = ULong(buffer+offset+sizeof(unsigned long)*i);
305 
306  offset = 148;
307  for ( i = 0; i < 32; i++ )
308  header.fip[i] = ULong(buffer+offset+sizeof(unsigned long)*i);
309 
310  offset = 276;
311  for ( i = 0; i < 8; i++ )
312  header.anotation_pointer[i] = Int(buffer+offset+sizeof(int)*i);
313 
314  offset = 308;
315  for ( i = 0; i < 8; i++ )
316  header.calibration_pointer[i] = Int(buffer+offset+sizeof(int)*i);
317 
318  offset = 340;
319  for ( i = 0; i < 8; i++ )
320  header.efficiency_pointer[i] = Int(buffer+offset+sizeof(int)*i);
321 
322  offset = 372;
323  for ( i = 0; i < 5; i++ )
324  header.data_array_descriptor1[i] = ULong(buffer+offset+sizeof(unsigned long)*i);
325 
326  offset = 392;
327  for ( i = 0; i < 5; i++ )
328  header.data_array_descriptor2[i] = ULong(buffer+offset+sizeof(unsigned long)*i);
329 
330  offset = 412;
331  header.base_address_string_space = Int(buffer+offset);
332 
333  offset = 416;
334  header.string_free_space = Int(buffer+offset);
335 
336  offset = 420;
337  header.top_string_space = ULong(buffer+offset);
338 
339  offset = 424;
340  header.base_address_count_space = ULong(buffer+offset);
341 
342  offset = 428;
343  header.count_free_space = ULong(buffer+offset);
344 
345  offset = 432;
346  header.top_count_space = ULong(buffer+offset);
347 
348  offset = 436;
349  for ( i = 0; i < 20; i++ )
350  header.unused[i] = ULong(buffer+offset+i*sizeof(unsigned long));
351 
352 
353 }
354 
355 //_________________________________________________________________
356 bool EGConverter::OpenEG(const char *basename)
357 {
358  TString filename = fName.Data(); filename += basename;
359 
360  if (!filename.EndsWith(fFileExt)) filename += fFileExt;
361 
362  CloseEG(); // to be sure it is not already open
363 
364  // open the file
365  fStreamIN.open(filename.Data()); fStreamIN.clear();
366  if ( ! fStreamIN.is_open() ){
367  fLog.GetProcessMethod() = "OpenEG(const char* )";
368  SetError(HistoConverter::kFail,
369  Form("Cannot open file %s",filename.Data()));
370  return false;
371  }
372 
373  // to read the header part
374  char buffer[512];
375  fStreamIN.read(buffer,512);
376  if ( ! fStreamIN.good() ) {
377  fLog.GetProcessMethod() = "OpenEG(const char* )";
378  SetError(HistoConverter::kFail,
379  Form("Cannot read EG header in %s",filename.Data()));
380  fStreamIN.close(); return false;
381  }
382 
383  // check out the magic number
384  unsigned long magic = ULong(buffer);
385  if ( magic != 0x189c5e39 && magic != 0x395e9c18 ) {
386  SetError(HistoConverter::kFail,
387  Form("[EGConverter::OpenEG] %s is not an eg file",filename.Data()));
388  fStreamIN.close(); return false;
389  }
390  if ( magic == 0x395e9c18 ) { fIsSwapping = !fIsSwapping; }
391 
392  // now decode the header part
393  ReadHeader(buffer,fHeader); return true;
394 }
395 
396 //_________________________________________________________________
397 bool EGConverter::IsEG(const char *basename, Option_t *o) const
398 {
399  TString filename = fName.Data(), option = o; filename += basename;
400 
401  if (!filename.EndsWith(fFileExt))
402  filename += fFileExt;
403 
404  ifstream file;
405  // open the file
406  file.open(filename.Data());
407  if ( ! file.is_open() ){
408  if ( gDebug > 0 ) {
409  fLog.SetProcessMethod("IsEG(const char*, Option_t* )");
410  fLog << debug << "Cannot open file " << basename << dolog;
411  }
412  return false;
413  }
414 
415  // to read the header part
416  char buffer[512]; file.read(buffer,512);
417  if ( !file.good() ) {
418  if ( gDebug > 0 ) {
419  fLog.SetProcessMethod("IsEG(const char*, Option_t* )");
420  fLog<< debug << "Cannot read EG header in " << basename << dolog;
421  }
422  file.close(); return false;
423  }
424 
425  // check out the magic number
426  unsigned long *magic = (unsigned long*)buffer, *fold = (unsigned long*)(buffer+40);
427  if ( magic[0] != 0x189c5e39 && magic[0] != 0x395e9c18 ) {
428  if ( gDebug > 0 ) {
429  fLog.SetProcessMethod("IsEG(const char*, Option_t* )");
430  fLog << debug << basename << " is not an eg file" << dolog;
431  }
432  file.close(); return false;
433  }
434  bool ok = true;
435  if ( magic[0] == 0x189c5e39 ) { // no byteswap
436  if ( option.Contains("1D") && (*fold) != 1 ) ok = false;
437  if ( option.Contains("2D") && (*fold) != 2 ) ok = false;
438  }
439  else { // byteswap
440  if ( option.Contains("1D") && (*fold) != 0x01000000 ) ok = false;
441  if ( option.Contains("2D") && (*fold) != 0x02000000 ) ok = false;
442  }
443 
444  file.close(); return ok;
445 }
446 
447 //_________________________________________________________________
448 void EGConverter::ls(Option_t *o) const
449 {
450  HistoConverter::ls(o);
451  TSystemDirectory dir; dir.SetDirectory(fName.Data()); TList *list = dir.GetListOfFiles();
452 
453  TIter iter(list); TObject *entry; int count = 0;
454  while ( (entry = iter()) ) {
455 
456  if ( IsEG(entry->GetName()) ) { // this is a true eg file
457  cout << " [" << count++ << "] " << entry->GetName() ;
458 
459  if ( (count+1) % 5 == 0 ) cout << endl;
460  else cout << "\t";
461  }
462 
463  }
464  cout << endl; if ( list ) delete list;
465 }
466 
467 //_________________________________________________________________
468 TH1 *EGConverter::Get(int which)
469 {
470  // list all the file to find the entry name correponding to which
471  TSystemDirectory dir; dir.SetDirectory(fName.Data()); TList *list = dir.GetListOfFiles();
472 
473  TIter iter(list); TObject *entry; int count = 0; TString result = "_EMPTY_";
474  while ( (entry = iter()) ) {
475  if ( IsEG(entry->GetName()) ) {
476  if ( which == count ) result = entry->GetName(); count++;
477  }
478  }
479  if ( list ) delete list;
480 
481  if ( result != "_EMPTY_" ) return Get(result.Data()); // an entry has been found
482 
483  fLog.GetProcessMethod() = "Get(Int_t )";
484  SetError(HistoConverter::kFail,
485  Form("Cannot find entry # %d",which));
486 
487  return NULL;
488 }
489 
490 //_________________________________________________________________
491 TH1 *EGConverter::Get(const char *name)
492 {
493  if (fName.IsNull())
494  fName = "./";
495 
496  if ( IsEG(name,"1D") ) {
497  TH1F *h = new TH1F();
498  if ( h ) {
499  h->SetName(name);
500  if ( !Read((*h)) ) { delete h; h = NULL; }
501  }
502  return h;
503  }
504  if ( IsEG(name,"2D") ) {
505  TH2F *h = new TH2F();
506  if ( h ) {
507  h->SetName(name);
508  if ( !Read((*h)) ) { delete h; h = NULL; }
509  }
510  return h;
511  }
512 
513  return NULL;
514 }
515 
516 //_________________________________________________________________
517 bool EGConverter::Read(TH1 &h)
518 {
519  if ( IsEG(h.GetName(),"1D") == false ) {
520  fLog.GetProcessMethod() = "Read(TH1& )";
521  SetError(HistoConverter::kFail,
522  Form("%s is not an EG 1D file",h.GetName()));
523  return false;
524  }
525  OpenEG(h.GetName()); // to open the file and load the header part
526 /* if ( fHeader.fold != 1 ) {
527  SetError(HistoConverter::kFail,
528  Form("[EGConverter::Read] %s is not a 1D spectrum",h.GetName()));
529  return false;
530  }*/
531  if ( gDebug > 0 ) PrintHeader();
532 
533  char *buffer = new char[fHeader.count_free_space];
534 
535  // read the array with data
536  fStreamIN.seekg(fHeader.base_address_count_space,ios::beg); fStreamIN.read(buffer,fHeader.count_free_space);
537  if ( fStreamIN.fail() ) {
538  fLog.GetProcessMethod() = "Read(TH1& )";
539  SetError(HistoConverter::kFail,
540  Form("Cannot read array in the EG file %s",h.GetName()));
541  CloseEG();
542  delete buffer;
543  return false;
544  }
545 
546  // now decode the spectrum
547  unsigned long i;
548  fLog << error << nline;
549  fLog.SetProcessMethod("Read(TH1& )");
550  switch(fHeader.data_array_descriptor1[1]){ // switch depending on the array (histo) type
551  case 0:
552  fLog << nline;
553  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
554  << " does not match EG array type 8 bit unsigned integer " << nline;
555  fLog << " ---> there might be some problems during the convertion " << nline;
556 
557  h.SetBins(fHeader.count_free_space,fHeader.base_info[0],fHeader.count_free_space);
558  for (i = 0; i < fHeader.count_free_space; i++)
559  h.Fill(i,buffer[i]);
560  break;
561  case 1:
562  if ( ! h.InheritsFrom("TH1C") ) {
563  fLog << nline;
564  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
565  << " does not match EG array type 8 bit signed integer " << nline;
566  fLog << " ---> there might be some problems during the convertion " << nline;
567  }
568  h.SetBins(fHeader.count_free_space,fHeader.base_info[0],fHeader.count_free_space);
569  for (i = 0; i < fHeader.count_free_space; i++)
570  h.Fill(i,buffer[i]);
571  break;
572  case 2:
573  fLog << nline;
574  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
575  << " does not match EG array type 16 bit unsigned integer " << nline;
576  fLog << " ---> there might be some problems during the convertion " << nline;
577  h.SetBins(fHeader.count_free_space/2,fHeader.base_info[0],fHeader.count_free_space/2);
578  for (i = 0; i < fHeader.count_free_space/2; i++)
579  h.Fill(i,UShort(buffer+2*i));
580  break;
581  case 3:
582  if ( ! h.InheritsFrom("TH1S") ) {
583  fLog << nline;
584  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
585  << " does not match EG array type 16 bit signed integer " << nline;
586  fLog << " ---> there might be some problems during the convertion " << nline;
587  }
588  h.SetBins(fHeader.count_free_space/2,fHeader.base_info[0],fHeader.count_free_space/2);
589  for (i = 0; i < fHeader.count_free_space/2; i++)
590  h.Fill(i,Short(buffer+2*i));
591  break;
592  case 4:
593  fLog << nline ;
594  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
595  << " does not match EG array type 32 bit unsigned integer " << nline;
596  fLog << " ---> there might be some problems during the convertion " << nline;
597  h.SetBins(fHeader.count_free_space/4,fHeader.base_info[0],fHeader.count_free_space/4);
598  for (i = 0; i < fHeader.count_free_space/4; i++)
599  h.Fill(i,UInt(buffer+4*i));
600  break;
601  case 5:
602  if ( ! h.InheritsFrom("TH1I") ) {
603  fLog << nline ;
604  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
605  << " does not match EG array type 32 bit signed integer " << nline;
606  fLog << " ---> there might be some problems during the convertion " << nline;
607  }
608  h.SetBins(fHeader.count_free_space/4,fHeader.base_info[0],fHeader.count_free_space/4);
609  for (i = 0; i < fHeader.count_free_space/4; i++)
610  h.Fill(i,Int(buffer+4*i));
611  break;
612  case 6:
613  if ( ! h.InheritsFrom("TH1F") ) {
614  fLog << nline;
615  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
616  << " does not match EG array type 32 bit floating point " << nline ;
617  fLog << " ---> there might be some problems during the convertion " << nline;
618  }
619  h.SetBins(fHeader.count_free_space/4,fHeader.base_info[0],fHeader.count_free_space/4);
620  for (i = 0; i < fHeader.count_free_space/4; i++)
621  h.Fill(i,Float(buffer+4*i));
622  break;
623  default:
624  fLog << error << "Unknown type "
625  << fHeader.data_array_descriptor1[1] << " ! " << nline;
626  }
627  delete buffer;
628 
629  fLog << dolog;
630  return true;
631 }
632 
633 //_________________________________________________________________
634 bool EGConverter::Write(const TH1 &h)
635 {
636  int type=0, i;
637  TString hname;
638  int file_id;
639  char *specc;
640  short *specs;
641  int * speci;
642  float *specf;
643  int error;
644  char string_end[1024];
645 
646 #if defined(R__BYTESWAP)
647  fIsSwapping = true; // writing always as big endian
648 #endif
649 
650  // write to char EG spectrum : type 1
651  if ( h.InheritsFrom("TH1C") ) // char
652  type = 1;
653 
654  // write to short EG spectrum : type 3
655  if ( h.InheritsFrom("TH1S") )
656  type = 3;
657 
658  // write to int EG spectrum : type 5
659  if ( h.InheritsFrom("TH1I") )
660  type = 5;
661 
662  // write to float EG spectrum : type 6
663  if ( h.InheritsFrom("TH1F") )
664  type = 6;
665 
666  if ( h.InheritsFrom("TH1D") ){
667  fLog.GetProcessMethod() = "Write(const TH1& )";
668  fLog << warning << "ROOT histogram type " << h.ClassName()
669  << " writen as float EG spectrum " << nline;
670  type = 6;
671  }
672 
673  hname = h.GetName(); hname.ReplaceAll(" ","");
674 
675  InitHeader(h.GetNbinsX(), 1, fHeader, hname, type);
676 
677  file_id = open(hname,O_WRONLY | O_CREAT, 0644);
678  if (file_id < 0) {
679  fLog.GetProcessMethod() = "Write(const TH1& )";
680  SetError(HistoConverter::kFail,
681  Form("Error writing %s file",h.GetName()));
682  return false;
683  }
684  lseek(file_id, 0, SEEK_SET);
685  if (write(file_id, (void *)&(fHeader), 512) != 512) {
686  fLog.GetProcessMethod() = "Write(const TH1& )";
687  SetError(HistoConverter::kFail,
688  Form("Error writing %s file",h.GetName()));
689  return false;
690  }
691 
692  error = 0;
693  Double_t tmp=0.0;
694  switch(type){
695  case 1: // char
696  specc = new char[h.GetNbinsX()];
697  for (i=0; i<h.GetNbinsX(); i++){
698  tmp = h.GetBinContent(i+1);
699  specc[i] = (char)tmp;
700  }
701  if (write(file_id, (void *) specc, h.GetNbinsX()) != h.GetNbinsX())
702  error = 1;
703  delete [] specc;
704  break;
705  case 3: // short
706  specs = new short[h.GetNbinsX()];
707  for (i=0; i<h.GetNbinsX(); i++){
708  tmp = h.GetBinContent(i+1);
709  specs[i] = Short((char*)&tmp);
710  }
711  if (write(file_id, (void *) specs, h.GetNbinsX()*2) != h.GetNbinsX()*2)
712  error = 1;
713  delete [] specs;
714  break;
715  case 5: // int
716  speci = new int[h.GetNbinsX()];
717  for (i=0; i<h.GetNbinsX(); i++){
718  tmp = h.GetBinContent(i+1);
719  speci[i] = Int((char*)&tmp);
720  }
721  if (write(file_id, (void *) speci, h.GetNbinsX()*4) != h.GetNbinsX()*4)
722  error = 1;
723  delete [] speci;
724  break;
725  case 6: // float
726  specf = new float[h.GetNbinsX()];
727  for (i=0; i<h.GetNbinsX(); i++){
728  tmp = h.GetBinContent(i+1);
729  specf[i] = Float((char*)&tmp);
730  }
731  if (write(file_id, (void *) specf, h.GetNbinsX()*4) != h.GetNbinsX()*4)
732  error = 1;
733  delete [] specf;
734  break;
735  }
736 
737  if (error) {
738  fLog.GetProcessMethod() = "Write(const TH1& )";
739  SetError(HistoConverter::kFail,
740  Form("Error writing %s file",h.GetName()));
741  return false;
742  }
743 
744  for(i=0; i<1024; i++)
745  string_end[i] = 0;
746 
747  strcpy(&string_end[4],"Gammaware Spectrum");
748  string_end[3] = strlen("Gammaware Spectrum");
749 
750  if (write(file_id, (void *) string_end, 1024) != 1024) {
751  fLog.GetProcessMethod() = "Write(const TH1& )";
752  SetError(HistoConverter::kFail,
753  Form("Error writing %s file",h.GetName()));
754  return false;
755  }
756 
757  close(file_id);
758  return true;
759 
760 }
761 
762 //_________________________________________________________________
763 bool EGConverter::Read(TH2 &h)
764 {
765  fLog.GetProcessMethod() = "Read(TH2& )";
766 
767  if ( IsEG(h.GetName(),"2D") == false ) {
768  fLog.GetProcessMethod() = "Read(TH2& )";
769  SetError(HistoConverter::kFail,
770  Form("%s is not an EG 2D file",h.GetName()));
771  return false;
772  }
773  OpenEG(h.GetName()); // to open the file and load the header part
774 /* if ( fHeader.fold != 2 ) {
775  SetError(HistoConverter::kFail,
776  Form("[EGConverter::Read] %s is not a 2D spectrum",h.GetName()));
777  return false;
778  } */
779  if ( gDebug > 0 ) PrintHeader();
780 
781  char *buffer = new char[fHeader.count_free_space];
782 
783  // read the array with data
784  fStreamIN.seekg(fHeader.base_address_count_space,ios::beg); fStreamIN.read(buffer,fHeader.count_free_space);
785  if ( fStreamIN.fail() ) {
786  SetError(HistoConverter::kFail,
787  Form("Cannot read array in the EG file %s",h.GetName()));
788  CloseEG(); delete buffer; return false;
789  }
790 
791  // now decode the spectrum
792  unsigned long i,j; Int_t cursor = 0;
793  fLog << error;
794 
795  switch(fHeader.data_array_descriptor1[1]) { // switch depending on the array (histo) type
796  case 0:
797  fLog << nline;
798  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
799  << " does not match EG array type 8 bit unsigned integer " << nline;
800  fLog << " ---> there might be some problems during the convertion " << nline;
801 
802  h.SetBins(fHeader.range[0],fHeader.base_info[0],fHeader.range[0],
803  fHeader.range[1],fHeader.base_info[1],fHeader.range[1]);
804 
805  if ( fHeader.data_array_descriptor1[0] == 0 ) { // symetric
806  for (i = 0; i < fHeader.range[0]; i++)
807  for (j = 0; j < fHeader.range[1]; j++)
808  h.Fill(i,j,buffer[cursor++]);
809  }
810  else { // asymetric
811  for (i = 0; i < fHeader.range[0]; i++)
812  for (j = i; j < fHeader.range[1]; j++) {
813  if ( i == j )
814  h.Fill(i,j,buffer[cursor++]);
815  else
816  h.Fill(i,j,buffer[cursor]); h.Fill(j,i,buffer[cursor++]);
817  } // j
818  }
819  break;
820  case 1:
821  if ( ! h.InheritsFrom("TH2C") ) {
822  fLog << nline;
823  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
824  << " does not match EG array type 8 bit signed integer " << nline ;
825  fLog << " ---> there might be some problems during the convertion " << nline ;
826  }
827  h.SetBins(fHeader.range[0],fHeader.base_info[0],fHeader.range[0],
828  fHeader.range[1],fHeader.base_info[1],fHeader.range[1]);
829 
830  if ( fHeader.data_array_descriptor1[0] == 0 ) { // symetric
831  for (i = 0; i < fHeader.range[0]; i++)
832  for (j = 0; j < fHeader.range[1]; j++)
833  h.Fill(i,j,buffer[cursor++]);
834  }
835  else { // asymetric
836  for (i = 0; i < fHeader.range[0]; i++)
837  for (j = i; j < fHeader.range[1]; j++) {
838  if ( i == j )
839  h.Fill(i,j,buffer[cursor++]);
840  else
841  h.Fill(i,j,buffer[cursor]); h.Fill(j,i,buffer[cursor++]);
842  } // j
843  }
844  break;
845  case 2:
846  fLog << nline ;
847  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
848  << " does not match EG array type 16 bit unsigned integer " << nline ;
849  fLog << " ---> there might be some problems during the convertion " << nline ;
850 
851  h.SetBins(fHeader.range[0],fHeader.base_info[0],fHeader.range[0],
852  fHeader.range[1],fHeader.base_info[1],fHeader.range[1]);
853 
854  if ( fHeader.data_array_descriptor1[0] == 0 ) { // symetric
855  for (i = 0; i < fHeader.range[0]; i++)
856  for (j = 0; j < fHeader.range[1]; j++)
857  { h.Fill(i,j,UShort(buffer+cursor)); cursor += 2; }
858  }
859  else { // asymetric
860  for (i = 0; i < fHeader.range[0]; i++)
861  for (j = i; j < fHeader.range[1]; j++) {
862  if ( i == j )
863  h.Fill(i,j,UShort(buffer+cursor));
864  else
865  {
866  UShort_t v = UShort(buffer+cursor);
867  h.Fill(i,j,v); h.Fill(j,i,v);
868  }
869  cursor += 2;
870  } // j
871  }
872  break;
873  case 3:
874  if ( ! h.InheritsFrom("TH2S") ) {
875  fLog << nline ;
876  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
877  << " does not match EG array type 16 bit signed integer " << nline ;
878  fLog << " ---> there might be some problems during the convertion " << nline ;
879  }
880 
881  h.SetBins(fHeader.range[0],fHeader.base_info[0],fHeader.range[0],
882  fHeader.range[1],fHeader.base_info[1],fHeader.range[1]);
883 
884  if ( fHeader.data_array_descriptor1[0] == 0 ) { // symetric
885  for (i = 0; i < fHeader.range[0]; i++)
886  for (j = 0; j < fHeader.range[1]; j++)
887  { h.Fill(i,j,Short(buffer+cursor)); cursor += 2; }
888  }
889  else { // asymetric
890  for (i = 0; i < fHeader.range[0]; i++)
891  for (j = i; j < fHeader.range[1]; j++) {
892  if ( i == j )
893  h.Fill(i,j,Short(buffer+cursor));
894  else
895  {
896  Short_t v = Short(buffer+cursor);
897  h.Fill(i,j,v); h.Fill(j,i,v);
898  }
899  cursor += 2;
900  } // j
901  }
902  break;
903  case 4:
904  fLog << nline ;
905  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
906  << " does not match EG array type 32 bit unsigned integer " << nline ;
907  fLog << " ---> there might be some problems during the convertion " << nline ;
908 
909  h.SetBins(fHeader.range[0],fHeader.base_info[0],fHeader.range[0],
910  fHeader.range[1],fHeader.base_info[1],fHeader.range[1]);
911 
912  if ( fHeader.data_array_descriptor1[0] == 0 ) { // symetric
913  for (i = 0; i < fHeader.range[0]; i++)
914  for (j = 0; j < fHeader.range[1]; j++)
915  { h.Fill(i,j,UInt(buffer+cursor)); cursor += 4; }
916  }
917  else { // asymetric
918  for (i = 0; i < fHeader.range[0]; i++)
919  for (j = i; j < fHeader.range[1]; j++) {
920  if ( i == j )
921  h.Fill(i,j,UInt(buffer+cursor));
922  else
923  {
924  UInt_t v = UInt(buffer+cursor);
925  h.Fill(i,j,v); h.Fill(j,i,v);
926  }
927  cursor += 4;
928  } // j
929  }
930  break;
931  case 5:
932  if ( ! h.InheritsFrom("TH2I") ) {
933  fLog << nline ;
934  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
935  << " does not match EG array type 32 bit signed integer " << nline;
936  fLog << " ---> there might be some problems during the convertion " << nline;
937  }
938 
939  h.SetBins(fHeader.range[0],fHeader.base_info[0],fHeader.range[0],
940  fHeader.range[1],fHeader.base_info[1],fHeader.range[1]);
941 
942  if ( fHeader.data_array_descriptor1[0] == 0 ) { // symetric
943  for (i = 0; i < fHeader.range[0]; i++)
944  for (j = 0; j < fHeader.range[1]; j++)
945  { h.Fill(i,j,Int(buffer+cursor)); cursor += 4; }
946  }
947  else { // asymetric
948  for (i = 0; i < fHeader.range[0]; i++)
949  for (j = i; j < fHeader.range[1]; j++) {
950  if ( i == j )
951  h.Fill(i,j,Int(buffer+cursor));
952  else
953  {
954  Int_t v = Int(buffer+cursor);
955  h.Fill(i,j,v); h.Fill(j,i,v);
956  }
957  cursor += 4;
958  } // j
959  }
960  break;
961  case 6:
962  if ( ! h.InheritsFrom("TH2F") ) {
963  fLog << nline ;
964  fLog << " Warning in [EGConverter::Read]: ROOT histogram type " << h.ClassName()
965  << " does not match EG array type 32 bit floating point " << nline;
966  fLog << " ---> there might be some problems during the convertion " << nline;
967  }
968  h.SetBins(fHeader.range[0],fHeader.base_info[0],fHeader.range[0],
969  fHeader.range[1],fHeader.base_info[1],fHeader.range[1]);
970 
971  if ( fHeader.data_array_descriptor1[0] == 0 ) { // symetric
972  for (i = 0; i < fHeader.range[0]; i++)
973  for (j = 0; j < fHeader.range[1]; j++)
974  { h.Fill(i,j,Float(buffer+cursor)); cursor += 4; }
975  }
976  else { // asymetric
977  for (i = 0; i < fHeader.range[0]; i++)
978  for (j = i; j < fHeader.range[1]; j++) {
979  if ( i == j )
980  h.Fill(i,j,Float(buffer+cursor));
981  else
982  {
983  Float_t v = Float(buffer+cursor);
984  h.Fill(i,j,v); h.Fill(j,i,v);
985  }
986  cursor += 4;
987  } // j
988  }
989  break;
990  default:
991  fLog << "Unknown type "
992  << fHeader.data_array_descriptor1[1] << " ! " << nline ;
993  }
994  delete buffer; return true;
995 }
996 
997 //_________________________________________________________________
998 bool EGConverter::Write(const TH2 &/*h*/)
999 {
1000  fLog.GetProcessMethod() = "Write(const TH2& )";
1001  SetError(HistoConverter::kFail,"NO IMPLEMENTATION !!");
1002  return false;
1003 }
1004 
1005 //_________________________________________________________________
1006 bool EGConverter::Read(THStack &hs)
1007 {
1008  TString hsname = hs.GetName();
1009 
1010  // to avoid blanck in name
1011  hsname.ReplaceAll(" ","");
1012 
1013  // pattern expression
1014  Bool_t wildcard = false;
1015  if ( hsname.Contains("*") )
1016  wildcard = true;
1017  TRegexp all("*",kTRUE), pattern(hsname.Data(),wildcard);
1018 
1019  if ( pattern.Status() != TRegexp::kOK ) { // to be sure the user gave a correct pattern
1020  if ( gDebug > 0 ) cerr << "pattern [*] intead of " << hsname << endl ;
1021  pattern = all;
1022  }
1023  else { if ( gDebug > 0 ) cerr << "pattern " << hsname << endl ; }
1024 
1025  // loop on files to load the good ones.
1026  TSystemDirectory dir; dir.SetDirectory(fName.Data()); TList *list = dir.GetListOfFiles();
1027 
1028  TIter iter(list); TObject *entry;
1029  while ( (entry = iter()) ) {
1030  if ( IsEG(entry->GetName()) ) { // should be added to the collection
1031  TH1 *h = Get(entry->GetName()); if ( h ) { hs.Add(h); }
1032  }
1033  }
1034  if ( list ) delete list;
1035 
1036  return true;
1037 }
1038 
1039 //_________________________________________________________________
1040 bool EGConverter::Write(const THStack &/*hs*/)
1041 {
1042  fLog.GetProcessMethod() = "Write(const THStack& )";
1043  SetError(HistoConverter::kFail,"NO IMPLEMENTATION !!");
1044  return false;
1045 }
1046 
1047 
virtual void ls(Option_t *) const
to show the spectra in this DB system on the standard output
void SetError(HistoConverter::EStatus status=kGood, const char *msgerror="")
to set/reset the status of this converter
printf("******************************************************************** \n")
virtual HistoConverter * NewDB(const char *) const
to creat a new DB system
Definition: EGConverter.cpp:76
LogMessage & error(LogMessage &)
static void AddPrototype(const char *, HistoConverter *)
to add a new type of database service
LogMessage & warning(LogMessage &)
float Float(char *buf)
short Short(char *buf)
LogMessage & nline(LogMessage &)
virtual bool Read(TH1 &)
to read an histogram
long Long(char *buf)
virtual TH1 * Get(int)
to get histo number i in the list
unsigned short UShort(char *buf)
LogMessage & dolog(LogMessage &)
virtual const char * GetType() const
to know what type of HistoConverter system it is
Definition: EGConverter.h:97
LogMessage & debug(LogMessage &)
virtual std::string & GetProcessName()
To get the Process name.
Definition: GwLogMessage.h:224
virtual ~EGConverter()
Definition: EGConverter.cpp:70
ADF::LogMessage & endl(ADF::LogMessage &log)
unsigned int UInt(char *buf)
virtual void SetProcessMethod(const char *)
To set the current method.
virtual void CheckDirectory(const char *name)
check if the given directory can be read/written
virtual std::string & GetProcessMethod()
To get the current method.
Definition: GwLogMessage.h:227
int Int(char *buf)
virtual bool Write(const TH1 &)
to write an histogram
unsigned long ULong(char *buf)