GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ASCConverter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2004-2006 by Christian, Finck, Olivier Stezowski *
3  * & Christophe Theisen *
4  * stezow(AT)ipnl.in2p3.fr, christophe.theisen(AT)cea.fr *
5  * *
6  * This program is free software; you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License as published by *
8  * the Free Software Foundation; either version 2 of the License, or *
9  * (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with this program; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20  ***************************************************************************/
21 
24 #ifndef GW_ASCCONVERTER_H
25 #include "ASCConverter.h"
26 #endif
27 
28 #ifndef ROOT_TRegexp
29 #include <TRegexp.h>
30 #endif
31 
32 #ifndef ROOT_TSystem
33 #include <TSystem.h>
34 #endif
35 
36 #ifndef ROOT_TSystemDirectory
37 #include <TSystemDirectory.h>
38 #endif
39 
40 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
41 #include "TList.h"
42 #endif
43 
44 #ifndef ROOT_TObjArray
45 #include "TObjArray.h"
46 #endif
47 
48 #ifndef ROOT_TObjString
49 #include "TObjString.h"
50 #endif
51 
52 #include <iostream>
53 using namespace std;
54 
55 namespace { ASCConverter gASCConverter; } // prototype ONLY use to create a new DB system
56 
57 //_________________________________________________________________
58 ASCConverter::ASCConverter(const char *name) : HistoConverter(name)
59 {
60  fType = "asc";
61  // default file extension for ascii, could be change by setter
62 
63  CheckDirectory(name);
64  fStreamIN.clear(); fCycle = '_'; // because ; is not supported by all file systems
65  fLog.GetProcessName() = "ASCConverter";
66 }
67 
68 //_________________________________________________________________
70 {
71  fType = "asc";
72  // default file extension for ascii, could be change by setter
73  fFileExt = ".asc";
74  //default option
75  fOptions = "h:0 c:1 s: p:1.0.1";
76  // add this interface to the DB service
77  AddPrototype(GetType(),this);
78 }
79 
80 //_________________________________________________________________
82 {
83 
84 }
85 
86 //_________________________________________________________________
87 HistoConverter *ASCConverter::NewDB(const char *name) const
88 {
89  return new ASCConverter(name);
90 }
91 
92 
93 
94 //_________________________________________________________________
95 void ASCConverter::ls(Option_t *o) const
96 {
97  HistoConverter::ls(o);
98  TSystemDirectory dir; dir.SetDirectory(fName.Data());
99  TList *list = dir.GetListOfFiles();
100  TIter iter(list);
101  TObject *entry;
102  Int_t count = 0;
103 
104  while ( (entry = iter()) ) {
105  TString tmp = entry->GetName();
106  if ( tmp.EndsWith(fFileExt) ) { // this is a true ascii file
107  cout << " [" << count++ << "] " << entry->GetName() ;
108  if ( (count+1) % 5 == 0 ) cout << endl;
109  else cout << "\t";
110  }
111  }
112  cout << endl;
113  if ( list ) delete list;
114 }
115 
116 //_________________________________________________________________
117 TH1 *ASCConverter::Get(int which)
118 {
119  // list all the file to find the entry number correponding to which
120  TSystemDirectory dir; dir.SetDirectory(fName.Data()); TList *list = dir.GetListOfFiles();
121  TIter iter(list); TObject *entry; int count = 0; TString result = "_EMPTY_";
122 
123  while ( (entry = iter()) ) {
124  TString tmp = entry->GetName();
125  if ( tmp.EndsWith(fFileExt) ) {
126  if ( which == count )
127  result = entry->GetName();
128  count++;
129  }
130  }
131  if ( list ) delete list;
132 
133  if ( result != "_EMPTY_" ) return Get(result.Data()); // an entry has been found
134  fLog.GetProcessMethod() = "Get(Int_t )";
135  SetError(HistoConverter::kFail,
136  Form("Cannot find entry # %d",which));
137  return NULL;
138 
139 }
140 
141 //_________________________________________________________________
142 TH1 *ASCConverter::Get(const char *name)
143 {
144  TH1F *h = new TH1F();
145  h->SetName(name);
146  if ( !Read((*h)) ) {
147  delete h;
148  h = NULL;
149  }
150  return h;
151 
152 }
153 
154 //_________________________________________________________________
155 bool ASCConverter::Read(TH1 &h)
156 {
157  TString filename = fName.Data();
158  if ( filename.IsNull() ) filename = "."; // for mine types
159 
160  if ( ! filename.EndsWith("/") ) filename+= "/"; // set file name as a full path name
161  filename += h.GetName();
162 
163 
164  if ( filename.EndsWith(fFileExt) == false ) filename += fFileExt;
165 
166  ifstream in(filename, ios::in);
167 
168  if ( !in ) {
169  fLog.GetProcessMethod() = "Read(TH1& )";
170  SetError(HistoConverter::kFail,
171  Form("Cannot open file %s",filename.Data()));
172  return false;
173  }
174 
175  // get format info
176  TArrayI params(6);
177  if ( !DecodeFormat(params) ) {
178  return false;
179  }
180 
181 
182  Int_t nbLines = params[0];
183  Int_t nbColumns = params[1];
184  Char_t sep = (char)params[2];
185  Int_t nbParams = params[3];
186  Int_t posBin = params[4];
187  Int_t posBinContent = params[5];
188 
189  vector<Int_t> histo; histo.clear();
190  vector<Int_t> bin; bin.clear();
191 
192 
193  Char_t line[255];
194  //skip header
195  for (Int_t i = 0; i < nbLines; ++i)
196  in.getline(line,255);
197 
198  // read data
199  TString sCnt;
200  TString sBin;
201  Int_t idxBin;
202  Int_t idxContent;
203 
204  while ( in.getline(line,255) ) {
205 
206  TString tmp(line);
207  TObjArray* stringList = tmp.Tokenize(TString(sep));
208 
209 
210  for (Int_t i = 0; i < nbColumns; ++i) {
211  if (posBin != 0) {
212  idxBin = (posBin-1) + nbParams*i;
213  sBin = ((TObjString*)stringList->At(idxBin))->GetString();
214  bin.push_back(sBin.Atoi());
215  }
216 
217  idxContent = (posBinContent-1) + nbParams*i;
218  sCnt = ((TObjString*)stringList->At(idxContent))->GetString();
219  histo.push_back(sCnt.Atoi());
220  }
221  delete stringList;
222 
223  }
224  in.close();
225 
226  h.SetBins(histo.size(),0,histo.size());
227  for (UInt_t i = 0; i < histo.size(); i++ )
228  if (bin.size() != 0)
229  h.SetBinContent(bin[i],histo[i]);
230  else
231  h.SetBinContent(i+1,histo[i]);
232 
233  in.close();
234 
235  return true;
236 }
237 
238 //_________________________________________________________________
239 bool ASCConverter::Write(const TH1 & h)
240 {
241  TString hname, filename; // set file name as a full path name
242  hname = h.GetName();
243  filename = CheckFileVersion(hname);
244 
245  filename.Prepend(fName.Data());
246  if ( gDebug > 0 ) {
247  fLog.GetProcessMethod() = "Write(const TH1& )";
248  SetError(HistoConverter::kFail, Form("file to store the spectrum %s", filename.Data()) );
249  }
250 
251  if (fVerboseLevel)
252  fLog << info << "Writing spectrum " << filename << nline ;
253 
254  ofstream out(filename.Data(), ios::out);
255 
256  if (!out) {
257  fLog.GetProcessMethod() = "Write(const TH1& )";
258  SetError(HistoConverter::kFail,
259  Form("Cannot open %s in writing mode",filename.Data()));
260  return false;
261  }
262 
263 
264  // get format info
265  TArrayI params(6);
266  if ( !DecodeFormat(params) ) {
267  return false;
268  }
269 
270 
271  Int_t nbLines = params[0];
272  Int_t nbColumns = params[1];
273  Char_t sep = (char)params[2];
274  Int_t nbParams = params[3];
275  Int_t posBin = params[4];
276  Int_t posBinContent = params[5];
277  Int_t idxBin = -1;
278  Int_t idxContent = 0;
279  Int_t bin = 1;
280 
281  //write dummy header
282  for (Int_t i = 0; i < nbLines; ++i)
283  out << "Header generated by [ASCConverter::Write(TH1 &h)]" << endl;
284 
285  Int_t size = h.GetNbinsX()/nbColumns;
286 
287  for (Int_t j = 0; j < size; ++j) {
288 
289  for (Int_t i = 0; i < nbColumns; ++i) {
290  if (posBin != 0 )
291  idxBin = (posBin-1) + nbParams*i;
292  idxContent = (posBinContent-1) + nbParams*i;
293  if (i == idxBin)
294  out << h.GetBin(bin);
295  else if (i == idxContent) {
296  out << h.GetBinContent(bin++);
297  }
298  else
299  out << "0";
300  if (i < nbColumns-1)
301  out << sep;
302  }
303  out << endl;
304  }
305  return true;
306 }
307 
308 //_________________________________________________________________
309 bool ASCConverter::Read(TH2 &/*h*/)
310 {
311  fLog.GetProcessMethod() = "Read(TH2& )";
312  SetError(HistoConverter::kFail,"NO IMPLEMENTATION !!") ;
313  return false;
314 }
315 
316 //_________________________________________________________________
317 bool ASCConverter::Write(const TH2 &/*h*/)
318 {
319  fLog.GetProcessMethod() = "Write(const TH2& )";
320  SetError(HistoConverter::kFail,"NO IMPLEMENTATION !!");
321  return false;
322 }
323 
324 //_________________________________________________________________
325 bool ASCConverter::Read(THStack &/*hs*/)
326 {
327  fLog.GetProcessMethod() = "Read(THStack& )";
328  SetError(HistoConverter::kFail,"NO IMPLEMENTATION !!");
329  return false;
330 }
331 
332 //_________________________________________________________________
333 bool ASCConverter::Write(const THStack &/*hs*/)
334 {
335  fLog.GetProcessMethod() = "Write(const THStack& )";
336  SetError(HistoConverter::kFail,"NO IMPLEMENTATION !!");
337  return false;
338 }
339 
340 
341 //_________________________________________________________________
342 Bool_t ASCConverter::DecodeFormat(TArrayI& params)
343 {
344 
345  // decode options
346  TString option = Normalize(fOptions.Data());
347  TString type = "[";
348 
349  Int_t last = 0;
350  Int_t idx = 0;
351  Int_t nbLines = 0;
352  Int_t nbColumns = 0;
353  Int_t nbParams = 0;
354  Int_t posBin = 0;
355  Int_t posBinContent = 0;
356  char sep = 0;
357 
358  //take always the last set option separated by [...]
359  Int_t length = option.Length();
360  while (last < length) {
361  last = option.Index(type, idx);
362  if (last == -1) break;
363  idx = last + type.Length();
364  }
365  TString format(option(idx, length -idx));
366  TString keys;
367  TObjArray* stringList = format.Tokenize(TString(" "));
368  if (stringList->GetEntries() > 4) {
369  fLog.GetProcessMethod() = "DecodeFormat(TArrayI& )";
370  SetError(HistoConverter::kFail,"Too many blanks in the format option !!");
371  return false;
372  }
373 
374  for (Int_t i = 0; i< stringList->GetEntries(); ++i) {
375  keys = ((TObjString*)stringList->At(i))->GetString();
376  const Char_t* k = keys.Data();
377  switch(k[0])
378  {
379  case 'h' :
380  sscanf(k, "h:%d", &nbLines);
381  params[0] = nbLines;
382  break;
383  case 'c' :
384  sscanf(k, "c:%d", &nbColumns);
385  params[1] = nbColumns;
386  break;
387  case 's' :
388  sscanf(k, "s:%c", &sep);
389  params[2] = (Int_t)sep;
390  break;
391  case 'p' :
392  sscanf(k, "p:%d.%d.%d", &nbParams, &posBin, &posBinContent);
393  params[3] = nbParams; params[4] = posBin; params[5] = posBinContent;
394  break;
395  }
396  }
397 
398  return true;
399 
400 }
401 
402 //_____________________________________________________________________________
403 TString ASCConverter::Normalize(const char* line)
404 {
408 
409  TString rv(line);
410 
411  if ( rv.Length() <= 0 ) return TString();
412 
413  while ( rv[0] == ' ' )
414  {
415  rv.Remove(0,1);
416  }
417  while ( rv[rv.Length()-1] == ' ' )
418  {
419  rv.Remove(rv.Length()-1,1);
420  }
421  Ssiz_t i(0);
422  bool kill = false;
423  for ( i = 0; i < rv.Length(); ++i )
424  {
425  if ( rv[i] == ' ' )
426  {
427  if (kill)
428  {
429  rv.Remove(i,1);
430  --i;
431  }
432  else
433  {
434  kill = true;
435  }
436  }
437  else
438  {
439  kill = false;
440  }
441  }
442  return rv;
443 }
444 
void SetError(HistoConverter::EStatus status=kGood, const char *msgerror="")
to set/reset the status of this converter
virtual bool Read(TH1 &)
Read/write 1-D histogram.
virtual ~ASCConverter()
virtual HistoConverter * NewDB(const char *) const
instanciate new HistoConverter
static void AddPrototype(const char *, HistoConverter *)
to add a new type of database service
LogMessage & nline(LogMessage &)
TH1F * histo[MaxValue]
Definition: ReadDaqAlone.C:31
LogMessage & info(LogMessage &)
manipulator to modify the LogMessage
static TString Normalize(const char *line)
method to normalize string chains
virtual const char * GetType() const
get type
Definition: ASCConverter.h:65
virtual void ls(Option_t *) const
to show the spectra in this DB system on the standard output
LogMessage & sep(LogMessage &)
virtual bool Write(const TH1 &)
to write an histogram
virtual std::string & GetProcessName()
To get the Process name.
Definition: GwLogMessage.h:224
ADF::LogMessage & endl(ADF::LogMessage &log)
virtual TH1 * Get(int)
Get histogram from number Id.
static int fVerboseLevel
const Int_t size
Definition: BenchIO.C:24
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
TString CheckFileVersion(TString filename)