FrameTools.cxx
Go to the documentation of this file.
4 
5 #include <iterator>
6 #include <algorithm>
7 #include <unordered_map>
8 #include <unordered_set>
9 #include <numeric>
10 
11 using namespace WireCell;
12 
13 
15 {
16  auto traces = frame->traces();
17  auto tbin_mm = FrameTools::tbin_range(*traces.get());
18 
19  const double tref = frame->time();
20  const double tick = frame->tick();
21  const double tmin = tref + tbin_mm.first*tick; // low edge
22  const double tmax = tref + tbin_mm.second*tick; // high edge
23 
24  if (tmax <= time) { // high edge may be exactly equal to target time and frame does not span.
25  return -1;
26  }
27  if (tmin >= time) { // low edge may be exactly equal to target time and frame does not span.
28  return +1;
29  }
30  return 0;
31 }
32 std::pair<IFrame::pointer, IFrame::pointer> FrameTools::split(IFrame::pointer frame, double time)
33 {
34  int cmp = frmtcmp(frame, time);
35  if (cmp < 0) {
36  return std::pair<IFrame::pointer, IFrame::pointer>(frame, nullptr);
37  }
38  if (cmp > 0) {
39  return std::pair<IFrame::pointer, IFrame::pointer>(nullptr, frame);
40  }
41  // now gotta do the hard work.
42 
43  const double tref = frame->time();
44  const double tick = frame->tick();
45  const int ident = frame->ident();
46 
47  // Every tick equal or larger than this is in the second frame.
48  const double fnticks = (time - tref)/tick;
49  const int tbin_split = 0.5 + fnticks;
50 
51 
52  ITrace::vector mtraces, ptraces;
53  for (auto trace : (*frame->traces())) {
54  const int tbin = trace->tbin();
55 
56  if (tbin >= tbin_split) {
57  ptraces.push_back(trace);
58  continue;
59  }
60 
61  const ITrace::ChargeSequence& wave = trace->charge();
62  const int lbin = tbin + wave.size();
63 
64  if (lbin <= tbin_split) {
65  mtraces.push_back(trace);
66  continue;
67  }
68  const int ind_split = tbin_split - tbin;
69  ITrace::ChargeSequence mcharge(wave.begin(), wave.begin() + ind_split);
70  ITrace::ChargeSequence pcharge(wave.begin() + ind_split, wave.end());
71 
72  const int chid = trace->channel();
73 
74  auto mtrace = std::make_shared<SimpleTrace>(chid, tbin, mcharge);
75  mtraces.push_back(mtrace);
76  auto ptrace = std::make_shared<SimpleTrace>(chid, tbin_split, pcharge);
77  ptraces.push_back(ptrace);
78  }
79  // fixme: what about ident, cmm, tags....
80  IFrame::pointer mframe = std::make_shared<SimpleFrame>(ident, tref, mtraces, tick);
81  IFrame::pointer pframe = std::make_shared<SimpleFrame>(ident, tref, ptraces, tick);
82  return std::pair<IFrame::pointer, IFrame::pointer>(mframe, pframe);
83 }
84 
85 
86 
87 
88 
89 
91 {
92  auto traces = frame->traces();
93  size_t ntraces = traces->size();
94 
95  std::unordered_set<size_t> tagged;
96  for (auto tag : frame->trace_tags()) {
97  const auto& taglist = frame->tagged_traces(tag);
98  tagged.insert(taglist.begin(), taglist.end());
99  }
100  std::vector<size_t> all(ntraces), untagged;
101  std::iota(all.begin(), all.end(), 0);
102  std::set_difference(all.begin(), all.end(), tagged.begin(), tagged.end(),
103  std::inserter(untagged, untagged.begin()));
104  ITrace::vector ret;
105  for (size_t ind : untagged) {
106  ret.push_back(traces->at(ind));
107  }
108  return ret;
109 }
110 
112 {
113  if (tag == "") {
114  return untagged_traces(frame);
115  }
116  ITrace::vector ret;
117  auto const& all_traces = frame->traces();
118  for (size_t index : frame->tagged_traces(tag)) {
119  ret.push_back(all_traces->at(index));
120  }
121  if (!ret.empty()) {
122  return ret;
123  }
124  auto ftags = frame->frame_tags();
125  if (std::find(ftags.begin(), ftags.end(), tag) == ftags.end()) {
126  return ret;
127  }
128  return *all_traces; // must make copy of shared pointers
129 }
130 
131 
133 {
134  const auto nchans = traces.size();
135  FrameTools::channel_list ret(nchans,0);
136  for (size_t ind=0; ind != nchans; ++ind) {
137  ret[ind] = traces[ind]->channel();
138  }
139  return ret;
140 }
141 
142 
143 std::pair<int,int> FrameTools::tbin_range(const ITrace::vector& traces)
144 {
145  const auto siz = traces.size();
146  std::vector<int> tbins(siz), tlens(siz);
147  for (size_t ind=0; ind != siz; ++ind) {
148  const auto trace = traces[ind];
149  const int tbin = trace->tbin();
150  tbins[ind] = tbin;
151  tlens[ind] = tbin+trace->charge().size();
152  }
153  return std::pair<int,int>(
154  *std::min_element(tbins.begin(), tbins.end()),
155  *std::max_element(tlens.begin(), tlens.end()));
156 }
157 
159  const ITrace::vector& traces,
161  channel_list::iterator chend,
162  int tbin)
163 {
164  std::unordered_map<int,int> index;
165  // one col is one tick
166  // one row is one channel
167  // array is indexed in order: (irow, icol)
168  const int ncols = array.cols();
169  const int nrows = std::min((int)array.rows(), (int)std::distance(chit,chend));
170  for (int ind = 0; ind != nrows and chit != chend; ++ind, ++chit) {
171  index[*chit] = ind;
172  }
173  for (const auto trace : traces) {
174 
175  // resolve which row a the channel is at
176  const int ch = trace->channel();
177  auto it = index.find(ch);
178  if (it == index.end()) {
179  continue;
180  }
181  const int irow = it->second;
182 
183  const auto& charge = trace->charge();
184  const int nticks = charge.size();
185  const int dtbin = trace->tbin() - tbin;
186  int icol0 = 0, itick0 = 0;
187  if (dtbin < 0) {
188  itick0 = -dtbin;
189  }
190  if (dtbin > 0) {
191  icol0 = dtbin;
192  }
193 
194  const int ncols_left = ncols - icol0;
195  const int nticks_left = nticks - itick0;
196  if (ncols_left <= 0 or nticks_left <= 0) {
197  continue;
198  }
199  const int nleft = std::min(ncols_left, nticks_left);
200  for (int ind=0; ind != nleft; ++ind) {
201  array(irow, icol0+ind) += charge.at(itick0 + ind);
202  }
203  }
204 }
ITrace::vector tagged_traces(IFrame::pointer frame, IFrame::tag_t tag)
Definition: FrameTools.cxx:111
intermediate_table::iterator iterator
std::shared_ptr< const IFrame > pointer
Definition: IData.h:19
void fill(Array::array_xxf &array, const ITrace::vector &traces, channel_list::iterator ch_begin, channel_list::iterator ch_end, int tbin=0)
Definition: FrameTools.cxx:158
std::vector< pointer > vector
Definition: IData.h:21
const double tick
const int nticks
std::vector< int > channel_list
Definition: FrameTools.h:41
Binning tbins(nticks, t0, t0+readout_time)
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:228
ITrace::vector untagged_traces(IFrame::pointer frame)
Definition: FrameTools.cxx:90
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
channel_list channels(const ITrace::vector &traces)
Definition: FrameTools.cxx:132
int frmtcmp(IFrame::pointer frame, double time)
Definition: FrameTools.cxx:14
std::pair< int, int > tbin_range(const ITrace::vector &traces)
Definition: FrameTools.cxx:143
Definition: Main.h:22
std::pair< IFrame::pointer, IFrame::pointer > split(IFrame::pointer frame, double time)
Definition: FrameTools.cxx:32
std::string tag_t
Definition: IFrame.h:28
static QInternalList< QTextCodec > * all
Definition: qtextcodec.cpp:63
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
Definition: format.h:1970
unsigned nrows(sqlite3 *db, std::string const &tablename)
Definition: helpers.cc:84
std::vector< float > ChargeSequence
Sequential collection of charge.
Definition: ITrace.h:21
Eigen::ArrayXXf array_xxf
A real, 2D array.
Definition: Array.h:54