Skip to content
5 changes: 4 additions & 1 deletion fcl/caf/cafmaker_add_detsim2d_icarus.fcl
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ physics.producers.mcreco.G4ModName: @erase
physics.producers.mcreco.MCParticleLabel: "largeant"
physics.producers.mcreco.SimChannelLabel: "daq:simpleSC"

this_cal_constants: [1.343e-2, 1.338e-2, 0.01227]
# Mini production, pre signal shape tuning
# this_cal_constants: [1.343e-2, 1.338e-2, 0.01227]
# Post signal shape tuning
this_cal_constants: [1.343e-2, 1.338e-2, 0.01285]
#include "set_caf_calconst.fcl"
3 changes: 3 additions & 0 deletions fcl/detsim/detsim_2d_icarus_fitFR.fcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "detsim_2d_icarus.fcl"

physics.producers.daq: @local::icarus_simwire_wirecell_fitSR
27 changes: 27 additions & 0 deletions icaruscode/TPC/ICARUSWireCell/detsimmodules_wirecell_ICARUS.fcl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ icarus_simwire_wirecell:
// Make available parameters via Jsonnet's std.extVar()
params: {
files_fields: "garfield-icarus-fnal-rev1.json.bz2"
file_rcresp: "" # use the RCResponse by default
}
structs: {
# load values from simulationservices_icarus.fcl
Expand All @@ -49,9 +50,35 @@ icarus_simwire_wirecell:
# Scaling Parameters from int and coh noise components
int_noise_scale: 1.0
coh_noise_scale: 1.09

# Gain and shaping time
gain0: 14.9654 # mV/fC
gain1: 14.9654 # mV/fC
gain2: 14.9654 # mV/fC

shaping0: 1.3 # us
shaping1: 1.3 # us
shaping2: 1.3 # us

# Time offsets for truth matching
time_offset_u: 1.0 # us
time_offset_v: 1.0 # us
time_offset_y: 1.0 # us

}
}
}

icarus_simwire_wirecell_fitSR: @local::icarus_simwire_wirecell
# Add in the ER tail
icarus_simwire_wirecell_fitSR.wcls_main.params.file_rcresp: "icarus_fnal_rc_tail.json"
# Add in the tuned field responses
icarus_simwire_wirecell_fitSR.wcls_main.params.files_fields: "icarus_fnal_fit_ks.json.bz2"
# futz with shaping+gain values (note these are really just scale factors and should not be taken literally)
icarus_simwire_wirecell_fitSR.wcls_main.structs.gain0: 10.2636323 # mV/fC
icarus_simwire_wirecell_fitSR.wcls_main.structs.gain1: 12.1420344 # mV/fC
icarus_simwire_wirecell_fitSR.wcls_main.structs.gain2: 13.0261362 # mV/fC
icarus_simwire_wirecell_fitSR.wcls_main.structs.shaping1: 1.45 # us


END_PROLOG
171 changes: 171 additions & 0 deletions icaruscode/TPC/ICARUSWireCell/icarus/icarus_tools.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// This file provides a function which takes a params object (see
// ../params/) and returns a data structure with a number of
// sub-objects that may configure various WCT "tool" type componets
// which are not INodes.

// Some attributes are merely default and you may wish to override
// them. For example, the default IDFT FftwDFT and to instead ues
// TorchDFT you may do something like:
//
// local default_tools = tools_maker(params)
// local tools = std.mergePatch(default_tools,
// {dft: {type: "TorchDFT", data: {device: "gpu"}}});
//

local wc = import "wirecell.jsonnet";

function(params)
{
// The IRandom pRNG
random : {
type: "Random",
data: {
generator: "default",
seeds: [0,1,2,3,4],
}
},
// The IDFT FFT implementation
dft : {
type: "FftwDFT",
},

// One FR per field file.
fields : std.mapWithIndex(function (n, fname) {
type: "FieldResponse",
name: "field%d"%n,
data: { filename: fname }
}, params.files.fields),

field: $.fields[0], // the nominal field

// The number of ticks for response waveforms. For simulation
// this must be enlarged beyond what is wanted in the output
// readout in order to accept catch early activity into the first
// few readout ticks. When responses are used to deconvolve then
// this should best be shortened. Note: sigproc at time of
// writing did not use components for Elec or RC so are not
// currently subject to this config.
local sim_response_binning = {
tick: params.daq.tick,
nticks: params.sim.ductor.nticks, // MUST match ductor
},

perchanresp : {
type: "PerChannelResponse",
data: {
filename: params.files.chresp,
}
},
// It's a little awkward to NOT use PerChannelResponse because you
// need to give an empty string to a component that wants to use
// it an an empty list to the "uses". Here we package that little
// "if" branch. It's a general pattern not specific to this
// object. Might want to make wc.tn() convert "null" into "" and
// g.uses() convert [null] into [].
perchanresp_nameuses : if std.type(params.files.chresp) == 'null'
then {name:"", uses:[]}
else {name:wc.tn(self.perchanresp), uses:[self.perchanresp]},


wires : {
type: "WireSchemaFile",
data: { filename: params.files.wires }
},

elec_resp : std.mapWithIndex(function (n, e) {
type: if std.objectHas(e, "type")
then e.type
else "ColdElecResponse", // default
name: "Plane%iElectronicsResponse" % n,
data: sim_response_binning {
shaping: e.shaping,
gain: e.gain,
postgain: e.postgain,
filename: if std.objectHas(e, "filename")
then e.filename
else ""
},
}, params.elec),

rc_resp : {
type: if std.objectHas(params, 'rc_resp') && std.objectHas(params.rc_resp, "type")
then params.rc_resp.type
else "RCResponse", // default
data: std.prune(sim_response_binning {
width: if std.objectHas(params, 'rc_resp') && std.objectHas(params.rc_resp, 'width')
then params.rc_resp.width else null,

filename: if std.objectHas(params, 'rc_resp') && std.objectHas(params.rc_resp, 'filename')
then params.rc_resp.filename else null,

postgain: if std.objectHas(params, 'rc_resp') && std.objectHas(params.rc_resp, 'postgain')
then params.rc_resp.postgain else null,

start: if std.objectHas(params, 'rc_resp') && std.objectHas(params.rc_resp, 'start')
then params.rc_resp.start else null,
})
},


sys_resp : {
type: "ResponseSys",
data: sim_response_binning {
start: params.sys_resp.start,
magnitude: params.sys_resp.magnitude,
time_smear: params.sys_resp.time_smear,
}
},

// there is one trio of PIRs (one per wire plane in a face) for
// each field response. WARNING/fixme: this sets the default DFT
// with no way to override! This config structure needs a redo!
pirs : std.mapWithIndex(function (n, fr) [
{
type: "PlaneImpactResponse",
name : "PIR%splane%d" % [fr.name, plane],
data : sim_response_binning {
plane: plane,
dft: wc.tn($.dft),
field_response: wc.tn(fr),
// note twice we give rc so we have rc^2 in the final convolution
short_responses: if params.sys_status == false
then [wc.tn($.elec_resp[plane])]
else [wc.tn($.elec_resp[plane]), wc.tn($.sys_resp)],
overall_short_padding: if std.objectHas(params, 'overall_short_padding')
then params.overall_short_padding
else if params.sys_status == false
then 0.1*wc.ms
// cover the full time range of the convolved short responses
else 0.1*wc.ms - params.sys_resp.start,
// long_responses: [wc.tn($.rc_resp), wc.tn($.rc_resp)],
long_responses: if std.objectHas(params, 'rc_resp')
then std.makeArray(params.rc_resp.rc_layers, function(x) wc.tn($.rc_resp))
else [wc.tn($.rc_resp), wc.tn($.rc_resp)],
long_padding: 1.5*wc.ms,
},
uses: [$.dft, fr, $.elec_resp[plane], $.rc_resp, $.sys_resp],
} for plane in [0,1,2]], $.fields),

// One anode per detector "volume"
anodes : [{
type : "AnodePlane",
name : vol.name,
data : {
// This ID is used to pick out which wires in the
// WireSchema belong to this anode plane.
ident : vol.wires,
nimpacts: params.sim.nimpacts,
// The wire schema file
wire_schema: wc.tn($.wires),

faces : vol.faces,
},
uses: [$.wires],
} for vol in params.det.volumes],

// Arbitrarily call out the first anode to make single-anode
// detector config slightly cleaner.
anode: $.anodes[0],

}

9 changes: 5 additions & 4 deletions icaruscode/TPC/ICARUSWireCell/icarus/params.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,16 @@ base {
fullscale: [0.8*wc.millivolt, 3.3*wc.volt],
},

elec: super.elec {
elec: [super.elec {
type: "WarmElecResponse",
// gain: 17.8075*wc.mV/wc.fC, // 0.027 fC/(ADC*us)
// Set gain to (roughly) match data ADC values (docdb 25161)
// Old values:
// ICARUS nominal: 17.8075*wc.mV/wc.fC // 0.027 fC/(ADC*us)
// Match data ADC values (docdb 25161): 14.9654*wc.mV/wc.fC, // 0.0321 fC/(ADC*us)
gain: 14.9654*wc.mV/wc.fC, // 0.0321 fC/(ADC*us)
shaping: 1.3*wc.us,
postgain: 1.0,
start: 0,
},
}, for _ in [0, 1, 2]],


sim: super.sim {
Expand Down
17 changes: 4 additions & 13 deletions icaruscode/TPC/ICARUSWireCell/icarus/simparams.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,6 @@ base {
// chresp: null,
//},

// This sets a relative gain at the input to the ADC. Note, if
// you are looking to fix SimDepoSource, you are in the wrong
// place. See the "scale" parameter of wcls.input.depos() defined
// in pgrapher/common/ui/wcls/nodes.jsonnet.
elec: super.elec {
// postgain: 1.0,
// shaping: 2.2 * wc.us,
},

sys_status: false,
sys_resp: {
// overall_short_padding should take into account this offset "start".
Expand All @@ -56,8 +47,8 @@ base {
time_smear: 1.0 * wc.us,
},

rc_resp: {
width: 1.1*wc.ms,
rc_layers: 1,
}
rc_resp: {
width: 1.1*wc.ms,
rc_layers: 1,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ local params = params_init {
},
};

local tools_maker = import 'pgrapher/common/tools.jsonnet';
local tools_maker = import 'pgrapher/experiment/icarus/icarus_tools.jsonnet';
local tools = tools_maker(params);

local wcls_maker = import 'pgrapher/ui/wcls/nodes.jsonnet';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ local f = import 'pgrapher/common/funcs.jsonnet';
local wc = import 'wirecell.jsonnet';

local io = import 'pgrapher/common/fileio.jsonnet';
local tools_maker = import 'pgrapher/common/tools.jsonnet';
local tools_maker = import 'pgrapher/experiment/icarus/tools.jsonnet';
// local params = import 'pgrapher/experiment/icarus/simparams.jsonnet';
local base = import 'pgrapher/experiment/icarus/simparams.jsonnet';
local params = base {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,28 @@ local f = import 'pgrapher/common/funcs.jsonnet';
local wc = import 'wirecell.jsonnet';

local io = import 'pgrapher/common/fileio.jsonnet';
local tools_maker = import 'pgrapher/common/tools.jsonnet';
local tools_maker = import 'pgrapher/experiment/icarus/icarus_tools.jsonnet';
// local params = import 'pgrapher/experiment/icarus/simparams.jsonnet';
local base = import 'pgrapher/experiment/icarus/simparams.jsonnet';

// load the electronics response parameters
local er_params = [
{
gain: std.extVar('gain0')*wc.mV/wc.fC,
shaping: std.extVar('shaping0')*wc.us,
},

{
gain: std.extVar('gain1')*wc.mV/wc.fC,
shaping: std.extVar('shaping1')*wc.us,
},

{
gain: std.extVar('gain2')*wc.mV/wc.fC,
shaping: std.extVar('shaping2')*wc.us,
},
];

local params = base {
lar: super.lar {
// Longitudinal diffusion constant
Expand All @@ -24,6 +43,25 @@ local params = base {
files: super.files {
fields: [ std.extVar('files_fields'), ],
},

rc_resp: if std.extVar('file_rcresp') != "" then
{
// "icarus_fnal_rc_tail.json"
filename: std.extVar('file_rcresp'),
postgain: 1.0,
start: 0.0,
tick: 0.4*wc.us,
nticks: 4255,
type: "JsonElecResponse",
rc_layers: 1
}
else super.rc_resp,

elec: std.mapWithIndex(function (n, eparam)
super.elec[n] + {
gain: eparam.gain,
shaping: eparam.shaping,
}, er_params),
};

local tools = tools_maker(params);
Expand Down Expand Up @@ -181,15 +219,15 @@ local wcls_simchannel_sink = g.pnode({

// GP: The shaping time of the electronics response (1.3us) shifts the peak
// of the field response time. Eyeballing simulation times, it does this
// by a bit less than the 1.3us.
// by a bit less than the 1.3us (1us).
//
// N.B. for future: there is likely an additional offset on the two induction
// planes due to where the deconvolution precisely defines where the "peak"
// of the pulse is. One may want to refine these parameters to account for that.
// This perturbation shouldn't be more than a tick or two.
u_time_offset: 1.0 * wc.us,
v_time_offset: 1.0 * wc.us,
y_time_offset: 1.0 * wc.us,
u_time_offset: std.extVar('time_offset_u') * wc.us,
v_time_offset: std.extVar('time_offset_v') * wc.us,
y_time_offset: std.extVar('time_offset_y') * wc.us,

g4_ref_time: -1500 * wc.us, // G4RefTime from detectorclocks_icarus.fcl
use_energy: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ local f = import 'pgrapher/common/funcs.jsonnet';
local wc = import 'wirecell.jsonnet';

local io = import 'pgrapher/common/fileio.jsonnet';
local tools_maker = import 'pgrapher/common/tools.jsonnet';
local tools_maker = import 'pgrapher/experiment/icarus/tools.jsonnet';
local params = import 'pgrapher/experiment/icarus/simparams.jsonnet';

local tools = tools_maker(params);
Expand Down
2 changes: 1 addition & 1 deletion icaruscode/TPC/ICARUSWireCell/icarus/wct-sim-check.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ local f = import 'pgrapher/common/funcs.jsonnet';
local wc = import 'wirecell.jsonnet';

local io = import 'pgrapher/common/fileio.jsonnet';
local tools_maker = import 'pgrapher/common/tools.jsonnet';
local tools_maker = import 'pgrapher/experiment/icarus/icarus_tools.jsonnet';
local params = import 'pgrapher/experiment/icarus/simparams.jsonnet';

local tools = tools_maker(params);
Expand Down