VDColdboxTDEChannelMapService_service.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: VDColdboxTDEChannelMapService
3 // File: VDColdboxTDEChannelMapService_service.cc
4 // Author: Vyacheslav Galymov
5 //
6 // Mappings for VD CRP1 from docdb 23910
7 //
8 // Classes to facility channel order translation between different
9 // representations
10 //
11 // seqn - unique counter to give channel data position in the record
12 // crate - utca crate number starting
13 // card - AMC card number
14 // cardch - AMC card channel number
15 // crp - CRP number
16 // view - view number (0/1/2)
17 // viewch - view channel number
18 //
19 // Boost multi_index_container provides interface to search and order various
20 // indicies. The container structure is defined in TDEChannelTable, which has
21 // the following interfaces:
22 // - raw sequence index, tag IndexRawSeqn
23 // - crate number, tag IndexCrate, to get all channels to a given crate
24 // - crate number and card number, tag IndexCrateCard,
25 // to get all channels for a given card in a crate
26 // - crate, card, and channel number, tag IndexCrateCardChan, to access
27 // a given channel of a given card in a given crate
28 // - CRP index, tag IndexCrp, to access channels assigned to a given CRP
29 // - CRP index and view index, tag IndexCrpView, to access channels assigned to
30 // a given view in a specified CRP
31 // - CRP index, view index, and channel number, tag IndexCrpViewChan, to access
32 // a given view channel in a given CRP
33 //
34 ////////////////////////////////////////////////////////////////////////
35 
36 // framework libraries
38 #include "cetlib_except/exception.h" // cet::exception
39 
40 // boost
41 #include <boost/range.hpp>
42 #include <boost/range/adaptors.hpp>
43 
44 // c++
45 #include <iostream>
46 #include <iomanip>
47 #include <utility>
48 
50 #include "tde_cmap_utils.h"
51 
53 using std::vector;
54 
55 // ctor
58 {
59  mapname_ = "";
60  ntot_ = 0;
61  ncrates_ = 0;
62  ncrps_ = 0;
63  nch_ = 64;
64 
65  std::string MapName = p.get<std::string>("MapName", "vdcb1crp");
66  unsigned ncrateInMap = p.get<unsigned>("MapCrateNb", 3);
67  unsigned ncardsInMap = p.get<unsigned>("MapCardNb", 10);
68  unsigned nviewsInMap = p.get<unsigned>("MapViewNb", 1);
69  fLogLevel = p.get<int>("LogLevel", 0);
70  //initialize channel map
71  initMap( MapName, ncrateInMap, ncardsInMap, nviewsInMap );
72 
73  if( fLogLevel >= 3){
74  auto all_chans = find_by_seqn(0, ntot());
75  print( all_chans );
76  }
77 }
78 
79 
80 //
81 // initMap
83  unsigned ncards, unsigned nviews )
84 {
85  // already defined?
86  if( mapname_.compare( mapname ) == 0 ) {
87  return;
88  }
89 
90  clearMap();
91  mapname_ = mapname;
92  if( mapname.compare("vdcb1crp") == 0 ) {
93  vdcb1crpMap();
94  } else {
95  simpleMap( ncrates, ncards, nviews );
96  }
97 }
98 
99 
100 //
101 // clearMap
103 {
104  tde::ChannelTable().swap( chanTable );
105  ncrates_ = 0;
106  ncrps_ = 0;
107  ntot_ = 0;
108  mapname_ = "";
109  crateidx_.clear();
110  crpidx_.clear();
111 }
112 
113 
114 //
115 // a simple channel map for testing purposes
117  unsigned nviews )
118 {
119  unsigned nctot = ncards * ncrates; // total number of cards
120  unsigned ncview = nctot / nviews; // allocate the same for each view
121  unsigned nch = nch_; // number of ch per card (fixed)
122 
123  unsigned seqn = 0;
124  unsigned crate = 0;
125  unsigned crp = 0;
126  unsigned view = 0;
127  unsigned vch = 0;
128  for( unsigned card = 0; card < nctot; card++ )
129  {
130  if( card > 0 ) {
131  if( card % ncards == 0 ) crate++;
132  if( card % ncview == 0 ) {view++; vch=0;}
133  }
134  for( unsigned ch = 0; ch < nch; ch++ ){
135  add( seqn++, crate, card % ncards, ch, crp, view, vch++);
136  }
137  }
138  //
139 }
140 
141 
142 
143 //
144 // add channl ID to map
145 void dune::VDColdboxTDEChannelMapService::add( unsigned seq, unsigned crate, unsigned card,
146  unsigned cch, unsigned crp, unsigned view,
147  unsigned vch, unsigned short state )
148 {
149  chanTable.insert( ChannelId(seq, crate, card, cch, crp, view, vch, state) );
150  //
151  ntot_ = chanTable.size();
152 
153  crateidx_.insert( crate );
154  ncrates_ = crateidx_.size();
155 
156  crpidx_.insert( crp );
157  ncrps_ = crpidx_.size();
158 }
159 
160 //
161 //
162 //
163 boost::optional<ChannelId> dune::VDColdboxTDEChannelMapService::find_by_seqn( unsigned seqn ) const
164 {
165  auto it = chanTable.get<dune::tde::IndexRawSeqnHash>().find( seqn );
166  if( it != chanTable.get<dune::tde::IndexRawSeqnHash>().end() )
167  return *it;
168 
169  return boost::optional<ChannelId>();
170 }
171 
172 //
173 // the most low level info
174 std::vector<ChannelId> dune::VDColdboxTDEChannelMapService::find_by_seqn( unsigned from, unsigned to ) const
175 {
176  if( to < from ) std::swap( from, to );
177 
178  std::vector<ChannelId> res;
179 
180  if( from == to )
181  {
182  if( boost::optional<ChannelId> id = find_by_seqn( from ) )
183  res.push_back( *id );
184  //auto it = chanTable.find(from);
185  //if( it != chanTable.end() )
186  //res.push_back( *it );
187  }
188  else
189  {
190  auto first = chanTable.get<dune::tde::IndexRawSeqn>().lower_bound( from );
191  auto last = chanTable.get<dune::tde::IndexRawSeqn>().upper_bound( to );
192  res.insert( res.begin(), first, last );
193  }
194 
195  return res;
196 }
197 
198 //
199 //
200 std::vector<ChannelId> dune::VDColdboxTDEChannelMapService::find_by_crate( unsigned crate, bool ordered ) const
201 {
202  if( not ordered ) // get from hashed index
203  {
204  const auto r = chanTable.get<dune::tde::IndexCrate>().equal_range( crate );
205  std::vector<ChannelId> res(r.first, r.second);
206  return res;
207  }
208 
209  const auto r = chanTable.get<dune::tde::IndexCrateCardChan>().equal_range( boost::make_tuple(crate) );
210  std::vector<ChannelId> res(r.first, r.second);
211 
212  return res;
213 }
214 
215 //
216 //
217 std::vector<ChannelId> dune::VDColdboxTDEChannelMapService::find_by_crate_card( unsigned crate, unsigned card, bool ordered ) const
218 {
219  if( not ordered ) // get from hashed index
220  {
221  const auto r = chanTable.get<dune::tde::IndexCrateCard>().equal_range( boost::make_tuple(crate, card) );
222  std::vector<ChannelId> res(r.first, r.second);
223  return res;
224  }
225 
226  // ordered accodring to channel number
227  const auto r = chanTable.get<dune::tde::IndexCrateCardChan>().equal_range( boost::make_tuple( crate, card) );
228  std::vector<ChannelId> res(r.first, r.second);
229 
230  return res;
231 }
232 
233 //
234 //
236  unsigned card, unsigned chan ) const
237 {
238  auto it = chanTable.get<dune::tde::IndexCrateCardChanHash>().find( boost::make_tuple(crate, card, chan) );
239  if( it != chanTable.get<dune::tde::IndexCrateCardChanHash>().end() )
240  return *it;
241 
242  return boost::optional<ChannelId>();
243 }
244 
245 //
246 //
247 std::vector<ChannelId> dune::VDColdboxTDEChannelMapService::find_by_crp( unsigned crp, bool ordered ) const
248 {
249  if( not ordered ) // get from hashed index
250  {
251  const auto r = chanTable.get<dune::tde::IndexCrp>().equal_range( crp );
252  std::vector<ChannelId> res(r.first, r.second);
253  return res;
254  }
255 
256  const auto r = chanTable.get<dune::tde::IndexCrpViewChan>().equal_range( crp );
257  std::vector<ChannelId> res(r.first, r.second);
258  //return res;
259  return res;
260 }
261 
262 //
263 //
264 std::vector<ChannelId> dune::VDColdboxTDEChannelMapService::find_by_crp_view( unsigned crp, unsigned view, bool ordered ) const
265 {
266  if( not ordered ) // get from hashed index
267  {
268  const auto r = chanTable.get<dune::tde::IndexCrpView>().equal_range( boost::make_tuple(crp, view) );
269  std::vector<ChannelId> res(r.first, r.second);
270  return res;
271  }
272 
273  // ordered accodring to channel number
274  const auto r = chanTable.get<dune::tde::IndexCrpViewChan>().equal_range( boost::make_tuple(crp, view) );
275  std::vector<ChannelId> res(r.first, r.second);
276  return res;
277 }
278 
279 //
280 //
281 boost::optional<ChannelId> dune::VDColdboxTDEChannelMapService::find_by_crp_view_chan( unsigned crp,
282  unsigned view, unsigned chan ) const
283 {
284  auto it = chanTable.get<dune::tde::IndexCrpViewChanHash>().find( boost::make_tuple(crp, view, chan) );
285  if( it != chanTable.get<dune::tde::IndexCrpViewChanHash>().end() )
286  return *it;
287 
288  return boost::optional<ChannelId>();
289 }
290 
291 //
292 // Map to CRP channels
293 int dune::VDColdboxTDEChannelMapService::MapToCRP(int seqch, int &crp, int &view, int &chv) const
294 {
295  crp = view = chv = -1;
296  if( boost::optional<ChannelId> id = find_by_seqn( (unsigned)seqch ) )
297  {
298  if( !id->exists() ) return -1;
299  crp = id->crp();
300  view = id->view();
301  chv = id->viewch();
302  return 1;
303  }
304 
305  return -1;
306 }
307 
308 //
309 // Map to DAQ channel sequence
310 int dune::VDColdboxTDEChannelMapService::MapToDAQ(int crp, int view, int chv, int &seqch) const
311 {
312  seqch = -1;
313  if( boost::optional<ChannelId> id = find_by_crp_view_chan( (unsigned)crp, (unsigned)view, (unsigned)chv ) )
314  {
315  if( !id->exists() ) return -1;
316  seqch = id->seqn();
317  return 1;
318  }
319  return -1;
320 }
321 
322 //
323 // number of cards assigned to a given crate
325 {
326  // assumes it is sorted according to card number
327  unsigned count = 0;
328  auto r = chanTable.get<dune::tde::IndexCrateCardChan>().equal_range( crate );
329  ssize_t last = -1;
330  for( ChannelId const &ch : boost::make_iterator_range( r ) )
331  {
332  if( !ch.exists() ) continue;
333  unsigned val = ch.card();
334  if( val != last )
335  {
336  count++;
337  last = val;
338  }
339  }
340 
341  return count;
342 }
343 
344 //
345 // number of views assigned to a given CRP
346 unsigned dune::VDColdboxTDEChannelMapService::nviews( unsigned crp ) const
347 {
348  // assumes it is sorted according to crp number
349  unsigned count = 0;
350  auto r = chanTable.get<dune::tde::IndexCrpViewChan>().equal_range( crp );
351  ssize_t last = -1;
352  for( ChannelId const &ch : boost::make_iterator_range( r ) )
353  {
354  if( !ch.exists() ) continue;
355  unsigned val = ch.view();
356  if( val != last )
357  {
358  count++;
359  last = val;
360  }
361  }
362 
363  return count;
364 }
365 
366 //
367 //
368 void dune::VDColdboxTDEChannelMapService::print( std::vector<ChannelId> &vec )
369 {
370  for( auto it = vec.begin();it!=vec.end();++it )
371  {
372  unsigned seqn = it->seqn();
373  unsigned crate = it->crate();
374  unsigned card = it->card();
375  unsigned cch = it->cardch();
376  unsigned crp = it->crp();
377  unsigned view = it->view();
378  unsigned vch = it->viewch();
379  unsigned state = it->state();
380  bool exists = it->exists();
381  std::cout<<std::setw(7)<<seqn
382  <<std::setw(4)<<crate
383  <<std::setw(3)<<card
384  <<std::setw(3)<<cch
385  <<std::setw(3)<<crp
386  <<std::setw(2)<<view
387  <<std::setw(4)<<vch
388  <<std::setw(2)<<state
389  <<std::setw(2)<<exists<<std::endl;
390  }
391 }
392 
393 // CRP for 1st coldbox test
395 
396  //int ncrates = 3;
397  int nslots = 10;
398  int nview = 3;
399 
400  // utca crate 1
401  dune::tde::crate c1( 0, nslots );
402  vector<int> c1_kel{34, 36, 35, 38, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49};
403  c1.add_crp_connection( 0, 0, c1_kel );
404 
405  // utca crate 2
406  dune::tde::crate c2( 1, nslots );
407  vector<int> c2_kel{14, 16, 15, 18, 17, 19, 20, 22, 21, 25, 23, 24, 26, 27, 28, 32, 29, 30, 31, 33};
408  c2.add_crp_connection( 0, 0, c2_kel );
409 
410  // utca crate 3
411  dune::tde::crate c3( 2, nslots );
412  vector<int> c3_kel{0, 2, 1, 5, 3, 4, 6, 7, 8, 12, 9, 10, 11, 13};
413  c3.add_crp_connection( 0, 0, c3_kel );
414 
415  vector<dune::tde::crate> crates{c1, c2, c3};
416 
417  // all connector mappings should include ADC channel inversion on AMCs
418  // the inversion is in group of 8ch: AMC ch 0 -> 7 should be remapped to 7 -> 0
419 
420  // kel connector orientation in a given view, chans 0 -> 31
421  vector<unsigned> kel_nor = { 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9,
422  8, 23, 22, 21, 20, 19, 18, 17, 16, 31, 30, 29, 28, 27, 26, 25, 24 };
423  // kel connector orientation in a given view, chans 31 -> 0
424  vector<unsigned> kel_inv = {24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22,
425  23, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 };
426 
427 
428  // kel connectors for each view sorted in the view channel order
429  // induction 1
430  vector<int> kel_view0{1,5,8,12,15,18,21,25,28,32,35,38};
431  std::reverse(kel_view0.begin(), kel_view0.end());
432  // induction 2
433  vector<int> kel_view1{40,41,42,43,44,45,46,47,48,49, 13,11,10,9,7,6,4,3,2,0};
434  // collection
435  vector<int> kel_view2{14,16,17,19,20,22,23,24,26,27,29,30,31,33,34,36,37,39};
436  std::reverse(kel_view2.begin(), kel_view2.end());
437 
438 
439  dune::tde::crp_connectors crp_conn( 0, nview );
440  int ch_start = 0;
441  for( auto const k : kel_view0 ){
442  //crp_conn.add_connector( k, 0, true, ch_start );
443  crp_conn.add_connector( k, 0, false, ch_start );
444  ch_start += dune::tde::ch_per_kel;
445  }
446  ch_start = 0;
447  for( auto const k : kel_view1 ){
448  //bool reverse = (k <= 13);
449  bool reverse = (k > 13);
450  crp_conn.add_connector( k, 1, reverse, ch_start );
451  ch_start += dune::tde::ch_per_kel;
452  }
453 
454  ch_start = 0;
455  for( auto const k : kel_view2 ){
456  //crp_conn.add_connector( k, 2, true, ch_start );
457  crp_conn.add_connector( k, 2, false, ch_start );
458  ch_start += dune::tde::ch_per_kel;
459  }
460 
461  // only one crp
462  unsigned crp_id = 0;
463  unsigned seqn = 0;
464 
465  // map the existing DAQ channels to 4th view
466  // not connected view id
467  unsigned view_na = (unsigned)nview;
468  unsigned view_na_ch = 0;
469 
470  for( auto const &utca : crates ) {
471  unsigned utca_id = (unsigned)utca._id;
472  //if( utca_id <= 1 ) continue;
473  auto utca_conn = utca._crp_conn;
474  auto utca_nconn = utca_conn.size();
475  auto utca_slots = (unsigned)utca._cards;
476  for( unsigned amc = 0; amc < utca_slots; ++amc ){
477  // unconnected AMCs
478  if( amc >= utca_nconn ){
479  for( unsigned cardch = 0; cardch < dune::tde::ch_per_amc; ++cardch ){
480  add( seqn++, utca_id, amc, cardch, crp_id, view_na, view_na_ch++, 1);
481  }
482  continue;
483  }
484 
485  // connected to CRU
486  auto conn = utca_conn[ amc ];
487  unsigned islot = (unsigned)std::get<0>(conn);
488  //unsigned icrp = (unsigned)std::get<1>(conn);
489  auto kel1_id = std::get<2>(conn);
490  auto kel2_id = std::get<3>(conn);
491  if( islot != amc ){
492  throw cet::exception("VDColdboxTDEChannelMap")
493  <<"Mismatch in slot and AMC index: slot "
494  << islot<<" != amc "<<amc<<"\n";
495  //amc = islot;
496  }
497 
498  // 1st connector
499  if( kel1_id < (int)crp_conn._kels.size() ){
500  auto kel_ = std::next(crp_conn._kels.begin(), kel1_id);
501  if( kel_->_id != kel1_id ) {
502  throw cet::exception("VDColdboxTDEChannelMap")
503  <<"Mismatch in KEL1 numbering\n";
504  }
505 
506  vector<unsigned> order_ = (kel_->_reverse)? kel_inv : kel_nor;
507  unsigned iview = (unsigned)kel_->_view;
508  unsigned vch_start = (unsigned)kel_->_first_view_ch;
509  for( unsigned cardch = 0; cardch < dune::tde::ch_per_kel; ++cardch ){
510  unsigned viewch = vch_start + order_[cardch];
511  add( seqn++, utca_id, amc, cardch, crp_id, iview, viewch, 0);
512  }
513  } // 1st connector
514 
515  // 2nd connector
516  if( kel2_id < (int)crp_conn._kels.size() ){
517  auto kel_ = std::next(crp_conn._kels.begin(), kel2_id);
518  if( kel_->_id != kel2_id ) {
519  throw cet::exception("VDColdboxTDEChannelMap")
520  <<"Mismatch in KEL2 numbering\n";
521  }
522 
523  vector<unsigned> order_ = (kel_->_reverse)? kel_inv : kel_nor;
524  unsigned iview = (unsigned)kel_->_view;
525  unsigned vch_start = (unsigned)kel_->_first_view_ch;
526  for( unsigned cardch = 0; cardch < dune::tde::ch_per_kel; ++cardch ){
527  unsigned viewch = vch_start + order_[cardch];
528  add( seqn++, utca_id, amc, cardch + dune::tde::ch_per_kel, crp_id, iview, viewch, 0);
529  }
530  }// 2nd connector
531  } // loop over AMCs
532  } // loop over crates
533 
534  //cout<<" seqn = "<<seqn<<endl;
535  // that is it...
536 }
537 
538 
539 
crate(int id, int cards)
void add(unsigned seq, unsigned crate, unsigned card, unsigned cch, unsigned crp, unsigned view, unsigned vch, unsigned short state=0)
std::string string
Definition: nybbler.cc:12
void initMap(std::string mapname, unsigned ncrates=1, unsigned ncards=10, unsigned nviews=1)
void add_crp_connection(int icrp, int fslot, const std::vector< int > &kel_ids)
std::vector< tde::ChannelId > find_by_crate(unsigned crate, bool ordered=true) const
struct vector vector
void simpleMap(unsigned ncrates, unsigned ncards, unsigned nviews)
std::vector< tde::ChannelId > find_by_crp_view(unsigned crp, unsigned view, bool ordered=true) const
bool exists(std::string path)
int MapToCRP(int seqch, int &crp, int &view, int &chv) const
void print(std::vector< tde::ChannelId > &vec)
void swap(Handle< T > &a, Handle< T > &b)
struct dune::tde::crate crate
boost::optional< tde::ChannelId > find_by_crate_card_chan(unsigned crate, unsigned card, unsigned chan) const
T get(std::string const &key) const
Definition: ParameterSet.h:271
multi_index_container< ChannelId, indexed_by< ordered_unique< tag< IndexRawSeqn >, const_mem_fun< ChannelId, const unsigned,&ChannelId::seqn > >, hashed_unique< tag< IndexRawSeqnHash >, const_mem_fun< ChannelId, const unsigned,&ChannelId::seqn > >, hashed_non_unique< tag< IndexCrate >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::crate > >, hashed_non_unique< tag< IndexCrateCard >, composite_key< ChannelId, const_mem_fun< ChannelId, const unsigned short,&ChannelId::crate >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::card > > >, ordered_unique< tag< IndexCrateCardChan >, composite_key< ChannelId, const_mem_fun< ChannelId, const unsigned short,&ChannelId::crate >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::card >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::cardch > > >, hashed_unique< tag< IndexCrateCardChanHash >, composite_key< ChannelId, const_mem_fun< ChannelId, const unsigned short,&ChannelId::crate >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::card >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::cardch > > >, hashed_non_unique< tag< IndexCrp >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::crp > >, hashed_non_unique< tag< IndexCrpView >, composite_key< ChannelId, const_mem_fun< ChannelId, const unsigned short,&ChannelId::crp >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::view > > >, ordered_unique< tag< IndexCrpViewChan >, composite_key< ChannelId, const_mem_fun< ChannelId, const unsigned short,&ChannelId::crp >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::view >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::viewch > > >, hashed_unique< tag< IndexCrpViewChanHash >, composite_key< ChannelId, const_mem_fun< ChannelId, const unsigned short,&ChannelId::crp >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::view >, const_mem_fun< ChannelId, const unsigned short,&ChannelId::viewch > > > > > ChannelTable
int MapToDAQ(int crp, int view, int chv, int &seqch) const
p
Definition: test.py:223
VDColdboxTDEChannelMapService(fhicl::ParameterSet const &p, art::ActivityRegistry &areg)
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
boost::optional< tde::ChannelId > find_by_seqn(unsigned seqn) const
#define DEFINE_ART_SERVICE(svc)
const short ch_per_amc
boost::optional< tde::ChannelId > find_by_crp_view_chan(unsigned crp, unsigned view, unsigned chan) const
const short ch_per_kel
static unsigned int reverse(QString &chars, unsigned char *level, unsigned int a, unsigned int b)
Definition: qstring.cpp:11649
std::vector< tde::ChannelId > find_by_crate_card(unsigned crate, unsigned card, bool ordered=true) const
std::vector< tde::ChannelId > find_by_crp(unsigned crp, bool ordered=true) const
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)