42 error(
"Response::Schema::load(): empty field response file name");
47 error(
"Response::Schema::load(): failed to load {}", filename);
54 std::vector<PlaneResponse>
planes;
55 for (
auto plane : fr[
"planes"]) {
57 auto plr =
plane[
"PlaneResponse"];
59 std::vector<PathResponse> paths;
60 for (
auto path : plr[
"paths"]) {
61 auto par = path[
"PathResponse"];
63 for (
auto c : par[
"current"][
"array"][
"elements"]) {
64 current.push_back(
c.asDouble());
66 auto wcpath =
PathResponse(current, par[
"pitchpos"].asDouble(), par[
"wirepos"].asDouble());
67 paths.push_back(wcpath);
71 plr[
"planeid"].asInt(),
72 plr[
"location"].asDouble(),
73 plr[
"pitch"].asDouble());
75 planes.push_back(wcplr);
78 auto adir = fr[
"axis"];
81 fr[
"origin"].asDouble(),
82 fr[
"tstart"].asDouble(),
83 fr[
"period"].asDouble(),
84 fr[
"speed"].asDouble());
104 std::vector<PlaneResponse> newplanes;
106 std::vector<PathResponse> newpaths;
110 std::map<int, realseq_t> avgs;
114 std::map<int,realseq_t> fresp_map;
115 std::map<int,std::pair<double,double>> pitch_pos_range_map;
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;
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.;
131 if (fresp_map.find(-eff_num) == fresp_map.end()){
132 fresp_map[-eff_num] = path.current;
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.;
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);
149 for (
size_t i=0;i!=pitch_pos.size();i++){
150 int eff_num = pitch_pos.at(i);
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);
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);
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));
167 wire_regions.insert( round((pitch_pos.at(i)*0.01*pitch+0.001*pitch)/pitch));
173 for(
auto it = wire_regions.begin(); it!=wire_regions.end(); it++){
175 if (avgs.find(wire_no) == avgs.end()) {
178 for (
auto it1 = fresp_map.begin(); it1!= fresp_map.end(); it1++){
179 int resp_num = (*it1).first;
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;
186 if (high_limit > (wire_no+0.5)*pitch ){
187 high_limit = (wire_no+0.5)*pitch;
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;
202 for (
auto it : avgs) {
203 int region = it.first;
207 for (
int k=0;
k!=nsamples;
k++){
208 sum += response.at(
k);
212 newpaths.push_back(
PathResponse(response, region*pitch, 0.0));
231 std::vector<PlaneResponse> newplanes;
233 std::vector<PathResponse> newpaths;
240 for (
int k=0;
k!=nsamples;
k++){
241 ave_response.at(
k) += path.current.at(
k);
259 int ncols = pr.
paths[0].current.size();
262 if (set_nrows< nrows || set_ncols < ncols){
263 error(
"Response: array dimension not correct! ");
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];
282 int ncols = pr.
paths[0].current.size();
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];
306 const double tick = (domain.second-domain.first)/nsamples;
307 for (
int ind=0; ind < nsamples; ++ind) {
308 double t = domain.first + ind*
tick;
309 ret[ind] = (*this)(
t);
315 const int nsamples = tbins.
nbins();
317 for (
int ind=0; ind<nsamples; ++ind) {
319 ret[ind] = (*this)(time);
356 const double reltime = time/shaping;
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;
379 if (freq==0)
return 0;
382 return exp(-0.5*
pow(freq/sigma,power));
387 return 1-exp(-
pow(freq/tau,2));
408 : _width(width), _offset(offset), _tick(tick)
431 :
_tick(tick), _mag(magnitude), _smear(smear),
_offset(offset)
443 else if(time < _tick+_offset && time >=
_offset){
double pitch
The pitch distance between neighboring wires.
double tstart
Time at which drift paths begin.
double center(int ind) const
virtual double operator()(double freq) const
SimpleRC(double width=1.0 *units::ms, double tick=0.5 *units::us, double offset=0.0)
Schema::FieldResponse wire_region_average(const Schema::FieldResponse &fr)
PlaneResponse * plane(int ident)
static const double microsecond
double period
The sampling period of the response function.
HfFilter(double sigma, double power, bool flag)
void dump(const char *filename, const FieldResponse &fr)
virtual double operator()(double time) const
Binning tbins(nticks, t0, t0+readout_time)
Array::array_xxf as_array(const Schema::PlaneResponse &pr)
Schema::FieldResponse average_1D(const Schema::FieldResponse &fr)
double coldelec(double time, double gain=7.8, double shaping=1.0 *units::us)
The cold electronics response function.
virtual double operator()(double freq) const
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
WireCell::Waveform::realseq_t generate(const WireCell::Waveform::Domain &domain, int nsamples)
FIXME: eradicate Domain in favor of Binning.
virtual double operator()(double time) const
Json::Value load(const std::string &filename, const externalvars_t &extvar=externalvars_t(), const externalvars_t &extcode=externalvars_t())
std::vector< PlaneResponse > planes
List of PlaneResponse objects.
ColdElec(double gain=14 *units::mV/units::fC, double shaping=1.0 *units::us)
static int max(int a, int b)
Point Vector
An alias for Point.
IFrame::pointer sum(std::vector< IFrame::pointer > frames, int ident)
FieldResponse load(const char *filename)
double hf_filter(double freq, double sigma=1, double power=2, bool zero_freq_removal=true)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
virtual double operator()(double time) const
unsigned nrows(sqlite3 *db, std::string const &tablename)
std::vector< PathResponse > paths
List of PathResponse objects.
Hold info about multiple plane responses in the detector.
int planeid
A numerical identifier for the plane.
SysResp(double tick=0.5 *units::us, double magnitude=1.0, double smear=0.0 *units::us, double offset=0.0 *units::us)
Eigen::ArrayXXf array_xxf
A real, 2D array.
double lf_filter(double freq, double tau=0.02)
double speed
The nominal drift speed.
void error(const char *fmt, const Args &...args)