Wire Cell News

Updates on the Wire Cell Toolkit.

Response Refactoring

In WCT we try to follow the mantra "everything is a component". One corollary to that is we try to avoid hard-wiring dependencies by having functionality accessed by hard-wired construction of concrete classes. The various classes having to do with responses suffered from not being available as components. This led to the entire toolkit having hard-wired behavior which hampers support for multiple detectors. This post describes some recent steps to fix this problem.

Survey of Responses

There are various responses that matter in LArTPC. In WCT they include:

field response
a waveform giving induced current for a point charge drifting along a path determined by some starting point ("impact position")
electronics response
strictly referring to the functional form, parameterized by a gain (in units of Voltage/Charge) and a shaping (peaking) time which gives a voltage waveform when convolved with a charge waveform. This is models the effect of the BNL cold electronics.
rcrc response
the RC filters in the MicroBooNE electronics after the cold amplifier.
plane impact response
a roll-up of the above and used for simulation components (Ductor via ImpactZipper)

Field Response Functions

The field response functions (FR) are a large family of waveforms defined along many impact positions that span (so far) up to +/- 10 wires on either side of the "wire of interest" and defined at 1/10 pitch positions. These are (currently) calculated by Garfield and then converted to JSON (see the command wirecell-sigproc convert-garfield). Because they represent a lot of detailed data in a rather specific and not so friendly format it is recommended that users, for the most part, treat these files as "binary blobs".

However, they represent critical data for simulation and signal processing. They need to be used by many components. In order to avoid loading and reloading the same files they should not be loaded directly but rather accessed in components by (you guessed it) another component. The component interface is IFieldResponse is rather trivial, providing just one method field_response() which returns a reference to the top Response::Schema::FieldResponse data structure.

When you need the FR set you should lookup a IFieldResponse component based on a configuration parameter given to your component:

std::string fr_type_name = ...;  // eg, maybe "FieldResponse:InstanceName"
auto ifr = Factory::find_tn(fr_type_name);
auto fr = ifr->field_response();

You can then iterate through planes and wires until getting actual response functions.

Electronics Response

The Electronics Response is a single function giving a waveform parameterized by gain and shaping time. It has a functional form defined deep inside wire-cell-util but your component code should avoid using it directly and instead use an IWaveform component that provides it. With such a component you can get the waveform sample vector as well as start time and sampling period.

The ElecResponse component is currently the only one available and it takes gain and shaping as well as a relative post shaping gain (postgain). Your component may look up a configured version. Again, your component should take the instance name to use as a configuration parameter.

std::string er_type_name = ...;
auto er = Factory::find_tn(er_type_name);
cerr << "Tick is " << er->waveform_period() << endl;
auto spec = dft(er->waveform_samples()); // do FFT

RC Response

The RC response is simply that of an RC circuit. It's parameterized by a "width" in units of time. It also delegates to a hard-wired function deep in wire-cell-util and your component code should look it up just like ER.

Plane Impact Response

The plane impact response (PIR) is a special purpose component which rolls up the FRs and optionally some number of other responses. It performs a convolution of each FR function with all the other response and gives access to the result on a per-impact basis. This component is primarily used by the signal simulation. It has one implementation in wire-cell-gen which can be configured with the FR instance name and a list of instance names for "other" responses. For simulating MicroBooNE for the "other" response includes one ER and two RCs (of the same name so that an RC2 response is effected).

Why Refactoring?

So, what's with the refactoring? Well, we used to violate "everything is a component" guideline with all these responses. This started mostly due to laziness in not getting around to making them honest components. But there were some misuse of them as well, particularly with using PIR:

  • to get some simple configuration parameters that a component should best be configured directly. (Eg, why get a giant PIR with its dependencies just to know how many ticks to make in a readout?)
  • for things that the Pimpos class can provide (this class deserves its own post, and probably should become a component).
  • to get at the FRs instead of getting them directly.

Also, given the hard-wiring, we were unable to support different responses as needed to support different detectors (eg, the RC2 is MicroBooNE-specific). This refactoring was needed to break that hard-wiring.

What now

Mostly this refactoring is not a change that users will care about. However, some things may have broken in the near term. There are also now some configuration items that are no longer hard-wired and need to be supplied in configuration. Work is ongoing to improve the official config examples to catch up with these changes. By the next release this will be all sorted.