ProtoDUNESPCRTSorter.cxx
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////
2 /// \file CRTSorter.cxx
3 /// \brief A function to sort the CRTs for ProtoDUNESP
4 /// \version $Id: $
5 /// \author e.tyley@sheffield.ac.uk
6 ////////////////////////////////////////////////////////////////////////
7 //LArSoft includes
8 
11 //#include "larcoreobj/SimpleTypesAndConstants/geo_vectors_utils.h"
12 
14 
15 
16 //c++ includes
17 #include <numeric> //std::accumulate was moved here in c++14
18 
19 namespace
20 {
21  // function to work out the edge where the CRT reads out, the outside edge of the CRT
22  geo::Vector_t FindEdge(const geo::AuxDetGeo& det,const geo::Vector_t Center)
23  {
24  // Work out whether the CRT is vertical or horizontal
25  const bool yPos = (det.toWorldCoords(geo::AuxDetGeo::LocalPoint_t(0, 0, det.Length()/2.)).Y() - det.GetCenter().Y()
26  < det.toWorldCoords(geo::AuxDetGeo::LocalPoint_t(0, 0, det.Length()/2.)).X() - det.GetCenter().X());
27 
28  double xCo = det.GetCenter().X();
29  double yCo = det.GetCenter().Y();
30  double len = det.Length();
31 
32  // Work out whoch way to push the CRT position to make it represent the correct edge
33  // if yPos(Reads out in X) push in x to the edge of the detector
34 
35  if (yPos)
36  {
37  if (det.GetCenter().X()>Center.X()) xCo+=len/2.;
38  else xCo-=len/2.;
39  }
40  else
41  {
42  if (det.GetCenter().Y()>Center.Y()) yCo+=len/2.;
43  else yCo-=len/2.;
44  }
45  //Return the vector of the edge of the CRT
46 
47  return geo::Vector_t(xCo,yCo,det.GetCenter().Z());
48  }
49 
50 
51  template <class ITERATOR>
52  void SortInSpiral(const ITERATOR begin, const ITERATOR end)
53  {
54 
55  int counter = end-begin; //Calculate number of CRT panels
56  //Calculate the center point by averaging the position of the panels
57 
58  const geo::Vector_t center = std::accumulate(begin, end, geo::Vector_t(0., 0., 0.), [&counter](geo::Vector_t sum, const auto geo)
59  {return sum+geo->GetCenter()/counter;});
60 
61  //const geo::Vector_t vertical(0., 1., 0.);
62  //std::cout<<"Center: "<<center.X()<<" X, "<<center.Y()<<"Y and "<<center.Z()<<"Z With counter: "<<counter<<std::endl;
63  //Sort by angle between vector from center of all AuxDetGeos to edge of each AuxDetGeo
64  //If this is really a bottleneck, one could probably write some
65  //multi-return-statement version that's more efficient.
66 
67  std::sort(begin, end, [&center](const geo::AuxDetGeo* first,const geo::AuxDetGeo* second)
68  {
69  //Find the readout edge of each CRT
70  geo::Vector_t firstEdge = FindEdge(*first,center);
71  geo::Vector_t secondEdge = FindEdge(*second,center);
72 
73  //Calculate the vector from the center to each edge
74  geo::Vector_t firstVec = firstEdge-center;
75  geo::Vector_t secondVec = secondEdge-center;
76 
77  //Calculate the angle Phi (Angle in X-Y Plane)
78  double firstPhi = firstVec.Phi();
79  double secondPhi = secondVec.Phi();
80 
81 
82  //We want to start at verticle (pi) and go in a spiral from there //so this means pushing the angles of >pi to the end of the array
83  //by subtracting 2*pi
84 
85  if (firstPhi>1.57) firstPhi-=6.28;
86  if (secondPhi>1.57) secondPhi-=6.28;
87 
88  if ((*first).GetCenter().Z() <0.0){
89  return firstPhi > secondPhi;
90  } else {
91  return firstPhi < secondPhi;
92  }
93 
94  });
95 
96  // loop through the sorted vector and print out to check it is working as intended
97  /*
98  for(ITERATOR geo = (begin); geo != end; ++geo)
99  {
100  geo::Vector_t firstEdge = FindEdge(*(*geo),center);
101  geo::Vector_t firstVec = firstEdge-center;
102  double firstPhi = firstVec.Phi();
103 
104  if (firstPhi>1.57) {
105  firstPhi-=3.14;
106  std::cout<<"Angle Phi -2*pi: "<<firstPhi<<std::endl;
107  }
108 
109  else{std::cout<<"Angle Phi: "<<firstPhi<<std::endl;}
110  //std::cout<<"Angle Phi: "<<firstPhi<<std::endl;
111  //std::cout<<(*geo)->GetCenter().X()<<"X, "<<(*geo)->GetCenter().Y()<<"Y and "<<(*geo)->GetCenter().Z()<<"Z"<<std::endl;
112  //std::cout<<"Edge: "<<firstEdge.X()<<"X, "<<firstEdge.Y()<<"Y and "<<firstEdge.Z()<<"Z"<<std::endl;
113  //std::cout<<"Vec: "<<firstVec.X()<<"X, "<<firstVec.Y()<<"Y and "<<firstVec.Z()<<"Z"<<std::endl;
114  }
115  */
116  }
117 
118 
119  //Return the first ITERATOR to pointer-to-AuxDetGeo that is more than zTolerance distant from the one before
120  //it and end if no element between begin and end is far enough from its neighbor.
121 
122  template <class ITERATOR>
123  ITERATOR FindFirstDownstream(const ITERATOR begin, const ITERATOR end, const double zTolerance)
124  {
125  if(begin == end) return end; //In a container of size 1, there is no way to use this algorithm to
126  //find out whether this range contains an upstream or a downstream volume
127 
128  //std::cout<<"test2"<<std::endl;
129  ITERATOR prev = begin;
130  for(ITERATOR geo = std::next(begin); geo != end; ++geo)
131  {
132  //std::cout<<fabs(((*geo)->GetCenter() - (*prev)->GetCenter()).Z())<<std::endl;
133  //std::cout<<((*prev)->GetCenter()).Z()<<std::endl;
134 
135  if(fabs(((*geo)->GetCenter() - (*prev)->GetCenter()).Z()) > zTolerance)
136  {
137  return geo;
138  }
139  prev = geo;
140  }
141  return end;
142  }
143 
144  template <class CONTAINER>
145  std::vector<size_t> map(const CONTAINER& sorted, const CONTAINER& unsorted)
146  {
147  std::vector<size_t> mymap;
148  for(size_t i = 0; i < sorted.size(); ++i)
149  {
150  auto ThisAdgeo = sorted[i];
151  for(size_t j = 0; j < unsorted.size(); ++j)
152  {
153  auto ThisUnsorted = unsorted[j];
154 
155  if (ThisAdgeo->Name() == ThisUnsorted->Name())
156  {
157  mymap.push_back(j);
158  //std::cout<<ThisAdgeo->Name()<<" Sorted CRT "<< i <<" Unsorted CRT "<< j <<std::endl;
159  }
160  }
161  }
162  return mymap;
163  }
164 
165  //Wrapper so that I don't have to care whether this is a std:vector<const geo::AuxDetGeo*> or std::vector<geo::AuxDetGeo*>.
166  //I'm not going to change the AuxDetGeos, so I just require that iterators passed dereference to a const AuxDetGeo*.
167  template <class CONTAINER>
168  std::vector<size_t> doMapping(CONTAINER& unsorted)
169  {
170  std::cout<<"called"<<std::endl;
171  auto adgeo = unsorted;
172  //auto unsorted = adgeo;
173  const double thickest = 800.;
174 
175  //std::cout<<"test"<<std::endl;
176  std::sort(adgeo.begin(), adgeo.end(), [](const auto& first, const auto& second)
177  { return (first->GetCenter()).Z() < (second->GetCenter()).Z() ;} );
178 
179  //Then, find an iterator to the first downstream AuxDetGeo
180  //std::cout<<"test"<<std::endl;
181  const auto firstDownstream = ::FindFirstDownstream(adgeo.begin(), adgeo.end(), thickest);
182  std::cout<<"test"<<std::endl;
183 
184  //Last, sort upstream and downstream containers in a spiral about their center.
185  ::SortInSpiral(adgeo.begin(), firstDownstream); //upstream
186  ::SortInSpiral(firstDownstream, adgeo.end()); //downstream
187 
188  std::vector<size_t> mapping = ::map(adgeo,unsorted); //TODO: Rewrite this to use iterators?
189  std::cout<<"end"<<std::endl;
190  return mapping;
191  }
192 }
193 
194 namespace CRTSorter
195 {
196  std::vector<size_t> Mapping(std::vector<geo::AuxDetGeo*>& adgeo) //Overload for validation via geometry sorting
197  {
198  return doMapping(adgeo);
199  }
200 
201  std::vector<size_t> Mapping(std::vector<const geo::AuxDetGeo*>& adgeo) //Overload for kludge after geometry sorting where only
202  //const geo::AuxDetGeo& is available
203  {
204  return doMapping(adgeo);
205  }
206 }
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
geo::Point3DBase_t< AuxDetGeoCoordinatesTag > LocalPoint_t
Type of points in the local GDML auxiliary detector frame.
Definition: AuxDetGeo.h:64
Encapsulate the geometry of an auxiliary detector.
double Length() const
Definition: AuxDetGeo.h:102
std::vector< size_t > Mapping(std::vector< geo::AuxDetGeo * > &adgeo)
def center(depos, point)
Definition: depos.py:117
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
LArSoft geometry interface.
Definition: ChannelGeo.h:16
geo::Point_t toWorldCoords(LocalPoint_t const &local) const
Transform point from local auxiliary detector frame to world frame.
Definition: AuxDetGeo.h:124
QTextStream & endl(QTextStream &s)
void GetCenter(double *xyz, double localz=0.0) const
Return the center position of an AuxDet.
Definition: AuxDetGeo.cxx:62