Public Member Functions | Private Attributes | List of all members
WireCell::Gen::AnodePlane Class Reference

#include <AnodePlane.h>

Inheritance diagram for WireCell::Gen::AnodePlane:
WireCell::IAnodePlane WireCell::IConfigurable WireCell::IComponent< IAnodePlane > WireCell::IComponent< IConfigurable > WireCell::Interface WireCell::Interface

Public Member Functions

 AnodePlane ()
 
virtual ~AnodePlane ()
 
virtual void configure (const WireCell::Configuration &config)
 Accept a configuration. More...
 
virtual WireCell::Configuration default_configuration () const
 Optional, override to return a hard-coded default configuration. More...
 
virtual int ident () const
 IAnodePlane interface. More...
 
virtual int nfaces () const
 Return number of faces (eg, MicroBooNE=1, DUNE=2) More...
 
virtual IAnodeFace::pointer face (int ident) const
 Return a anode face by its ident number. More...
 
virtual IAnodeFace::vector faces () const
 Return all faces. More...
 
virtual WirePlaneId resolve (int channel) const
 Resolve a channel ident number to a WirePlaneId. More...
 
virtual std::vector< int > channels () const
 Return a collection of all channels. More...
 
virtual IChannel::pointer channel (int chident) const
 Return an IChannel with the associated channel ID. More...
 
virtual IWire::vector wires (int channel) const
 Return all wires connected into the given channel ident number. More...
 
- Public Member Functions inherited from WireCell::IAnodePlane
virtual ~IAnodePlane ()
 
- Public Member Functions inherited from WireCell::IComponent< IAnodePlane >
virtual ~IComponent ()
 
- Public Member Functions inherited from WireCell::Interface
virtual ~Interface ()
 
- Public Member Functions inherited from WireCell::IConfigurable
virtual ~IConfigurable ()
 
- Public Member Functions inherited from WireCell::IComponent< IConfigurable >
virtual ~IComponent ()
 

Private Attributes

int m_ident
 
IAnodeFace::vector m_faces
 
std::unordered_map< int, int > m_c2wpid
 
std::unordered_map< int, IWire::vectorm_c2wires
 
std::vector< int > m_channels
 
std::unordered_map< int, IChannel::pointerm_ichannels
 
Log::logptr_t l
 

Additional Inherited Members

- Public Types inherited from WireCell::IComponent< IAnodePlane >
typedef std::shared_ptr< IAnodePlanepointer
 Access subclass facet by pointer. More...
 
typedef std::vector< pointervector
 Vector of shared pointers. More...
 
- Public Types inherited from WireCell::Interface
typedef std::shared_ptr< Interfacepointer
 
- Public Types inherited from WireCell::IComponent< IConfigurable >
typedef std::shared_ptr< IConfigurablepointer
 Access subclass facet by pointer. More...
 
typedef std::vector< pointervector
 Vector of shared pointers. More...
 

Detailed Description

Definition at line 18 of file AnodePlane.h.

Constructor & Destructor Documentation

Gen::AnodePlane::AnodePlane ( )

Definition at line 28 of file AnodePlane.cxx.

29  : m_ident(0)
30  , l(Log::logger("geom"))
31 {
32 }
logptr_t logger(std::string name)
Definition: Logging.cxx:71
virtual WireCell::Gen::AnodePlane::~AnodePlane ( )
inlinevirtual

Definition at line 22 of file AnodePlane.h.

22 {}

Member Function Documentation

IChannel::pointer Gen::AnodePlane::channel ( int  chident) const
virtual

Return an IChannel with the associated channel ID.

Implements WireCell::IAnodePlane.

Definition at line 297 of file AnodePlane.cxx.

298 {
299  auto it = m_ichannels.find(chident);
300  if (it == m_ichannels.end()) {
301  return nullptr;
302  }
303  return it->second;
304 }
std::unordered_map< int, IChannel::pointer > m_ichannels
Definition: AnodePlane.h:48
std::vector< int > Gen::AnodePlane::channels ( ) const
virtual

Return a collection of all channels.

Implements WireCell::IAnodePlane.

Definition at line 306 of file AnodePlane.cxx.

307 {
308  return m_channels;
309 }
std::vector< int > m_channels
Definition: AnodePlane.h:47
void Gen::AnodePlane::configure ( const WireCell::Configuration config)
virtual

Accept a configuration.

Implements WireCell::IConfigurable.

Definition at line 108 of file AnodePlane.cxx.

109 {
110  m_faces.clear();
111  m_ident = get<int>(cfg, "ident", 0);
112 
113  // check for obsolete config params:
114  if (!cfg["wires"].isNull()) {
115  l->warn("AnodePlane configuration is obsolete.");
116  l->warn("Use \"wire_store\" to name components instead of directly giving file names");
117  l->warn("This job will likely throw an exception next");
118  }
119 
120  // AnodePlane used to have the mistake of tight coupling with
121  // field response functions.
122  if (!cfg["fields"].isNull() or !cfg["field_response"].isNull()) {
123  l->warn("AnodePlane does not require any field response functions.");
124  }
125 
126  auto jfaces = cfg["faces"];
127  if (jfaces.isNull() or jfaces.empty() or (jfaces[0].isNull() and jfaces[1].isNull())) {
128  l->critical("at least two faces need to be defined, got:\n{}", jfaces);
129  THROW(ValueError() << errmsg{"AnodePlane: error in configuration"});
130  }
131 
132 
133  const int nimpacts = get<int>(cfg, "nimpacts", default_nimpacts);
134 
135 
136  // get wire schema
137  const string ws_name = get<string>(cfg, "wire_schema");
138  if (ws_name.empty()) {
139  l->critical("\"wire_schema\" parameter must specify an IWireSchema component");
140  THROW(ValueError() << errmsg{"\"wire_schema\" parameter must specify an IWireSchema component"});
141  }
142  auto iws = Factory::find_tn<IWireSchema>(ws_name); // throws if not found
143  const WireSchema::Store& ws_store = iws->wire_schema_store();
144 
145  // keep track which channels we know about in this anode.
146  m_channels.clear();
147 
148  const WireSchema::Anode& ws_anode = ws_store.anode(m_ident);
149 
150  std::vector<WireSchema::Face> ws_faces = ws_store.faces(ws_anode);
151  const size_t nfaces = ws_faces.size();
152 
153  channel_wire_collector_t chwcollector;
154 
155  m_faces.resize(nfaces);
156  // note, WireSchema requires front/back face ordering in an anode
157  for (size_t iface=0; iface<nfaces; ++iface) {
158  const auto& ws_face = ws_faces[iface];
159  std::vector<WireSchema::Plane> ws_planes = ws_store.planes(ws_face);
160  const size_t nplanes = ws_planes.size();
161 
162  // location of imaginary boundary planes
163  bool sensitive_face = true;
164  auto jface = jfaces[(int)iface];
165  if (jface.isNull()) {
166  sensitive_face = false;
167  l->debug("anode {} face {} is not sensitive", m_ident, iface);
168  }
169  const double response_x = jface["response"].asDouble();
170  const double anode_x = get(jface, "anode", response_x);
171  const double cathode_x = jface["cathode"].asDouble();
172  l->debug("AnodePlane: X planes: \"cathode\"@ {}m, \"response\"@{}m, \"anode\"@{}m",
173  cathode_x / units::m, response_x / units::m, anode_x/units::m);
174 
175  IWirePlane::vector planes(nplanes);
176  // note, WireSchema requires U/V/W plane ordering in a face.
177  for (size_t iplane=0; iplane<nplanes; ++iplane) {
178  const auto& ws_plane = ws_planes[iplane];
179 
180  WirePlaneId wire_plane_id(iplane2layer[iplane], iface, m_ident);
181  if (wire_plane_id.index() < 0) {
182  l->critical("Bad wire plane id: {}", wire_plane_id.ident());
183  THROW(ValueError() << errmsg{format("bad wire plane id: %d", wire_plane_id.ident())});
184  }
185 
186  // (wire,pitch) directions
187  auto wire_pitch_dirs = ws_store.wire_pitch(ws_plane);
188  auto ecks_dir = wire_pitch_dirs.first.cross(wire_pitch_dirs.second);
189 
190  std::vector<int> plane_chans = ws_store.channels(ws_plane);
191  m_channels.insert(m_channels.end(), plane_chans.begin(), plane_chans.end());
192 
193  std::vector<WireSchema::Wire> ws_wires = ws_store.wires(ws_plane);
194  const size_t nwires = ws_wires.size();
195  IWire::vector wires(nwires);
196 
197  // note, WireSchema requires wire-in-plane ordering
198  for (size_t iwire=0; iwire<nwires; ++iwire) {
199  const auto& ws_wire = ws_wires[iwire];
200  const int chanid = plane_chans[iwire];
201 
202  Ray ray(ws_wire.tail, ws_wire.head);
203  auto iwireptr = make_shared<SimpleWire>(wire_plane_id, ws_wire.ident,
204  iwire, chanid, ray,
205  ws_wire.segment);
206  wires[iwire] = iwireptr;
207  m_c2wires[chanid].push_back(iwireptr);
208  m_c2wpid[chanid] = wire_plane_id.ident();
209  chwcollector(iwireptr);
210  } // wire
211 
212  const BoundingBox bb = ws_store.bounding_box(ws_plane);
213  const Ray bb_ray = bb.bounds();
214  const Vector plane_center = 0.5*(bb_ray.first + bb_ray.second);
215 
216  const double pitchmin = wire_pitch_dirs.second.dot(wires[0]->center() - plane_center);
217  const double pitchmax = wire_pitch_dirs.second.dot(wires[nwires-1]->center() - plane_center);
218  const Vector pimpos_origin(response_x, plane_center.y(), plane_center.z());
219 
220  l->debug("AnodePlane: face:{}, plane:{}, origin:{} mm",
221  iface, iplane, pimpos_origin/units::mm);
222 
223  Pimpos* pimpos = new Pimpos(nwires, pitchmin, pitchmax,
224  wire_pitch_dirs.first, wire_pitch_dirs.second,
225  pimpos_origin, nimpacts);
226 
227  IChannel::vector plane_channels;
228  {
229  for (auto w : wires) {
230  if (w->segment() > 0) {
231  continue;
232  }
233 
234  const int chanid = w->channel();
235  SimpleChannel* sch = chwcollector(chanid);
236  sch->set_index(plane_channels.size());
237  IChannel::pointer ich(sch);
238  m_ichannels[chanid] = ich;
239  plane_channels.push_back(ich);
240  }
241  }
242  sort(wires.begin(), wires.end(), IWireCompareIndex()); // redundant?
243  planes[iplane] = make_shared<WirePlane>(ws_plane.ident, pimpos, wires, plane_channels);
244 
245  // Last iteration, use W plane to define volume
246  if (iplane == nplanes-1) {
247  const double mean_pitch = (pitchmax - pitchmin) / (nwires-1);
248  BoundingBox sensvol;
249  if (sensitive_face) {
250  auto v1 = bb_ray.first;
251  auto v2 = bb_ray.second;
252  // Enlarge to anode/cathode planes in X and by 1/2 pitch in Z.
253  Point p1( anode_x, v1.y(), std::min(v1.z(), v2.z()) - 0.5*mean_pitch);
254  sensvol(p1);
255  Point p2(cathode_x, v2.y(), std::max(v1.z(), v2.z()) + 0.5*mean_pitch);
256  sensvol(p2);
257  }
258 
259  l->debug("AnodePlane: face:{} with {} planes and sensvol: {}",
260  ws_face.ident, planes.size(), sensvol.bounds());
261 
262  m_faces[iface] = make_shared<AnodeFace>(ws_face.ident, planes, sensvol);
263  }
264  } // plane
265  } // face
266 
267  // remove any duplicate channels
268  std::sort(m_channels.begin(), m_channels.end());
269  auto chend = std::unique(m_channels.begin(), m_channels.end());
270  m_channels.resize( std::distance(m_channels.begin(), chend) );
271 
272 }
std::unordered_map< int, int > m_c2wpid
Definition: AnodePlane.h:45
std::pair< Point, Point > Ray
A line segment running from a first (tail) to a second (head) point.
Definition: Point.h:21
const int nwires
std::shared_ptr< const IChannel > pointer
Definition: IData.h:19
static const double m
Definition: Units.h:63
D3Vector< double > Point
A 3D Cartesian point in double precision.
Definition: Point.h:15
std::unordered_map< int, IWire::vector > m_c2wires
Definition: AnodePlane.h:46
boost::error_info< struct tag_errmsg, std::string > errmsg
Definition: Exceptions.h:54
cfg
Definition: dbjson.py:29
std::vector< pointer > vector
Definition: IData.h:21
const WirePlaneLayer_t iplane2layer[3]
Definition: WirePlaneId.h:14
std::vector< int > m_channels
Definition: AnodePlane.h:47
std::vector< pointer > vector
Vector of shared pointers.
Definition: IComponent.h:36
#define THROW(e)
Definition: Exceptions.h:25
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
def wire_plane_id(plane, face, apa)
Definition: schema.py:236
static const double mm
Definition: Units.h:55
std::unordered_map< int, IChannel::pointer > m_ichannels
Definition: AnodePlane.h:48
std::vector< float > Vector
virtual int nfaces() const
Return number of faces (eg, MicroBooNE=1, DUNE=2)
Definition: AnodePlane.h:32
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
virtual IWire::vector wires(int channel) const
Return all wires connected into the given channel ident number.
Definition: AnodePlane.cxx:311
Pimpos pimpos(nwires, min_wire_pitch, max_wire_pitch)
def center(depos, point)
Definition: depos.py:117
IAnodeFace::vector m_faces
Definition: AnodePlane.h:43
const int default_nimpacts
Definition: AnodePlane.cxx:36
WireCell::Configuration Gen::AnodePlane::default_configuration ( ) const
virtual

Optional, override to return a hard-coded default configuration.

This number is used to take from the wire file the anode

Name of a IWireSchema component.

Reimplemented from WireCell::IConfigurable.

Definition at line 38 of file AnodePlane.cxx.

39 {
41 
42  /// This number is used to take from the wire file the anode
43  put(cfg, "ident", 0);
44 
45  /// Name of a IWireSchema component.
46  // note: this used to be a "wires" parameter directly specifying a filename.
47  put(cfg, "wire_schema", "");
48 
49  // Number of impact positions per wire pitch. This should likely
50  // match exactly what the field response functions use.
51  put(cfg, "nimpacts", default_nimpacts);
52 
53  // The AnodePlane has to two faces, one of which may be "null".
54  // Face 0 or "front" is the one that is toward the positive X-axis
55  // (wire coordinate system). A face consists of wires and some
56  // bounds on the X-coordinate in the form of three planes:
57  //
58  // - response :: The response plane demarks the location where the
59  // complex fields near the wires are considered sufficiently
60  // regular.
61  //
62  // - anode and cathode :: These two planes bracket the region in X
63  // - for the volume associated with the face. The transverse
64  // - range is determined by the wires. If anode is not given then
65  // - response will be used instead. Along with wires, these
66  // - determine the sensitive bounding box of the AnodeFaces.
67  //
68  // eg: faces: [
69  // {response: 10*wc.cm - 6*wc.mm, 2.5604*wc.m},
70  // null,
71  // ]
72 
73  cfg["faces"][0] = Json::nullValue;
74  cfg["faces"][1] = Json::nullValue;
75 
76  return cfg;
77 }
void put(Configuration &cfg, const std::string &dotpath, const T &val)
Put value in configuration at the dotted path.
cfg
Definition: dbjson.py:29
Json::Value Configuration
Definition: Configuration.h:50
const int default_nimpacts
Definition: AnodePlane.cxx:36
IAnodeFace::pointer Gen::AnodePlane::face ( int  ident) const
virtual

Return a anode face by its ident number.

Implements WireCell::IAnodePlane.

Definition at line 275 of file AnodePlane.cxx.

276 {
277  for (auto ptr : m_faces) {
278  if (ptr->ident() == ident) {
279  return ptr;
280  }
281  }
282  return nullptr;
283 }
virtual int ident() const
IAnodePlane interface.
Definition: AnodePlane.h:31
const void * ptr(const T *p)
Definition: format.h:3138
IAnodeFace::vector m_faces
Definition: AnodePlane.h:43
virtual IAnodeFace::vector WireCell::Gen::AnodePlane::faces ( ) const
inlinevirtual

Return all faces.

Implements WireCell::IAnodePlane.

Definition at line 34 of file AnodePlane.h.

34 { return m_faces; }
IAnodeFace::vector m_faces
Definition: AnodePlane.h:43
virtual int WireCell::Gen::AnodePlane::ident ( ) const
inlinevirtual

IAnodePlane interface.

Implements WireCell::IAnodePlane.

Definition at line 31 of file AnodePlane.h.

31 { return m_ident; }
virtual int WireCell::Gen::AnodePlane::nfaces ( ) const
inlinevirtual

Return number of faces (eg, MicroBooNE=1, DUNE=2)

Implements WireCell::IAnodePlane.

Definition at line 32 of file AnodePlane.h.

32 { return m_faces.size(); }
IAnodeFace::vector m_faces
Definition: AnodePlane.h:43
WirePlaneId Gen::AnodePlane::resolve ( int  channel) const
virtual

Resolve a channel ident number to a WirePlaneId.

Implements WireCell::IAnodePlane.

Definition at line 286 of file AnodePlane.cxx.

287 {
288  const WirePlaneId bogus(0xFFFFFFFF);
289 
290  auto got = m_c2wpid.find(channel);
291  if (got == m_c2wpid.end()) {
292  return bogus;
293  }
294  return WirePlaneId(got->second);
295 }
std::unordered_map< int, int > m_c2wpid
Definition: AnodePlane.h:45
virtual IChannel::pointer channel(int chident) const
Return an IChannel with the associated channel ID.
Definition: AnodePlane.cxx:297
IWire::vector Gen::AnodePlane::wires ( int  chident) const
virtual

Return all wires connected into the given channel ident number.

Implements WireCell::IAnodePlane.

Definition at line 311 of file AnodePlane.cxx.

312 {
313  auto it = m_c2wires.find(channel);
314  if (it == m_c2wires.end()) {
315  return IWire::vector();
316  }
317  return it->second;
318 }
std::unordered_map< int, IWire::vector > m_c2wires
Definition: AnodePlane.h:46
std::vector< pointer > vector
Definition: IData.h:21
virtual IChannel::pointer channel(int chident) const
Return an IChannel with the associated channel ID.
Definition: AnodePlane.cxx:297

Member Data Documentation

Log::logptr_t WireCell::Gen::AnodePlane::l
private

Definition at line 49 of file AnodePlane.h.

std::unordered_map<int, IWire::vector> WireCell::Gen::AnodePlane::m_c2wires
private

Definition at line 46 of file AnodePlane.h.

std::unordered_map<int, int> WireCell::Gen::AnodePlane::m_c2wpid
private

Definition at line 45 of file AnodePlane.h.

std::vector<int> WireCell::Gen::AnodePlane::m_channels
private

Definition at line 47 of file AnodePlane.h.

IAnodeFace::vector WireCell::Gen::AnodePlane::m_faces
private

Definition at line 43 of file AnodePlane.h.

std::unordered_map<int, IChannel::pointer> WireCell::Gen::AnodePlane::m_ichannels
private

Definition at line 48 of file AnodePlane.h.

int WireCell::Gen::AnodePlane::m_ident
private

Definition at line 42 of file AnodePlane.h.


The documentation for this class was generated from the following files: