Gaudi Framework, version v23r6

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

Generated at Wed Jan 30 2013 17:13:41 for Gaudi Framework, version v23r6 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004