CMS 3D CMS Logo

DTGeometryValidate.cc
Go to the documentation of this file.
7 
11 
13 
16 
17 #include <TFile.h>
18 #include <TH1.h>
19 
20 #include <cmath>
21 #include <limits>
22 #include <string>
23 #include <type_traits>
24 #include <algorithm>
25 
26 using namespace std;
27 
28 template<class T>
29 typename enable_if<!numeric_limits<T>::is_integer, bool>::type
30  almost_equal(T x, T y, int ulp)
31 {
32  // the machine epsilon has to be scaled to the magnitude of the values used
33  // and multiplied by the desired precision in ULPs (units in the last place)
34  return abs(x-y) <= numeric_limits<T>::epsilon() * abs(x+y) * ulp
35  // unless the result is subnormal
36  || abs(x-y) < numeric_limits<T>::min();
37 }
38 
39 using namespace edm;
40 
41 class DTGeometryValidate : public one::EDAnalyzer<>
42 {
43 public:
44  explicit DTGeometryValidate(const ParameterSet&);
45  ~DTGeometryValidate() override {}
46 
47 private:
48  void beginJob() override;
49  void analyze(const edm::Event&, const edm::EventSetup&) override;
50  void endJob() override;
51 
52  void validateDTChamberGeometry();
53  void validateDTLayerGeometry();
54 
55  void compareTransform(const GlobalPoint&, const TGeoMatrix*);
56  void compareShape(const GeomDet*, const float*);
57 
58  float getDistance(const GlobalPoint&, const GlobalPoint&);
59  float getDiff(const float, const float);
60 
61  void makeHistograms(const char*);
62  void makeHistogram(const string&, vector<float>&);
63 
64  void clearData() {
65  globalDistances_.clear();
66  topWidths_.clear();
67  bottomWidths_.clear();
68  lengths_.clear();
69  thicknesses_.clear();
70  }
71 
75  TFile* outFile_;
76  vector<float> globalDistances_;
77  vector<float> topWidths_;
78  vector<float> bottomWidths_;
79  vector<float> lengths_;
80  vector<float> thicknesses_;
81  string infileName_;
82  string outfileName_;
84 };
85 
86 
88  : dtGeometryToken_{esConsumes<DTGeometry, MuonGeometryRecord>(edm::ESInputTag{})},
89  infileName_(iConfig.getUntrackedParameter<string>("infileName", "cmsGeom10.root")),
90  outfileName_(iConfig.getUntrackedParameter<string>("outfileName", "validateDTGeometry.root")),
91  tolerance_(iConfig.getUntrackedParameter<int>("tolerance", 6))
92 {
94  outFile_ = new TFile(outfileName_.c_str(), "RECREATE");
95 }
96 
97 void
99 {
100  dtGeometry_ = eventSetup.getHandle(dtGeometryToken_);
101 
102  if(dtGeometry_.isValid()) {
103  LogVerbatim("DTGeometry") << "Validating DT chamber geometry";
105 
106  LogVerbatim("DTGeometry") <<"Validating DT layer geometry";
108  }
109  else
110  LogVerbatim("DTGeometry") << "Invalid DT geometry";
111 }
112 
113 void
115 
116  clearData();
117 
118  for(auto const& it : dtGeometry_->chambers()) {
119  DTChamberId chId = it->id();
120  GlobalPoint gp = it->surface().toGlobal(LocalPoint(0.0, 0.0, 0.0));
121 
122  const TGeoMatrix* matrix = fwGeometry_.getMatrix(chId.rawId());
123 
124  if(!matrix) {
125  LogVerbatim("DTGeometry") << "Failed to get matrix of DT chamber with detid: "
126  << chId.rawId();
127  continue;
128  }
129 
130  compareTransform(gp, matrix);
131 
132  auto const& shape = fwGeometry_.getShapePars(chId.rawId());
133 
134  if(!shape) {
135  LogVerbatim("DTGeometry") << "Failed to get shape of DT chamber with detid: "
136  << chId.rawId();
137  continue;
138  }
139 
140  compareShape(it, shape);
141  }
142 
143  makeHistograms("DT Chamber");
144 }
145 
146 void
148 
149  clearData();
150 
151  vector<float> wire_positions;
152 
153  for(auto const& it : dtGeometry_->layers()) {
154  DTLayerId layerId = it->id();
155  GlobalPoint gp = it->surface().toGlobal(LocalPoint(0.0, 0.0, 0.0));
156 
157  const TGeoMatrix* matrix = fwGeometry_.getMatrix(layerId.rawId());
158 
159  if (!matrix) {
160  LogVerbatim("DTGeometry") << "Failed to get matrix of DT layer with detid: "
161  << layerId.rawId();
162  continue;
163  }
164 
165  compareTransform(gp, matrix);
166 
167  auto const& shape = fwGeometry_.getShapePars(layerId.rawId());
168 
169  if(!shape) {
170  LogVerbatim("DTGeometry") << "Failed to get shape of DT layer with detid: "
171  << layerId.rawId();
172  continue;
173  }
174 
175  compareShape(it, shape);
176 
177  auto const& parameters = fwGeometry_.getParameters(layerId.rawId());
178 
179  if(parameters == nullptr) {
180  LogVerbatim("DTGeometry") << "Parameters empty for DT layer with detid: "
181  << layerId.rawId();
182  continue;
183  }
184 
185  float width = it->surface().bounds().width();
186  assert(width == parameters[6]);
187 
188  float thickness = it->surface().bounds().thickness();
189  assert(thickness == parameters[7]);
190 
191  float length = it->surface().bounds().length();
192  assert(length == parameters[8]);
193 
194  int firstChannel = it->specificTopology().firstChannel();
195  assert(firstChannel == parameters[3]);
196 
197  int lastChannel = it->specificTopology().lastChannel();
198  int nChannels = parameters[5];
199  assert(nChannels == (lastChannel-firstChannel)+1);
200 
201  for(int wireN = firstChannel; wireN - lastChannel <= 0; ++wireN) {
202  float localX1 = it->specificTopology().wirePosition(wireN);
203  float localX2 = (wireN -(firstChannel-1)-0.5f)*parameters[0] - nChannels/2.0f*parameters[0];
204  wire_positions.emplace_back(getDiff(localX1, localX2));
205  }
206  }
207 
208  makeHistogram("DT Layer Wire localX", wire_positions);
209  makeHistograms("DT Layer");
210 }
211 
212 void
214  const TGeoMatrix* matrix)
215 {
216  double local[3] = { 0.0, 0.0, 0.0 };
217  double global[3];
218 
219  matrix->LocalToMaster(local, global);
220 
221  float distance = getDistance(GlobalPoint(global[0], global[1], global[2]), gp);
222  globalDistances_.push_back(distance);
223 }
224 
225 void
226 DTGeometryValidate::compareShape(const GeomDet* det, const float* shape)
227 {
228  float shapeTopWidth;
229  float shapeBottomWidth;
230  float shapeLength;
231  float shapeThickness;
232 
233  if(shape[0] == 1) {
234  shapeTopWidth = shape[2];
235  shapeBottomWidth = shape[1];
236  shapeLength = shape[4];
237  shapeThickness = shape[3];
238  }
239  else if(shape[0] == 2) {
240  shapeTopWidth = shape[1];
241  shapeBottomWidth = shape[1];
242  shapeLength = shape[2];
243  shapeThickness = shape[3];
244  }
245  else {
246  LogVerbatim("DTGeometry") << "Failed to get box or trapezoid from shape";
247  return;
248  }
249 
250  float topWidth, bottomWidth;
251  float length, thickness;
252 
253  const Bounds* bounds = &(det->surface().bounds());
254 
255  if(const TrapezoidalPlaneBounds* tpbs = dynamic_cast<const TrapezoidalPlaneBounds*>(bounds))
256  {
257  array<const float, 4> const & ps = tpbs->parameters();
258 
259  assert(ps.size() == 4);
260 
261  bottomWidth = ps[0];
262  topWidth = ps[1];
263  thickness = ps[2];
264  length = ps[3];
265  }
266  else if((dynamic_cast<const RectangularPlaneBounds*>(bounds))) {
267  length = det->surface().bounds().length()*0.5;
268  topWidth = det->surface().bounds().width()*0.5;
269  bottomWidth = topWidth;
270  thickness = det->surface().bounds().thickness()*0.5;
271  }
272  else {
273  LogVerbatim("DTGeometry") << "Failed to get bounds";
274  return;
275  }
276  topWidths_.push_back(fabs(shapeTopWidth - topWidth));
277  bottomWidths_.push_back(fabs(shapeBottomWidth - bottomWidth));
278  lengths_.push_back(fabs(shapeLength - length));
279  thicknesses_.push_back(fabs(shapeThickness - thickness));
280 }
281 
282 float
284 {
285  return sqrt((p1.x()-p2.x())*(p1.x()-p2.x())+
286  (p1.y()-p2.y())*(p1.y()-p2.y())+
287  (p1.z()-p2.z())*(p1.z()-p2.z()));
288 }
289 
290 float
291 DTGeometryValidate::getDiff(const float val1, const float val2) {
292  if(almost_equal(val1, val2, tolerance_))
293  return 0.0f;
294  else
295  return (val1 - val2);
296 }
297 
298 void
300 {
301  outFile_->cd();
302 
303  string d(detector);
304 
305  string gdn = d+": distance between points in global coordinates";
307 
308  string twn = d + ": absolute difference between top widths (along X)";
310 
311  string bwn = d + ": absolute difference between bottom widths (along X)";
313 
314  string ln = d + ": absolute difference between lengths (along Y)";
315  makeHistogram(ln, lengths_);
316 
317  string tn = d + ": absolute difference between thicknesses (along Z)";
319 }
320 
321 void
322 DTGeometryValidate::makeHistogram(const string& name, vector<float>& data)
323 {
324  if(data.empty())
325  return;
326 
327  const auto [minE, maxE] = minmax_element(begin(data), end(data));
328 
329  TH1D hist(name.c_str(), name.c_str(), 100, *minE*(1+0.10), *maxE*(1+0.10));
330 
331  for(auto const& it : data)
332  hist.Fill(it);
333 
334  hist.GetXaxis()->SetTitle("[cm]");
335  hist.Write();
336 }
337 
338 void
340  outFile_->cd();
341 }
342 
343 void
345  LogVerbatim("DTGeometry") << "Done.";
346  LogVerbatim("DTGeometry") << "Results written to "<< outfileName_;
347  outFile_->Close();
348 }
349 
type
Definition: HCALResponse.h:21
enable_if<!numeric_limits< T >::is_integer, bool >::type almost_equal(T x, T y, int ulp)
virtual float length() const =0
const std::vector< const DTChamber * > & chambers() const
Return a vector of all Chamber.
Definition: DTGeometry.cc:102
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:32
~DTGeometryValidate() override
const float * getParameters(unsigned int id) const
Definition: FWGeometry.cc:446
float getDistance(const GlobalPoint &, const GlobalPoint &)
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
DTGeometryValidate(const ParameterSet &)
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
T y() const
Definition: PV3DBase.h:63
float getDiff(const float, const float)
const Bounds & bounds() const
Definition: Surface.h:120
void makeHistograms(const char *)
void endJob() override
const TGeoMatrix * getMatrix(unsigned int id) const
Definition: FWGeometry.cc:186
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
example_stream void analyze(const edm::Event &, const edm::EventSetup &) override
void compareShape(const GeomDet *, const float *)
void beginJob()
Definition: Breakpoints.cc:14
virtual float width() const =0
const float * getShapePars(unsigned int id) const
Definition: FWGeometry.cc:462
void compareTransform(const GlobalPoint &, const TGeoMatrix *)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::ESGetToken< DTGeometry, MuonGeometryRecord > dtGeometryToken_
vector< float > globalDistances_
edm::ESHandle< DTGeometry > dtGeometry_
void loadMap(const char *fileName)
Definition: FWGeometry.cc:56
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
vector< float > topWidths_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
#define end
Definition: vmac.h:39
T min(T a, T b)
Definition: MathUtil.h:58
double p2[4]
Definition: TauolaWrapper.h:90
vector< float > lengths_
vector< float > thicknesses_
void beginJob() override
virtual float thickness() const =0
const std::vector< const DTLayer * > & layers() const
Return a vector of all SuperLayer.
Definition: DTGeometry.cc:112
#define begin
Definition: vmac.h:32
HLT enums.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
double p1[4]
Definition: TauolaWrapper.h:89
vector< float > bottomWidths_
Definition: Bounds.h:22
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:139
bool isValid() const
Definition: ESHandle.h:44
void makeHistogram(const string &, vector< float > &)
long double T
T x() const
Definition: PV3DBase.h:62
Definition: event.py:1
void analyze(const edm::Event &, const edm::EventSetup &) override