Gaudi Framework, version v25r0

Home   Generated: Mon Feb 17 2014
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CollectionCloneAlg.cpp
Go to the documentation of this file.
1 // ====================================================================
2 // CollectionCloneAlg.cpp
3 // --------------------------------------------------------------------
4 //
5 // Author : Markus Frank
6 //
7 // ====================================================================
13 #include "GaudiKernel/Tokenizer.h"
14 #include "GaudiKernel/IRegistry.h"
15 #include "GaudiKernel/Algorithm.h"
16 #include "GaudiKernel/MsgStream.h"
17 #include "GaudiKernel/SmartIF.h"
18 #include "GaudiKernel/NTuple.h"
20 #include <vector>
21 
22 namespace {
23  template <class T> static long upper(const INTupleItem* item) {
24  const NTuple::_Data<T>* it = dynamic_cast<const NTuple::_Data<T>*>(item);
25  return long(it->range().upper());
26  }
27 
28  template<class TYP> static
30  INTuple* tuple,
31  INTupleItem* src,
32  const TYP& null)
33  {
34  NTuple::_Data<TYP>* source = dynamic_cast<NTuple::_Data<TYP>*>(src);
35  TYP low = source->range().lower();
36  TYP high = source->range().upper();
37  long hasIdx = source->hasIndex();
38  long ndim = source->ndim();
39  const std::string& name = source->name();
40  std::string idxName;
41  long dim[4], idxLen = 0;
42  long dim1 = 1, dim2 = 1;
43  INTupleItem* it = 0;
44  for ( int i = 0; i < ndim; i++ )
45  dim[i] = source->dim(i);
47  if ( hasIdx ) {
48  const INTupleItem* index = source->indexItem();
49  idxName = index->name();
50  switch( index->type() ) {
52  idxLen = upper<unsigned char>(index);
53  break;
55  idxLen = upper<unsigned short>(index);
56  break;
57  case DataTypeInfo::UINT:
58  idxLen = upper<unsigned int>(index);
59  break;
61  idxLen = upper<unsigned long>(index);
62  break;
63  case DataTypeInfo::CHAR:
64  idxLen = upper<char>(index);
65  break;
67  idxLen = upper<short>(index);
68  break;
69  case DataTypeInfo::INT:
70  idxLen = upper<int>(index);
71  break;
72  case DataTypeInfo::LONG:
73  idxLen = upper<long>(index);
74  break;
75  default:
76  log << MSG::ERROR << "Column " << idxName
77  << " is not a valid index column!" << endmsg;
78  return StatusCode::FAILURE;
79  }
80  }
81  switch( ndim ) {
82  case 0:
83  it = NTuple::_Item<TYP>::create (tuple, name, typeid(TYP), low, high, null);
84  break;
85  case 1:
86  dim1 = (hasIdx) ? idxLen : dim[0];
87  it = NTuple::_Array<TYP>::create (tuple,
88  name,
89  typeid(TYP),
90  idxName,
91  dim1,
92  low,
93  high,
94  null);
95  break;
96  case 2:
97  dim1 = (hasIdx) ? idxLen : dim[0];
98  dim2 = (hasIdx) ? dim[0] : dim[1];
99  it = NTuple::_Matrix<TYP>::create ( tuple,
100  name,
101  typeid(TYP),
102  idxName,
103  dim1,
104  dim2,
105  low,
106  high,
107  null);
108  break;
109  default:
110  return StatusCode::FAILURE;
111  }
112  return tuple->add(it);
113  }
114 }
115 
143 public:
144 
146  CollectionCloneAlg(const std::string& name, ISvcLocator* pSvcLocator)
147  : Algorithm(name, pSvcLocator), m_dataSvc(0)
148  {
149  declareProperty("EvtTupleSvc", m_tupleSvc="EvtTupleSvc");
150  declareProperty("Input", m_inputs);
151  declareProperty("Output", m_output);
152  }
155  }
156 
158  virtual StatusCode initialize() {
159  MsgStream log(msgSvc(), name());
160  m_rootName = "";
161  m_outName = "";
162  m_criteria = "";
163  m_selectorName = "";
165  if ( sc.isSuccess() ) {
166  std::string fun;
167  Tokenizer tok(true);
168  tok.analyse(m_output, " ", "", "", "=", "'", "'");
169  for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++ ) {
170  const std::string& tag = (*i).tag();
171  const std::string& val = (*i).value();
172  switch( ::toupper(tag[0]) ) {
173  case 'D':
174  m_outName = val;
175  break;
176  case 'S':
177  m_criteria = val;
178  break;
179  case 'F':
180  fun = val;
181  break ;
182  default:
183  break;
184  }
185  }
186  if ( m_outName.empty() ) {
187  log << MSG::ERROR << "Failed to analyze output specs:" << m_output << endmsg;
188  return StatusCode::FAILURE;
189  }
190  if ( fun.length() > 0 || m_criteria.length() > 0 ) {
191  if ( m_criteria.length() > 0 && fun.length() == 0 ) fun = "NTuple::Selector";
192  m_selectorName = fun;
193  return StatusCode::SUCCESS;
194  }
195  return sc;
196  }
197  log << MSG::ERROR << "Failed to access service \""
198  << m_tupleSvc << "\"." << endmsg;
199  return sc;
200  }
201 
203  virtual StatusCode finalize() {
204  if ( m_dataSvc ) m_dataSvc->release();
205  m_dataSvc = 0;
206  return StatusCode::SUCCESS;
207  }
208 
210  virtual StatusCode execute() {
211  StatusCode status = connect();
212  if ( status.isSuccess() ) {
213  status = mergeInputTuples();
214  }
215  return status;
216  }
217 
219  virtual StatusCode book(const NTuple::Tuple* nt) {
220  MsgStream log(msgSvc(), name());
221  const INTuple::ItemContainer& items = nt->items();
224  NTuple::Tuple* tuple = m_dataSvc->book(m_outName, nt->clID(), nt->title());
225  for (i = items.begin(); i != items.end(); ++i) {
226  long type = (*i)->type();
227  switch(type) {
228  case DataTypeInfo::UCHAR:
229  status = createItem(log, tuple, *i, (unsigned char)0);
230  break;
232  status = createItem(log, tuple, *i, (unsigned short)0);
233  break;
234  case DataTypeInfo::UINT:
235  status = createItem(log, tuple, *i, (unsigned int)0);
236  break;
237  case DataTypeInfo::ULONG:
238  status = createItem(log, tuple, *i, (unsigned long)0);
239  break;
240  case DataTypeInfo::CHAR:
241  status = createItem(log, tuple, *i, char(0));
242  break;
243  case DataTypeInfo::SHORT:
244  status = createItem(log, tuple, *i, short(0));
245  break;
246  case DataTypeInfo::INT:
247  status = createItem(log, tuple, *i, int(0));
248  break;
249  case DataTypeInfo::LONG:
250  status = createItem(log, tuple, *i, long(0));
251  break;
252  case DataTypeInfo::BOOL:
253  status = createItem(log, tuple, *i, false);
254  break;
255  case DataTypeInfo::FLOAT:
256  status = createItem(log, tuple, *i, float(0.0));
257  break;
259  status = createItem(log, tuple, *i, double(0.0));
260  break;
262  status = createItem(log, tuple, *i, (IOpaqueAddress*)0);
263  break;
265  status = createItem(log, tuple, *i, (void*)0);
266  break;
268 // status = createItem(log, tuple, *i, (std::string*)0);
269 // break;
271 // status = createItem(log, tuple, *i, (char*)0);
272 // break;
274  default:
275  status = StatusCode::FAILURE;
276  break;
277  }
278  }
279  return status;
280  }
281 
282  // Perform some basic checks
283  virtual StatusCode checkInput(const NTuple::Tuple* clone, const NTuple::Tuple* src) {
284  MsgStream log(msgSvc(), name());
285  if ( 0 != clone && 0 != src ) {
286  const INTuple::ItemContainer& clone_items = clone->items();
287  const std::string clone_id = clone->registry()->identifier();
288  const std::string src_id = src->registry()->identifier();
289 
291  log << MSG::ERROR;
292  for (i = clone_items.begin(); i != clone_items.end(); ++i) {
293  const INTupleItem* itm = *i;
294  const std::string& nam = itm->name();
295  const INTupleItem* src_itm = src->find(nam);
296  if ( !src_itm ) {
297  log << "Tuple item " << nam << " not present in " << src_id << endmsg;
298  return StatusCode::FAILURE;
299  }
300  if ( itm->type() != src_itm->type() ) {
301  log << "Tuple item " << nam << " are of different types in "
302  << src_id << ":" << src_itm->typeName() << " <-> "
303  << clone_id << ":" << itm->typeName() << endmsg;
304  return StatusCode::FAILURE;
305  }
306  if ( itm->ndim() != src_itm->ndim() ) {
307  log << "Tuple item " << nam << " have different dimensions in "
308  << src_id << ":" << src_itm->ndim() << " <-> "
309  << clone_id << ":" << itm->ndim() << endmsg;
310  return StatusCode::FAILURE;
311  }
312  for (int j=0; j<itm->ndim(); ++j) {
313  if ( src_itm->dim(j) != itm->dim(j) ) {
314  log << "Tuple item " << nam << " have different dimensions in "
315  << src_id << "[" << j << "]:" << src_itm->dim(j) << " <-> "
316  << clone_id << "[" << j << "]:" << itm->dim(j) << endmsg;
317  return StatusCode::FAILURE;
318  }
319  }
320  if ( itm->hasIndex() != src_itm->hasIndex() ) {
321  log << "Tuple item " << nam << " has different index colums "
322  << src_id << ":" << src_itm->hasIndex() << " <-> "
323  << clone_id << ":" << itm->hasIndex() << endmsg;
324  return StatusCode::FAILURE;
325  }
326  if ( itm->hasIndex() ) {
327  if ( itm->index() != src_itm->index() ) {
328  log << "Tuple item " << nam << " has different index colums "
329  << src_id << ":" << src_itm->index() << " <-> "
330  << clone_id << ":" << itm->index() << endmsg;
331  return StatusCode::FAILURE;
332  }
333  }
334  }
335  return StatusCode::SUCCESS;
336  }
337  return StatusCode::FAILURE;
338  }
339 
342  MsgStream log(msgSvc(), name());
344  if ( 0 != out ) {
345  const INTuple::ItemContainer& clone_items = out->items();
346  std::vector<GenericAddress> addrVector(clone_items.size());
348  NTuplePtr nt(m_dataSvc, input);
349  size_t k = 0, nentry = 0;
350  if ( 0 != nt ) {
351  const INTuple::ItemContainer& source_items = nt->items();
352  for (k=0; k < source_items.size(); ++k ) {
353  if ( source_items[k]->type() == DataTypeInfo::OBJECT_ADDR ) {
354  *(IOpaqueAddress**)source_items[k]->buffer() = &addrVector[k];
355  }
356  }
357  while ( status.isSuccess() ) {
358  status = m_dataSvc->readRecord(nt.ptr());
359  if ( status.isSuccess() ) {
361  nentry++;
362  for (k=0,i = source_items.begin(); i != source_items.end(); ++i,++k) {
363  const INTupleItem* src_itm = *i;
364  const INTupleItem* out_itm = out->find(src_itm->name());
365  size_t size = 0;
366  switch((*i)->type()) {
367  case DataTypeInfo::UCHAR:
368  size = sizeof(unsigned char);
369  break;
371  size = sizeof(unsigned short);
372  break;
373  case DataTypeInfo::UINT:
374  size = sizeof(unsigned int);
375  break;
376  case DataTypeInfo::ULONG:
377  size = sizeof(unsigned long);
378  break;
379  case DataTypeInfo::CHAR:
380  size = sizeof(char);
381  break;
382  case DataTypeInfo::SHORT:
383  size = sizeof(short);
384  break;
385  case DataTypeInfo::INT:
386  size = sizeof(int);
387  break;
388  case DataTypeInfo::LONG:
389  size = sizeof(long);
390  break;
391  case DataTypeInfo::BOOL:
392  size = sizeof(bool);
393  break;
394  case DataTypeInfo::FLOAT:
395  size = sizeof(float);
396  break;
398  size = sizeof(double);
399  break;
401  *(std::string*)out_itm->buffer() = *(std::string*)src_itm->buffer();
402  size = 0;
403  break;
405  size = ::strlen((const char*)src_itm->buffer())+1;
406  break;
408  {
409  *(void**)out_itm->buffer() = *(void**)src_itm->buffer();
410  size = 0;
411  }
412  break;
414  {
415  IOpaqueAddress* ppA1 = &addrVector[k];
416  IOpaqueAddress** ppA2 = (IOpaqueAddress**)out_itm->buffer();
417  *ppA2 = ppA1;
418  size = 0;
419  }
420  break;
422  default:
423  size = 0;
424  break;
425  }
426  if ( size > 0 ) {
427  ::memcpy((void*)out_itm->buffer(), src_itm->buffer(), size*src_itm->length());
428  }
429  }
430  status = m_dataSvc->writeRecord(out.ptr());
431  if ( !status.isSuccess() ) {
432  log << MSG::ERROR << "Failed to write record " << nentry
433  << " from " << input << " to " << m_outName << endmsg;
434  }
435  }
436  }
437  log << MSG::INFO << "End of reading tuple " << input
438  << " after " << nentry << " entries." << endmsg;
439 
440  if ( nentry > 0 || m_selectorName != "" ) {
441  return StatusCode::SUCCESS;
442  }
443  return StatusCode::FAILURE;
444  }
445  log << MSG::ERROR << "Failed to access input: " << input << endmsg;
446  }
447  return StatusCode::FAILURE;
448  }
449 
453  for (size_t i=0; i < m_inputs.size(); ++i) {
455  if ( !(0 == nt) ) {
457  if ( 0 == out ) {
458  status = book(nt);
459  }
460  else {
461  status = checkInput(out, nt);
462  }
463  if ( !status.isSuccess() ) {
464  return status;
465  }
466  else if ( m_selectorName != "" ) {
467  SmartIF<ISelectStatement> stmt(ObjFactory::create(m_selectorName, serviceLocator()));
468  if ( stmt.isValid( ) ) {
469  if ( m_criteria.length() > 0 ) stmt->setCriteria(m_criteria);
470  nt->attachSelector(stmt);
471  }
472  else {
473  MsgStream log(msgSvc(), name());
474  log << MSG::ERROR << "Failed to attach tuple selector to " << m_inputs[i] << endmsg;
475  return StatusCode::FAILURE;
476  }
477  }
478  }
479  else {
480  MsgStream log(msgSvc(), name());
481  log << MSG::ERROR << "Failed to access tuple: " << m_inputs[i] << endmsg;
482  return StatusCode::FAILURE;
483  }
484  }
485  return StatusCode::SUCCESS;
486  }
487 
490  MsgStream log(msgSvc(), name());
491  for (size_t inp=0; inp < m_inputs.size(); ++inp) {
493  if ( !sc.isSuccess() ) {
494  log << MSG::ERROR << "Failed to merge tuple:" << m_inputs[inp] << endmsg;
495  return sc;
496  }
497  }
498  return StatusCode::SUCCESS;
499  }
500 };

Generated at Mon Feb 17 2014 14:37:48 for Gaudi Framework, version v25r0 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004