AdcMultiChannelPlotter_tool.cc
Go to the documentation of this file.
1 // AdcMultiChannelPlotter_t.cc
2 
10 #include <iostream>
11 #include <sstream>
12 
13 using std::cout;
14 using std::endl;
15 using std::ostringstream;
16 
17 //**********************************************************************
18 
20 : m_LogLevel(ps.get<Index>("LogLevel")),
21  m_PlotChannelRanges(ps.get<NameVector>(prefix + "ChannelRanges")),
22  m_PlotChannelGroups(ps.get<NameVector>(prefix + "ChannelGroups")),
23  m_PlotOverlayGroups(ps.get<Index>(prefix + "OverlayGroups")),
24  m_PlotDataView(ps.get<Name>(prefix + "DataView")),
25  m_PlotName(ps.get<Name>(prefix + "Name")),
26  m_PlotSummaryNames(ps.get<NameVector>(prefix + "SummaryNames")),
27  m_PlotSizeX(ps.get<Index>(prefix + "SizeX")),
28  m_PlotSizeY(ps.get<Index>(prefix + "SizeY")),
29  m_PlotSplitX(ps.get<Index>(prefix + "SplitX")),
30  m_PlotSplitY(ps.get<Index>(prefix + "SplitY")) {
31  const Name myname = "AdcMultiChannelPlotter::ctor: ";
32  if ( m_LogLevel >= 1 ) {
33  cout << myname << " LogLevel: " << m_LogLevel << endl;
34  bool first = true;
35  cout << myname << " " << prefix + "ChannelRanges: [";
36  for ( Name crn : m_PlotChannelRanges ) {
37  if ( first ) first = false;
38  else cout << ", ";
39  cout << crn;
40  }
41  cout << "]" << endl;
42  cout << myname << " " << prefix + "ChannelGroups: [";
43  first = true;
44  for ( Name cgn : m_PlotChannelGroups ) {
45  if ( first ) first = false;
46  else cout << ", ";
47  cout << cgn;
48  }
49  cout << "]" << endl;
50  cout << myname << " " << prefix << "OverlayGroups: " << m_PlotOverlayGroups << endl;
51  cout << myname << " " << prefix << "DataView: " << m_PlotDataView << endl;
52  cout << myname << " " << prefix << "Name: " << m_PlotName << endl;
53  cout << myname << " " << prefix << "SummaryNames: [";
54  first = true;
55  for ( Name name : m_PlotSummaryNames ) {
56  if ( first ) first = false;
57  else cout << ", ";
58  cout << name;
59  }
60  cout << "]" << endl;
61  cout << myname << " " << prefix << "SizeX: " << m_PlotSizeX << endl;
62  cout << myname << " " << prefix << "SizeY: " << m_PlotSizeY << endl;
63  cout << myname << " " << prefix << "SplitX: " << m_PlotSplitX << endl;
64  cout << myname << " " << prefix << "SplitY: " << m_PlotSplitY << endl;
65  }
66  Name stringBuilder = "adcStringBuilder";
68  if ( ptm == nullptr ) {
69  cout << myname << "ERROR: Tool manager not found." << endl;
70  } else {
71  // Fetch the string builder.
72  m_adcStringBuilder = ptm->getShared<AdcChannelStringTool>(stringBuilder);
73  if ( m_adcStringBuilder == nullptr ) {
74  cout << myname << "WARNING: AdcChannelStringTool not found: " << stringBuilder << endl;
75  }
76  // Build pad descriptions from groups.
77  if ( haveChannelGroups() && ptm != nullptr ) {
78  const IndexRangeGroupTool* pcgt = ptm->getShared<IndexRangeGroupTool>("channelGroups");
79  if ( pcgt == nullptr ) {
80  cout << myname << "ERROR: IndexRangeGroupTool not found: channelGroups" << endl;
81  } else {
82  for ( Name cgn : m_PlotChannelGroups ) {
83  IndexRangeGroup grp = pcgt->get(cgn);
84  if ( ! grp.isValid() ) {
85  cout << myname << "WARNING: Skipping invalid group " << cgn << endl;
86  continue;
87  }
88  m_cgmap[cgn] = grp;
89  Pad* ppad = nullptr;
90  for ( const IndexRange& ran : grp.ranges ) {
91  Name crn = ran.name;
92  if ( ! ran.isValid() ) {
93  cout << myname << "WARNING: Skipping invalid range " << crn << " in group " << cgn << endl;
94  continue;
95  }
96  if ( ppad == nullptr ) {
97  m_pads.emplace_back(cgn);
98  ppad = &m_pads.back();
99  }
100  if ( ppad->crmap.find(crn) != ppad->crmap.end() ) {
101  cout << myname << "WARNING: Ignoring duplicate channel range group " << cgn << endl;
102  continue;
103  }
104  ppad->crnames.push_back(crn);
105  ppad->crmap[crn] = ran;
106  if ( ! overlayGroups() ) ppad = nullptr;
107  } // end loop over ranges in group
108  } // end loop over groups
109  }
110  }
111  // Build pad descriptions from ranges.
112  if ( haveChannelRanges() && ptm != nullptr ) {
113  const IndexRangeTool* pcrt = ptm->getShared<IndexRangeTool>("channelRanges");
114  if ( pcrt == nullptr ) {
115  cout << myname << "ERROR: IndexRangeTool not found: channelRanges" << endl;
116  } else {
117  for ( Name crn : m_PlotChannelRanges ) {
118  IndexRange ran = pcrt->get(crn);
119  if ( ! ran.isValid() ) {
120  cout << myname << "WARNING: Skipping invalid range " << crn << endl;
121  continue;
122  }
123  m_pads.emplace_back(crn); // Use range name as group name
124  Pad& pad = m_pads.back();
125  pad.crnames.push_back(crn);
126  pad.crmap[crn] = ran;
127  } // end loop over ranges
128  }
129  }
130  }
131  if ( m_LogLevel >= 1 ) cout << myname << "Drawing pad count is " << m_pads.size() << endl;
132 }
133 
134 //**********************************************************************
135 
137  // viewSummary(); // Can't call this here b/c it uses virtual calls.
138 }
139 
140 //**********************************************************************
141 
143  const Name myname = "AdcMultiChannelPlotter::viewMap: ";
144  DataMap ret;
145  if ( acds.size() == 0 ) return ret;
146  if ( ! getBaseState().hasRun() ) {
147  getBaseState().setRun(acds.begin()->second.run);
148  }
149  getBaseState().event = acds.begin()->second.event;
150  Index npadx = 0;
151  Index npady = 0;
152  Index npadOnPage = 0;
153  if ( getPlotName().size() && m_PlotSplitX > 0 ) {
154  npadx = m_PlotSplitX;
156  npadOnPage = npadx*npady;
157  }
158  if ( getLogLevel() >= 2 ) {
159  cout << myname << "Per page pad count is " << npadOnPage << " (" << npady << " x " << npadx << ")" << endl;
160  }
161  Name plotName;
162  TPadManipulator* pmantop = nullptr;
163  bool doRanges = haveChannelRanges() || haveChannelGroups();
164  PadVector localPads;
165  // Build pad vector for single channels.
166  if ( ! doRanges ) {
167  for ( AdcChannelDataMap::value_type iacd : acds ) {
168  const AdcChannelData& acd = iacd.second;
169  Index icha = acd.channel;
170  getBaseState().channels.insert(icha);
171  ostringstream sscha;
172  sscha << icha;
173  Name scha = sscha.str();
174  while ( scha.size() < 6 ) scha = "0" + scha;
175  scha = "chan" + scha;
176  localPads.emplace_back(scha);
177  Pad& pad = localPads.back();
178  pad.crnames.push_back(scha);
179  pad.crmap[scha] = IndexRange(icha, icha+1);
180  }
181  }
182  const PadVector& pads = doRanges ? m_pads : localPads;
183  Index npad = pads.size();
184  if ( getLogLevel() >= 4 ) cout << myname << "Pad count is " << npad << endl;
185  Index ncha = 0;
186  Index nplt = 0;
187  Index ipadOnPage = 0;
188  for ( Index ipad=0; ipad<npad; ++ipad ) {
189  const Pad& pad = pads[ipad];
190  Name cgn = pad.cgname;
191  if ( getLogLevel() >= 4 ) {
192  cout << myname << " Processing pad " << ipad << " for channel group " << cgn << endl;
193  }
194  Index ncr = pad.crnames.size();
195  for ( Index icr=0; icr<ncr; ++icr ) {
196  Name crn = pad.crnames[icr];
197  const IndexRange& ran = pad.crmap.at(crn);
198  if ( ! ran.isValid() ) {
199  cout << "ERROR: Range " << crn << " in pad group " << cgn << " is invalid. Aborting." << endl;
200  abort();
201  }
202  if ( getLogLevel() >= 5 ) {
203  cout << myname << " Processing range " << ran << endl;
204  }
205  AdcChannelDataMap::const_iterator iacd1 = acds.lower_bound(ran.first());
206  if ( iacd1 == acds.end() ) {
207  if ( getLogLevel() >= 5 ) cout << myname << " Skipping range above data." << endl;
208  continue;
209  }
210  AdcChannelDataMap::const_iterator iacd2 = acds.upper_bound(ran.last());
211  if ( iacd2 == iacd1 ) {
212  if ( getLogLevel() >= 5 ) cout << myname << " Skipping range below data." << endl;
213  continue;
214  }
215  AcdVector acdvec;
216  Index ncha = 0;
217  for ( AdcChannelDataMap::const_iterator iacd=iacd1; iacd!=iacd2; ++iacd ) {
218  const AdcChannelData& acd = iacd->second;
219  Index icha = iacd->first;
220  if ( ! acd.hasView(getDataView()) ) {
221  cout << myname << "WARNING: View " << getDataView() << " is missing for channel "
222  << icha << "." << endl;
223  }
224  Index ndve = acd.viewSize(getDataView());
225  for ( Index idve=0; idve<ndve; ++idve ) {
226  acdvec.push_back(acd.viewEntry(getDataView(), idve));
227  }
228  ++ncha;
229  }
230  if ( getLogLevel() >= 4 ) {
231  Index nacd = acdvec.size();
232  cout << myname << " Processing channel range " << crn << " with " << nacd
233  << " entr" << (nacd == 1 ? "y" : "ies" ) << " in " << ncha << " channel"
234  << (ncha == 1 ? "" : "s") << "." << endl;
235  }
236  // If needed, create a new canvas and a name.
237  const AdcChannelData& acdFirst = *acdvec[0];
238  if ( pmantop == nullptr ) {
239  if ( getLogLevel() >= 3 ) cout << myname << " Creating canvas for run " << acdFirst.run
240  << ", event " << acdFirst.event << "." << endl;
241  pmantop = new TPadManipulator;
243  if ( npadOnPage > 1 ) pmantop->split(npadx, npady);
245  StringManipulator sman(plotName, false);
246  Name cgrn = overlayGroups() ? cgn : crn;
247  sman.replace("%CGNAME%", cgn);
248  sman.replace("%CRNAME%", crn);
249  sman.replace("%CGRNAME%", cgrn);
250  sman.replace("%VIEW%", getDataView());
251  plotName = sman.str();
252  if ( getLogLevel() >= 4 ) {
253  if ( plotName.size() ) cout << myname << " Created pad with plot name " << plotName << endl;
254  else cout << myname << " Created pad with no plot name." << endl;
255  }
256  }
257  // View this channel range.
258  TPadManipulator* ppadPage = pmantop->man(ipadOnPage);
259  if ( ppadPage == nullptr ) {
260  cout << myname << "ERROR: View pad " << ipadOnPage << " not found for pad " << ipad << ", channel range " << crn << "." << endl;
261  } else {
262  viewMapChannels(crn, acdvec, *ppadPage, ncr, icr);
263  ncha += acds.size();
264  }
265  }
266  // Handle the end of a plot file.
267  ++ipadOnPage;
268  bool lastpad = (npadOnPage == 0) || (ipadOnPage == npadOnPage) || (ipad+1 == npad);
269  if ( lastpad && pmantop != nullptr ) {
270  if ( plotName.size() ) {
271  if ( getLogLevel() >= 3 ) cout << myname << " Printing canvas to " << plotName << endl;
272  pmantop->print(plotName);
273  } else {
274  if ( getLogLevel() >= 3 ) cout << myname << " Not printing canvas for channel group "
275  << cgn << "." << endl;
276  }
277  delete pmantop;
278  pmantop = nullptr;
279  ipadOnPage = 0;
280  ++nplt;
281  }
282  }
283  delete pmantop;
284  ret.setInt("multiChannelNChannel", ncha);
285  ret.setInt("multiChannelNPlot", nplt);
286  return ret;
287 }
288 
289 //**********************************************************************
290 
292  const Name myname = "AdcMultiChannelPlotter::viewSummary: ";
293  if ( getPlotSummaryName(ilev).size() == 0 ) {
294  if ( getLogLevel() >= 3 ) cout << myname << "Summmary plots not named for level " << ilev << endl;
295  return;
296  }
297  if ( getLogLevel() >= 3 ) cout << myname << "Creating summmary plots for level " << ilev << endl;
298  Index npadx = 0;
299  Index npady = 0;
300  Index npadOnPage = 1;
301  if ( m_PlotSplitX > 0 ) {
302  npadx = m_PlotSplitX;
304  npadOnPage = npadx*npady;
305  }
306  if ( getLogLevel() >= 2 ) {
307  cout << myname << "Pad count/page is " << npadOnPage << " (" << npady << " x " << npadx << ")" << endl;
308  }
309  TPadManipulator* pmantop = nullptr;
310  PadVector localPads;
311  // Build pad vector for single channels.
312  bool doRanges = haveChannelRanges() || haveChannelGroups();
313  if ( ! doRanges ) {
314  for ( Index icha : getBaseState().channels ) {
315  ostringstream sscha;
316  sscha << icha;
317  Name scha = sscha.str();
318  while ( scha.size() < 6 ) scha = "0" + scha;
319  scha = "chan" + scha;
320  localPads.emplace_back(scha);
321  Pad& pad = localPads.back();
322  pad.crnames.push_back(scha);
323  pad.crmap[scha] = IndexRange(icha, icha+1);
324  }
325  }
326  const PadVector& pads = doRanges ? m_pads : localPads;
327  Index npad = pads.size();
328  Name plotName;
329  AdcChannelData acdPrint;
330  acdPrint.run = getBaseState().run();
331  acdPrint.event = getBaseState().event;
332  if ( getLogLevel() >= 3 ) cout << myname << "Pad count is " << npad << endl;
333  for ( Index ipad =0; ipad<npad; ++ipad ) {
334  const Pad& pad = pads[ipad];
335  Name cgn = pad.cgname;
336  Index ipadOnPage = npad == 0 ? 0 : ipad % npadOnPage;
337  if ( getLogLevel() >= 4 ) cout << myname << " Channel group " << cgn
338  << " channel range count is " << pad.crnames.size() << endl;
339  Index ncrn = pad.crnames.size();
340  // # CRNs included in plot.
341  for ( Index icrn=0; icrn<ncrn; ++icrn ) {
342  Name crn = pad.crnames[icrn];
343  if ( getLogLevel() >= 4 ) {
344  cout << myname << " Processing group/range " << cgn << "/" << crn << endl;
345  }
346  // If needed, create a new canvas and a name.
347  acdPrint.channel = pad.crmap.at(crn).begin;
348  if ( pmantop == nullptr ) {
349  if ( getLogLevel() >= 3 ) cout << myname << " Creating canvas for run " << acdPrint.run
350  << ", event " << acdPrint.event << "." << endl;
351  pmantop = new TPadManipulator;
353  if ( npadOnPage > 1 ) pmantop->split(npadx, npady);
354  DataMap dmPrint;
355  //dmPrint.setInt("CHAN1", ran.first());
356  //dmPrint.setInt("CHAN2", ran.last());
357  plotName = AdcChannelStringTool::build(m_adcStringBuilder, acdPrint, dmPrint, getPlotSummaryName(ilev));
358  StringManipulator sman(plotName, false);
359  sman.replace("%CRNAME%", crn);
360  sman.replace("%CGNAME%", cgn);
361  sman.replace("%VIEW%", getDataView());
362  }
363  // View this channel range.
364  int rstat = viewMapSummary(ilev, cgn, crn, *pmantop->man(ipadOnPage), ncrn, icrn);
365  if ( rstat >= 1 ) cout << myname << "WARNING: viewMapSummary returned error code " << rstat << endl;
366  if ( getLogLevel() >= 5 ) cout << myname << " Pad " << ipadOnPage << " extra object count: "
367  << pmantop->man(ipadOnPage)->objects().size() << endl;
368  }
369  // Handle the end of a plot file.
370  bool lastpad = (npadOnPage == 0) || (ipadOnPage+1 == npadOnPage) || (ipad+1 == npad);
371  if ( lastpad && pmantop != nullptr ) {
372  if ( getLogLevel() >= 3 ) cout << myname << " Printing summary canvas to " << plotName << endl;
373  pmantop->print(plotName);
374  delete pmantop;
375  pmantop = nullptr;
376  }
377  }
378 }
379 
380 //**********************************************************************
381 
383  const Name myname = "AdcMultiChannelPlotter::getChannelGroup: ";
384  ChannelGroupMap::const_iterator icgr = m_cgmap.find(cgn);
385  if ( icgr == m_cgmap.end() ) {
386  // Not an error -- we may index by range or channel name instead of group name.
387  //cout << myname << "ERROR: Group not found: " << cgn << endl;
388  static const IndexRangeGroup badcgr;
389  return badcgr;
390  }
391  return icgr->second;
392 }
393 
394 //**********************************************************************
static QCString name
Definition: declinfo.cpp:673
std::vector< Name > NameVector
static const double ps
Definition: Units.h:102
Name getPlotSummaryName(Index ilev) const
BaseState & getBaseState() const
int replace(std::string substr, const T &xsub)
int setCanvasSize(int wx, int wy)
int split(Index nx, Index ny)
intermediate_table::const_iterator const_iterator
bool isValid() const
Definition: IndexRange.h:57
const std::string & str()
Name name
Definition: IndexRange.h:32
void viewSummary(Index ilev) const
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
Index last() const
Definition: IndexRange.h:59
AdcMultiChannelPlotter(const fhicl::ParameterSet &ps, Name prefix="Plot")
const IndexRangeGroup & getChannelGroup(Name cgn) const
static std::string build(const AdcChannelStringTool *ptool, const AdcChannelData &acd, const DataMap &dm, std::string spat)
AdcChannel channel
DataMap viewMap(const AdcChannelDataMap &acds) const override
void setInt(Name name, int val)
Definition: DataMap.h:131
virtual int viewMapSummary(Index ilev, Name cgn, Name crn, TPadManipulator &man, Index ncr, Index icr) const =0
virtual IndexRangeGroup get(Name nam) const =0
std::vector< Pad > PadVector
RangeVector ranges
Index first() const
Definition: IndexRange.h:58
virtual int viewMapChannels(Name crn, const AcdVector &acds, TPadManipulator &man, Index ncr, Index icr) const =0
const AdcChannelData * viewEntry(Name vpnam, AdcIndex ient) const
size_t viewSize() const
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
const TObjVector & objects() const
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
bool hasView(Name vnam) const
const AdcChannelStringTool * m_adcStringBuilder
TPadManipulator * man(unsigned int ipad=0)
if(!yymsg) yymsg
bool isValid() const
int print(std::string fname, std::string spat="{,}")
static DuneToolManager * instance(std::string fclname="", int dbg=1)
std::vector< const AdcChannelData * > AcdVector
T * getShared(std::string name)
QTextStream & endl(QTextStream &s)
virtual IndexRange get(Name nam) const =0