GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AgataKeyFactory.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2004 by Olivier Stezowski *
3  * stezow(AT)ipnl.in2p3.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 ADF_DefaultKeyFactory
24 #include "AgataKeyFactory.h"
25 #endif
26 #include <sstream>
27 #include <iomanip>
28 
29 // common to all agata keys
30 void ADF::AgataKey::Print(std::ostream &out) const
31 {
32  out << "[AgataKey"
33  << " (" << GetVersion().GetMajor() << "," << GetVersion().GetMinor() << ")] "
34  << std::dec << std::setw(4) << GetFrameLength()
35  << " 0x" << std::hex << GetMessage()
36  << " " << std::dec << std::setw(15) << GetEventNumber()
37  << " " << std::setw(16) << GetTimeStamp();
38  //<< std::endl; // user should decide, like in Key::Print()
39 }
40 
41 
42 Bool_t ADF::AgataKey::Convert(const Key *akey)
43 {
44  // reset status
45  fBuffer->SetStatus();
46 
47  if ( IsAKey(akey) ) { // this is also an agatakey !!
48 
49  const ADF::AgataKey *agatakey = dynamic_cast<const AgataKey *>(akey);
50 
51  SetDataLength(agatakey->GetDataLength());
52  SetMessage(agatakey->GetMessage());
53  SetEventNumber(agatakey->GetEventNumber());
54  SetTimeStamp(agatakey->GetTimeStamp());
55  }
56  else ADF::Key::Convert(akey); // default action of conversion i.e copy just length
57 
58  return fBuffer->GetStatus() == BaseBuffer::kGood;
59 }
60 
61 // specific keys
62 #include "AgataKeyFactory.icpp"
63 
64 #include <fstream>
65 
66 using namespace ADF;
67 
68 AgataKeyFactory::AgataKeyFactory () :
69  AKeyFactory<AgataKeyFactory>("Agata"),
70  fMessageTable(),
71  fHardcodedMessageTable(),
72  fIsPatchEvent(false)
73 {
74  // Log related
75  fLog.GetProcessName() = "ADF::AgataKeyFactory";
76 
77  // DotConf related i.e. current definition
78  SetRID("ADF::AgataKeyFactory");
79  SetWithRecord(true);
80  SetMaxVersion(0);
81 
82  // add hardcoded table : never reset or modified
83  fHardcodedMessageTable["agata"] = std::pair<UInt_t,UInt_t>(0x0A000000,0x0F000000);
84  fHardcodedMessageTable["data"] = std::pair<UInt_t,UInt_t>(0x0A000100,0x0F000F00);
85  fHardcodedMessageTable["meta"] = std::pair<UInt_t,UInt_t>(0x0A001100,0x0F00FF00);
86  fHardcodedMessageTable["conf"] = std::pair<UInt_t,UInt_t>(0x0A000200,0x0F000F00);
87  fHardcodedMessageTable["algo"] = std::pair<UInt_t,UInt_t>(0x0A000300,0x0F000F00);
88  fHardcodedMessageTable["info"] = std::pair<UInt_t,UInt_t>(0x0A000400,0x0F000F00);
89  fHardcodedMessageTable["rmess"] = std::pair<UInt_t,UInt_t>(0x0A000500,0x0F000F00);
90  fHardcodedMessageTable["cmess"] = std::pair<UInt_t,UInt_t>(0x0A000600,0x0F000F00);
91  fHardcodedMessageTable["event"] = std::pair<UInt_t,UInt_t>(0xCA000000,0xFF000000);
92 }
93 
94 void AgataKeyFactory::Reset(const Char_t * /*opt*/)
95 {
96  // reset patch, set again @ reading of the keys. by default for version -1
97  fIsPatchEvent = false;
98 
99  // clear message table BUT NOT the hard coded part
100  fMessageTable.clear();
101 }
102 
104 {
105  // cannot deal with request asking for a version greater that what can manage this version
106  if ( item.GetFactoryVersion() > GetMaxVersion() )
107  return 0x0;
108 
109  AgataKey *key = 0x0; std::string keytype = item.GetItemName();
110 
111  // set the correct version
112  if ( item.GetVersion() == Version(0,0) ) {
113  key = new AgataKey_0_0(GetEndian());
114  }
115  if ( item.GetVersion() == Version(1,0) ) {
116  key = new AgataKey_1_0(GetEndian());
117  }
118  if ( item.GetVersion() == Version(2,0) ) {
119  key = new AgataKey_2_0(GetEndian());
120  }
121  if ( item.GetVersion() == Version(4,0) ) {
122  key = new AgataKey_4_0(GetEndian());
123  }
124 
125  // set message type for that key
126  if ( key ) {
127  // in case message table is not loaded or wrong, default is a generic agata key
128  UInt_t message = fHardcodedMessageTable["agata"].first, mask = fHardcodedMessageTable["agata"].second ;
129 
130  // patch to deal with unversionned version (-1) which was defining event key like standard algorithms
131  if ( fIsPatchEvent && keytype == "event:data:psa" )
132  keytype = "data:eb";
133  if ( fIsPatchEvent && keytype == "event:data" )
134  keytype = "data:merger";
135 
136  // iterator on the map
137  std::map<std::string,std::pair<UInt_t,UInt_t> >::iterator im;
138 
139  // look if it exists
140  Short_t isin = 0;
141  for (im = fMessageTable.begin() ; im != fMessageTable.end() ; im++ ) {
142  if ( im->first == keytype ) { isin = 1; break; }
143  }
144  for (im = fHardcodedMessageTable.begin() ; im != fHardcodedMessageTable.end() ; im++ ) {
145  if ( im->first == keytype ) { isin = 2; break; }
146  }
147  switch (isin) {
148  case 0:
149  delete key; key = 0x0;
150  break;
151  case 1:
152  message = fMessageTable[keytype].first;
153  mask = fMessageTable[keytype].second;
154  break;
155  case 2:
156  message = fHardcodedMessageTable[keytype].first;
157  mask = fHardcodedMessageTable[keytype].second;
158  break;
159  }
160  if ( key )
161  { key->ChangeType(message,mask); key->SetMessage(message); }
162  else {
163  fLog << error << " Key type " << item << " has not been found in the Agata key factory, version " << GetVersion() << nline;
164  if ( fLog.IsDebug(1) ) {
166  DoConfigure( fLog() );
168  }
169  }
170  }
171  else {
172  fLog << error << " Key " << item << " is not known by the Agata key factory, version " << nline;
173  if ( fLog.IsDebug(1) ) {
175  DoConfigure( fLog() );
177  }
178  }
179 
180  return key;
181 }
182 
183 Bool_t AgataKeyFactory::ProcessLine(const std::string &aline)
184 {
185  UInt_t ui1, ui2; std::pair<UInt_t,UInt_t> tmpp; std::string tmp, keytype, stream_option = GetStreamOption(); Bool_t ok = true;
186 
187  // decode the line
188  std::istringstream decode(aline);
189  // just to be sure ...
190  decode.clear();
191  decode >> tmp >> std::hex >> ui1 >> ui2 ;
192 
193  if ( !decode.good() ) { // not the expected format
194  return false;
195  }
196  else {
197  tmpp.first = ui1;
198  tmpp.second = ui2;
199  keytype = tmp;
200  }
201 
202  if ( GetVersion() == -1 && stream_option.find("Init") == std::string::npos ) {
203  // in the very first version (unversionned, -1) of the factory, the treatment of the event key was not global enough.
204  // the factory has been modified so that :
205  // it inits with version -1 but a more complete set of keys
206  // it allows to work with version 0 of the factory that includes has a general approach of events and allows to add new keys.
207 
208  // as a consequence, any attempt to reconfigure/init this for version -1 is blocked there ... only the version # is modified once the record header is read.
209  // another consequence is the patch set in the DoNew method to deal with the two particular cases of event:data:psa and event:data
210  // NOTE : reading data produced with version -1 force keeping version -1 way of coding event:data:psa and event:data
211 
212  // test : if version -1, check if it is there . true if yes otherwise false
213  if ( fMessageTable.count(tmp) == 1 )
214  return true;
215  if ( fHardcodedMessageTable.count(tmp) == 1 )
216  return true;
217 
218  return false;
219  }
220  //
221  if ( GetVersion() == -1 && keytype == "data:eb" && ui1 == 0xFA010103 ) {
222  if ( fLog.IsDebug(5) )
223  fLog << info << " Switch to patch == true for version - 1 " << keytype << nline; //
224  fIsPatchEvent = true;
225  } // @ this level in init mode ==> put it in the message table
226  if ( GetVersion() == -1 && keytype == "event:data:psa" && ui1 == 0xCA010102 ) {
227  if ( fLog.IsDebug(5) )
228  fLog << info << " Switch to patch == true for version - 1 " << keytype << nline; //
229  fIsPatchEvent = true;
230  } // @ this level in init mode ==> put it in the message table ... second check, jsut to be sure in case one is accidentally erase in conf file
231 
232  // check whether or not it is an harcoded key
233  if ( fHardcodedMessageTable.count(tmp) == 1 ) {
234  if ( fLog.IsDebug(5) )
235  fLog << info << " Attemp to modify an hard coded key " << tmp << " ... ignored "<< nline; // cannot be changed
236  }
237  else {
238  // because the key in the std::map is unique, it is change automatically in case the key is already in the map
239  if ( fMessageTable.count(keytype) == 1 ) { // already in the table, change definition
240  if ( stream_option.find("==") != std::string::npos || stream_option.find("Init") != std::string::npos )
241  fMessageTable[keytype] = tmpp;
242  else
243  ok = false;
244  }
245  if ( fMessageTable.count(keytype) == 0 ) { // not yet in the table
246  if ( stream_option.find("+") != std::string::npos || stream_option.find("Init") != std::string::npos )
247  fMessageTable[keytype] = tmpp;
248  else
249  ok = false;
250  }
251  }
252  // printf("TABLE SIZE %d\n",fMessageTable.size());
253  return ok;
254 }
255 
256 Bool_t AgataKeyFactory::GetMessage(std::string keyName, UInt_t &message, UInt_t &mask)
257 {
258  Bool_t found = false;
259 
260  // iterator on the map
261  std::map<std::string,std::pair<UInt_t,UInt_t> >::iterator im;
262 
263  for (im = fMessageTable.begin() ; im != fMessageTable.end() ; im++ ) {
264  if ( im->first == keyName ) {
265  message = im->second.first; mask = im->second.second;
266  found = true;
267  break;
268  }
269  }
270  // in case, look also in the hardcoded ones
271  if(!found) {
272  for (im = fHardcodedMessageTable.begin() ; im != fHardcodedMessageTable.end() ; im++ ) {
273  if ( im->first == keyName ) {
274  message = im->second.first; mask = im->second.second;
275  found = true;
276  break;
277  }
278  }
279  }
280 
281  return found;
282 }
283 
284 const char *AgataKeyFactory::GetMessage(UInt_t message)
285 {
286  const char *st = 0x0;
287 
288  // iterator on the map
289  std::map<std::string,std::pair<UInt_t,UInt_t> >::iterator im;
290 
291  for (im = fMessageTable.begin() ; im != fMessageTable.end() ; im++ ) {
292  if ( im->second.first == message ) {
293  st = im->first.c_str();
294  // patch around version -1
295  if ( fIsPatchEvent && im->first == "data:eb" )
296  st = "event:data:psa";
297  if ( fIsPatchEvent && im->first == "data:merger" )
298  st = "event:data";
299  break;
300  }
301  }
302  if ( !st ) {
303  for (im = fHardcodedMessageTable.begin() ; im != fHardcodedMessageTable.end() ; im++ ) {
304  if ( im->second.first == message ) {
305  st = im->first.c_str();
306  break;
307  }
308  }
309  }
310  return st ? st : "UnknownKey";
311 }
312 
313 Bool_t AgataKeyFactory::DoConfigure (std::ostream & out)
314 {
315  // add a start record
316  AddRecord(out,'b');
317 
318  if ( fMessageTable.size() > 0 ) { // write only non-hardcoded part
319  // iterator on the map
320  std::map<std::string,std::pair<UInt_t,UInt_t> >::iterator im;
321  for (im = fMessageTable.begin() ; im != fMessageTable.end() ; im++ ) {
322  out << im->first << "\t\t"
323  << std::hex << im->second.first << "\t" << im->second.second << std::dec << " \n" ;
324  }
325  }
326 
327  // add an end of record
328  AddRecord(out,'e');
329 
330  return out.good();
331 }
332 
333 
334 
335 
336 
337 
338 
virtual void SetLevel(ELevel lev, unsigned short verbosity=0u)
To get the current level of the message.
virtual void Reset(const Char_t *="")
Reset the table.
Base class for a Key.
Definition: Key.h:56
LogMessage & info(LogMessage &)
manipulator to modify the LogMessage
virtual Short_t GetVersion() const
to get the curent version of this object
Definition: DotConf.h:258
virtual BaseBuffer::EEndian GetEndian() const
Endian type for the keys delivered by this factory.
Definition: KeyFactory.h:99
Short_t GetMaxVersion() const
this class could managed moddification of the versionned part up to MaxVersion : should be set in the...
Definition: DotConf.h:242
virtual Bool_t DoConfigure(std::ostream &)
write the message table
Interface to AgataKey.
LogMessage & error(LogMessage &)
virtual Bool_t ProcessLine(const std::string &)
During configuration, process a single line.
virtual void Print(std::ostream &out=std::cout) const
Print the content of the key.
virtual Bool_t Convert(const Key *akey)
convert a key to another key ... not an easy task ... use it carefully
virtual ULong64_t GetTimeStamp() const =0
To set the timestamp.
virtual Key * DoNew(const FactoryItem &)
Ask this factory for a new AgataKey.
virtual UInt_t GetEventNumber() const =0
To get the event number encoded.
Short_t GetFactoryVersion() const
Ask the factory version.
Definition: FactoryItem.h:82
Base class for version numbers.
Definition: Version.h:38
virtual UInt_t GetDataLength() const
bool IsDebug(short debug_to_test) const
to test if the required debug level is lower that the global one
LogMessage & nline(LogMessage &)
LogMessage fLog
the log messenger ... to know the object hae been properly intitialised/modified
Definition: DotConf.h:100
header file for AgataKeyFactory.cpp
virtual void ChangeType(UInt_t messtype, UInt_t messmask)
to modify the Agata type for this key
UShort_t GetMinor() const
Definition: Version.h:61
Version GetVersion() const
Definition: Key.h:77
Version GetVersion() const
Definition: FactoryItem.h:88
virtual Bool_t Convert(const Key *akey)
convert a key to another key ... not an easy task ... use it carefully
Definition: Key.h:226
virtual const Char_t * GetStreamOption() const
get/set option
Definition: DotConf.h:262
virtual UInt_t GetFrameLength() const
virtual void SetMessage(UInt_t)=0
To set the message type.
const std::string & GetItemName() const
Definition: FactoryItem.h:78
Bool_t AddRecord(std::ostream &, char t= 'b')
Add a begin or end of record, return true if done.
Definition: DotConf.cpp:198
Bool_t GetMessage(std::string keyName, UInt_t &message, UInt_t &mask)
to check if a given keyname is in the list of known keys (return true in this case, false otherwise) and to access the corresponding message type, mask
Base class for a AgataKeyFactory.
Base class for any KeyFactory implementation.
Definition: KeyFactory.h:215
Base class that described an item in a Factory.
Definition: FactoryItem.h:52
virtual UInt_t GetMessage() const =0
To get the message type encoded.
UShort_t GetMajor() const
Definition: Version.h:60