GeoObjectSorter35.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file GeoObjectSorter35.cxx
3 /// \brief Interface to algorithm class for sorting standard geo::XXXGeo objects
4 ///
5 /// \version $Id: $
6 /// \author brebel@fnal.gov
7 ////////////////////////////////////////////////////////////////////////
8 
16 
17 #include "fhiclcpp/ParameterSet.h"
19 
20 #include <cmath> // for std::abs
21 
22 namespace geo{
23 
24  //----------------------------------------------------------------------------
25  static bool sortAuxDet35(const AuxDetGeo& ad1, const AuxDetGeo& ad2)
26  {
27 
28  double xyz1[3] = {0.};
29  double xyz2[3] = {0.};
30  double local[3] = {0.};
31  ad1.LocalToWorld(local, xyz1);
32  ad2.LocalToWorld(local, xyz2);
33 
34  // AuxDet groups in 35t may have a couple-cm difference in vertical pos
35  // Adjusting for this messes up sorting between the top layers of AuxDets
36  float VertEps(0);
37  if ( strncmp( (ad1.TotalVolume())->GetName(), "volAuxDetTrap", 13) == 0 ) VertEps = 13;
38  else if( strncmp( (ad1.TotalVolume())->GetName(), "volAuxDetBox", 12) == 0 ) VertEps = 1;
39 
40  // First sort all AuxDets into same-y groups
41  if( xyz1[1] < xyz2[1] && xyz2[1]-xyz1[1] >= VertEps ) return true;
42 
43  // Within a same-y group, sort AuxDets into same-x groups
44  if( std::abs(xyz2[1]-xyz1[1]) < VertEps && xyz1[0] < xyz2[0]) return true;
45 
46  // Within a same-x, same-y group, sort AuxDets according to z
47  if(xyz1[0] == xyz2[0] && std::abs(xyz2[1]-xyz1[1]) < VertEps && xyz1[2] < xyz2[2]) return true;
48 
49  // none of those are true, so return false
50  return false;
51 
52  }
53 
54  //----------------------------------------------------------------------------
55  static bool sortAuxDetSensitive35(const AuxDetSensitiveGeo& ad1, const AuxDetSensitiveGeo& ad2)
56  {
57 
58  double xyz1[3] = {0.};
59  double xyz2[3] = {0.};
60  double local[3] = {0.};
61  ad1.LocalToWorld(local, xyz1);
62  ad2.LocalToWorld(local, xyz2);
63 
64  // AuxDet groups in 35t may have a couple-cm difference in vertical pos
65  // Adjusting for this messes up sorting between the top layers of AuxDets
66  float VertEps(0);
67  if ( strncmp( (ad1.TotalVolume())->GetName(), "volAuxDetTrapSensitive", 13) == 0 ) VertEps = 13;
68  else if( strncmp( (ad1.TotalVolume())->GetName(), "volAuxDetBoxSensitive", 12) == 0 ) VertEps = 1;
69 
70  // First sort all AuxDets into same-y groups
71  if( xyz1[1] < xyz2[1] && xyz2[1]-xyz1[1] >= VertEps ) return true;
72 
73  // Within a same-y group, sort AuxDets into same-x groups
74  if( std::abs(xyz2[1]-xyz1[1]) < VertEps && xyz1[0] < xyz2[0]) return true;
75 
76  // Within a same-x, same-y group, sort AuxDets according to z
77  if(xyz1[0] == xyz2[0] && std::abs(xyz2[1]-xyz1[1]) < VertEps && xyz1[2] < xyz2[2]) return true;
78 
79  // none of those are true, so return false
80  return false;
81 
82  }
83 
84 
85  //----------------------------------------------------------------------------
86  // Define sort order for cryostats in APA configuration
87  // same as standard
88  static bool sortCryo35(const CryostatGeo& c1, const CryostatGeo& c2)
89  {
90  double xyz1[3] = {0.}, xyz2[3] = {0.};
91  double local[3] = {0.};
92  c1.LocalToWorld(local, xyz1);
93  c2.LocalToWorld(local, xyz2);
94 
95  return xyz1[0] < xyz2[0];
96  }
97 
98 
99  //----------------------------------------------------------------------------
100  // Define sort order for tpcs in APA configuration.
101  static bool sortTPC35(const TPCGeo& t1, const TPCGeo& t2)
102  {
103  double xyz1[3] = {0.};
104  double xyz2[3] = {0.};
105  double local[3] = {0.};
106  t1.LocalToWorld(local, xyz1);
107  t2.LocalToWorld(local, xyz2);
108 
109  // very useful for aligning volume sorting with GDML bounds
110  // --> looking at this output is one way to find the z-borders between APAs,
111  // which tells soreWire35 to sort depending on z position via "InVertSplitRegion"
112  //mf::LogVerbatim("sortTPC35") << "tpx z range = " << xyz1[2] - t1->Length()/2
113  // << " to " << xyz1[2] + t1->Length()/2;
114 
115  // The goal is to number TPCs first in the x direction so that,
116  // in the case of APA configuration, TPCs 2c and 2c+1 make up APA c.
117  // then numbering will go in y then in z direction.
118 
119  // First sort all TPCs into same-z groups
120  if(xyz1[2] < xyz2[2]) return true;
121 
122  // Within a same-z group, sort TPCs into same-y groups
123  if(xyz1[2] == xyz2[2] && xyz1[1] < xyz2[1]) return true;
124 
125  // Within a same-z, same-y group, sort TPCs according to x
126  if(xyz1[2] == xyz2[2] && xyz1[1] == xyz2[1] && xyz1[0] < xyz2[0]) return true;
127 
128  // none of those are true, so return false
129  return false;
130  }
131 
132 
133  //----------------------------------------------------------------------------
134  // Define sort order for planes in APA configuration
135  // same as standard, but implemented differently
136  static bool sortPlane35(const PlaneGeo& p1, const PlaneGeo& p2)
137  {
138  double xyz1[3] = {0.};
139  double xyz2[3] = {0.};
140  double local[3] = {0.};
141  p1.LocalToWorld(local, xyz1);
142  p2.LocalToWorld(local, xyz2);
143 
144  //mf::LogVerbatim("sortPlanes35") << "Sorting planes: ("
145  // << xyz1[0] <<","<< xyz1[1] <<","<< xyz1[2] << ") and ("
146  // << xyz2[0] <<","<< xyz2[1] <<","<< xyz2[2] << ")";
147 
148  return xyz1[0] > xyz2[0];
149  }
150 
151  //----------------------------------------------------------------------------
152  // we want the wires to be sorted such that the smallest corner wire
153  // on the readout end of a plane is wire zero, with wire number
154  // increasing away from that wire.
155 
156  // Since 35t has an APA which is both above and below the world origin,
157  // we cannot use the APA trick. If we could ask where wire 0 was, we could
158  // still do this in a single implimentation, but we aren't sure what wire
159  // center we will be getting, so this reversed sorting must be handled
160  // at the plane level where there is one vertical center.
161  // If the plane center is above, count from top down (the top stacked and
162  // largest APAs) If the plane is below (bottom stacked APA) count bottom up
163  struct sortWire35{
164 
166 
168  : detVersion(detv)
169  {}
170 
171  bool operator()(WireGeo const& w1, WireGeo const& w2){
172  double xyz1[3] = {0.};
173  double xyz2[3] = {0.};
174 
175  w1.GetCenter(xyz1); w2.GetCenter(xyz2);
176 
177 
178  //mf::LogVerbatim("sortWire35") << "Sorting wires: ("
179  // << xyz1[0] <<","<< xyz1[1] <<","<< xyz1[2] << ") and ("
180  // << xyz2[0] <<","<< xyz2[1] <<","<< xyz2[2] << ")";
181 
182 
183  // immedieately take care of vertical wires regardless of which TPC
184  // vertical wires should always have same y, and always increase in z direction
185  if( xyz1[1]==xyz2[1] && xyz1[2]<xyz2[2] ) return true;
186 
187  ///////////////////////////////////////////////////////////
188  // Hard code a number to tell sorting when to look
189  // for top/bottom APAs and when to look for only one
190  bool InVertSplitRegion = false;
191  if(detVersion=="dune35t") InVertSplitRegion = xyz1[2] > 76.35; // the old
192  else if(detVersion=="dune35t4apa") InVertSplitRegion = ((51 < xyz1[2]) // the new...
193  && (xyz1[2] < 102)); //
194  else if(detVersion=="dune35t4apa_v2") InVertSplitRegion = ((52.74 < xyz1[2]) // ...and improved
195  && (xyz1[2] < 106.23));
196  else if( detVersion=="dune35t4apa_v3"
197  || detVersion=="dune35t4apa_v4"
198  || detVersion=="dune35t4apa_v5"
199  || detVersion=="dune35t4apa_v6"
200  ) InVertSplitRegion = ((51.41045 < xyz1[2])
201  && (xyz1[2] < 103.33445));
202  ///////////////////////////////////////////////////////////
203 
204  // we want the wires to be sorted such that the smallest corner wire
205  // on the readout end of a plane is wire zero, with wire number
206  // increasing away from that wire.
207 
208  if( InVertSplitRegion ){
209 
210  // if a bottom TPC, count from bottom up
211  if( xyz1[1]<0 && xyz1[1] < xyz2[1] ) return true;
212 
213  // if a top TPC, count from top down
214  if( xyz1[1]>0 && xyz1[1] > xyz2[1] ) return true;
215 
216  }
217  else {
218 
219  if( xyz1[1] > xyz2[1] ) return true;
220 
221  }
222 
223  return false;
224  }
225  };
226 
227  //----------------------------------------------------------------------------
229  : fDetVersion(p.get< std::string >("DetectorVersion", "dune35t4apa"))
230  {
231  }
232 
233  //----------------------------------------------------------------------------
234  void GeoObjectSorter35::SortAuxDets(std::vector<geo::AuxDetGeo> & adgeo) const
235  {
236  std::sort(adgeo.begin(), adgeo.end(), sortAuxDet35);
237  }
238 
239  //----------------------------------------------------------------------------
240  void GeoObjectSorter35::SortAuxDetSensitive(std::vector<geo::AuxDetSensitiveGeo> & adgeo) const
241  {
242  std::sort(adgeo.begin(), adgeo.end(), sortAuxDetSensitive35);
243  }
244 
245  //----------------------------------------------------------------------------
246  void GeoObjectSorter35::SortCryostats(std::vector<geo::CryostatGeo> & cgeo) const
247  {
248  std::sort(cgeo.begin(), cgeo.end(), sortCryo35);
249  }
250 
251  //----------------------------------------------------------------------------
252  void GeoObjectSorter35::SortTPCs(std::vector<geo::TPCGeo> & tgeo) const
253  {
254  std::sort(tgeo.begin(), tgeo.end(), sortTPC35);
255  }
256 
257  //----------------------------------------------------------------------------
258  void GeoObjectSorter35::SortPlanes(std::vector<geo::PlaneGeo> & pgeo,
259  geo::DriftDirection_t const driftDir) const
260  {
261  // sort the planes to increase in drift direction
262  // The drift direction has to be set before this method is called. It is set when
263  // the CryostatGeo objects are sorted by the CryostatGeo::SortSubVolumes method
264  if (driftDir == geo::kPosX) std::sort(pgeo.rbegin(), pgeo.rend(), sortPlane35);
265  else if(driftDir == geo::kNegX) std::sort(pgeo.begin(), pgeo.end(), sortPlane35);
266  else if(driftDir == geo::kUnknownDrift)
267  throw cet::exception("TPCGeo") << "Drift direction is unknown, can't sort the planes\n";
268  }
269 
270  //----------------------------------------------------------------------------
271  void GeoObjectSorter35::SortWires(std::vector<geo::WireGeo> & wgeo) const
272  {
273  sortWire35 sw35(fDetVersion);
274 
275  std::sort(wgeo.begin(), wgeo.end(), sw35);
276  }
277 
278 
279 }
void SortCryostats(std::vector< geo::CryostatGeo > &cgeo) const
Geometry description of a TPC wireThe wire is a single straight segment on a wire plane...
Definition: WireGeo.h:65
static bool sortTPC35(const TPCGeo &t1, const TPCGeo &t2)
Drift direction is unknown.
Definition: geo_types.h:158
sortWire35(std::string detv)
void LocalToWorld(const double *auxdet, double *world) const
Transform point from local auxiliary detector frame to world frame.
Definition: AuxDetGeo.h:120
Encapsulate the construction of a single cyostat.
std::string string
Definition: nybbler.cc:12
bool operator()(WireGeo const &w1, WireGeo const &w2)
Geometry information for a single TPC.
Definition: TPCGeo.h:38
STL namespace.
Drift towards negative X values.
Definition: geo_types.h:162
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
T abs(T value)
Encapsulate the geometry of the sensitive portion of an auxiliary detector.
void SortWires(std::vector< geo::WireGeo > &wgeo) const
enum geo::driftdir DriftDirection_t
Drift direction: positive or negative.
static bool sortAuxDet35(const AuxDetGeo &ad1, const AuxDetGeo &ad2)
void SortPlanes(std::vector< geo::PlaneGeo > &pgeo, geo::DriftDirection_t driftDir) const
Interface to algorithm class for standard sorting of geo::XXXGeo objects.
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:82
const TGeoVolume * TotalVolume() const
p
Definition: test.py:223
Encapsulate the geometry of an auxiliary detector.
Encapsulate the geometry of a wire.
void LocalToWorld(const double *cryo, double *world) const
Transform point from local cryostat frame to world frame.
Definition: CryostatGeo.h:387
void SortAuxDets(std::vector< geo::AuxDetGeo > &adgeo) const
static bool sortAuxDetSensitive35(const AuxDetSensitiveGeo &ad1, const AuxDetSensitiveGeo &ad2)
Drift towards positive X values.
Definition: geo_types.h:161
Encapsulate the construction of a single detector plane.
const TGeoVolume * TotalVolume() const
Definition: AuxDetGeo.h:106
std::string fDetVersion
string of the detector version
void SortAuxDetSensitive(std::vector< geo::AuxDetSensitiveGeo > &adgeo) const
static bool sortCryo35(const CryostatGeo &c1, const CryostatGeo &c2)
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
Definition: WireGeo.cxx:73
static bool sortPlane35(const PlaneGeo &p1, const PlaneGeo &p2)
void LocalToWorld(const double *auxdet, double *world) const
Transform point from local auxiliary detector frame to world frame.
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void SortTPCs(std::vector< geo::TPCGeo > &tgeo) const
LArSoft geometry interface.
Definition: ChannelGeo.h:16
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
Definition: TPCGeo.h:563
GeoObjectSorter35(fhicl::ParameterSet const &p)
void LocalToWorld(const double *plane, double *world) const
Transform point from local plane frame to world frame.
Definition: PlaneGeo.h:1343
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane.