Namespaces | Classes | Functions
WireCell::Response Namespace Reference

Namespaces

 Schema
 

Classes

class  ColdElec
 A functional object caching gain and shape. More...
 
class  Generator
 
class  HfFilter
 
class  LfFilter
 
class  SimpleRC
 
class  SysResp
 

Functions

Schema::FieldResponse wire_region_average (const Schema::FieldResponse &fr)
 
Schema::FieldResponse average_1D (const Schema::FieldResponse &fr)
 
Array::array_xxf as_array (const Schema::PlaneResponse &pr)
 
Array::array_xxf as_array (const Schema::PlaneResponse &pr, int set_nrows, int set_ncols)
 
double coldelec (double time, double gain=7.8, double shaping=1.0 *units::us)
 The cold electronics response function. More...
 
double hf_filter (double freq, double sigma=1, double power=2, bool zero_freq_removal=true)
 
double lf_filter (double freq, double tau=0.02)
 

Function Documentation

Array::array_xxf WireCell::Response::as_array ( const Schema::PlaneResponse pr)

Return the plane's response as a 2D array. This is a straight copy of the plane's current vectors into rows of the returned array. The first "path" will be in row 0. Each column thus contains the same sample (aka tick) across all current waveforms. Column 0 is first sample. The plane response input data is taken at face value an not attempt to resolve any implicit symmetries is made.

Definition at line 279 of file Response.cxx.

280 {
281  int nrows = pr.paths.size();
282  int ncols = pr.paths[0].current.size();
283  Array::array_xxf ret(nrows, ncols); // warning, uninitialized
284 
285  for (int irow = 0; irow < nrows; ++irow) {
286  auto& path = pr.paths[irow];
287  for (int icol = 0; icol < ncols; ++icol) {
288  ret(irow,icol) = path.current[icol]; // maybe there is a fast way to do this copy?
289  }
290  }
291  return ret;
292 }
unsigned nrows(sqlite3 *db, std::string const &tablename)
Definition: helpers.cc:84
Eigen::ArrayXXf array_xxf
A real, 2D array.
Definition: Array.h:54
Array::array_xxf WireCell::Response::as_array ( const Schema::PlaneResponse pr,
int  set_nrows,
int  set_ncols 
)

Definition at line 256 of file Response.cxx.

257 {
258  int nrows = pr.paths.size();
259  int ncols = pr.paths[0].current.size();
260  Array::array_xxf ret= Array::array_xxf::Zero(set_nrows, set_ncols); // warning, uninitialized
261 
262  if (set_nrows< nrows || set_ncols < ncols){
263  error("Response: array dimension not correct! ");
264  return ret;
265  }
266 
267  for (int irow = 0; irow < nrows; ++irow) {
268  if (irow < set_nrows){
269  auto& path = pr.paths[irow];
270  for (int icol = 0; icol < ncols; ++icol) {
271  if (icol < set_ncols)
272  ret(irow,icol) = path.current[icol]; // maybe there is a fast way to do this copy?
273  }
274  }
275  }
276  return ret;
277 }
error
Definition: include.cc:26
unsigned nrows(sqlite3 *db, std::string const &tablename)
Definition: helpers.cc:84
Eigen::ArrayXXf array_xxf
A real, 2D array.
Definition: Array.h:54
Response::Schema::FieldResponse WireCell::Response::average_1D ( const Schema::FieldResponse fr)

Definition at line 224 of file Response.cxx.

225 {
226  using namespace WireCell::Waveform;
227  using namespace WireCell::Response::Schema;
228 
230 
231  std::vector<PlaneResponse> newplanes;
232  for (auto plane : fr_wire_avg.planes) {
233  std::vector<PathResponse> newpaths;
234 
235  int nsamples = Response::as_array(plane).cols();
236 
237  realseq_t ave_response(nsamples,0);
238 
239  for (auto path : plane.paths) {
240  for (int k=0;k!=nsamples;k++){
241  ave_response.at(k) += path.current.at(k);
242  }
243  }
244 
245  newpaths.push_back(PathResponse(ave_response,0.0,0.0));
246 
247  newplanes.push_back(PlaneResponse(newpaths,
248  plane.planeid,
249  plane.location,
250  plane.pitch));
251  }
252  return FieldResponse(newplanes, fr.axis, fr.origin, fr.tstart, fr.period, fr.speed);
253 }
Sequence< real_t > realseq_t
Definition: Waveform.h:31
Schema::FieldResponse wire_region_average(const Schema::FieldResponse &fr)
Definition: Response.cxx:99
Array::array_xxf as_array(const Schema::PlaneResponse &pr)
Definition: Response.cxx:279
std::vector< PlaneResponse > planes
List of PlaneResponse objects.
Definition: Response.h:78
Hold info about multiple plane responses in the detector.
Definition: Response.h:75
double WireCell::Response::coldelec ( double  time,
double  gain = 7.8,
double  shaping = 1.0*units::us 
)

The cold electronics response function.

Definition at line 350 of file Response.cxx.

351 {
352  if (time <=0 || time >= 10 * units::microsecond) { // range of validity
353  return 0.0;
354  }
355 
356  const double reltime = time/shaping;
357 
358  // a scaling is needed to make the anti-Lapalace peak match the expected gain
359  // fixme: this scaling is slightly dependent on shaping time. See response.py
360  gain *= 10*1.012;
361 
362  return 4.31054*exp(-2.94809*reltime)*gain
363  -2.6202*exp(-2.82833*reltime)*cos(1.19361*reltime)*gain
364  -2.6202*exp(-2.82833*reltime)*cos(1.19361*reltime)*cos(2.38722*reltime)*gain
365  +0.464924*exp(-2.40318*reltime)*cos(2.5928*reltime)*gain
366  +0.464924*exp(-2.40318*reltime)*cos(2.5928*reltime)*cos(5.18561*reltime)*gain
367  +0.762456*exp(-2.82833*reltime)*sin(1.19361*reltime)*gain
368  -0.762456*exp(-2.82833*reltime)*cos(2.38722*reltime)*sin(1.19361*reltime)*gain
369  +0.762456*exp(-2.82833*reltime)*cos(1.19361*reltime)*sin(2.38722*reltime)*gain
370  -2.620200*exp(-2.82833*reltime)*sin(1.19361*reltime)*sin(2.38722*reltime)*gain
371  -0.327684*exp(-2.40318*reltime)*sin(2.5928*reltime)*gain +
372  +0.327684*exp(-2.40318*reltime)*cos(5.18561*reltime)*sin(2.5928*reltime)*gain
373  -0.327684*exp(-2.40318*reltime)*cos(2.5928*reltime)*sin(5.18561*reltime)*gain
374  +0.464924*exp(-2.40318*reltime)*sin(2.5928*reltime)*sin(5.18561*reltime)*gain;
375 }
microsecond_as<> microsecond
Type of time stored in microseconds, in double precision.
Definition: spacetime.h:114
double WireCell::Response::hf_filter ( double  freq,
double  sigma = 1,
double  power = 2,
bool  zero_freq_removal = true 
)

Definition at line 377 of file Response.cxx.

377  {
378  if (flag){
379  if (freq==0) return 0;
380  }
381 
382  return exp(-0.5*pow(freq/sigma,power));
383 
384 }
constexpr T pow(T x)
Definition: pow.h:72
double WireCell::Response::lf_filter ( double  freq,
double  tau = 0.02 
)

Definition at line 386 of file Response.cxx.

386  {
387  return 1-exp(-pow(freq/tau,2));
388 }
constexpr T pow(T x)
Definition: pow.h:72
Response::Schema::FieldResponse WireCell::Response::wire_region_average ( const Schema::FieldResponse fr)

Return a reduced FieldResponse structure where the Path::Response::current arrays are reduced by averaging over each wire region.

Warning! this function is NOT GENERAL. It is actually specific to Garfield 1D line of paths with half the impact positions represented!

Definition at line 99 of file Response.cxx.

100 {
101  using namespace WireCell::Waveform;
102  using namespace WireCell::Response::Schema;
103 
104  std::vector<PlaneResponse> newplanes;
105  for (auto plane : fr.planes) {
106  std::vector<PathResponse> newpaths;
107 
108  double pitch = plane.pitch;
109 
110  std::map<int, realseq_t> avgs;
111  //std::map<int, int> nums;
112 
113 
114  std::map<int,realseq_t> fresp_map;
115  std::map<int,std::pair<double,double>> pitch_pos_range_map;
116 
117  // figure out the range of each response ...
118 
119  int nsamples=0;
120 
121  for (auto path : plane.paths) {
122  int eff_num = path.pitchpos/(0.01 * pitch);
123  if (fresp_map.find(eff_num) == fresp_map.end()){
124  fresp_map[eff_num] = path.current;
125  }else{
126  nsamples = path.current.size();
127  for (int k=0;k!=nsamples;k++){
128  fresp_map[eff_num].at(k) = (fresp_map[eff_num].at(k) + path.current.at(k))/2.;
129  }
130  }
131  if (fresp_map.find(-eff_num) == fresp_map.end()){
132  fresp_map[-eff_num] = path.current;
133  }else{
134  int nsamples = path.current.size();
135  for (int k=0;k!=nsamples;k++){
136  fresp_map[-eff_num].at(k) = (fresp_map[-eff_num].at(k) + path.current.at(k))/2.;
137  }
138  }
139  }
140 
141 
142  std::vector<int> pitch_pos;
143  for (auto it = fresp_map.begin(); it!= fresp_map.end(); it++){
144  pitch_pos.push_back((*it).first);
145  }
146 
147  double min = -1e9;
148  double max = 1e9;
149  for (size_t i=0;i!=pitch_pos.size();i++){
150  int eff_num = pitch_pos.at(i);
151  if (i==0){
152  pitch_pos_range_map[eff_num] = std::make_pair(min,(pitch_pos.at(i) + pitch_pos.at(i+1))/2.*0.01*pitch);
153  }else if (i==pitch_pos.size()-1){
154  pitch_pos_range_map[eff_num] = std::make_pair((pitch_pos.at(i) + pitch_pos.at(i-1))/2.*0.01*pitch,max);
155  }else{
156  pitch_pos_range_map[eff_num] = std::make_pair((pitch_pos.at(i) + pitch_pos.at(i-1))/2.*0.01*pitch,(pitch_pos.at(i) + pitch_pos.at(i+1))/2.*0.01*pitch);
157  }
158  }
159 
160 
161  // figure out how many wires ...
162  std::set<int> wire_regions;
163  for (size_t i=0;i!=pitch_pos.size();i++){
164  if (pitch_pos.at(i)>0){
165  wire_regions.insert( round((pitch_pos.at(i)*0.01*pitch-0.001*pitch)/pitch));
166  }else{
167  wire_regions.insert( round((pitch_pos.at(i)*0.01*pitch+0.001*pitch)/pitch));
168  }
169  }
170 
171 
172  // do the average ...
173  for(auto it = wire_regions.begin(); it!=wire_regions.end(); it++){
174  int wire_no = *it;
175  if (avgs.find(wire_no) == avgs.end()) {
176  avgs[wire_no] = realseq_t(nsamples);
177  }
178  for (auto it1 = fresp_map.begin(); it1!= fresp_map.end(); it1++){
179  int resp_num = (*it1).first;
180  realseq_t& response = (*it1).second;
181  double low_limit = pitch_pos_range_map[resp_num].first;
182  double high_limit = pitch_pos_range_map[resp_num].second;
183  if (low_limit < (wire_no - 0.5)*pitch ){
184  low_limit = (wire_no - 0.5)*pitch;
185  }
186  if (high_limit > (wire_no+0.5)*pitch ){
187  high_limit = (wire_no+0.5)*pitch;
188  }
189 
190  //
191 
192  if (high_limit > low_limit){
193  for (int k=0;k!=nsamples;k++){
194  avgs[wire_no].at(k) += response.at(k) * (high_limit - low_limit) / pitch;
195  }
196  }
197  }
198  }
199 
200 
201  // do average.
202  for (auto it : avgs) {
203  int region = it.first;
204  realseq_t& response = it.second;
205 
206  double sum = 0;
207  for (int k=0;k!=nsamples;k++){
208  sum += response.at(k);
209  }
210 
211  // pack up everything for return.
212  newpaths.push_back(PathResponse(response, region*pitch, 0.0));
213  }
214  newplanes.push_back(PlaneResponse(newpaths,
215  plane.planeid,
216  plane.location,
217  plane.pitch));
218  }
219  return FieldResponse(newplanes, fr.axis, fr.origin, fr.tstart, fr.period, fr.speed);
220 }
Sequence< real_t > realseq_t
Definition: Waveform.h:31
static int max(int a, int b)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
Val sum(const Sequence< Val > &seq)
Return sum of all entries in sequence.
Definition: Waveform.h:178
Hold info about multiple plane responses in the detector.
Definition: Response.h:75