Belle II Software development
CDCGeometryPar.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <framework/gearbox/Gearbox.h>
10#include <framework/gearbox/GearDir.h>
11#include <framework/logging/Logger.h>
12#include <framework/utilities/FileSystem.h>
13
14#include <cdc/geometry/CDCGeometryPar.h>
15#include <cdc/geometry/CDCGeoControlPar.h>
16#include <cdc/simulation/CDCSimControlPar.h>
17#include <cdc/utilities/OpenFile.h>
18
19//#include <float.h>
20
21#include <cmath>
22#include <boost/format.hpp>
23//#include <iostream>
24#include <iomanip>
25
26#include <boost/iostreams/filtering_stream.hpp>
27//#include <boost/iostreams/device/file.hpp>
28//#include <boost/iostreams/filter/gzip.hpp>
29
30#include <Math/ChebyshevPol.h>
31
32using namespace std;
33using namespace boost;
34using namespace Belle2;
35using namespace CDC;
36
38
40{
43}
44
46{
47
49
50 if (gcp.getT0InputType()) {
52 if ((*m_t0FromDB).isValid()) {
53 (*m_t0FromDB).addCallback(this, &CDCGeometryPar::setT0);
54 }
55 }
56
57 if (gcp.getBwInputType()) {
59 if ((*m_badWireFromDB).isValid()) {
60 (*m_badWireFromDB).addCallback(this, &CDCGeometryPar::setBadWire);
61 }
62 }
63
64 if (gcp.getPropSpeedInputType()) {
66 if ((*m_propSpeedFromDB).isValid()) {
67 (*m_propSpeedFromDB).addCallback(this, &CDCGeometryPar::setPropSpeed);
68 }
69 }
70
71 if (gcp.getTwInputType()) {
73 if ((*m_timeWalkFromDB).isValid()) {
74 (*m_timeWalkFromDB).addCallback(this, &CDCGeometryPar::setTW);
75 }
76 }
77
78 if (gcp.getXtInputType()) {
80 if ((*m_xtRelFromDB).isValid()) {
81 (*m_xtRelFromDB).addCallback(this, &CDCGeometryPar::setXtRel);
82 }
83 }
84
85 if (gcp.getSigmaInputType()) {
87 if ((*m_sResolFromDB).isValid()) {
88 (*m_sResolFromDB).addCallback(this, &CDCGeometryPar::setSResol);
89 }
90 }
91
92 if (gcp.getFFactorInputType()) {
94 if ((*m_fFactorFromDB).isValid()) {
95 (*m_fFactorFromDB).addCallback(this, &CDCGeometryPar::setFFactor);
96 }
97 }
98
99 if (gcp.getChMapInputType()) {
101 if ((*m_chMapFromDB).isValid()) {
102 (*m_chMapFromDB).addCallback(this, &CDCGeometryPar::setChMap);
103 }
104 }
105
106 if (gcp.getDisplacementInputType()) {
108 if ((*m_displacementFromDB).isValid()) {
109 (*m_displacementFromDB).addCallback(this, &CDCGeometryPar::setDisplacement);
110 }
111 }
112
113 if (gcp.getAlignmentInputType()) {
115 if ((*m_alignmentFromDB).isValid()) {
116 (*m_alignmentFromDB).addCallback(this, &CDCGeometryPar::setWirPosAlignParams);
117 }
118 }
119
120 if (gcp.getMisalignment()) {
121 if (gcp.getMisalignmentInputType()) {
123 if ((*m_misalignmentFromDB).isValid()) {
124 (*m_misalignmentFromDB).addCallback(this, &CDCGeometryPar::setWirPosMisalignParams);
125 }
126 }
127 }
128
129 //TODO in future: make a new (singleton?) class and move all EDepToADC things there.
130 if (gcp.getEDepToADCInputType()) {
132 if ((*m_eDepToADCConversionsFromDB).isValid()) {
133 (*m_eDepToADCConversionsFromDB).addCallback(this, &CDCGeometryPar::setEDepToADCConversions);
134 }
135 }
136
137 clear();
138 if (geom) {
139 // B2INFO("CDCGeometryPar: Read Geometry object");
140 readFromDB(*geom);
141 } else {
142 // std::cout <<"readcalled" << std::endl;
143 // read();
144 // B2FATAL("CDCGeometryPar: Strange that readFromDB is not called !");
145 B2WARNING("CDCGeometryPar: Strange that readFromDB is not called! Please make sure that CDC is included in Geometry.");
146 }
147}
148
150{
151 // B2INFO("CDCGeometryPar: destructor called");
152 // if (m_t0FromDB) delete m_t0FromDB;
153 // if (m_badWireFromDB) delete m_badWireFromDB;
154 // if (m_propSpeedFromDB) delete m_propSpeedFromDB;
155 // if (m_timeWalkFromDB) delete m_timeWalkFromDB;
156 // if (m_xtRelFromDB) delete m_xtRelFromDB;
157 // if (m_sResolFromDB) delete m_sResolFromDB;
158 // if (m_chMapFromDB) delete [] m_chMapFromDB;
159 // if (m_displacementFromDB) delete [] m_displacementFromDB;
160 // if (m_chMapFromDB) delete m_chMapFromDB;
161 // if (m_displacementFromDB) delete m_displacementFromDB;
162 // if (m_alignmentFromDB) delete m_alignmentFromDB;
163 // if (m_misalignmentFromDB) delete m_misalignmentFromDB;
164 // B2INFO("CDCGeometryPar: destructor ended");
165}
166
168{
169 m_version = "unknown";
170 m_nSLayer = 0;
171 m_nFLayer = 0;
173 m_senseWireTension = 0.0;
174 m_senseWireDensity = 0.0;
176
177 m_tdcOffset = 0; //not used; to be removed later
178 m_clockFreq4TDC = 0.0;
179 m_tdcBinWidth = 0.0;
180 m_nominalDriftV = 0.0;
181 m_nominalPropSpeed = 0.0;
183
184 for (unsigned i = 0; i < 4; ++i) {
185 m_rWall[i] = 0;
186 for (unsigned j = 0; j < 2; ++j)
187 m_zWall[i][j] = 0;
188 }
189 for (unsigned i = 0; i < c_maxNSenseLayers; ++i) {
190 m_rSLayer[i] = 0;
191 m_zSForwardLayer[i] = 0;
192 m_dzSForwardLayer[i] = 0;
193 m_zSBackwardLayer[i] = 0;
194 m_dzSBackwardLayer[i] = 0;
195 m_cellSize[i] = 0;
196 m_nWires[i] = 0;
197 m_offSet[i] = 0;
198 m_nShifts[i] = 0;
199 m_propSpeedInv[i] = 0.;
200 }
201 for (unsigned i = 0; i < c_maxNFieldLayers; ++i) {
202 m_rFLayer[i] = 0;
203 m_zFForwardLayer[i] = 0;
204 m_zFBackwardLayer[i] = 0;
205 }
206
207 for (unsigned L = 0; L < c_maxNSenseLayers; ++L) {
208 for (unsigned C = 0; C < c_maxNDriftCells; ++C) {
209 for (unsigned i = 0; i < 3; ++i) {
210 m_FWirPos [L][C][i] = 0.;
211 m_BWirPos [L][C][i] = 0.;
212 m_FWirPosMisalign[L][C][i] = 0.;
213 m_BWirPosMisalign[L][C][i] = 0.;
214 m_FWirPosAlign [L][C][i] = 0.;
215 m_BWirPosAlign [L][C][i] = 0.;
216 }
217 for (unsigned i = 0; i < 7; ++i) {
218 m_eDepToADCParams[L][C][i] = 0.;
219 }
220 m_WireSagCoef [L][C] = 0.;
221 m_WireSagCoefMisalign[L][C] = 0.;
222 m_WireSagCoefAlign [L][C] = 0.;
223 m_t0 [L][C] = 0.;
224 }
225 }
226
227 for (unsigned L = 0; L < c_maxNSenseLayers; ++L) {
228 for (unsigned i = 0; i < 2; ++i) {
229 for (unsigned alpha = 0; alpha < c_maxNAlphaPoints; ++alpha) {
230 for (unsigned theta = 0; theta < c_maxNThetaPoints; ++theta) {
231 for (unsigned xtparam = 0; xtparam < c_nXTParams; ++xtparam) {
232 m_XT[L][i][alpha][theta][xtparam] = 0.;
233 }
234
235 for (unsigned sigmaparam = 0; sigmaparam < c_nSigmaParams; ++sigmaparam) {
236 m_Sigma[L][i][alpha][theta][sigmaparam] = 0.;
237 }
238 }
239 }
240 }
241 }
242
243 for (unsigned board = 0; board < c_nBoards; ++board) {
244 for (unsigned i = 0; i < 2; ++i) {
245 m_timeWalkCoef[board][i] = 0.;
246 }
247 for (unsigned channel = 0; channel < 48; ++channel) {
248 m_boardAndChannelToWire[board][channel] = 0.;
249 }
250 }
251
252 for (unsigned superLayer = 0; superLayer < c_nSuperLayers; ++superLayer) {
253 for (unsigned layer = 0; layer < 8; ++layer) {
254 m_shiftInSuperLayer[superLayer][layer] = 0;
255 }
256 }
257
258}
259
261{
262 m_globalPhiRotation = geom.getGlobalPhiRotation();
263 // m_globalPhiRotation = geom.getGlobalOffsetC();
264
265 // Get inner wall parameters
266 m_rWall[0] = geom.getInnerWall(2).getRmin();
267 m_zWall[0][0] = geom.getInnerWall(0).getZbwd();
268 m_zWall[0][1] = geom.getInnerWall(0).getZfwd();
269
270 m_rWall[1] = geom.getInnerWall(0).getRmax();
271 m_zWall[1][0] = geom.getInnerWall(0).getZbwd();
272 m_zWall[1][1] = geom.getInnerWall(0).getZbwd();
273
274 // Get outer wall parameters
275 m_rWall[2] = geom.getOuterWall(0).getRmin();
276 m_zWall[2][0] = geom.getOuterWall(0).getZbwd();
277 m_zWall[2][1] = geom.getOuterWall(0).getZfwd();
278
279 m_rWall[3] = geom.getOuterWall(1).getRmax();
280 m_zWall[3][0] = geom.getOuterWall(0).getZbwd();
281 m_zWall[3][1] = geom.getOuterWall(0).getZfwd();
282
283 // Get sense layers parameters
285 m_nSLayer = geom.getNSenseLayers();
286
288 // std::cout << m_materialDefinitionMode << std::endl;
289 if (m_materialDefinitionMode == 0) {
290 B2DEBUG(100, "CDCGeometryPar: Define a mixture of gases and wires in the tracking volume.");
291 } else if (m_materialDefinitionMode == 2) {
292 // B2INFO("CDCGeometryPar: Define all sense and field wires explicitly in the tracking volume.");
293 B2FATAL("CDCGeometryPar: Materialdefinition=2 is disabled for now.");
294 } else {
295 B2FATAL("CDCGeometryPar: Materialdefinition mode you specify is invalid.");
296 }
297
298 // Get mode for wire z-position
300 //Set z corrections (from input data)
301 B2DEBUG(100, "CDCGeometryPar: Sense wire z mode:" << m_senseWireZposMode);
302
303 //
304 // The DB version should be implemented ASAP.
305 //
306 GearDir content = GearDir("/Detector/DetectorComponent[@name=\"CDC\"]/Content/");
307 GearDir gbxParams(content);
308 // if (m_senseWireZposMode == 1) readDeltaz(gbxParams);
309
310
311 //
312 // Sense wires.
313 //
314 for (const auto& sense : geom.getSenseLayers()) {
315 uint layerId = sense.getId();
316
317 m_rSLayer[layerId] = sense.getR();
318 m_zSBackwardLayer[layerId] = sense.getZbwd();
319 m_zSForwardLayer[layerId] = sense.getZfwd();
320 m_nWires[layerId] = sense.getNWires();
321 m_nShifts[layerId] = sense.getNShifts();
322 m_offSet[layerId] = sense.getOffset();
323 m_cellSize[layerId] = 2 * M_PI * m_rSLayer[layerId] / (double) m_nWires[layerId];
324 m_dzSBackwardLayer[layerId] = sense.getDZbwd();
325 m_dzSForwardLayer[layerId] = sense.getDZfwd();
326
327 //correction to z-position
328 if (m_senseWireZposMode == 0) {
329 } else if (m_senseWireZposMode == 1) {
330 // m_zSBackwardLayer[layerId] += m_bwdDz[layerId];
331 // m_zSForwardLayer [layerId] += m_fwdDz[layerId];
332 m_zSBackwardLayer[layerId] += m_dzSBackwardLayer[layerId];
333 m_zSForwardLayer [layerId] -= m_dzSForwardLayer [layerId];
334 } else {
335 B2FATAL("CDCGeometryPar: invalid wire z definition mode specified");
336 }
337
338 //Set design sense-wire related params.
339 const int nWires = m_nWires[layerId];
340 for (int iCell = 0; iCell < nWires; ++iCell) {
341 setDesignWirParam(layerId, iCell);
342 }
343
344 }
345
346 // Get field layers parameters
347 for (const auto& field : geom.getFieldLayers()) {
348 uint layerId = field.getId();
349
350 m_rFLayer[layerId] = field.getR();
351 m_zFBackwardLayer[layerId] = field.getZbwd();
352 m_zFForwardLayer[layerId] = field.getZfwd();
353 }
354
355 // Get sense wire diameter
356 m_senseWireDiameter = geom.getSenseDiameter();
357
358 // Get sense wire tension
359 m_senseWireTension = geom.getSenseTension();
360
361 // // Get sense wire density
362 m_senseWireDensity = 19.3; // g/cm3 <- tentatively hard-coded here
363
364 // Get field wire diameter
365 m_fieldWireDiameter = geom.getFieldDiameter();
366
367 // Get information on the number of (super) layers etc.
368 m_nSenseWires = geom.getNSenseWires();
369 m_nFieldWires = geom.getNFieldWires();
370 m_maxNSenseLayers = geom.getNumberOfSenseLayers();
371 m_maxNFieldLayers = geom.getNumberOfFieldLayers();
372 m_maxNSuperLayers = geom.getMaxNumberOfSuperLayers();
373 m_firstLayerOffset = geom.getOffsetOfFirstLayer();
374 m_firstSuperLayerOffset = geom.getOffsetOfFirstSuperLayer();
375 m_maxNCellsPerLayer = geom.getMaxNumberOfCellsPerLayer();
376
377 //Set various quantities (should be moved to CDC.xml later...)
378 m_clockFreq4TDC = geom.getClockFrequency();
379 if (not m_clockSettings.isValid())
380 B2FATAL("HardwareClockSettings payloads are not valid.");
381 const double officialClockFreq4TDC = 2 * m_clockSettings->getAcceleratorRF(); // in GHz
382 if (abs(m_clockFreq4TDC - officialClockFreq4TDC) / m_clockFreq4TDC > 1.e-4) {
383 B2WARNING("ClockFreq4TDC changed from cdclocal " << scientific << setprecision(6) << m_clockFreq4TDC << " to official " <<
384 officialClockFreq4TDC << " (GHz) (difference larger than 0.01%)");
385 m_clockFreq4TDC = officialClockFreq4TDC;
386 }
387 B2DEBUG(100, "CDCGeometryPar: Clock freq. for TDC= " << m_clockFreq4TDC << " (GHz).");
388 m_tdcBinWidth = 1. / m_clockFreq4TDC; //in ns
389 B2DEBUG(100, "CDCGeometryPar: TDC bin width= " << m_tdcBinWidth << " (ns).");
390
391 m_nominalDriftV = 4.e-3; //in cm/ns
392 m_nominalDriftVInv = 1. / m_nominalDriftV; //in ns/cm
393 m_nominalPropSpeed = 27.25; //in cm/nsec (Belle's result, provided by iwasaki san)
394
395 m_nominalSpaceResol = geom.getNominalSpaceResolution();
397
398 //Set displacement params. (from input data)
400 B2DEBUG(100, "CDCGeometryPar: Load displacement params. (=1); not load (=0):" << m_displacement);
401 if (m_displacement) {
402 if (gcp.getDisplacementInputType()) {
403 B2DEBUG(100, "CDCGeometryPar: Read displacement from DB");
405 } else {
406 readWirePositionParams(c_Base, &geom);
407 }
408 }
409
410 //Set alignment params. (from input data)
412 B2DEBUG(100, "CDCGeometryPar: Load alignment params. (=1); not load (=0):" <<
414 if (m_alignment) {
415 if (gcp.getAlignmentInputType()) {
416 B2DEBUG(100, "CDCGeometryPar: Read alignment from DB");
418 } else {
419 readWirePositionParams(c_Aligned, &geom);
420 }
421 }
422
423 //Set misalignment params. (from input data)
425 B2DEBUG(100, "CDCGeometryPar: Load misalignment params. (=1); not load (=0):" <<
427 if (m_misalignment) {
428 if (gcp.getMisalignmentInputType()) {
429 B2DEBUG(100, "CDCGeometryPar: Read misalignment from DB");
431 } else {
432 readWirePositionParams(c_Misaligned, &geom);
433 }
434 }
435
436 // Get control params. for CDC FullSim
441 if (m_modLeftRightFlag) {
442 B2FATAL("ModifiedLeftRightFlag = true is disabled for now; need to update a G4-related code in framework...");
443 }
444 //N.B. The following two lines are hard-coded since only =1 are used now.
445 m_xtFileFormat = 1;
447
448 m_XTetc = true;
449 if (m_XTetc) {
450 if (gcp.getXtInputType()) {
451 B2DEBUG(100, "CDCGeometryPar: Read xt from DB");
452 setXtRel(); //Set xt param. (from DB)
453 } else {
454 readXT(gbxParams); //Read xt params. (from file)
455 }
456
457 if (gcp.getSigmaInputType()) {
458 B2DEBUG(100, "CDCGeometryPar: Read sigma from DB");
459 setSResol(); //Set sigma param. (from DB)
460 } else {
461 readSigma(gbxParams); //Read sigma params. (from file)
462 }
463
464 if (gcp.getFFactorInputType()) {
465 B2DEBUG(100, "CDCGeometryPar: Read fudge factors from DB");
466 setFFactor(); //Set fudge factors (from DB)
467 } else {
468 readFFactor(gbxParams); //Read fudge factors (from file)
469 }
470
471 if (gcp.getPropSpeedInputType()) {
472 B2DEBUG(100, "CDCGeometryPar: Read prop-speed from DB");
473 setPropSpeed(); //Set prop-speed (from DB)
474 } else {
475 readPropSpeed(gbxParams); //Read propagation speed
476 }
477
478 if (gcp.getT0InputType()) {
479 B2DEBUG(100, "CDCGeometryPar: Read t0 from DB");
480 setT0(); //Set t0 (from DB)
481 } else {
482 readT0(gbxParams); //Read t0 (from file)
483 }
484
485 if (gcp.getBwInputType()) {
486 B2DEBUG(100, "CDCGeometryPar: Read badwire from DB");
487 setBadWire(); //Set bad-wire (from DB)
488 } else {
489 // readBadWire(gbxParams); //Read bad-wire (from file)
490 B2FATAL("Text file input mode for bdwires is disabled now!");
491 }
492
493 if (gcp.getChMapInputType()) {
494 B2DEBUG(100, "CDCGeometryPar: Read ch-map from DB");
495 setChMap(); //Set ch-map (from DB)
496 } else {
497 readChMap(); //Read ch-map
498 }
499
500 if (gcp.getTwInputType()) {
501 B2DEBUG(100, "CDCGeometryPar: Read time-walk from DB");
502 setTW(); //Set time-walk coeffs. (from DB)
503 } else {
504 readTW(gbxParams); //Read time-walk coeffs. (from file)
505 }
506 B2DEBUG(100, "CDCGeometryPar: Time-walk param. mode= " << m_twParamMode);
507
508 if (gcp.getEDepToADCInputType()) {
509 B2DEBUG(29, "CDCGeometryPar: Read EDepToADC from DB");
510 if ((*m_eDepToADCConversionsFromDB).isValid()) {
511 setEDepToADCConversions(); //Set edep-to-adc (from DB)
512 }
513 } else {
514 readEDepToADC(gbxParams); //Read edep-to-adc params. (from file)
515 }
516 }
517
518 m_XTetc4Recon = 0;
519 // B2INFO("CDCGeometryPar: Load x-t etc. params. for reconstruction (=1); not load and use the same ones for digitization (=0):" <<
520 // B2INFO("CDCGeometryPar: Use the same x-t etc. for reconstruction as those used for digitization");
521 if (m_XTetc4Recon) {
522 readXT(gbxParams, 1);
523 readSigma(gbxParams, 1);
524 readPropSpeed(gbxParams, 1);
525 readT0(gbxParams, 1);
526 readTW(gbxParams, 1);
527 }
528
529 //calculate and save shifts in super-layers
531
532}
533
534/*
535//TODO: move the following two functions to cdc/utilities <-done
536// Open a file
537void CDCGeometryPar::openFile(std::ifstream& ifs, const std::string& fileName0) const
538{
539 std::string fileName1 = "/data/cdc/" + fileName0;
540 std::string fileName = FileSystem::findFile(fileName1);
541
542 if (fileName == "") {
543 fileName = FileSystem::findFile(fileName0);
544 }
545
546 if (fileName == "") {
547 B2FATAL("CDCGeometryPar: " << fileName1 << " not exist!");
548 } else {
549 B2INFO("CDCGeometryPar: open " << fileName1);
550 ifs.open(fileName.c_str());
551 if (!ifs) B2FATAL("CDCGeometryPar: cannot open " << fileName1 << " !");
552 }
553}
554// Open a file using boost (to be able to read a gzipped file)
555void CDCGeometryPar::openFile(boost::iostreams::filtering_istream& ifs, const std::string& fileName0) const
556{
557 std::string fileName1 = "/data/cdc/" + fileName0;
558 std::string fileName = FileSystem::findFile(fileName1);
559
560 if (fileName == "") {
561 fileName = FileSystem::findFile(fileName0);
562 }
563
564 if (fileName == "") {
565 B2FATAL("CDCGeometryPar: " << fileName1 << " not exist!");
566 } else {
567 B2INFO("CDCGeometryPar: open " << fileName1);
568 if ((fileName.rfind(".gz") != string::npos) && (fileName.length() - fileName.rfind(".gz") == 3)) {
569 ifs.push(boost::iostreams::gzip_decompressor());
570 }
571 ifs.push(boost::iostreams::file_source(fileName));
572 if (!ifs) B2FATAL("CDCGeometryPar: cannot open " << fileName1 << " !");
573 }
574}
575*/
576
577// Read displacement or (mis)alignment params.
578//void CDCGeometryPar::readWirePositionParams(EWirePosition set, const CDCGeometry* geom, const GearDir gbxParams)
580{
581
582 std::string fileName0;
584 if (geom) {
585 if (set == c_Base) {
586 fileName0 = gcp.getDisplacementFile();
587 } else if (set == c_Misaligned) {
588 fileName0 = gcp.getMisalignmentFile();
589 } else if (set == c_Aligned) {
590 fileName0 = gcp.getAlignmentFile();
591 }
592 } else {
593 if (set == c_Base) {
594 fileName0 = gcp.getDisplacementFile();
595 } else if (set == c_Misaligned) {
596 fileName0 = gcp.getMisalignmentFile();
597 } else if (set == c_Aligned) {
598 fileName0 = gcp.getAlignmentFile();
599 }
600 }
601
602 // ifstream ifs;
603 // openFile(ifs, fileName0);
604 boost::iostreams::filtering_istream ifs;
605 openFileB(ifs, fileName0);
606
607 uint iL(0), iC(0);
608 const int np = 3;
609 double back[np], fwrd[np], tension;
610 unsigned nRead = 0;
611
612 while (true) {
613 ifs >> iL >> iC;
614 for (int i = 0; i < np; ++i) {
615 ifs >> back[i];
616 }
617 for (int i = 0; i < np; ++i) {
618 ifs >> fwrd[i];
619 }
620 // if (set != c_Base) ifs >> tension;
621 ifs >> tension;
622
623 if (ifs.eof()) break;
624
625 if (iL < m_firstLayerOffset) {
626 continue;
627 }
628
629 ++nRead;
630
631 for (int i = 0; i < np; ++i) {
632 if (set == c_Base) {
633 m_BWirPos[iL][iC][i] += (iL < m_firstLayerOffset) ? 0 : back[i];
634 m_FWirPos[iL][iC][i] += (iL < m_firstLayerOffset) ? 0 : fwrd[i];
635 } else if (set == c_Misaligned) {
636 m_BWirPosMisalign[iL][iC][i] = m_BWirPos[iL][iC][i] + ((iL < m_firstLayerOffset) ? 0 : back[i]);
637 m_FWirPosMisalign[iL][iC][i] = m_FWirPos[iL][iC][i] + ((iL < m_firstLayerOffset) ? 0 : fwrd[i]);
638 } else if (set == c_Aligned) {
639 m_BWirPosAlign[iL][iC][i] = m_BWirPos[iL][iC][i] + ((iL < m_firstLayerOffset) ? 0 : back[i]);
640 m_FWirPosAlign[iL][iC][i] = m_FWirPos[iL][iC][i] + ((iL < m_firstLayerOffset) ? 0 : fwrd[i]);
641 }
642 }
643
644 // double baseTension = 0.;
645
646 if (set == c_Base) {
648 (8.*(m_senseWireTension + tension));
649 // std::cout <<"base iL, iC, m_senseWireTension, tension= " << iL <<" " << iC <<" "<< m_senseWireTension <<" "<< tension << std::endl;
650 } else if (set == c_Misaligned) {
651 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
653 m_senseWireDiameter / (8.* (baseTension + tension));
654 // std::cout <<"misa iL, iC,basetension, tension= " << iL <<" " << iC <<" "<< baseTension <<" "<< tension << std::endl;
655 } else if (set == c_Aligned) {
656 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
658 m_senseWireDiameter / (8.*(baseTension + tension));
659 // std::cout <<"algn iL, iC,basetension, tension= " << iL <<" " << iC <<" "<< baseTension <<" "<< tension << std::endl;
660 }
661 // std::cout << "baseTension,tension= " << baseTension <<" "<< tension << std::endl;
662
663 /*
664 if (m_debug) {
665 std::cout << iL << " " << iC;
666 for (int i = 0; i < np; ++i) cout << " " << back[i];
667 for (int i = 0; i < np; ++i) cout << " " << fwrd[i];
668 std::cout << " " << tension << std::endl;
669 }
670 */
671
672 }
673
674 if (nRead != m_nSenseWires) B2FATAL("CDCGeometryPar::readWirePositionParams: #lines read-in (=" << nRead <<
675 ") is inconsistent with total #sense wires (=" << m_nSenseWires << ") !");
676
677 // ifs.close();
678 boost::iostreams::close(ifs);
679}
680
681
682// Set alignment wire positions
684{
685 // Layer alignment
686 for (unsigned iL = 0; iL < c_maxNSenseLayers; ++iL) {
687
688 if (iL < m_firstLayerOffset) {
689 continue;
690 }
691
692 // wire number 511 = no wire
693 auto layerID = WireID(iL, 511);
694
695 // Alignment parameters for layer iL
696 double d_layerXbwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerX);
697 double d_layerYbwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerY);
698 double d_layerPhiBwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerPhi);
699
700 double d_layerXfwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDx) + d_layerXbwd;
701 double d_layerYfwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDy) + d_layerYbwd;
702 double d_layerPhiFwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDPhi) + d_layerPhiBwd;
703
704 for (unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
705 // Positions (nominal+displacement) of wire-ends of wire iC in layer iL
706 double wireXbwd = m_BWirPos[iL][iC][0];
707 double wireYbwd = m_BWirPos[iL][iC][1];
708 double wireZbwd = m_BWirPos[iL][iC][2];
709
710 double wireXfwd = m_FWirPos[iL][iC][0];
711 double wireYfwd = m_FWirPos[iL][iC][1];
712 double wireZfwd = m_FWirPos[iL][iC][2];
713
714 // Aligned positions of wire-ends are obtained by rotating "nominal+displacement" positions and shifting them using
715 // common parameters for layer rotation and shifts (at corresponding end-caps)
716 m_BWirPosAlign[iL][iC][0] = d_layerXbwd + cos(d_layerPhiBwd) * wireXbwd + sin(d_layerPhiBwd) * wireYbwd;
717 m_BWirPosAlign[iL][iC][1] = d_layerYbwd - sin(d_layerPhiBwd) * wireXbwd + cos(d_layerPhiBwd) * wireYbwd;
718 m_BWirPosAlign[iL][iC][2] = wireZbwd;
719
720 m_FWirPosAlign[iL][iC][0] = d_layerXfwd + cos(d_layerPhiFwd) * wireXfwd + sin(d_layerPhiFwd) * wireYfwd;
721 m_FWirPosAlign[iL][iC][1] = d_layerYfwd - sin(d_layerPhiFwd) * wireXfwd + cos(d_layerPhiFwd) * wireYfwd;
722 m_FWirPosAlign[iL][iC][2] = wireZfwd;
723 } //end of cell loop
724 } //end of layer loop
725
726 const int np = 3;
727 double back[np], fwrd[np];
728
729 for (unsigned iL = 0; iL < c_maxNSenseLayers; ++iL) {
730
731 if (iL < m_firstLayerOffset) {
732 continue;
733 }
734
735 for (unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
736 // std::cout << "iLiC= " << iL <<" "<< iC << std::endl;
737 WireID wire(iL, iC);
738 back[0] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdX);
739 back[1] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdY);
740 back[2] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdZ);
741
742 fwrd[0] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdX);
743 fwrd[1] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdY);
744 fwrd[2] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdZ);
745
746 for (int i = 0; i < np; ++i) {
747 // On top of the wire-end positions corrected for layer alignment, we apply possible
748 // fine corrections per wire
749 m_BWirPosAlign[iL][iC][i] += back[i];
750 m_FWirPosAlign[iL][iC][i] += fwrd[i];
751 }
752
753 // double baseTension = 0.;
754 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
755 double tension = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireTension);
756 // std::cout << back[0] <<" "<< back[1] <<" "<< back[2] <<" "<< fwrd[0] <<" "<< fwrd[1] <<" "<< fwrd[2] <<" "<< tension << std::endl;
757 m_WireSagCoefAlign[iL][iC] = M_PI * m_senseWireDensity *
758 m_senseWireDiameter * m_senseWireDiameter / (8.*(baseTension + tension));
759 // std::cout << "baseTension,tension= " << baseTension <<" "<< tension << std::endl;
760 } //end of layer loop
761 } //end of cell loop
762}
763
764
765// Set misalignment wire positions
766//TODO: merge this and setWirPosAlignParam() somehow
768{
769 const int np = 3;
770 double back[np], fwrd[np];
771
772 for (unsigned iL = 0; iL < c_maxNSenseLayers; ++iL) {
773
774 if (iL < m_firstLayerOffset) {
775 continue;
776 }
777
778 for (unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
779 // std::cout << "iLiC= " << iL <<" "<< iC << std::endl;
780 WireID wire(iL, iC);
781 back[0] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdX);
782 back[1] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdY);
783 back[2] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdZ);
784
785 fwrd[0] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdX);
786 fwrd[1] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdY);
787 fwrd[2] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdZ);
788
789 for (int i = 0; i < np; ++i) {
790 m_BWirPosMisalign[iL][iC][i] = m_BWirPos[iL][iC][i] + back[i];
791 m_FWirPosMisalign[iL][iC][i] = m_FWirPos[iL][iC][i] + fwrd[i];
792 }
793
794 // double baseTension = 0.;
795 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
796 double tension = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireTension);
797 // std::cout << back[0] <<" "<< back[1] <<" "<< back[2] <<" "<< fwrd[0] <<" "<< fwrd[1] <<" "<< fwrd[2] <<" "<< tension << std::endl;
799 m_senseWireDiameter * m_senseWireDiameter / (8.*(baseTension + tension));
800 // std::cout << "baseTension,tension= " << baseTension <<" "<< tension << std::endl;
801 } //end of layer loop
802 } //end of cell loop
803}
804
805
806// Read x-t params.
807void CDCGeometryPar::readXT(const GearDir& gbxParams, const int mode)
808{
809 if (m_xtFileFormat == 0) {
810 // oldReadXT(gbxParams, mode);
811 } else {
812 newReadXT(gbxParams, mode);
813 }
814}
815
816
817// Read x-t params. (new)
818void CDCGeometryPar::newReadXT(const GearDir& gbxParams, const int mode)
819{
820 m_linearInterpolationOfXT = true; //must be true now
821
822 std::string fileName0 = CDCGeoControlPar::getInstance().getXtFile();
823 if (mode == 1) {
824 fileName0 = gbxParams.getString("xt4ReconFileName");
825 }
826
827 boost::iostreams::filtering_istream ifs;
828 openFileB(ifs, fileName0);
829 //TODO: use openFile() in cdc/utilities instead of the following 18 lines <- done
830 /*
831 std::string fileName1 = "/data/cdc/" + fileName0;
832 std::string fileName = FileSystem::findFile(fileName1);
833
834 if (fileName == "") {
835 fileName = FileSystem::findFile(fileName0);
836 }
837
838 if (fileName == "") {
839 B2FATAL("CDCGeometryPar: " << fileName1 << " not exist!");
840 } else {
841 B2INFO("CDCGeometryPar: open " << fileName1);
842 if ((fileName.rfind(".gz") != string::npos) && (fileName.length() - fileName.rfind(".gz") == 3)) {
843 ifs.push(boost::iostreams::gzip_decompressor());
844 }
845 ifs.push(boost::iostreams::file_source(fileName));
846 if (!ifs) B2FATAL("CDCGeometryPar: cannot open " << fileName1 << " !");
847 }
848 */
849
850 //read alpha bin info.
851 unsigned short nAlphaBins = 0;
852 if (ifs >> nAlphaBins) {
853 if (nAlphaBins == 0 || nAlphaBins > c_maxNAlphaPoints) B2FATAL("Fail to read alpha bins !");
854 } else {
855 B2FATAL("Fail to read alpha bins !");
856 }
857 m_nAlphaPoints = nAlphaBins;
858 double alpha0, alpha1, alpha2;
859 for (unsigned short i = 0; i < nAlphaBins; ++i) {
860 ifs >> alpha0 >> alpha1 >> alpha2;
861 m_alphaPoints[i] = alpha2;
862 }
863
864 //read theta bin info.
865 unsigned short nThetaBins = 0;
866 if (ifs >> nThetaBins) {
867 if (nThetaBins == 0 || nThetaBins > c_maxNThetaPoints) B2FATAL("CDCGeometryPar: fail to read theta bins !");
868 } else {
869 B2FATAL("CDCGeometryPar: fail to read theta bins !");
870 }
871 m_nThetaPoints = nThetaBins;
872 double theta0, theta1, theta2;
873
874 for (unsigned short i = 0; i < nThetaBins; ++i) {
875 ifs >> theta0 >> theta1 >> theta2;
876 m_thetaPoints[i] = theta2;
877 }
878
879 short np = 0;
880 unsigned short iCL, iLR;
881 const unsigned short npx = c_nXTParams - 1;
882 double xtc[npx];
883 double theta, alpha, dummy1;
884
885 ifs >> m_xtParamMode >> np;
886 if (m_xtParamMode < 0 || m_xtParamMode > 3) B2FATAL("CDCGeometryPar: invalid xt-parameterization mode read !");
887
888 if (np <= 0 || np > npx) B2FATAL("CDCGeometryPar: no. of xt-params. outside limits !");
889
890 const double epsi = 0.1;
891
892 while (ifs >> iCL) {
893
894 if (iCL < m_firstLayerOffset) {
895 continue;
896 }
897
898 ifs >> theta >> alpha >> dummy1 >> iLR;
899 for (int i = 0; i < np; ++i) {
900 ifs >> xtc[i];
901 }
902
903 int itheta = -99;
904 for (unsigned short i = 0; i < nThetaBins; ++i) {
905 if (fabs(theta - m_thetaPoints[i]) < epsi) {
906 itheta = i;
907 break;
908 }
909 }
910 if (itheta < 0) B2FATAL("CDCGeometryPar: thetas in xt.dat are inconsistent !");
911
912 int ialpha = -99;
913 for (unsigned short i = 0; i < nAlphaBins; ++i) {
914 if (fabs(alpha - m_alphaPoints[i]) < epsi) {
915 ialpha = i;
916 break;
917 }
918 }
919 if (ialpha < 0) B2FATAL("CDCGeometryPar: alphas in xt.dat are inconsistent !");
920
921 for (int i = 0; i < np; ++i) {
922 m_XT[iCL][iLR][ialpha][itheta][i] = xtc[i];
923 }
924
925 double boundT = xtc[6];
926 if (m_xtParamMode == 1) {
927 m_XT[iCL][iLR][ialpha][itheta][np] = ROOT::Math::Chebyshev5(boundT, xtc[0], xtc[1], xtc[2], xtc[3], xtc[4], xtc[5]);
928 } else {
929 m_XT[iCL][iLR][ialpha][itheta][np] =
930 xtc[0] + boundT
931 * (xtc[1] + boundT
932 * (xtc[2] + boundT
933 * (xtc[3] + boundT
934 * (xtc[4] + boundT
935 * (xtc[5])))));
936 }
937 } //end of while loop
938
939 // ifs.close();
940 boost::iostreams::close(ifs);
941
942 //convert unit
943 const double degrad = M_PI / 180.;
944 for (unsigned i = 0; i < nAlphaBins; ++i) {
945 m_alphaPoints[i] *= degrad;
946 }
947 for (unsigned i = 0; i < nThetaBins; ++i) {
948 m_thetaPoints[i] *= degrad;
949 }
950
951}
952
953
954// Read space resol. params.
955void CDCGeometryPar::readSigma(const GearDir& gbxParams, const int mode)
956{
957 if (m_sigmaFileFormat == 0) {
958 // oldReadSigma(gbxParams, mode);
959 } else {
960 newReadSigma(gbxParams, mode);
961 }
962}
963
964void CDCGeometryPar::newReadSigma(const GearDir& gbxParams, const int mode)
965{
966 m_linearInterpolationOfSgm = true; //must be true now
967
968 std::string fileName0 = CDCGeoControlPar::getInstance().getSigmaFile();
969 if (mode == 1) {
970 fileName0 = gbxParams.getString("sigma4ReconFileName");
971 }
972
973 ifstream ifs;
974 // openFile(ifs, fileName0);
975 openFileA(ifs, fileName0);
976
977 //read alpha bin info.
978 unsigned short nAlphaBins = 0;
979 if (ifs >> nAlphaBins) {
980 if (nAlphaBins == 0 || nAlphaBins > c_maxNAlphaPoints) B2FATAL("Fail to read alpha bins !");
981 } else {
982 B2FATAL("Fail to read alpha bins !");
983 }
984 m_nAlphaPoints4Sgm = nAlphaBins;
985 // std:: cout << nAlphaBins << std::endl;
986 double alpha0, alpha1, alpha2;
987 for (unsigned short i = 0; i < nAlphaBins; ++i) {
988 ifs >> alpha0 >> alpha1 >> alpha2;
989 m_alphaPoints4Sgm[i] = alpha2;
990 // std:: cout << alpha2 << std::endl;
991 }
992
993 //read theta bin info.
994 unsigned short nThetaBins = 0;
995 if (ifs >> nThetaBins) {
996 if (nThetaBins == 0 || nThetaBins > c_maxNThetaPoints) B2FATAL("CDCGeometryPar: fail to read theta bins !");
997 } else {
998 B2FATAL("CDCGeometryPar: fail to read theta bins !");
999 }
1000 m_nThetaPoints4Sgm = nThetaBins;
1001 // std:: cout << nThetaBins << std::endl;
1002 double theta0, theta1, theta2;
1003
1004 for (unsigned short i = 0; i < nThetaBins; ++i) {
1005 ifs >> theta0 >> theta1 >> theta2;
1006 m_thetaPoints4Sgm[i] = theta2;
1007 // std:: cout << theta2 << std::endl;
1008 }
1009
1010 unsigned short np = 0;
1011 unsigned short iCL, iLR;
1012 double sigma[c_nSigmaParams]; // cppcheck-suppress constVariable
1013 double theta, alpha;
1014
1015 ifs >> m_sigmaParamMode >> np;
1016 // std:: cout << m_sigmaParamMode <<" "<< np << std::endl;
1017 if (m_sigmaParamMode < 0 || m_sigmaParamMode > 4) B2FATAL("CDCGeometryPar: invalid sigma-parameterization mode read !");
1018
1019 if (np > c_nSigmaParams) B2FATAL("CDCGeometryPar: no. of sigma-params. outside limits !");
1020
1021 ifs >> m_maxSpaceResol;
1022
1023 const double epsi = 0.1;
1024
1025 while (ifs >> iCL) {
1026
1027 if (iCL < m_firstLayerOffset) {
1028 continue;
1029 }
1030
1031 ifs >> theta >> alpha >> iLR;
1032 // std::cout << iCL <<" "<< theta <<" "<< alpha <<" "<< iLR << std::endl;
1033 for (int i = 0; i < np; ++i) {
1034 ifs >> sigma[i];
1035 }
1036
1037 int itheta = -99;
1038 for (unsigned short i = 0; i < nThetaBins; ++i) {
1039 if (fabs(theta - m_thetaPoints4Sgm[i]) < epsi) {
1040 itheta = i;
1041 break;
1042 }
1043 }
1044 if (itheta < 0) B2FATAL("CDCGeometryPar: thetas in sigma.dat are inconsistent !");
1045
1046 int ialpha = -99;
1047 for (unsigned short i = 0; i < nAlphaBins; ++i) {
1048 if (fabs(alpha - m_alphaPoints4Sgm[i]) < epsi) {
1049 ialpha = i;
1050 break;
1051 }
1052 }
1053 if (ialpha < 0) B2FATAL("CDCGeometryPar: alphas in sigma.dat are inconsistent !");
1054
1055 for (int i = 0; i < np; ++i) {
1056 m_Sigma[iCL][iLR][ialpha][itheta][i] = sigma[i];
1057 }
1058 } //end of while loop
1059
1060 ifs.close();
1061
1062 //convert unit
1063 const double degrad = M_PI / 180.;
1064 for (unsigned i = 0; i < nAlphaBins; ++i) {
1065 m_alphaPoints4Sgm[i] *= degrad;
1066 }
1067 for (unsigned i = 0; i < nThetaBins; ++i) {
1068 m_thetaPoints4Sgm[i] *= degrad;
1069 }
1070
1071 // std::cout << "end of newreadsigma " << std::endl;
1072}
1073
1074
1075// Read fudge factors
1076void CDCGeometryPar::readFFactor(const GearDir& gbxParams, const int mode)
1077{
1078 std::string fileName0 = CDCGeoControlPar::getInstance().getFFactorFile();
1079 if (mode == 1) {
1080 fileName0 = gbxParams.getString("fudgeFactorFileName");
1081 }
1082 B2WARNING("readFFactor is not ready! " << fileName0);
1083 //TODO; implement the following part.
1084}
1085
1086
1087// Read propagation speed param.
1088void CDCGeometryPar::readPropSpeed(const GearDir& gbxParams, const int mode)
1089{
1090 std::string fileName0 = CDCGeoControlPar::getInstance().getPropSpeedFile();
1091 if (mode == 1) {
1092 fileName0 = gbxParams.getString("propSpeed4ReconFileName");
1093 }
1094
1095 ifstream ifs;
1096 // openFile(ifs, fileName0);
1097 openFileA(ifs, fileName0);
1098
1099 uint iL;
1100 double speed;
1101 unsigned nRead = 0;
1102
1103 while (true) {
1104 ifs >> iL >> speed;
1105 if (ifs.eof()) break;
1106
1107 ++nRead;
1108
1109 m_propSpeedInv[iL] = (iL < m_firstLayerOffset) ? 0 : 1. / speed;
1110
1111 if (m_debug) B2DEBUG(150, iL << " " << speed);
1112 }
1113
1114 if (nRead != c_maxNSenseLayers) B2FATAL("CDCGeometryPar::readPropSpeed: #lines read-in (=" << nRead <<
1115 ") is inconsistent with total #layers (=" << c_maxNSenseLayers << ") !");
1116
1117 ifs.close();
1118}
1119
1120/*
1121// Read deltaz params.
1122void CDCGeometryPar::readDeltaz(const GearDir gbxParams)
1123{
1124 std::string fileName0 = gbxParams.getString("deltazFileName");
1125 fileName0 = "/data/cdc/" + fileName0;
1126 std::string fileName = FileSystem::findFile(fileName0);
1127
1128 ifstream ifs;
1129
1130 if (fileName == "") {
1131 B2FATAL("CDCGeometryPar: " << fileName0 << " not exist!");
1132 } else {
1133 B2INFO("CDCGeometryPar: " << fileName0 << " exists.");
1134 ifs.open(fileName.c_str());
1135 if (!ifs) B2FATAL("CDCGeometryPar: cannot open " << fileName0 << " !");
1136 }
1137
1138 int iL;
1139 unsigned nRead = 0;
1140
1141 while (ifs >> iL) {
1142 ifs >> m_bwdDz[iL] >> m_fwdDz[iL];
1143 ++nRead;
1144 if (m_debug) cout << iL << " " << m_bwdDz[iL] << " " << m_fwdDz[iL] << endl;
1145 }
1146
1147 if (nRead != c_maxNSenseLayers) B2FATAL("CDCGeometryPar::readDeltaz: #lines read-in (=" << nRead <<
1148 ") is inconsistent with total #layers (=" << c_maxNSenseLayers << ") !");
1149
1150 ifs.close();
1151}
1152*/
1153
1154
1155// Read t0 params.
1156void CDCGeometryPar::readT0(const GearDir& gbxParams, int mode)
1157{
1158 std::string fileName0 = CDCGeoControlPar::getInstance().getT0File();
1159 if (mode == 1) {
1160 fileName0 = gbxParams.getString("t04ReconFileName");
1161 }
1162
1163 ifstream ifs;
1164 // openFile(ifs, fileName0);
1165 openFileA(ifs, fileName0);
1166
1167 uint iL(0), iC(0);
1168 float t0(0);
1169 unsigned nRead = 0;
1170
1171 while (true) {
1172 ifs >> iL >> iC >> t0;
1173
1174 if (iL < m_firstLayerOffset) {
1175 continue;
1176 }
1177
1178 if (ifs.eof()) break;
1179
1180 ++nRead;
1181
1182 m_t0[iL][iC] = (iL < m_firstLayerOffset) ? 0. : t0;
1183
1184 if (m_debug) {
1185 B2DEBUG(150, iL << " " << iC << " " << t0);
1186 }
1187 }
1188
1189 if (nRead != m_nSenseWires) B2FATAL("CDCGeometryPar::readT0: #lines read-in (=" << nRead <<
1190 ") is inconsistent with total #sense wires (=" << m_nSenseWires << ") !");
1191
1192 ifs.close();
1193
1194 calcMeanT0();
1195}
1196
1197
1198/*
1199// Read bad-wires.
1200void CDCGeometryPar::readBadWire(const GearDir gbxParams, int mode)
1201{
1202 std::string fileName0 = CDCGeoControlPar::getInstance().getBwFile();
1203 if (mode == 1) {
1204 fileName0 = gbxParams.getString("bw4ReconFileName");
1205 }
1206
1207 ifstream ifs;
1208 // openFile(ifs, fileName0);
1209 openFileA(ifs, fileName0);
1210
1211 int iCL(0), iW(0);
1212 unsigned nRead = 0;
1213
1214 while (true) {
1215 ifs >> iCL >> iW;
1216
1217 if (ifs.eof()) break;
1218
1219 ++nRead;
1220
1221 m_badWire.push_back(WireID(iCL, iW));
1222
1223 if (m_debug) {
1224 B2DEBUG(150, iCL << " " << iW);
1225 }
1226 }
1227
1228 if (nRead > m_nSenseWires) B2FATAL("CDCGeometryPar::readBadWire: #lines read-in (=" << nRead <<
1229 ") is larger than the total #sense wires (=" << m_nSenseWires << ") !");
1230
1231 ifs.close();
1232}
1233*/
1234
1235
1236// Read time-walk parameters
1237void CDCGeometryPar::readTW(const GearDir& gbxParams, const int mode)
1238{
1239 std::string fileName0 = CDCGeoControlPar::getInstance().getTwFile();
1240 if (mode == 1) {
1241 fileName0 = gbxParams.getString("tw4ReconFileName");
1242 }
1243
1244 ifstream ifs;
1245 // openFile(ifs, fileName0);
1246 openFileA(ifs, fileName0);
1247
1248 unsigned short nPars(0);
1249 ifs >> m_twParamMode >> nPars;
1250 if (m_twParamMode > 1) {
1251 B2FATAL("CDCGeometryPar::readTW: invalid mode specified!");
1252 }
1253 if (nPars > 2) {
1254 B2FATAL("CDCGeometryPar::readTW: invalid #params specified!");
1255 }
1256
1257 unsigned iBoard = 0;
1258 unsigned nRead = 0;
1259 // Read board id and coefficients
1260 while (ifs >> iBoard) {
1261 for (unsigned short i = 0; i < nPars; ++i) {
1262 ifs >> m_timeWalkCoef[iBoard][i];
1263 }
1264 ++nRead;
1265 }
1266
1267 if (nRead != c_nBoards) B2FATAL("CDCGeometryPar::readTW: #lines read-in (=" << nRead << ") is inconsistent with #boards (=" <<
1268 c_nBoards
1269 << ") !");
1270
1271 ifs.close();
1272}
1273
1274
1275// Read ch-map
1276//void CDCGeometryPar::readChMap(const GearDir gbxParams)
1278{
1279 std::string fileName0 = CDCGeoControlPar::getInstance().getChMapFile();
1280
1281 ifstream ifs;
1282 // openFile(ifs, fileName0);
1283 openFileA(ifs, fileName0);
1284
1285 unsigned short iSL, iL, iW, iB, iC;
1286 unsigned nRead = 0;
1287
1288 while (true) {
1289 // Read a relation
1290 ifs >> iSL >> iL >> iW >> iB >> iC;
1291 if (ifs.eof()) break;
1292 if (iSL >= c_nSuperLayers or iSL < m_firstSuperLayerOffset) continue;
1293
1294 ++nRead;
1295 WireID wID(iSL, iL, iW);
1296 m_wireToBoard.insert(pair<WireID, unsigned short>(wID, iB));
1297 }
1298
1299 if (nRead != m_nSenseWires) B2FATAL("CDCGeometryPar::readChMap: #lines read-in (=" << nRead <<
1300 ") is inconsistent with #sense-wires (="
1301 << m_nSenseWires << ") !");
1302
1303 ifs.close();
1304}
1305
1306
1307// Read edep-to-adc
1308void CDCGeometryPar::readEDepToADC(const GearDir& gbxParams, const int mode)
1309{
1310 // B2WARNING("CDCGeometryPar: readEDepToADC is not ready!");
1311 std::string fileName0 = CDCGeoControlPar::getInstance().getEDepToADCFile();
1312 if (mode == 1) {
1313 fileName0 = gbxParams.getString("fudgeFactorFileName");
1314 }
1315
1316 ifstream ifs;
1317 // openFileA(ifs, fileName0);
1318 std::string fileName1 = "/data/cdc/" + fileName0;
1319 std::string fileName = FileSystem::findFile(fileName1, true);
1320
1321 if (fileName == "") {
1322 fileName = FileSystem::findFile(fileName0, true);
1323 }
1324
1325 if (fileName == "") {
1326 B2FATAL("CDC::openFile: " << fileName0 << " not exist!");
1327 } else {
1328 // B2INFO("CDC::openFile: open " << fileName);
1329 B2DEBUG(29, "CDC::openFile: open " << fileName);
1330 ifs.open(fileName.c_str());
1331 if (!ifs) B2FATAL("CDC::openFile: cannot open " << fileName << " !");
1332 }
1333
1334 unsigned short paramMode(0), nParams(0);
1335 ifs >> paramMode >> nParams;
1336 if (paramMode > 1) B2FATAL("Param mode > 1!");
1337 if (nParams > 7) B2FATAL("No. of params. > 7!");
1338 unsigned short groupId(0);
1339 ifs >> groupId;
1340 B2DEBUG(29, paramMode << " " << nParams << " " << groupId);
1341 if (groupId > 0) B2FATAL("GgroupId > 0!");
1342
1343
1344 unsigned short cLMin[c_nSuperLayers], cLMax[c_nSuperLayers]; //min and max clayer per super-layer
1345 cLMin[0] = 0;
1346 cLMax[0] = 7;
1347 for (unsigned int sl = 1; sl < c_nSuperLayers; ++sl) {
1348 cLMin[sl] = cLMax[0] + 6 * sl - 5;
1349 cLMax[sl] = cLMax[0] + 6 * sl;
1350 }
1351
1352 unsigned short id = 0;
1353 double coef = 0.;
1354 unsigned short nRead = 0;
1355 while (ifs >> id) {
1356 for (unsigned short i = 0; i < nParams; ++i) {
1357 ifs >> coef;
1358 for (unsigned short cL = cLMin[id]; cL <= cLMax[id]; ++cL) { //clayer loop
1359 for (unsigned short cell = 0; cell < m_nWires[cL]; ++cell) { //cell loop
1360 m_eDepToADCParams[cL][cell][i] = (cL < m_firstLayerOffset) ? 0 : coef;
1361 // B2DEBUG(29, "cL,cell,i,coef= "<< cL <<" "<< cell <<" "<< i <<" "<< coef);
1362 }
1363 }
1364 }
1365 ++nRead;
1366 if (nRead > c_nSuperLayers) B2FATAL("No. of read in lines > " << c_nSuperLayers << " !");
1367 }
1368
1369 ifs.close();
1370}
1371
1372
1373// Set t0 (from DB)
1375{
1376 for (unsigned short iCL = 0; iCL < c_maxNSenseLayers; ++iCL) {
1377 for (unsigned short iW = 0; iW < c_maxNDriftCells; ++iW) {
1378 m_t0[iCL][iW] = 0.;
1379 }
1380 }
1381
1382 for (auto const& ent : (*m_t0FromDB)->getT0s()) {
1383 const WireID wid = WireID(ent.first);
1384 const unsigned short iCL = wid.getICLayer();
1385 const unsigned short iW = wid.getIWire();
1386 m_t0[iCL][iW] = (iCL < m_firstLayerOffset) ? 0. : ent.second;
1387 }
1388
1389 calcMeanT0();
1390}
1391
1392
1393// Calculate mean t0
1394void CDCGeometryPar::calcMeanT0(double minT0, double maxT0, int maxIt, double nStdv, double epsi)
1395{
1396 double oldMeanT0 = 0;
1397 unsigned short it1 = 0;
1398 for (unsigned short it = 0; it < maxIt; ++it) {
1399 it1 = it;
1400 double effiSum = 0.;
1401 m_meanT0 = 0.;
1402 double stdvT0 = 0;
1403 for (unsigned short iCL = 0; iCL < c_maxNSenseLayers; ++iCL) {
1404 for (unsigned short iW = 0; iW < m_nWires[iCL]; ++iW) {
1405 if (m_t0[iCL][iW] < minT0 || m_t0[iCL][iW] > maxT0) continue;
1406 const WireID wid = WireID(iCL, iW);
1407 if (isHotWire(wid)) continue;
1408 if (isBadWire(wid)) continue;
1409 double effi = 1.;
1410 isDeadWire(wid, effi);
1411 effiSum += effi;
1412 m_meanT0 += (iCL < m_firstLayerOffset) ? 0. : effi * m_t0[iCL][iW];
1413 stdvT0 += (iCL < m_firstLayerOffset) ? 0. : effi * m_t0[iCL][iW] * m_t0[iCL][iW];
1414 }
1415 }
1416 if (effiSum > 0.) {
1417 m_meanT0 /= effiSum;
1418 stdvT0 /= effiSum;
1419 stdvT0 = sqrt(fabs(stdvT0 - m_meanT0 * m_meanT0));
1420 B2DEBUG(29, it << " " << effiSum << " " << m_meanT0 << " " << stdvT0);
1421 if (fabs(m_meanT0 - oldMeanT0) < epsi) break;
1422 oldMeanT0 = m_meanT0;
1423 minT0 = m_meanT0 - nStdv * stdvT0;
1424 maxT0 = m_meanT0 + nStdv * stdvT0;
1425 } else {
1426 B2FATAL("Wire efficiency sum <= 0!");
1427 }
1428 }
1429 if (it1 == maxIt - 1) B2WARNING("Max. iterations(=" << maxIt << ") needed to calculte the mean t0. Strange.");
1430}
1431
1432
1433// Set bad-wire (from DB)
1435{
1436 // m_badWire = (*m_badWireFromDB)->getWires();
1437 calcMeanT0();
1438}
1439
1440
1441// Set prop.-speed (from DB)
1443{
1444 for (unsigned short iCL = 0; iCL < (*m_propSpeedFromDB)->getEntries(); ++iCL) {
1445 m_propSpeedInv[iCL] = (iCL < m_firstLayerOffset) ? 0. : 1. / (*m_propSpeedFromDB)->getSpeed(iCL);
1446 }
1447}
1448
1449
1450// Set time-walk coefficient (from DB)
1452{
1453 // (*m_timeWalkFromDB)->dump();
1454 m_twParamMode = (*m_timeWalkFromDB)->getTwParamMode();
1455
1456 for (unsigned short iBd = 0; iBd < (*m_timeWalkFromDB)->getEntries(); ++iBd) {
1457 int np = ((*m_timeWalkFromDB)->getTimeWalkParams(iBd)).size();
1458 for (int i = 0; i < np; ++i) {
1459 m_timeWalkCoef[iBd][i] = ((*m_timeWalkFromDB)->getTimeWalkParams(iBd))[i];
1460 }
1461 }
1462}
1463
1464
1465// Set xt params. (from DB)
1467{
1468 m_linearInterpolationOfXT = true; //must be true now
1469
1470 // std::cout <<"setXtRelation called" << std::endl;
1471 m_nAlphaPoints = (*m_xtRelFromDB)->getNoOfAlphaBins();
1472 for (unsigned short i = 0; i < m_nAlphaPoints; ++i) {
1473 m_alphaPoints[i] = (*m_xtRelFromDB)->getAlphaPoint(i);
1474 // std::cout << m_alphaPoints[i]*180./M_PI << std::endl;
1475 }
1476
1477 m_nThetaPoints = (*m_xtRelFromDB)->getNoOfThetaBins();
1478 for (unsigned short i = 0; i < m_nThetaPoints; ++i) {
1479 m_thetaPoints[i] = (*m_xtRelFromDB)->getThetaPoint(i);
1480 // std::cout << m_thetaPoints[i]*180./M_PI << std::endl;
1481 }
1482
1483 m_xtParamMode = (*m_xtRelFromDB)->getXtParamMode();
1484
1485 for (unsigned short iCL = 0; iCL < c_maxNSenseLayers; ++iCL) {
1486 if (iCL < m_firstLayerOffset) {
1487 // m_XT is initialized to 0, but reading
1488 // (*m_xtRelFromDB)->getXtParams(iCL, iLR, iA, iT)
1489 // could fail if iCL < m_firstLayerOffset, thus continue as m_XT would be set to 0 in this case anyway
1490 continue;
1491 }
1492 for (unsigned short iLR = 0; iLR < 2; ++iLR) {
1493 for (unsigned short iA = 0; iA < m_nAlphaPoints; ++iA) {
1494 for (unsigned short iT = 0; iT < m_nThetaPoints; ++iT) {
1495 const std::vector<float> params = (*m_xtRelFromDB)->getXtParams(iCL, iLR, iA, iT);
1496 unsigned short np = params.size();
1497 // std::cout <<"np4xt= " << np << std::endl;
1498 for (unsigned short i = 0; i < np; ++i) {
1499 m_XT[iCL][iLR][iA][iT][i] = params[i];
1500 }
1501
1502 double boundT = m_XT[iCL][iLR][iA][iT][6];
1503 if (m_xtParamMode == 1) {
1504 m_XT[iCL][iLR][iA][iT][np] = ROOT::Math::Chebyshev5(boundT, m_XT[iCL][iLR][iA][iT][0], m_XT[iCL][iLR][iA][iT][1],
1505 m_XT[iCL][iLR][iA][iT][2], m_XT[iCL][iLR][iA][iT][3], m_XT[iCL][iLR][iA][iT][4], m_XT[iCL][iLR][iA][iT][5]);
1506 } else {
1507 m_XT[iCL][iLR][iA][iT][np] =
1508 m_XT[iCL][iLR][iA][iT][0] + boundT
1509 * (m_XT[iCL][iLR][iA][iT][1] + boundT
1510 * (m_XT[iCL][iLR][iA][iT][2] + boundT
1511 * (m_XT[iCL][iLR][iA][iT][3] + boundT
1512 * (m_XT[iCL][iLR][iA][iT][4] + boundT
1513 * (m_XT[iCL][iLR][iA][iT][5])))));
1514 }
1515 }
1516 }
1517 }
1518 }
1519
1520}
1521
1522
1523// Set sigma params. (from DB)
1525{
1526 m_linearInterpolationOfSgm = true; //must be true now
1527
1528 // std::cout <<"setSResol called" << std::endl;
1529 m_nAlphaPoints4Sgm = (*m_sResolFromDB)->getNoOfAlphaBins();
1530 for (unsigned short i = 0; i < m_nAlphaPoints4Sgm; ++i) {
1531 m_alphaPoints4Sgm[i] = (*m_sResolFromDB)->getAlphaPoint(i);
1532 // std::cout << m_alphaPoints4Sgm[i]*180./M_PI << std::endl;
1533 }
1534
1535 m_nThetaPoints4Sgm = (*m_sResolFromDB)->getNoOfThetaBins();
1536 for (unsigned short i = 0; i < m_nThetaPoints4Sgm; ++i) {
1537 m_thetaPoints4Sgm[i] = (*m_sResolFromDB)->getThetaPoint(i);
1538 // std::cout << m_thetaPoints4Sgm[i]*180./M_PI << std::endl;
1539 }
1540
1541 // std::cout << "m_nAlphaPoints4Sgm= " << m_nAlphaPoints4Sgm << std::endl;
1542 // std::cout << "m_nThetaPoints4Sgm= " << m_nThetaPoints4Sgm << std::endl;
1543
1544 m_sigmaParamMode = (*m_sResolFromDB)->getSigmaParamMode();
1545
1546 m_maxSpaceResol = (*m_sResolFromDB)->getMaxSpaceResol();
1547
1548 for (unsigned short iCL = 0; iCL < c_maxNSenseLayers; ++iCL) {
1549 for (unsigned short iLR = 0; iLR < 2; ++iLR) {
1550 for (unsigned short iA = 0; iA < m_nAlphaPoints4Sgm; ++iA) {
1551 for (unsigned short iT = 0; iT < m_nThetaPoints4Sgm; ++iT) {
1552 const std::vector<float> params = (*m_sResolFromDB)->getSigmaParams(iCL, iLR, iA, iT);
1553 unsigned short np = params.size();
1554 // std::cout <<"np4sigma= " << np << std::endl;
1555 for (unsigned short i = 0; i < np; ++i) {
1556 m_Sigma[iCL][iLR][iA][iT][i] = (iCL < m_firstLayerOffset) ? 0. : params[i];
1557 }
1558 }
1559 }
1560 }
1561 }
1562
1563}
1564
1565
1566// Set fudge factors (from DB)
1568{
1569 unsigned short groupId = (*m_fFactorFromDB)->getGroupID();
1570 unsigned short nEnt = (*m_fFactorFromDB)->getEntries();
1571 B2DEBUG(29, "setFFactor called: groupId,nEnt= " << groupId << " " << nEnt);
1572
1573 if (groupId == 0) { //per all-layers mode
1574 } else {
1575 B2FATAL("CDCGeometryPar:: Invalid group-id " << groupId << " specified!");
1576 }
1577
1578 for (unsigned short id = 0; id < nEnt; ++id) {
1579 unsigned short np = ((*m_fFactorFromDB)->getFactors(id)).size();
1580 if (np != 3) B2FATAL("CDCGeometryPar:: No. of fudge factors != 3!");
1581 for (unsigned short i = 0; i < np; ++i) {
1582 m_fudgeFactorForSigma[i] = ((*m_fFactorFromDB)->getFactors(id))[i];
1583 B2DEBUG(29, i << " " << m_fudgeFactorForSigma[i]);
1584 }
1585 }
1586
1590 B2DEBUG(29, "fudge factors= " << m_fudgeFactorForSigma[0] << " " << m_fudgeFactorForSigma[1] << " " << m_fudgeFactorForSigma[2]);
1591}
1592
1593
1594// Set ch-map (from DB)
1596{
1597 for (const auto& cm : (*m_chMapFromDB)) {
1598 const unsigned short isl = cm.getISuperLayer();
1599 if (isl >= c_nSuperLayers or isl < m_firstSuperLayerOffset) continue;
1600 const uint il = cm.getILayer();
1601 const int iw = cm.getIWire();
1602 const int iBd = cm.getBoardID();
1603 const WireID wID(isl, il, iw);
1604 m_wireToBoard.insert(pair<WireID, unsigned short>(wID, iBd));
1605 const int iCh = cm.getBoardChannel();
1606 m_wireToChannel.insert(pair<WireID, unsigned short>(wID, iCh));
1607 m_boardAndChannelToWire[iBd][iCh] = wID.getEWire();
1608 }
1609}
1610
1611// Set edep-to-ADC conversion params. (from DB)
1613{
1614 unsigned short groupId = (*m_eDepToADCConversionsFromDB)->getGroupID();
1615 unsigned short nEnt = (*m_eDepToADCConversionsFromDB)->getEntries();
1616 if (groupId == 0) { //per super-layer mode
1617 if (nEnt > c_nSuperLayers) B2FATAL("CDCGeometryPar:: group-id " << groupId << " and #entries " << nEnt << " are inconsistent!");
1618 } else if (groupId == 1) { //per layer mode
1619 if (nEnt > c_maxNSenseLayers) B2FATAL("CDCGeometryPar:: group-id " << groupId << " and #entries " << nEnt << " are inconsistent!");
1620 } else {
1621 B2FATAL("CDCGeometryPar:: Invalid group-id " << groupId << " specified !");
1622 }
1623
1624 unsigned short cLMin[c_nSuperLayers], cLMax[c_nSuperLayers]; //min and max clayer per super-layer
1625 cLMin[0] = 0;
1626 cLMax[0] = 7;
1627 for (unsigned int sl = 1; sl < c_nSuperLayers; ++sl) {
1628 cLMin[sl] = cLMax[0] + 6 * sl - 5;
1629 cLMax[sl] = cLMax[0] + 6 * sl;
1630 }
1631
1632 for (unsigned short id = 0; id < nEnt; ++id) {
1633 unsigned short np = ((*m_eDepToADCConversionsFromDB)->getParams(id)).size();
1634 if (np > 7) B2FATAL("CDCGeometryPar:: No. of edep-to-ADC conversion params. > 7");
1635 if (groupId == 0) { //per super-layer; id=super-layer
1636 for (unsigned short cL = cLMin[id]; cL <= cLMax[id]; ++cL) { //clayer loop
1637 for (unsigned short cell = 0; cell < m_nWires[cL]; ++cell) { //cell loop
1638 for (unsigned short i = 0; i < np; ++i) {
1639 m_eDepToADCParams[cL][cell][i] = (cL < m_firstLayerOffset) ? 0. : ((*m_eDepToADCConversionsFromDB)->getParams(id))[i];
1640 }
1641 }
1642 }
1643 } else if (groupId == 1) { //per clayer; id=clayer
1644 for (unsigned short cell = 0; cell < m_nWires[id]; ++cell) { //cell loop
1645 for (unsigned short i = 0; i < np; ++i) {
1646 m_eDepToADCParams[id][cell][i] = (id < m_firstLayerOffset) ? 0. : ((*m_eDepToADCConversionsFromDB)->getParams(id))[i];
1647 }
1648 }
1649 } else if (groupId == 2) { //per wire
1650 //not ready
1651 B2FATAL("CDCGeometryPar::setEDepToADCConversions(): groupId=2 not ready!");
1652 }
1653 }
1654}
1655
1656
1657double CDCGeometryPar::getEDepToADCConvFactor(unsigned short iCL, unsigned short iW, double edep, double dx, double costh)
1658{
1659 // double convF = (100.0 / 3.2); //keV -> count
1660 //Model assumed here is from CLEO-c:
1661 //Igen = Imea * [1 + alf*Imea/cth] / [1 + gam*Imea/cth];
1662 //cth = |costh| + dlt;
1663 //Igen: original dE/dx; Imea: measured dE/dx with space-charge effect
1664 const double mainF = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][0];
1665 const double& alf = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][1];
1666 const double& gam = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][2];
1667 const double& dlt = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][3];
1668 const double& a = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][4];
1669 const double& b = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][5];
1670 const double cth = fabs(costh) + dlt;
1671 const double iGen = edep / dx; // keV/cm
1672 const double tmp = cth - gam * iGen;
1673 const double disc = tmp * tmp + 4.*alf * cth * iGen;
1674
1675 double iMea = 0.;
1676 if (alf == 0.) {
1677 iMea = cth * iGen / tmp;
1678 } else if (disc >= 0.) {
1679 iMea = (-tmp + sqrt(disc)) / (2.*alf);
1680 // if (alf < 0.) {
1681 // B2INFO("alf<0:CHECK");
1682 // B2INFO(-tmp + sqrt(disc)) / (2.*alf));
1683 // B2INFO(-tmp - sqrt(disc)) / (2.*alf));
1684 // }
1685 }
1686
1687 double convF = mainF;
1688 if (iMea > 0.) {
1689 convF = mainF * std::min(iMea / iGen, 1.);
1690 // if (iMea > iGen) B2DEBUG(29, "iMea > iGen " << iMea <<" "<< iGen);
1691 } else {
1692 //TODO: check the following issue more
1693 // B2WARNING("CDCGeometryPar: Measured dE/dx <= 0!");
1694 // B2DEBUG(29, "CDCGeometryPar: Measured dE/dx <= 0!");
1695 // B2DEBUG(29, "iGen,iMea= " << std::setw(15) << std::scientific << std::setprecision(8) << iGen <<" "<< iMea);
1696 // B2DEBUG(29, "dx,mainF,alf,gam,dlt,cth,tmp,disc= " << dx <<" "<< mainF <<" "<< alf <<" "<< gam <<" "<< dlt <<" "<<" "<< tmp <<" "<< disc);
1697 }
1698 convF *= 1. + a * (costh - b);
1699 return convF;
1700}
1701
1702
1704{}
1705
1706const B2Vector3D CDCGeometryPar::wireForwardPosition(uint layerID, int cellID, EWirePosition set) const
1707{
1708 // return early in case of empty layer, i.e. layerID < m_firstLayerOffset
1709 if (layerID < m_firstLayerOffset) {
1710 return B2Vector3D(0, 0, 0);
1711 }
1712
1713 // std::cout <<"cdcgeopar::fwdpos set= " << set << std::endl;
1714 B2Vector3D wPos(m_FWirPosAlign[layerID][cellID][0],
1715 m_FWirPosAlign[layerID][cellID][1],
1716 m_FWirPosAlign[layerID][cellID][2]);
1717
1718 if (set == c_Misaligned) {
1719 wPos.SetX(m_FWirPosMisalign[layerID][cellID][0]);
1720 wPos.SetY(m_FWirPosMisalign[layerID][cellID][1]);
1721 wPos.SetZ(m_FWirPosMisalign[layerID][cellID][2]);
1722 } else if (set == c_Base) {
1723 wPos.SetX(m_FWirPos [layerID][cellID][0]);
1724 wPos.SetY(m_FWirPos [layerID][cellID][1]);
1725 wPos.SetZ(m_FWirPos [layerID][cellID][2]);
1726 }
1727
1728 return wPos;
1729}
1730
1731const B2Vector3D CDCGeometryPar::wireForwardPosition(uint layerID, int cellID, double z, EWirePosition set) const
1732{
1733 // return early in case of empty layer, i.e. layerID < m_firstLayerOffset
1734 if (layerID < m_firstLayerOffset) {
1735 return B2Vector3D(0, 0, 0);
1736 }
1737
1738 double yb_sag = 0.;
1739 double yf_sag = 0.;
1740 getWireSagEffect(set, layerID, cellID, z, yb_sag, yf_sag);
1741
1742 B2Vector3D wPos(m_FWirPosAlign[layerID][cellID][0], yf_sag,
1743 m_FWirPosAlign[layerID][cellID][2]);
1744 if (set == c_Misaligned) {
1745 wPos.SetX(m_FWirPosMisalign[layerID][cellID][0]);
1746 wPos.SetZ(m_FWirPosMisalign[layerID][cellID][2]);
1747 } else if (set == c_Base) {
1748 wPos.SetX(m_FWirPos [layerID][cellID][0]);
1749 wPos.SetZ(m_FWirPos [layerID][cellID][2]);
1750 }
1751
1752 return wPos;
1753}
1754
1755const B2Vector3D CDCGeometryPar::wireBackwardPosition(uint layerID, int cellID, EWirePosition set) const
1756{
1757 // return early in case of empty layer, i.e. layerID < m_firstLayerOffset
1758 if (layerID < m_firstLayerOffset) {
1759 return B2Vector3D(0, 0, 0);
1760 }
1761
1762 B2Vector3D wPos(m_BWirPosAlign[layerID][cellID][0],
1763 m_BWirPosAlign[layerID][cellID][1],
1764 m_BWirPosAlign[layerID][cellID][2]);
1765
1766 if (set == c_Misaligned) {
1767 wPos.SetX(m_BWirPosMisalign[layerID][cellID][0]);
1768 wPos.SetY(m_BWirPosMisalign[layerID][cellID][1]);
1769 wPos.SetZ(m_BWirPosMisalign[layerID][cellID][2]);
1770 } else if (set == c_Base) {
1771 wPos.SetX(m_BWirPos [layerID][cellID][0]);
1772 wPos.SetY(m_BWirPos [layerID][cellID][1]);
1773 wPos.SetZ(m_BWirPos [layerID][cellID][2]);
1774 }
1775
1776 return wPos;
1777}
1778
1779const B2Vector3D CDCGeometryPar::wireBackwardPosition(uint layerID, int cellID, double z, EWirePosition set) const
1780{
1781 // return early in case of empty layer, i.e. layerID < m_firstLayerOffset
1782 if (layerID < m_firstLayerOffset) {
1783 return B2Vector3D(0, 0, 0);
1784 }
1785
1786 double yb_sag = 0.;
1787 double yf_sag = 0.;
1788 getWireSagEffect(set, layerID, cellID, z, yb_sag, yf_sag);
1789
1790 B2Vector3D wPos(m_BWirPosAlign[layerID][cellID][0], yb_sag,
1791 m_BWirPosAlign[layerID][cellID][2]);
1792 if (set == c_Misaligned) {
1793 wPos.SetX(m_BWirPosMisalign[layerID][cellID][0]);
1794 wPos.SetZ(m_BWirPosMisalign[layerID][cellID][2]);
1795 } else if (set == c_Base) {
1796 wPos.SetX(m_BWirPos [layerID][cellID][0]);
1797 wPos.SetZ(m_BWirPos [layerID][cellID][2]);
1798 }
1799
1800 return wPos;
1801}
1802
1803double CDCGeometryPar::getWireSagCoef(EWirePosition set, uint layerID, int cellID) const
1804{
1805 double coef = m_WireSagCoef[layerID][cellID];
1806 if (set == c_Misaligned) {
1807 coef = m_WireSagCoefMisalign[layerID][cellID];
1808 } else if (set == c_Aligned) {
1809 coef = m_WireSagCoefAlign [layerID][cellID];
1810 }
1811 return coef;
1812}
1813
1815{
1816 static double IRWL[c_maxNSenseLayers] = {0};
1817
1818 IRWL[0] = outerRadiusInnerWall();
1819 for (unsigned i = 1; i < nWireLayers(); i++)
1820 //IRWL[i] = (m_rSLayer[i - 1] + m_rSLayer[i]) / 2.;
1821 IRWL[i] = (i == m_firstLayerOffset) ? outerRadiusInnerWall() : m_rFLayer[i - 1];
1822
1823 return IRWL;
1824}
1825
1827{
1828 static double ORWL[c_maxNSenseLayers] = {0};
1829
1830 ORWL[nWireLayers() - 1] = innerRadiusOuterWall();
1831 for (unsigned i = 0; i < nWireLayers() - 1; i++)
1832 //ORWL[i] = (m_rSLayer[i] + m_rSLayer[i + 1]) / 2.;
1833 ORWL[i] = m_rFLayer[i];
1834
1835 return ORWL;
1836}
1837
1838unsigned CDCGeometryPar::cellId(unsigned layerId, const B2Vector3D& position) const
1839{
1840 if (layerId < m_firstLayerOffset) {
1841 return 0;
1842 }
1843
1844 const unsigned nWires = m_nWires[layerId];
1845
1846 double offset = m_offSet[layerId];
1847 //...Offset modification to be aligned to axial at z=0...
1848 const double phiSize = 2 * M_PI / double(nWires);
1849 /*{
1850 const double phiF = phiSize * offset
1851 + phiSize * 0.5 * double(m_nShifts[layerId]);
1852 const double phiB = phiSize * offset;
1853 const B2Vector3D f(m_rSLayer[layerId] * cos(phiF), m_rSLayer[layerId] * sin(phiF), m_zSForwardLayer[layerId]);
1854 const B2Vector3D b(m_rSLayer[layerId] * cos(phiB), m_rSLayer[layerId] * sin(phiB), m_zSBackwardLayer[layerId]);
1855
1856 const B2Vector3D v = f - b;
1857 const B2Vector3D u = v.Unit();
1858 const double beta = (0 - b.Z()) / u.Z();
1859 const B2Vector3D p = b + beta * u;
1860 double phi0 = - atan2(p.Y(), p.X());
1861 offset += phi0 / (2 * M_PI / double(nWires));
1862 }*/
1863
1864 unsigned j = 0;
1865 for (unsigned i = 0; i < 1; ++i) {
1866 const double phiF = phiSize * (double(i) + offset)
1867 + phiSize * 0.5 * double(m_nShifts[layerId]) + m_globalPhiRotation;
1868 const double phiB = phiSize * (double(i) + offset) + m_globalPhiRotation;
1869 const B2Vector3D f(m_rSLayer[layerId] * cos(phiF), m_rSLayer[layerId] * sin(phiF), m_zSForwardLayer[layerId]);
1870 const B2Vector3D b(m_rSLayer[layerId] * cos(phiB), m_rSLayer[layerId] * sin(phiB), m_zSBackwardLayer[layerId]);
1871 const B2Vector3D v = f - b;
1872 const B2Vector3D u = v.Unit();
1873 const double beta = (position.Z() - b.Z()) / u.Z();
1874 const B2Vector3D p = b + beta * u;
1875 double dPhi = std::atan2(position.Y(), position.X())
1876 - std::atan2(p.Y(), p.X())
1877 + phiSize / 2.;
1878 while (dPhi < 0) dPhi += (2. * M_PI);
1879 j = int(dPhi / phiSize);
1880 while (j >= nWires) j -= nWires;
1881 }
1882
1883 return j;
1884}
1885
1886void CDCGeometryPar::generateXML(const string& of)
1887{
1888 //...Open xml file...
1889 std::ofstream ofs(of.c_str(), std::ios::out);
1890 if (! ofs) {
1891 B2ERROR("CDCGeometryPar::read !!! can not open file : "
1892 << of);
1893 }
1894 ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1895 << endl
1896 << "<Subdetector type=\"CDC\">"
1897 << endl
1898 << " <Name>CDC BelleII </Name>"
1899 << endl
1900 << " <Description>CDC geometry parameters</Description>"
1901 << endl
1902 << " <Version>0</Version>"
1903 << endl
1904 << " <GeoCreator>CDCBelleII</GeoCreator>"
1905 << endl
1906 << " <Content>"
1907 << endl
1908 << " <Rotation desc=\"Rotation of the whole cdc detector (should be the same as beampipe)\" unit=\"mrad\">0.0</Rotation>"
1909 << endl
1910 << " <OffsetZ desc=\"The offset of the whole cdc in z with respect to the IP (should be the same as beampipe)\" unit=\"mm\">0.0</OffsetZ>"
1911 << endl
1912 << " <Material>CDCGas</Material>"
1913 << endl
1914 << endl;
1915
1916 ofs << " <SLayers>" << endl;
1917
1918 for (int i = 0; i < m_nSLayer; i++) {
1919 ofs << " <SLayer id=\"" << i << "\">" << endl;
1920 ofs << " <Radius desc=\"Radius of wires in this layer\" unit=\"mm\">" << senseWireR(i) << "</Radius>" << endl;
1921 ofs << " <BackwardZ desc=\"z position of this wire layer at backward endplate\" unit=\"mm\">" << senseWireBZ(
1922 i) << "</BackwardZ>" << endl;
1923 ofs << " <ForwardZ desc=\"z position of this wire layer at forward endplate\" unit=\"mm\">" << senseWireFZ(
1924 i) << "</ForwardZ>" << endl;
1925// ofs << " <BackwardPhi desc=\"azimuth angle of the first wire in this layer at backward endplate\" unit=\"rad\">" << wireBackwardPosition(i).phi() << "</BackwardPhi>" << endl;
1926// ofs << " <ForwardPhi desc=\"azimuth angle of the first wire in this layer at forward endplate\" unit=\"rad\">" << wireForwardPosition(i).phi() << "</ForwardPhi>" << endl;
1927 ofs << " <NHoles desc=\"the number of holes in this layer, 2*(cell number)\">" << nWiresInLayer(
1928 i) * 2 << "</NHoles>" << endl;
1929 ofs << " <NShift desc=\"the shifted hole number of each wire in this layer\">" << nShifts(i) << "</NShift>" << endl;
1930 ofs << " <Offset desc=\"wire offset in phi direction at endplate\">" << m_offSet[i] << "</Offset>" << endl;
1931 ofs << " </SLayer>" << endl;
1932 }
1933
1934 ofs << " </SLayers>" << endl;
1935 ofs << " <FLayers>" << endl;
1936
1937 for (int i = 0; i < m_nFLayer; i++) {
1938 ofs << " <FLayer id=\"" << i << "\">" << endl;
1939 ofs << " <Radius desc=\"Radius of field wires in this layer\" unit=\"mm\">" << fieldWireR(i) << "</Radius>" << endl;
1940 ofs << " <BackwardZ desc=\"z position of this field wire layer at backward endplate\" unit=\"mm\">" << fieldWireBZ(
1941 i) << "</BackwardZ>" << endl;
1942 ofs << " <ForwardZ desc=\"z position of this field wire layer at forward endplate\" unit=\"mm\">" << fieldWireFZ(
1943 i) << "</ForwardZ>" << endl;
1944 ofs << " </FLayer>" << endl;
1945 }
1946
1947 ofs << " </FLayers>" << endl;
1948
1949 ofs << " <InnerWall name=\"InnerWall\">" << endl;
1950 ofs << " <InnerR desc=\"Inner radius\" unit=\"mm\">" << innerRadiusInnerWall() << "</InnerR>" << endl;
1951 ofs << " <OuterR desc=\"Outer radius\" unit=\"mm\">" << outerRadiusInnerWall() << "</OuterR>" << endl;
1952 ofs << " <BackwardZ desc=\"z position at backward endplate\" unit=\"mm\">" << m_zWall[0][0] << "</BackwardZ>" << endl;
1953 ofs << " <ForwardZ desc=\"z position at forward endplate\" unit=\"mm\">" << m_zWall[0][1] << "</ForwardZ>" << endl;
1954 ofs << " </InnerWall>" << endl;
1955
1956 ofs << " <OuterWall name=\"OuterWall\">" << endl;
1957 ofs << " <InnerR desc=\"Inner radius\" unit=\"mm\">" << innerRadiusOuterWall() << "</InnerR>" << endl;
1958 ofs << " <OuterR desc=\"Outer radius\" unit=\"mm\">" << outerRadiusOuterWall() << "</OuterR>" << endl;
1959 ofs << " <BackwardZ desc=\"z position at backward endplate\" unit=\"mm\">" << m_zWall[2][0] << "</BackwardZ>" << endl;
1960 ofs << " <ForwardZ desc=\"z position at forward endplate\" unit=\"mm\">" << m_zWall[2][1] << "</ForwardZ>" << endl;
1961 ofs << " </OuterWall>" << endl;
1962
1963 ofs << " </Content>" << endl
1964 << "</Subdetector>" << endl;
1965}
1966
1967void CDCGeometryPar::getWireSagEffect(const EWirePosition set, const unsigned layerID, const unsigned cellID, const double Z,
1968 double& Yb_sag, double& Yf_sag) const
1969{
1970 //Input
1971 // set : c_Base, c_Misaligned or c_Aligned
1972 // layerID: layer id (0 - 55);
1973 // cellID: cell id in the layer;
1974 // Z: Z-coord. (cm) at which sense wire sag is computed.
1975 //
1976 //Output Yb_sag: Y-corrd. (cm) of intersection of a tangent and the backward endplate.
1977 // Here the tangent is computed from the 1'st derivative of
1978 // a paraboric wire (due to gravity) defined at Z.
1979 // Yf_sag: ibid. but for forward.
1980 //
1981 //N.B.- Maybe replaced with a bit more accurate formula.
1982 // - The electrostatic force effect is not included.
1983
1984 // return early in case of empty layer, i.e. layerID < m_firstLayerOffset
1985 if (layerID < m_firstLayerOffset) {
1986 Yb_sag = 0.;
1987 Yf_sag = 0.;
1988 return;
1989 }
1990
1991 double Xb = 0.;
1992 double Xf = 0.;
1993 double Yb = 0.;
1994 double Yf = 0.;
1995 double Zb = 0.;
1996 double Zf = 0.;
1997 double Coef = 0.;
1998
1999 if (set == c_Aligned) {
2000 Coef = m_WireSagCoefAlign[layerID][cellID];
2001 Yb = m_BWirPosAlign[layerID][cellID][1];
2002 Yf = m_FWirPosAlign[layerID][cellID][1];
2003 if (Coef == 0.) {
2004 Yb_sag = Yb;
2005 Yf_sag = Yf;
2006 return;
2007 }
2008 Xb = m_BWirPosAlign[layerID][cellID][0];
2009 Xf = m_FWirPosAlign[layerID][cellID][0];
2010 Zb = m_BWirPosAlign[layerID][cellID][2];
2011 Zf = m_FWirPosAlign[layerID][cellID][2];
2012
2013 } else if (set == c_Misaligned) {
2014 Coef = m_WireSagCoefMisalign[layerID][cellID];
2015 Yb = m_BWirPosMisalign[layerID][cellID][1];
2016 Yf = m_FWirPosMisalign[layerID][cellID][1];
2017 if (Coef == 0.) {
2018 Yb_sag = Yb;
2019 Yf_sag = Yf;
2020 return;
2021 }
2022 Xb = m_BWirPosMisalign[layerID][cellID][0];
2023 Xf = m_FWirPosMisalign[layerID][cellID][0];
2024 Zb = m_BWirPosMisalign[layerID][cellID][2];
2025 Zf = m_FWirPosMisalign[layerID][cellID][2];
2026
2027 } else if (set == c_Base) {
2028 Coef = m_WireSagCoef[layerID][cellID];
2029 Yb = m_BWirPos[layerID][cellID][1];
2030 Yf = m_FWirPos[layerID][cellID][1];
2031 if (Coef == 0.) {
2032 Yb_sag = Yb;
2033 Yf_sag = Yf;
2034 return;
2035 }
2036 Xb = m_BWirPos[layerID][cellID][0];
2037 Xf = m_FWirPos[layerID][cellID][0];
2038 Zb = m_BWirPos[layerID][cellID][2];
2039 Zf = m_FWirPos[layerID][cellID][2];
2040
2041 } else {
2042 B2FATAL("CDCGeometryPar::getWireSagEffect: called with an invalid set: " << " " << set);
2043 }
2044
2045 const double dx = Xf - Xb;
2046 const double dy = Yf - Yb;
2047 const double dz = Zf - Zb;
2048
2049 const double Zfp = sqrt(dz * dz + dx * dx); // Wire length in z-x plane since Zbp==0
2050 const double Zp = (Z - Zb) * Zfp / dz;
2051
2052 const double Y_sag = (Coef * (Zp - Zfp) + dy / Zfp) * Zp + Yb;
2053 const double dydz = (Coef * (2.*Zp - Zfp) * Zfp + dy) / dz;
2054
2055 Yb_sag = Y_sag + dydz * (Zb - Z);
2056 Yf_sag = Y_sag + dydz * (Zf - Z);
2057
2058}
2059
2060void CDCGeometryPar::setDesignWirParam(const unsigned layerID, const unsigned cellID)
2061{
2062 const unsigned L = layerID;
2063 const unsigned C = cellID;
2064
2065 const double offset = m_offSet[L];
2066 //...Offset modification to be aligned to axial at z=0...
2067 const double phiSize = 2 * M_PI / double(m_nWires[L]);
2068
2069 const double phiF = phiSize * (double(C) + offset)
2070 + phiSize * 0.5 * double(m_nShifts[L]) + m_globalPhiRotation;
2071
2072 m_FWirPos[L][C][0] = (L < m_firstLayerOffset) ? 0. : m_rSLayer[L] * cos(phiF);
2073 m_FWirPos[L][C][1] = (L < m_firstLayerOffset) ? 0. : m_rSLayer[L] * sin(phiF);
2074 m_FWirPos[L][C][2] = (L < m_firstLayerOffset) ? 0. : m_zSForwardLayer[L];
2075
2076 const double phiB = phiSize * (double(C) + offset) + m_globalPhiRotation;
2077
2078 m_BWirPos[L][C][0] = (L < m_firstLayerOffset) ? 0. : m_rSLayer[L] * cos(phiB);
2079 m_BWirPos[L][C][1] = (L < m_firstLayerOffset) ? 0. : m_rSLayer[L] * sin(phiB);
2080 m_BWirPos[L][C][2] = (L < m_firstLayerOffset) ? 0. : m_zSBackwardLayer[L];
2081
2082 for (int i = 0; i < 3; ++i) {
2083 m_FWirPosMisalign[L][C][i] = (L < m_firstLayerOffset) ? 0. : m_FWirPos[L][C][i];
2084 m_BWirPosMisalign[L][C][i] = (L < m_firstLayerOffset) ? 0. : m_BWirPos[L][C][i];
2085 m_FWirPosAlign [L][C][i] = (L < m_firstLayerOffset) ? 0. : m_FWirPos[L][C][i];
2086 m_BWirPosAlign [L][C][i] = (L < m_firstLayerOffset) ? 0. : m_BWirPos[L][C][i];
2087 }
2088
2090 (8. * m_senseWireTension);
2091 // m_WireSagCoef [L][C] = 0.;
2092 m_WireSagCoefMisalign[L][C] = (L < m_firstLayerOffset) ? 0. : m_WireSagCoef[L][C];
2093 m_WireSagCoefAlign [L][C] = (L < m_firstLayerOffset) ? 0. : m_WireSagCoef[L][C];
2094
2095}
2096
2097void CDCGeometryPar::outputDesignWirParam(const unsigned layerID, const unsigned cellID) const
2098{
2099
2100 const unsigned L = layerID;
2101 const unsigned C = cellID;
2102
2103 static bool first = true;
2104 static ofstream ofs;
2105 if (first) {
2106 first = false;
2107 ofs.open("alignment.dat");
2108 }
2109
2110 ofs << L << " " << C;
2111
2112 ofs << setiosflags(ios::showpoint | ios::uppercase);
2113
2114 for (int i = 0; i < 3; ++i) ofs << " " << setw(15) << setprecision(8) << m_BWirPos[L][C][i];
2115
2116 for (int i = 0; i < 3; ++i) ofs << " " << setw(15) << setprecision(8) << m_FWirPos[L][C][i];
2117 ofs << setiosflags(ios::fixed);
2118 ofs << " " << setw(4) << setprecision(1) << m_senseWireTension;
2119
2120 ofs << endl;
2121}
2122
2123double CDCGeometryPar::getDriftV(const double time, const unsigned short iCLayer, const unsigned short lr, const double alpha,
2124 const double theta) const
2125{
2126 if (iCLayer < m_firstLayerOffset || iCLayer >= c_maxNSenseLayers) {
2127 return 0.;
2128 }
2129
2130 double dDdt = 0.;
2131
2132 //calculate min. drift time
2133 double minTime = getMinDriftTime(iCLayer, lr, alpha, theta);
2134 double delta = time - minTime;
2135
2136 //convert incoming- to outgoing-lr
2137 unsigned short lro = getOutgoingLR(lr, alpha);
2138
2140 B2FATAL("linearInterpolationOfXT = false is not allowed now !");
2141 } else {
2142 double wal(0.);
2143 unsigned short ial[2] = {0};
2144 unsigned short ilr[2] = {lro, lro};
2145 getClosestAlphaPoints(alpha, wal, ial, ilr);
2146 double wth(0.);
2147 unsigned short ith[2] = {0};
2148 getClosestThetaPoints(alpha, theta, wth, ith);
2149
2150 unsigned short jal(0), jlr(0), jth(0);
2151 double w = 0.;
2152
2153 //use xt reversed at (x=0,t=tmin) for delta<0 ("negative drifttime")
2154 double timep = delta < 0. ? minTime - delta : time;
2155
2156 //compute linear interpolation (=weithed average over 4 points) in (alpha-theta) space
2157 for (unsigned k = 0; k < 4; ++k) {
2158 if (k == 0) {
2159 jal = ial[0];
2160 jlr = ilr[0];
2161 jth = ith[0];
2162 w = (1. - wal) * (1. - wth);
2163 } else if (k == 1) {
2164 jal = ial[0];
2165 jlr = ilr[0];
2166 jth = ith[1];
2167 w = (1. - wal) * wth;
2168 } else if (k == 2) {
2169 jal = ial[1];
2170 jlr = ilr[1];
2171 jth = ith[0];
2172 w = wal * (1. - wth);
2173 } else if (k == 3) {
2174 jal = ial[1];
2175 jlr = ilr[1];
2176 jth = ith[1];
2177 w = wal * wth;
2178 }
2179
2180 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2181
2182 if (timep < boundary) {
2183 if (m_xtParamMode == 1) {
2184 const double& c1 = m_XT[iCLayer][jlr][jal][jth][1];
2185 const double& c2 = m_XT[iCLayer][jlr][jal][jth][2];
2186 const double& c3 = m_XT[iCLayer][jlr][jal][jth][3];
2187 const double& c4 = m_XT[iCLayer][jlr][jal][jth][4];
2188 const double& c5 = m_XT[iCLayer][jlr][jal][jth][5];
2189 dDdt += w * ROOT::Math::Chebyshev4(timep, c1 + 3.*c3 + 5.*c5, 4.*c2 + 8.*c4, 6.*c3 + 10.*c5, 8.*c4, 10.*c5);
2190 } else {
2191 dDdt += w * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2192 * (2.*m_XT[iCLayer][jlr][jal][jth][2] + timep
2193 * (3.*m_XT[iCLayer][jlr][jal][jth][3] + timep
2194 * (4.*m_XT[iCLayer][jlr][jal][jth][4] + timep
2195 * (5.*m_XT[iCLayer][jlr][jal][jth][5])))));
2196 }
2197 } else {
2198 dDdt += w * m_XT[iCLayer][jlr][jal][jth][7];
2199 }
2200 } //end of weighted mean loop
2201 }
2202
2203 dDdt = fabs(dDdt);
2204 //n.b. following line not needed since dDdt > 0 even for delta < 0
2205 // if (delta < 0.) dDdt *= -1.;
2206 return dDdt;
2207
2208}
2209
2210//TODO: mearge with getDriftLength
2211double CDCGeometryPar::getDriftLength0(const double time, const unsigned short iCLayer, const unsigned short lr, const double alpha,
2212 const double theta) const
2213{
2214 if (iCLayer < m_firstLayerOffset || iCLayer >= c_maxNSenseLayers) {
2215 return 0.;
2216 }
2217
2218 double dist = 0.;
2219
2220 //convert incoming- to outgoing-lr
2221 unsigned short lro = getOutgoingLR(lr, alpha);
2222
2223 // std::cout << m_linearInterpolationOfXT << std::endl;
2224 // exit(-1);
2226 B2FATAL("linearInterpolationOfXT = false is not allowed now !");
2227 } else {
2228 double wal(0.);
2229 unsigned short ial[2] = {0};
2230 unsigned short ilr[2] = {lro, lro};
2231 getClosestAlphaPoints(alpha, wal, ial, ilr);
2232 double wth(0.);
2233 unsigned short ith[2] = {0};
2234 getClosestThetaPoints(alpha, theta, wth, ith);
2235
2236 unsigned short jal(0), jlr(0), jth(0);
2237 double w = 0.;
2238
2239 //use xt reversed at (x=0,t=tmin) for delta<0 ("negative drifttime")
2240 double timep = time;
2241 // std::cout << "iCLayer,alpha,theta,lro= " << iCLayer <<" "<< (180./M_PI)*alpha <<" "<< (180./M_PI)*theta <<" "<< lro << std::endl;
2242
2243 //compute linear interpolation (=weithed average over 4 points) in (alpha-theta) space
2244 for (unsigned k = 0; k < 4; ++k) {
2245 if (k == 0) {
2246 jal = ial[0];
2247 jlr = ilr[0];
2248 jth = ith[0];
2249 w = (1. - wal) * (1. - wth);
2250 } else if (k == 1) {
2251 jal = ial[0];
2252 jlr = ilr[0];
2253 jth = ith[1];
2254 w = (1. - wal) * wth;
2255 } else if (k == 2) {
2256 jal = ial[1];
2257 jlr = ilr[1];
2258 jth = ith[0];
2259 w = wal * (1. - wth);
2260 } else if (k == 3) {
2261 jal = ial[1];
2262 jlr = ilr[1];
2263 jth = ith[1];
2264 w = wal * wth;
2265 }
2266
2267 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2268
2269 if (timep < boundary) {
2270 if (m_xtParamMode == 1) {
2271 dist += w * ROOT::Math::Chebyshev5(timep, m_XT[iCLayer][jlr][jal][jth][0], m_XT[iCLayer][jlr][jal][jth][1],
2272 m_XT[iCLayer][jlr][jal][jth][2], m_XT[iCLayer][jlr][jal][jth][3], m_XT[iCLayer][jlr][jal][jth][4], m_XT[iCLayer][jlr][jal][jth][5]);
2273 } else {
2274 dist += w * (m_XT[iCLayer][jlr][jal][jth][0] + timep
2275 * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2276 * (m_XT[iCLayer][jlr][jal][jth][2] + timep
2277 * (m_XT[iCLayer][jlr][jal][jth][3] + timep
2278 * (m_XT[iCLayer][jlr][jal][jth][4] + timep
2279 * (m_XT[iCLayer][jlr][jal][jth][5]))))));
2280 }
2281 } else {
2282 dist += w * (m_XT[iCLayer][jlr][jal][jth][7] * (timep - boundary) + m_XT[iCLayer][jlr][jal][jth][8]);
2283 }
2284 // std::cout <<"k,w,dist= " << k <<" "<< w <<" "<< dist << std::endl;
2285 } //end of weighted mean loop
2286 }
2287
2288 // dist = fabs(dist);
2289 return dist;
2290
2291}
2292
2293double CDCGeometryPar::getDriftLength(const double time, const unsigned short iCLayer, const unsigned short lr, const double alpha,
2294 const double theta,
2295 const bool calculateMinTime,
2296 const double inputMinTime) const
2297{
2298 if (iCLayer < m_firstLayerOffset || iCLayer >= c_maxNSenseLayers) {
2299 return 0.;
2300 }
2301
2302 double dist = 0.;
2303
2304 //calculate min. drift time
2305 double minTime = calculateMinTime ? getMinDriftTime(iCLayer, lr, alpha, theta) : inputMinTime;
2306 double delta = time - minTime;
2307
2308 //convert incoming- to outgoing-lr
2309 unsigned short lro = getOutgoingLR(lr, alpha);
2310
2311 // std::cout << m_linearInterpolationOfXT << std::endl;
2312 // exit(-1);
2314 B2FATAL("linearInterpolationOfXT = false is not allowed now !");
2315 } else {
2316 double wal(0.);
2317 unsigned short ial[2] = {0};
2318 unsigned short ilr[2] = {lro, lro};
2319 getClosestAlphaPoints(alpha, wal, ial, ilr);
2320 double wth(0.);
2321 unsigned short ith[2] = {0};
2322 getClosestThetaPoints(alpha, theta, wth, ith);
2323
2324 unsigned short jal(0), jlr(0), jth(0);
2325 double w = 0.;
2326
2327 //use xt reversed at (x=0,t=tmin) for delta<0 ("negative drifttime")
2328 double timep = delta < 0. ? minTime - delta : time;
2329
2330 // std::cout << "iCLayer,alpha,theta,lro= " << iCLayer <<" "<< (180./M_PI)*alpha <<" "<< (180./M_PI)*theta <<" "<< lro << std::endl;
2331
2332 //compute linear interpolation (=weithed average over 4 points) in (alpha-theta) space
2333 for (unsigned k = 0; k < 4; ++k) {
2334 if (k == 0) {
2335 jal = ial[0];
2336 jlr = ilr[0];
2337 jth = ith[0];
2338 w = (1. - wal) * (1. - wth);
2339 } else if (k == 1) {
2340 jal = ial[0];
2341 jlr = ilr[0];
2342 jth = ith[1];
2343 w = (1. - wal) * wth;
2344 } else if (k == 2) {
2345 jal = ial[1];
2346 jlr = ilr[1];
2347 jth = ith[0];
2348 w = wal * (1. - wth);
2349 } else if (k == 3) {
2350 jal = ial[1];
2351 jlr = ilr[1];
2352 jth = ith[1];
2353 w = wal * wth;
2354 }
2355
2356 // std::cout << "k,w= " << k <<" "<< w << std::endl;
2357 // std::cout << "ial[0],[1],jal,wal= " << ial[0] <<" "<< ial[1] <<" "<< jal <<" "<< wal << std::endl;
2358 // std::cout << "ith[0],[1],jth,wth= " << ith[0] <<" "<< ith[1] <<" "<< jth <<" "<< wth << std::endl;
2359
2360 /*
2361 std::cout <<"iCLayer= " << iCLayer << std::endl;
2362 std::cout <<"lr= " << lr << std::endl;
2363 std::cout <<"jal,jth= " << jal <<" "<< jth << std::endl;
2364 std::cout <<"wal,wth= " << wal <<" "<< wth << std::endl;
2365 for (int i=0; i<9; ++i) {
2366 std::cout <<"a= "<< i <<" "<< m_XT[iCLayer][lro][jal][jth][i] << std::endl;
2367 }
2368 */
2369 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2370
2371 if (timep < boundary) {
2372 if (m_xtParamMode == 1) {
2373 dist += w * ROOT::Math::Chebyshev5(timep, m_XT[iCLayer][jlr][jal][jth][0], m_XT[iCLayer][jlr][jal][jth][1],
2374 m_XT[iCLayer][jlr][jal][jth][2], m_XT[iCLayer][jlr][jal][jth][3], m_XT[iCLayer][jlr][jal][jth][4], m_XT[iCLayer][jlr][jal][jth][5]);
2375 } else {
2376 dist += w * (m_XT[iCLayer][jlr][jal][jth][0] + timep
2377 * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2378 * (m_XT[iCLayer][jlr][jal][jth][2] + timep
2379 * (m_XT[iCLayer][jlr][jal][jth][3] + timep
2380 * (m_XT[iCLayer][jlr][jal][jth][4] + timep
2381 * (m_XT[iCLayer][jlr][jal][jth][5]))))));
2382 }
2383 } else {
2384 dist += w * (m_XT[iCLayer][jlr][jal][jth][7] * (timep - boundary) + m_XT[iCLayer][jlr][jal][jth][8]);
2385 }
2386 // std::cout <<"k,w,dist= " << k <<" "<< w <<" "<< dist << std::endl;
2387 } //end of weighted mean loop
2388 }
2389
2390 dist = fabs(dist);
2391 if (delta < 0.) dist *= -1.;
2392 return dist;
2393
2394}
2395
2396double CDCGeometryPar::getMinDriftTime(const unsigned short iCLayer, const unsigned short lr, const double alpha,
2397 const double theta) const
2398{
2399 if (iCLayer < m_firstLayerOffset || iCLayer >= c_maxNSenseLayers) {
2400 return 0.;
2401 }
2402
2403 double minTime = 0.;
2404
2405 //convert incoming- to outgoing-lr
2406 unsigned short lro = getOutgoingLR(lr, alpha);
2407
2409 B2FATAL("linearInterpolationOfXT = false is not allowed now !");
2410 } else {
2411 double wal(0.);
2412 unsigned short ial[2] = {0};
2413 unsigned short ilr[2] = {lro, lro};
2414 getClosestAlphaPoints(alpha, wal, ial, ilr);
2415 double wth(0.);
2416 unsigned short ith[2] = {0};
2417 getClosestThetaPoints(alpha, theta, wth, ith);
2418
2419 unsigned short jal(0), jlr(0), jth(0);
2420 double w = 0.;
2421
2422 double c[6] = {0.}, a[6] = {0.};
2423 for (unsigned k = 0; k < 4; ++k) {
2424 if (k == 0) {
2425 jal = ial[0];
2426 jlr = ilr[0];
2427 jth = ith[0];
2428 w = (1. - wal) * (1. - wth);
2429 } else if (k == 1) {
2430 jal = ial[0];
2431 jlr = ilr[0];
2432 jth = ith[1];
2433 w = (1. - wal) * wth;
2434 } else if (k == 2) {
2435 jal = ial[1];
2436 jlr = ilr[1];
2437 jth = ith[0];
2438 w = wal * (1. - wth);
2439 } else if (k == 3) {
2440 jal = ial[1];
2441 jlr = ilr[1];
2442 jth = ith[1];
2443 w = wal * wth;
2444 }
2445
2446 for (int i = 0; i < 5; ++i) {
2447 c[i] += w * m_XT[iCLayer][jlr][jal][jth][i];
2448 }
2449 }
2450
2451 if (m_xtParamMode == 1) { //convert c to coeff for normal-poly if Chebyshev
2452 a[0] = c[0] - c[2] + c[4];
2453 a[1] = c[1] - 3.*c[3] + 5.*c[5];
2454 a[2] = 2.*c[2] - 8.*c[4];
2455 a[3] = 4.*c[3] - 20.*c[5];
2456 a[4] = 8.*c[4];
2457 a[5] = 16.*c[5];
2458 } else { //normal-poly
2459 for (int i = 0; i < 5; ++i) a[i] = c[i];
2460 }
2461
2462 //estimate an initial value
2463 // bool check = false;
2464 // bool nointersection = false;
2465 if (a[2] != 0.) { //2nd-order approx. near t=0
2466 const double det = a[1] * a[1] - 4.*a[2] * a[0];
2467 if (det >= 0.) {
2468 //Choose the solution with dx/dt > 0 which gives x=0
2469 minTime = (-a[1] + sqrt(det)) / (2.*a[2]);
2470 } else {
2471 //Choose the solution with smallest x
2472 // nointersection = true;
2473 minTime = -a[1] / (2.*a[2]);
2474 // cout <<"smallest-x solution= " << minTime << endl;
2475 }
2476 } else if (a[1] != 0.) {
2477 minTime = -a[0] / a[1]; //1st-order approx.
2478 } else {
2479 B2WARNING("CDCGeometryPar::getMinDriftTime: minDriftTime not determined; assume zero.\n" << "layer(#0-55),lr,alpha(rad),theta= " <<
2480 iCLayer << " " << lr << " " << alpha << " " << theta);
2481 return minTime;
2482 }
2483
2484 // double minTime0 = minTime;
2485 //higher-order corr. using Newton method; trial to minimize x^2
2486 double edm; // = 10.; //(cm) (SG: fix to avoid cpp-check warning)
2487 // const double epsi4t = 0.01; //(ns)
2488 // const double epsi4x = 1.e-5; //(cm)
2489 const double epsi4x = 5.e-6; //(cm)
2490 // const unsigned short maxIter = 4;
2491 const unsigned short maxIter = 8;
2492 const double maxDt = 20.; //(ns)
2493 unsigned short nIter = 0;
2494 double minXsq = 1.e10; //(cm^2)
2495 double minMinTime = minTime;
2496 // double told = minTime + 1000.*epsi4t;
2497 // while (fabs(minTime - told) > epsi && nIter <= maxIter) {
2498 for (nIter = 0; nIter <= maxIter; ++nIter) {
2499 // told = minTime;
2500 double t = minTime;
2501 double x = a[0] + t * (a[1] + t * (a[2] + t * (a[3] + t * (a[4] + t * a[5]))));
2502 double x2 = x * x;
2503 if (x2 < minXsq) {
2504 minXsq = x2;
2505 minMinTime = t;
2506 }
2507 double xp = a[1] + t * (2 * a[2] + t * (3 * a[3] + t * (4 * a[4] + t * 5 * a[5])));
2508 double xpp = 2 * a[2] + t * (6 * a[3] + t * (12 * a[4] + t * 20 * a[5]));
2509 double den = xp * xp + x * xpp;
2510 if (den <= 0.) {
2511 den = xp * xp;
2512 }
2513
2514 if (den > 0.) {
2515 //estimated distance to min.
2516 edm = fabs(x * xp) / sqrt(den); //not in distance^2 but in distance
2517 if (edm < epsi4x) break; //converged
2518 }
2519
2520 double dt = 1.; //dt for den=0 (ns)
2521 if (den != 0.) {
2522 dt = x * xp / den;
2523 if (dt >= 0.) {
2524 dt = std::min(dt, maxDt);
2525 } else {
2526 dt = std::max(dt, -maxDt);
2527 }
2528 } else {
2529 B2WARNING("CDCGeometryPar::getMinDriftTime: den = 0\n" << "layer(#0-55),lr,alpha(rad),theta= " <<
2530 iCLayer << " "
2531 << lr <<
2532 " " << alpha << " " << theta);
2533 }
2534 minTime -= dt;
2535 } //end of iteration loop
2536
2537 //choose minMinTime for not-converged case
2538 if (nIter == (maxIter + 1)) minTime = minMinTime;
2539
2540 /*
2541 if (fabs(minTime) > 20.) {
2542 B2WARNING("CDCGeometryPar::getMinDriftTime: |minDriftTime| > 20ns. Ok ?\n" << "layer(#0-55),lr,alpha(rad),theta,minTime(ns)= " <<
2543 iCLayer << " "
2544 << lr <<
2545 " " << alpha << " " << theta << " " << minTime);
2546 }
2547 if (nointersection) {
2548 cout <<"final minTime= " << minTime << endl;
2549 cout <<"final minx = " << a[0] + a[1] * minTime + a[2] *pow(minTime,2) + a[3] *pow(minTime,3) + a[4] *pow(minTime,4) + a[5] *pow(minTime,5) << endl;
2550 }
2551 */
2552 /*
2553 if (check) {
2554 double dmin = 999.;
2555 double tmin = 999.;
2556 for (int i = -10000; i < 10000; ++i) {
2557 double ti = 0.01 * i;
2558 double dl = fabs(getDriftLength0(ti, iCLayer, lr, alpha, theta));
2559 if (dl < dmin) {
2560 dmin = dl;
2561 tmin = ti;
2562 }
2563 }
2564
2565 double smartd = getDriftLength0(minTime, iCLayer, lr, alpha, theta);
2566 if (check) {
2567 // if (fabs(smartd) > dmin && minTime < tmin && fabs(minTime - tmin) > 0.1) {
2568 B2WARNING("CDCGeometryPar::getMinDriftTime \n" << "layer(#0-55),lr,alpha(rad),theta= " <<
2569 iCLayer << " "
2570 << lr <<
2571 " " << alpha << " " << theta);
2572 B2INFO("det, minTime0= " << det << " " << minTime0);
2573 B2INFO("direct search n,tmin,dmin= " << nIter << " " << tmin << " " << dmin);
2574 B2INFO(" smart search n,tmin,dmin= " << nIter << " " << minTime << " " << getDriftLength0(minTime, iCLayer, lr, alpha, theta));
2575
2576 for (int i=-200; i < 200; ++i) {
2577 double ti = 0.25*i;
2578 double dl = getDriftLength0(ti, iCLayer, lr, alpha, theta);
2579 std::cout << ti <<" "<< dl << std::endl;
2580 }
2581 exit(-1);
2582 }
2583 }
2584 */
2585 }
2586
2587 return minTime;
2588}
2589
2590double CDCGeometryPar::getDriftTime(const double dist, const unsigned short iCLayer, const unsigned short lr, const double alpha,
2591 const double theta) const
2592{
2593 if (iCLayer < m_firstLayerOffset || iCLayer >= c_maxNSenseLayers) {
2594 return 0.;
2595 }
2596
2597 //to be replaced with a smarter algorithm...
2598
2599 const double eps = 2.5e-1;
2600 const double maxTrials = 100;
2601
2602 // int ialpha = getAlphaBin(alpha);
2603 // int itheta = getThetaBin(theta);
2604
2605 //convert incoming- to outgoing-lr
2606 // unsigned short lrp = getOutgoingLR(lr, alpha);
2607
2608 double maxTime = 2000.; //in ns (n.b. further reduction, 2->1us could be ok)
2609 // if (m_XT[iCLayer][lrp][ialpha][itheta][7] == 0.) {
2610 // maxTime = m_XT[iCLayer][lrp][ialpha][itheta][6];
2611 // }
2612
2613 double minTime = getMinDriftTime(iCLayer, lr, alpha, theta);
2614 double t0 = minTime;
2615 // std::cout << "minTime,x= " << t0 <<" "<< getDriftLength(t0, iCLayer, lr, alpha, theta) << std::endl;
2616 const bool calMinTime = false;
2617 // double d0 = getDriftLength(t0, iCLayer, lr, alpha, theta, calMinTime, minTime) - dist;
2618 double d0 = - dist;
2619
2620 unsigned i = 0;
2621 double t1 = maxTime;
2622 double time = dist * m_nominalDriftVInv;
2623 while (((t1 - t0) > eps) && (i < maxTrials)) {
2624 time = 0.5 * (t0 + t1);
2625 double d1 = getDriftLength(time, iCLayer, lr, alpha, theta, calMinTime, minTime) - dist;
2626 // std::cout <<"i,dist,t0,t1,d0,d1= " << i <<" "<< dist <<" "<< t0 <<" "<< t1 <<" "<< d0 <<" "<< d1 << std::endl;
2627 if (d0 * d1 > 0.) {
2628 t0 = time;
2629 } else {
2630 t1 = time;
2631 }
2632 ++i;
2633 }
2634
2635 if (i >= maxTrials - 1 || time > maxTime) {
2636 B2WARNING("CDCGeometryPar::getDriftTime " << dist << " " << iCLayer << " " << alpha << " " << lr << " " << t0 << " " << t1 << " " <<
2637 time << " " << d0);
2638 }
2639
2640 // std::cout <<"dist0,dist1= " << dist <<" "<< getDriftLength(time, iCLayer, lr, alpha, theta) <<" "<< getDriftLength(time, iCLayer, lr, alpha, theta) - dist << std::endl;
2641 // std::cout <<"dist0,dist1= " << dist <<" "<< getDriftLength(time, iCLayer, lr, 0., theta) <<" "<< getDriftLength(time, iCLayer, lr, 0., theta) - dist << std::endl;
2642 return time;
2643
2644}
2645
2646double CDCGeometryPar::getSigma(const double DriftL0, const unsigned short iCLayer, const unsigned short lr, const double alpha,
2647 const double theta) const
2648{
2649 if (iCLayer < m_firstLayerOffset || iCLayer >= c_maxNSenseLayers) {
2650 return 0.;
2651 }
2652
2653
2654 double sigma = 0.;
2655 //DriftL0 < 0 for the hit w/driftTime < 0; use |DriftL0| to avoid sigma=nan
2656 const double driftL = fabs(DriftL0);
2657
2658 //convert incoming- to outgoing-lr
2659 unsigned short lro = getOutgoingLR(lr, alpha);
2660
2662 B2FATAL("linearInterpolationOfSgm = false is not allowed now !");
2663 }
2665 double wal(0.);
2666 unsigned short ial[2] = {0};
2667 unsigned short ilr[2] = {lro, lro};
2668 getClosestAlphaPoints4Sgm(alpha, wal, ial, ilr);
2669 double wth(0.);
2670 unsigned short ith[2] = {0};
2671 getClosestThetaPoints4Sgm(alpha, theta, wth, ith);
2672
2673 //compute linear interpolation (=weithed average over 4 points) in (alpha-theta) space
2674 unsigned short jal(0), jlr(0), jth(0);
2675 double w = 0.;
2676 for (unsigned k = 0; k < 4; ++k) {
2677 if (k == 0) {
2678 jal = ial[0];
2679 jlr = ilr[0];
2680 jth = ith[0];
2681 w = (1. - wal) * (1. - wth);
2682 } else if (k == 1) {
2683 jal = ial[0];
2684 jlr = ilr[0];
2685 jth = ith[1];
2686 w = (1. - wal) * wth;
2687 } else if (k == 2) {
2688 jal = ial[1];
2689 jlr = ilr[1];
2690 jth = ith[0];
2691 w = wal * (1. - wth);
2692 } else if (k == 3) {
2693 jal = ial[1];
2694 jlr = ilr[1];
2695 jth = ith[1];
2696 w = wal * wth;
2697 }
2698 // std::cout << "k,w= " << k <<" "<< w << std::endl;
2699 // std::cout << "ial[0],[1],jal,wal= " << ial[0] <<" "<< ial[1] <<" "<< jal <<" "<< wal << std::endl;
2700 // std::cout << "ith[0],[1],jth,wth= " << ith[0] <<" "<< ith[1] <<" "<< jth <<" "<< wth << std::endl;
2701 /*
2702 std::cout <<"iCLayer= " << iCLayer << std::endl;
2703 std::cout <<"lr= " << lr << std::endl;
2704 std::cout <<"jal,jth= " << jal <<" "<< jth << std::endl;
2705 std::cout <<"wal,wth= " << wal <<" "<< wth << std::endl;
2706 for (int i=0; i<9; ++i) {
2707 std::cout <<"a= "<< i <<" "<< m_XT[iCLayer][lro][jal][jth][i] << std::endl;
2708 }
2709 */
2710 const double& P0 = m_Sigma[iCLayer][jlr][jal][jth][0];
2711 const double& P1 = m_Sigma[iCLayer][jlr][jal][jth][1];
2712 const double& P2 = m_Sigma[iCLayer][jlr][jal][jth][2];
2713 const double& P3 = m_Sigma[iCLayer][jlr][jal][jth][3];
2714 const double& P4 = m_Sigma[iCLayer][jlr][jal][jth][4];
2715 const double& P5 = m_Sigma[iCLayer][jlr][jal][jth][5];
2716 const double& P6 = m_Sigma[iCLayer][jlr][jal][jth][6];
2717
2718#if defined(CDC_DEBUG)
2719 cout << "driftL= " << driftL << endl;
2720 cout << "iCLayer= " << iCLayer << " " << jlr << " " << jal << " " << jth << endl;
2721 cout << "P0= " << P0 << endl;
2722 cout << "P1= " << P1 << endl;
2723 cout << "P2= " << P2 << endl;
2724 cout << "P3= " << P3 << endl;
2725 cout << "P4= " << P4 << endl;
2726 cout << "P5= " << P5 << endl;
2727 cout << "P6= " << P6 << endl;
2728#endif
2729 const double P7 = m_sigmaParamMode == 0 ? DBL_MAX : m_Sigma[iCLayer][jlr][jal][jth][7];
2730
2731 if (driftL < P7) {
2732 sigma += w * sqrt(P0 / (driftL * driftL + P1) + P2 * driftL + P3 +
2733 P4 * exp(P5 * (driftL - P6) * (driftL - P6)));
2734 } else {
2735 double forthTermAtP7 = P4 * exp(P5 * (P7 - P6) * (P7 - P6));
2736 const double& P8 = m_Sigma[iCLayer][jlr][jal][jth][8];
2737 if (m_sigmaParamMode == 1) {
2738 double sigmaAtP7 = sqrt(P0 / (P7 * P7 + P1) + P2 * P7 + P3 + forthTermAtP7);
2739 sigma += w * (P8 * (driftL - P7) + sigmaAtP7);
2740 } else if (m_sigmaParamMode == 2) {
2741 double onePls4AtP7 = sqrt(P0 / (P7 * P7 + P1) + forthTermAtP7);
2742 const double onePls4 = P8 * (driftL - P7) + onePls4AtP7;
2743 sigma += w * sqrt(P2 * driftL + P3 + onePls4 * onePls4);
2744 } else if (m_sigmaParamMode == 3) {
2745 forthTermAtP7 = sqrt(forthTermAtP7);
2746 const double forthTerm = P8 * (driftL - P7) + forthTermAtP7;
2747 sigma += w * sqrt(P0 / (driftL * driftL + P1) + P2 * driftL + P3 +
2748 forthTerm * forthTerm);
2749 } //end of mode
2750 } // end of driftL
2751 } //end of for loop
2752 }
2753
2754 sigma = std::min(sigma, m_maxSpaceResol);
2755 return sigma;
2756}
2757
2758unsigned short CDCGeometryPar::getOldLeftRight(const B2Vector3D& posOnWire, const B2Vector3D& posOnTrack,
2759 const B2Vector3D& momentum) const
2760{
2761 unsigned short lr = 0;
2762 double wCrossT = (posOnWire.Cross(posOnTrack)).Z();
2763
2764 if (wCrossT < 0.) {
2765 lr = 0;
2766 } else if (wCrossT > 0.) {
2767 lr = 1;
2768 } else {
2769 if ((posOnTrack - posOnWire).Perp() != 0.) {
2770 double wCrossP = (posOnWire.Cross(momentum)).Z();
2771 if (wCrossP > 0.) {
2772 if (posOnTrack.Perp() > posOnWire.Perp()) {
2773 lr = 0;
2774 } else {
2775 lr = 1;
2776 }
2777 } else if (wCrossP < 0.) {
2778 if (posOnTrack.Perp() < posOnWire.Perp()) {
2779 lr = 0;
2780 } else {
2781 lr = 1;
2782 }
2783 } else {
2784 lr = 0;
2785 }
2786 } else {
2787 lr = 0;
2788 }
2789 }
2790 return lr;
2791}
2792
2793unsigned short CDCGeometryPar::getNewLeftRightRaw(const B2Vector3D& posOnWire, const B2Vector3D& posOnTrack,
2794 const B2Vector3D& momentum) const
2795{
2796 const double distanceCrossP = ((posOnWire - posOnTrack).Cross(momentum)).Z();
2797 unsigned short int lr = (distanceCrossP > 0.) ? 1 : 0;
2798 return lr;
2799}
2800
2801//N.B. The following alpha and theta calculations are directly implemented in CDCRecoHit.cc tentatively to avoid a circular dependence betw cdc_dataobjects and cdclib. So be careful when changing the calculations !
2802double CDCGeometryPar::getAlpha(const B2Vector3D& posOnWire, const B2Vector3D& momentum) const
2803{
2804 const double wx = posOnWire.X();
2805 const double wy = posOnWire.Y();
2806 const double px = momentum.X();
2807 const double py = momentum.Y();
2808
2809 const double cross = wx * py - wy * px;
2810 const double dot = wx * px + wy * py;
2811
2812 return atan2(cross, dot);
2813}
2814
2815double CDCGeometryPar::getTheta(const B2Vector3D& momentum) const
2816{
2817 return atan2(momentum.Perp(), momentum.Z());
2818}
2819
2820
2821unsigned short CDCGeometryPar::getOutgoingLR(const unsigned short lr, const double alpha) const
2822{
2823 unsigned short lro = (fabs(alpha) <= 0.5 * M_PI) ? lr : abs(lr - 1);
2824 return lro;
2825}
2826
2827
2828double CDCGeometryPar::getOutgoingAlpha(const double alpha) const
2829{
2830 //convert incoming- to outgoing-alpha
2831 double alphao = alpha;
2832 if (alpha > 0.5 * M_PI) {
2833 alphao -= M_PI;
2834 } else if (alpha < -0.5 * M_PI) {
2835 alphao += M_PI;
2836 }
2837
2838 return alphao;
2839}
2840
2841double CDCGeometryPar::getOutgoingTheta(const double alpha, const double theta) const
2842{
2843 //convert incoming- to outgoing-theta
2844 double thetao = fabs(alpha) > 0.5 * M_PI ? M_PI - theta : theta;
2845 // std::cout << alpha <<" "<< thetao << std::endl;
2846 return thetao;
2847}
2848
2849void CDCGeometryPar::getClosestAlphaPoints(const double alpha, double& weight, unsigned short points[2],
2850 unsigned short lrs[2]) const
2851{
2852 double alphao = getOutgoingAlpha(alpha);
2853 weight = 1.;
2854
2855 if (alphao < m_alphaPoints[0]) {
2856 points[0] = m_nAlphaPoints - 1;
2857 points[1] = 0;
2858 if (m_nAlphaPoints > 1) {
2859 lrs[0] = abs(lrs[0] - 1); //flip lr
2860 weight = (alphao - (m_alphaPoints[points[0]] - M_PI)) / (m_alphaPoints[points[1]] - (m_alphaPoints[points[0]] - M_PI));
2861 }
2862 } else if (m_alphaPoints[m_nAlphaPoints - 1] <= alphao) {
2863 points[0] = m_nAlphaPoints - 1;
2864 points[1] = 0;
2865 if (m_nAlphaPoints > 1) {
2866 lrs[1] = abs(lrs[1] - 1); //flip lr
2867 weight = (alphao - m_alphaPoints[points[0]]) / (m_alphaPoints[points[1]] + M_PI - m_alphaPoints[points[0]]);
2868 }
2869 } else {
2870 const float* upper = std::upper_bound(m_alphaPoints,
2871 m_alphaPoints + m_nAlphaPoints, alphao);
2872 points[1] = upper - m_alphaPoints;
2873 points[0] = points[1] - 1;
2874 weight = (alphao - m_alphaPoints[points[0]]) / (m_alphaPoints[points[1]] - m_alphaPoints[points[0]]);
2875 }
2876}
2877
2878
2879void CDCGeometryPar::getClosestAlphaPoints4Sgm(const double alpha, double& weight, unsigned short points[2],
2880 unsigned short lrs[2]) const
2881{
2882 double alphao = getOutgoingAlpha(alpha);
2883 weight = 1.;
2884
2885 if (alphao < m_alphaPoints4Sgm[0]) {
2886 points[0] = m_nAlphaPoints4Sgm - 1;
2887 points[1] = 0;
2888 if (m_nAlphaPoints4Sgm > 1) {
2889 lrs[0] = abs(lrs[0] - 1); //flip lr
2890 weight = (alphao - (m_alphaPoints4Sgm[points[0]] - M_PI)) / (m_alphaPoints4Sgm[points[1]] - (m_alphaPoints4Sgm[points[0]] - M_PI));
2891 }
2892 } else if (m_alphaPoints4Sgm[m_nAlphaPoints4Sgm - 1] <= alphao) {
2893 points[0] = m_nAlphaPoints4Sgm - 1;
2894 points[1] = 0;
2895 if (m_nAlphaPoints4Sgm > 1) {
2896 lrs[1] = abs(lrs[1] - 1); //flip lr
2897 weight = (alphao - m_alphaPoints4Sgm[points[0]]) / (m_alphaPoints4Sgm[points[1]] + M_PI - m_alphaPoints4Sgm[points[0]]);
2898 }
2899 } else {
2900 const float* upper = std::upper_bound(m_alphaPoints4Sgm,
2902 points[1] = upper - m_alphaPoints4Sgm;
2903 points[0] = points[1] - 1;
2904 weight = (alphao - m_alphaPoints4Sgm[points[0]]) / (m_alphaPoints4Sgm[points[1]] - m_alphaPoints4Sgm[points[0]]);
2905 }
2906}
2907
2908
2909void CDCGeometryPar::getClosestThetaPoints(const double alpha, const double theta, double& weight, unsigned short points[2]) const
2910{
2911 const double thetao = getOutgoingTheta(alpha, theta);
2912
2913 if (thetao < m_thetaPoints[0]) {
2914 // points[0] = 0;
2915 // points[1] = 1;
2916 points[0] = 0;
2917 points[1] = 0;
2918 weight = 1.;
2919 } else if (m_thetaPoints[m_nThetaPoints - 1] <= thetao) {
2920 // points[0] = m_nThetaPoints - 2;
2921 // points[1] = m_nThetaPoints - 1;
2922 points[0] = m_nThetaPoints - 1;
2923 points[1] = m_nThetaPoints - 1;
2924 weight = 1.;
2925 } else {
2926 const float* upper = std::upper_bound(m_thetaPoints,
2927 m_thetaPoints + m_nThetaPoints, thetao);
2928 points[1] = upper - m_thetaPoints;
2929 points[0] = points[1] - 1;
2930 weight = (thetao - m_thetaPoints[points[0]]) / (m_thetaPoints[points[1]] - m_thetaPoints[points[0]]);
2931 }
2932}
2933
2934
2935void CDCGeometryPar::getClosestThetaPoints4Sgm(const double alpha, const double theta, double& weight,
2936 unsigned short points[2]) const
2937{
2938 const double thetao = getOutgoingTheta(alpha, theta);
2939
2940 if (thetao < m_thetaPoints4Sgm[0]) {
2941 points[0] = 0;
2942 points[1] = 0;
2943 weight = 1.;
2944 } else if (m_thetaPoints4Sgm[m_nThetaPoints4Sgm - 1] <= thetao) {
2945 points[0] = m_nThetaPoints4Sgm - 1;
2946 points[1] = m_nThetaPoints4Sgm - 1;
2947 weight = 1.;
2948 } else {
2949 const float* upper = std::upper_bound(m_thetaPoints4Sgm,
2951 points[1] = upper - m_thetaPoints4Sgm;
2952 points[0] = points[1] - 1;
2953 weight = (thetao - m_thetaPoints4Sgm[points[0]]) / (m_thetaPoints4Sgm[points[1]] - m_thetaPoints4Sgm[points[0]]);
2954 }
2955}
2956
2957
2959{
2960 // std::cout <<"setDisplacement called" << std::endl;
2961 for (const auto& disp : (*m_displacementFromDB)) {
2962 // const int iLayer0 = disp.getICLayer();
2963 // const int iWire0 = disp.getIWire();
2964 const int iLayer = WireID(disp.getEWire()).getICLayer();
2965 const int iWire = WireID(disp.getEWire()).getIWire();
2966 // if (iLayer0 != iLayer) B2FATAL("Layer0 != Layer");
2967 // if (iWire0 != iWire) B2FATAL("Wire0 != Wire");
2968 m_FWirPos[iLayer][iWire][0] += (iLayer < m_firstLayerOffset) ? 0. : disp.getXFwd();
2969 m_FWirPos[iLayer][iWire][1] += (iLayer < m_firstLayerOffset) ? 0. : disp.getYFwd();
2970 m_FWirPos[iLayer][iWire][2] += (iLayer < m_firstLayerOffset) ? 0. : disp.getZFwd();
2971 m_BWirPos[iLayer][iWire][0] += (iLayer < m_firstLayerOffset) ? 0. : disp.getXBwd();
2972 m_BWirPos[iLayer][iWire][1] += (iLayer < m_firstLayerOffset) ? 0. : disp.getYBwd();
2973 m_BWirPos[iLayer][iWire][2] += (iLayer < m_firstLayerOffset) ? 0. : disp.getZBwd();
2974 m_WireSagCoef[iLayer][iWire] = (iLayer < m_firstLayerOffset) ? 0. : M_PI * m_senseWireDensity * m_senseWireDiameter *
2975 m_senseWireDiameter / (8.*
2976 (m_senseWireTension + disp.getTension()));
2977 // std::cout <<"setdisp iL, iC, nominaltension, tension= " << iLayer <<" " << iWire <<" "<< m_senseWireTension <<" "<< disp.getTension() << std::endl;
2978 }
2979}
2980
2981
2983{
2984 const unsigned short nLayers[c_nSuperLayers] = {8, 6, 6, 6, 6, 6, 6, 6, 6}; //tentaive
2985
2986 for (unsigned short SLayer = 0; SLayer < c_nSuperLayers; ++SLayer) {
2987 unsigned short firstCLayer = 0;
2988 for (unsigned short i = 0; i < SLayer; ++i) {
2989 firstCLayer += nLayers[i];
2990 }
2991 // std::cout <<"SLayer,firstCLayer= " << SLayer <<" "<< firstCLayer << std::endl;
2992
2993 B2Vector3D firstBPos = wireBackwardPosition(firstCLayer, 0);
2994 for (unsigned short Layer = 0; Layer < nLayers[SLayer]; ++Layer) {
2995 unsigned short CLayer = firstCLayer + Layer;
2996
2997 if (CLayer == firstCLayer) {
2998 m_shiftInSuperLayer[SLayer][Layer] = 0;
2999
3000 } else if (CLayer == firstCLayer + 1) {
3001 B2Vector3D BPos = wireBackwardPosition(CLayer, 0);
3002 m_shiftInSuperLayer[SLayer][Layer] = (BPos.Cross(firstBPos)).Z() > 0. ? -1 : 1;
3003 // std::cout <<"CLayer,Layer,shift= " << CLayer <<" "<< Layer <<" "<< m_shiftInSuperLayer[SLayer][Layer] <<" "<< (BPos.Cross(firstBPos)).Z() << std::endl;
3004
3005 } else {
3006 if (Layer % 2 == 0) {
3007 m_shiftInSuperLayer[SLayer][Layer] = 0;
3008 } else {
3009 m_shiftInSuperLayer[SLayer][Layer] = m_shiftInSuperLayer[SLayer][1];
3010 }
3011 }
3012 // std::cout <<"CLayer,Layer,shift= " << CLayer <<" "<< Layer <<" "<< m_shiftInSuperLayer[SLayer][Layer] << std::endl;
3013 }
3014 }
3015}
3016
3017signed short CDCGeometryPar::getShiftInSuperLayer(unsigned short iSuperLayer, unsigned short iLayer) const
3018{
3019 return m_shiftInSuperLayer[iSuperLayer][iLayer];
3020}
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:435
void SetX(DataType x)
set X/1st-coordinate
Definition: B2Vector3.h:457
B2Vector3< DataType > Cross(const B2Vector3< DataType > &p) const
Cross product.
Definition: B2Vector3.h:296
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:431
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:433
void SetZ(DataType z)
set Z/3rd-coordinate
Definition: B2Vector3.h:461
void SetY(DataType y)
set Y/2nd-coordinate
Definition: B2Vector3.h:459
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:200
B2Vector3< DataType > Unit() const
Unit vector parallel to this.
Definition: B2Vector3.h:269
static const baseType layerDPhi
Layer rotation in global X-Y plane (gamma) dPhi = foward - backward endplate.
Definition: CDCAlignment.h:61
static const baseType layerDy
Layer shift in global Y dY = foward - backward endplate.
Definition: CDCAlignment.h:59
static const baseType wireBwdZ
Wire Z position w.r.t. nominal on backward endplate.
Definition: CDCAlignment.h:33
static const baseType layerDx
Layer shift in global X dX = foward - backward endplate.
Definition: CDCAlignment.h:57
static const baseType wireBwdY
Wire Y position w.r.t. nominal on backward endplate.
Definition: CDCAlignment.h:31
static const baseType wireFwdZ
Wire Z position w.r.t. nominal on forward endplate.
Definition: CDCAlignment.h:39
static const baseType wireFwdY
Wire Y position w.r.t. nominal on forward endplate.
Definition: CDCAlignment.h:37
static const baseType wireFwdX
Wire X position w.r.t. nominal on forward endplate.
Definition: CDCAlignment.h:35
static const baseType wireBwdX
Wire X position w.r.t. nominal on backward endplate.
Definition: CDCAlignment.h:29
static const baseType layerY
Layer shift in global Y at backward endplate.
Definition: CDCAlignment.h:52
static const baseType layerX
Layer shift in global X at backward endplate.
Definition: CDCAlignment.h:50
static const baseType layerPhi
Layer rotation in global X-Y plane (gamma) at backward endplate.
Definition: CDCAlignment.h:54
static const baseType wireTension
Wire tension w.r.t. nominal (=50. ?)
Definition: CDCAlignment.h:43
The Class for CDC geometry.
Definition: CDCGeometry.h:27
static const baseType wireBwdZ
Wire Z position w.r.t. nominal on backward endplate.
static const baseType wireBwdY
Wire Y position w.r.t. nominal on backward endplate.
static const baseType wireFwdZ
Wire Z position w.r.t. nominal on forward endplate.
static const baseType wireFwdY
Wire Y position w.r.t. nominal on forward endplate.
static const baseType wireFwdX
Wire X position w.r.t. nominal on forward endplate.
static const baseType wireBwdX
Wire X position w.r.t. nominal on backward endplate.
static const baseType wireTension
Wire tension w.r.t. nominal (=50. ?)
The Class for CDC Geometry Control Parameters.
bool getDebug() const
Get debug flag.
bool getSigmaInputType()
Get input type for sigma.
bool getMisalignmentInputType()
Get input type for wire misalignment.
std::string getT0File() const
Get input file name for t0.
bool getDisplacementInputType()
Get input type for wire displacement.
double getAddFudgeFactorForSigmaForMC() const
Get additional fudge factor for space resol for MC.
std::string getEDepToADCFile() const
Get input file name for edeptoadc.
std::string getDisplacementFile() const
Get input file name for wire displacement.
std::string getMisalignmentFile() const
Get input file name for wire misalignment.
std::string getAlignmentFile() const
Get input file name for wire alignment.
bool getAlignmentInputType()
Get input type for wire alignment.
double getMaterialDefinitionMode() const
Get material definition mode.
std::string getPropSpeedFile() const
Get input file name for prop-speed.
bool getT0InputType()
Get input type for t0.
bool getEDepToADCInputType()
Get input type for edeptoadc.
std::string getSigmaFile() const
Get input file name for sigma.
bool getAlignment() const
Get alignment switch.
bool getMisalignment() const
Get misalignment switch.
bool getDisplacement() const
Get displacement switch.
int getSenseWireZposMode() const
Get sense wire z position mode.
double getAddFudgeFactorForSigmaForData() const
Get additional fudge factor for space resol for data.
std::string getXtFile() const
Get input file name for xt-relation.
bool getTwInputType()
Get input type for time-walk.
std::string getFFactorFile() const
Get input file name for fudge factor.
bool getChMapInputType()
Get input type for channel map.
std::string getTwFile() const
Get input file name for time-walk.
bool getFFactorInputType()
Get input type for fuge factor.
bool getXtInputType()
Get input type for xt.
bool getBwInputType()
Get input type for bad wire.
bool getPropSpeedInputType()
Get input type for prop.
static CDCGeoControlPar & getInstance()
Static method to get a reference to the CDCGeoControlPar instance.
std::string getChMapFile() const
Get input file name for channel map.
The Class for CDC Geometry Parameters.
void outputDesignWirParam(unsigned layerID, unsigned cellID) const
Write the designed wire parameters to the alignment.dat (default).
std::map< WireID, unsigned short > m_wireToChannel
map relating wire-id and channel-id.
void setWirPosAlignParams()
Set wire alignment params.
int m_materialDefinitionMode
Control switch for gas and wire material definition.
unsigned short m_nAlphaPoints4Sgm
No.
void readSigma(const GearDir &gbxParams, int mode=0)
Read spatial resolution table.
void readTW(const GearDir &gbxParams, int mode=0)
Read time-walk parameter.
void setXtRel()
Set XT-relation table (from DB) (new).
float m_BWirPosMisalign[c_maxNSenseLayers][c_maxNDriftCells][3]
Wire position incl.
DBObjPtr< CDCBadWires > * m_badWireFromDB
bad-wires retrieved from DB.
double getTheta(const B2Vector3D &momentum) const
Returns track incident angle (theta in rad.).
void readT0(const GearDir &gbxParams, int mode=0)
Read t0 parameters (from a file).
void setT0()
Set t0 parameters (from DB)
float m_alphaPoints4Sgm[c_maxNAlphaPoints]
alpha sampling points for sigma (rad)
virtual ~CDCGeometryPar()
Destructor.
ushort m_maxNSuperLayers
Maximum number of Super Layers.
double m_fudgeFactorForSigma[3]
Fuge factor for space resol.
double outerRadiusInnerWall() const
Returns the outer radius of the inner wall.
int m_sigmaParamMode
Mode for sigma parameterization.
bool m_alignment
Switch for alignment.
float m_alphaPoints[c_maxNAlphaPoints]
alpha sampling points for xt (rad)
void getClosestAlphaPoints(const double alpha, double &wal, unsigned short points[2], unsigned short lrs[2]) const
Returns the two closest alpha points for the input track incident angle (alpha).
void readEDepToADC(const GearDir &gbxParams, int mode=0)
Read spatial edep-to-adc conv.
double m_globalPhiRotation
Global ratation in phi (rad.); only for sence wires now.
EWirePosition
Wire position set.
double innerRadiusOuterWall() const
Returns the inner radius of the outer wall.
unsigned cellId(unsigned layerId, const B2Vector3D &position) const
The method to get cell id based on given layer id and the position.
void newReadSigma(const GearDir &gbxParams, int mode=0)
Read spatial resolution table in new format.
void setEDepToADCConversions()
Set edep-to-ADC conversion params.
double m_nominalPropSpeed
Nominal propagation speed of the sense wire (27.25 cm/nsec).
int nShifts(int layerId) const
Returns number shift.
float m_thetaPoints[c_maxNThetaPoints]
theta sampling points for xt (rad)
void setDesignWirParam(unsigned layerID, unsigned cellID)
Set the desizend wire parameters.
void getWireSagEffect(EWirePosition set, unsigned layerID, unsigned cellID, double zw, double &ywb_sag, double &ywf_sag) const
Compute effects of the sense wire sag.
DBArray< CDCDisplacement > * m_displacementFromDB
displacement params.
bool m_XTetc
Switch for reading x-t etc.
void setShiftInSuperLayer()
Calculates and saves shifts in super-layers (to be used in searching hits in neighboring cells)
int m_nShifts[c_maxNSenseLayers]
The array to store shifted cell number in each sense wire layer.
bool m_wireSag
Switch for sense wire sag.
bool m_XTetc4Recon
Switch for selecting xt etc.
double getDriftLength0(double dt, unsigned short layer, unsigned short lr, double alpha=0., double theta=0.5 *M_PI) const
Return the drift dength to the sense wire; tentative ver.
unsigned short m_boardAndChannelToWire[c_nBoards][48]
array relating board-channel-id and wire-id.
unsigned short m_nThetaPoints4Sgm
No.
float m_WireSagCoef[c_maxNSenseLayers][c_maxNDriftCells]
Wire sag coefficient for each cell; ibid.
void generateXML(const std::string &of)
Generate an xml file used in gearbox.
void getClosestAlphaPoints4Sgm(const double alpha, double &wal, unsigned short points[2], unsigned short lrs[2]) const
Returns the two closest alpha points for sigma for the input track incident angle (alpha).
DBObjPtr< HardwareClockSettings > m_clockSettings
hardware clock settings
float m_eDepToADCParams[c_maxNSenseLayers][c_maxNDriftCells][7]
edep-to-ADC conv.
double m_minTrackLength
Minimum track length for G4 step.
double getAlpha(const B2Vector3D &posOnWire, const B2Vector3D &momentum) const
Returns track incident angle in rphi plane (alpha in rad.).
double fieldWireR(int layerId) const
Returns radius of field wire in each layer.
float m_FWirPosMisalign[c_maxNSenseLayers][c_maxNDriftCells][3]
Wire position incl.
const B2Vector3D wireForwardPosition(uint layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward position of the input sense wire.
bool isDeadWire(const WireID &wid, double &eff)
Inquire if the wire is dead.
unsigned m_nWires[c_maxNSenseLayers]
The array to store the wire number in each sense wire layre.
double getDriftV(double dt, unsigned short layer, unsigned short lr, double alpha=0., double theta=0.5 *M_PI) const
Get the realistic drift velocity.
double m_clockFreq4TDC
Clock frequency used for TDC (GHz).
int m_nFLayer
The number of field wire layer.
static CDCGeometryPar * m_B4CDCGeometryParDB
Pointer that saves the instance of this class.
DBObjPtr< CDCMisalignment > * m_misalignmentFromDB
misalignment params.
float m_XT[c_maxNSenseLayers][2][c_maxNAlphaPoints][c_maxNThetaPoints][c_nXTParams]
XT-relation coefficients for each layer, Left/Right, entrance angle and polar angle.
signed short m_shiftInSuperLayer[c_nSuperLayers][8]
shift in phi-direction wrt the 1st layer in each super layer
std::string m_version
The version of geometry parameters.
const B2Vector3D wireBackwardPosition(uint layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
bool m_linearInterpolationOfXT
Switch for linear interpolation of xt.
DBObjPtr< CDCSpaceResols > * m_sResolFromDB
sigma params.
void setDisplacement()
Set displacement of sense wire.
double getOutgoingAlpha(const double alpha) const
Converts incoming- to outgoing-alpha.
bool isHotWire(const WireID &wid)
Inquire if the wire is hot.
double m_meanT0
mean t0 over all wires; should be double.
bool m_debug
Switch for debug printing.
DBObjPtr< CDCTimeWalks > * m_timeWalkFromDB
time-walk coeffs.
ushort m_nSenseWires
Maximum number of Sense Wires.
unsigned short m_tdcOffset
Not used; to be removed later.
double getSigma(double dist, unsigned short layer, unsigned short lr, double alpha=0., double theta=0.5 *M_PI) const
Return the basic resolution of drift length (cm).
CDCGeometryPar(const CDCGeometry *=nullptr)
Singleton class.
unsigned short getOutgoingLR(const unsigned short lr, const double alpha) const
Converts incoming-lr to outgoing-lr.
ushort m_maxNSenseLayers
Maximum number of Sense Wire Layers.
void readWirePositionParams(EWirePosition set, const CDCGeometry *geom)
Read displacement or (mis)alignment params from text file.
float m_thetaPoints4Sgm[c_maxNThetaPoints]
theta sampling points for sigma (rad)
std::map< WireID, unsigned short > m_wireToBoard
map relating wire-id and board-id.
double getOutgoingTheta(const double alpha, const double theta) const
Converts incoming- to outgoing-theta.
double m_senseWireDiameter
The diameter of sense wires.
double offset(int layerID) const
Return wire offset in phi direction at endplate.
bool m_displacement
Switch for displacement.
int m_twParamMode
Mode for tw parameterization.
double senseWireBZ(int layerId) const
Returns backward z position of sense wire in each layer.
double m_dzSBackwardLayer[c_maxNSenseLayers]
Corrections for backward z position of sense wire layers.
double getMinDriftTime(unsigned short layer, unsigned short lr, double alpha=0., double theta=0.5 *M_PI) const
Return the min.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
double fieldWireBZ(int layerId) const
Returns backward z position of field wire in each layer.
void getClosestThetaPoints(const double alpha, const double theta, double &wth, unsigned short points[2]) const
Returns the two closest theta points for the input track incident angle (theta).
double senseWireFZ(int layerId) const
Returns forward z position of sense wire in each layer.
void readPropSpeed(const GearDir &gbxParams, int mode=0)
Read the propagation speed along the sense wire.
double innerRadiusInnerWall() const
Returns the inner radius of the inner wall.
DBObjPtr< CDCTimeZeros > * m_t0FromDB
t0s retrieved from DB.
int m_xtFileFormat
Format of xt input file.
int m_sigmaFileFormat
Format of sigma input file.
ushort m_firstSuperLayerOffset
Offset of the first super layer (for reduced CDC studies)
void setChMap()
Set channel map (from DB)
DBObjPtr< CDCFudgeFactorsForSigma > * m_fFactorFromDB
fudge factors retrieved from DB.
int m_nSLayer
The number of sense wire layer.
DBArray< CDCChannelMap > * m_chMapFromDB
channel map retrieved from DB.
void calcMeanT0(double minT0=3800, double maxT0=5800, int maxIt=10, double nStdv=3, double epsi=0.1)
Calculate mean t0 in ns (over all good wires)
void readFromDB(const CDCGeometry &)
Gets geometry parameters from database.
DBObjPtr< CDCXtRelations > * m_xtRelFromDB
xt params.
double m_nominalDriftV
Nominal drift velocity (4.0x10^-3 cm/nsec).
float m_FWirPos[c_maxNSenseLayers][c_maxNDriftCells][3]
Wire position incl.
float m_WireSagCoefAlign[c_maxNSenseLayers][c_maxNDriftCells]
Wire sag coefficient incl.
double m_zSForwardLayer[c_maxNSenseLayers]
The array to store forward z position of sense wire layers.
bool m_linearInterpolationOfSgm
Switch for linear interpolation of sigma.
DBObjPtr< CDCPropSpeeds > * m_propSpeedFromDB
prop.
void setBadWire()
Set bad-wires (from DB)
int m_xtParamMode
Mode for xt parameterization.
float m_FWirPosAlign[c_maxNSenseLayers][c_maxNDriftCells][3]
Wire position incl.
double fieldWireFZ(int layerId) const
Returns forward z position of field wire in each layer.
double m_dzSForwardLayer[c_maxNSenseLayers]
Corrections for forward z position of sense wire layers.
double getEDepToADCConvFactor(unsigned short layer, unsigned short cell, double edep, double dx, double costh)
Return edep-to-ADC conversion factor.
double m_nominalDriftVInv
Inverse of the nominal drift velocity.
const double * innerRadiusWireLayer() const
Returns an array of inner radius of wire layers.
double getDriftTime(double dist, unsigned short layer, unsigned short lr, double alpha, double theta) const
Return the drift time to the sense wire.
signed short getShiftInSuperLayer(unsigned short iSuperLayer, unsigned short iLayer) const
Returns shift in the super-layer.
double getWireSagCoef(EWirePosition set, uint layerId, int cellId) const
Returns coefficient for the sense wire sag.
void readChMap()
Read channel map between wire-id and electronics-id.
double m_zFForwardLayer[c_maxNFieldLayers]
The array to store forward z position of field wire layers.
double m_rSLayer[c_maxNSenseLayers]
The array to store radius of sense wire layers.
double m_fieldWireDiameter
The diameter of field wires.
double m_zFBackwardLayer[c_maxNFieldLayers]
The array to store backward z position of field wire layers.
ushort m_nFieldWires
Maximum number of Field Wires.
float m_WireSagCoefMisalign[c_maxNSenseLayers][c_maxNDriftCells]
Wire sag coefficient incl.
double getDriftLength(double dt, unsigned short layer, unsigned short lr, double alpha=0., double theta=0.5 *M_PI, bool calculateMinTime=true, double minTime=0.) const
Return the drift dength to the sense wire.
double m_cellSize[c_maxNSenseLayers]
The array to store cell size in each sense wire layer.
float m_BWirPosAlign[c_maxNSenseLayers][c_maxNDriftCells][3]
Wire position incl.
double outerRadiusOuterWall() const
Returns the outer radius of the outer wall.
float m_t0[c_maxNSenseLayers][c_maxNDriftCells]
t0 for each sense-wire (in nsec).
void setWirPosMisalignParams()
Set wire misalignment params.
double m_offSet[c_maxNSenseLayers]
The array to store z offset of sense wire layers.
void setTW()
Set time-walk parameters.
void setSResol()
Set spatial resolution (from DB).
double m_zSBackwardLayer[c_maxNSenseLayers]
The array to store backward z position of sense wire layers.
unsigned short getOldLeftRight(const B2Vector3D &posOnWire, const B2Vector3D &posOnTrack, const B2Vector3D &momentum) const
Returns old left/right.
float m_propSpeedInv[c_maxNSenseLayers]
Inverse of propagation speed of the sense wire.
ushort m_maxNCellsPerLayer
Maximum number wires within a layer.
double m_zWall[4][2]
The array to store z position of inner wall and outer wall.
bool isBadWire(const WireID &wid)
Inquire if the wire is totally-dead.
DBObjPtr< CDCAlignment > * m_alignmentFromDB
alignment params.
ushort m_maxNFieldLayers
Maximum number of Field Wire Layers.
bool m_misalignment
Switch for misalignment.
double m_senseWireDensity
The density of sense wires.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
ushort m_firstLayerOffset
Offset of the first layer (for reduced CDC studies)
void Print() const
Print some debug information.
float m_timeWalkCoef[c_nBoards][2]
coefficients for time walk.
void readFFactor(const GearDir &gbxParams, int mode=0)
Read fudge factors.
unsigned short m_nThetaPoints
No.
double m_maxSpaceResol
max space resolution allowed (cm).
double m_thresholdEnergyDeposit
Energy thresh.
float m_BWirPos[c_maxNSenseLayers][c_maxNDriftCells][3]
Wire position incl.
float m_Sigma[c_maxNSenseLayers][2][c_maxNAlphaPoints][c_maxNThetaPoints][c_nSigmaParams]
position resulution for each layer.
void readXT(const GearDir &gbxParams, int mode=0)
Read XT-relation table.
double m_rFLayer[c_maxNFieldLayers]
The array to store radius of field wire layers.
void newReadXT(const GearDir &gbxParams, int mode=0)
Read XT-relation table in new format.
double m_nominalSpaceResol
Nominal spacial resolution (0.0130 cm).
unsigned nWireLayers() const
Returns a number of wire layers.
unsigned short m_nAlphaPoints
No.
unsigned short getNewLeftRightRaw(const B2Vector3D &posOnWire, const B2Vector3D &posOnTrack, const B2Vector3D &momentum) const
Returns new left/right_raw.
int m_senseWireZposMode
Mode for sense wire z position corr.
double m_rWall[4]
The array to store radius of inner wall and outer wall.
double m_tdcBinWidth
TDC bin width (nsec/bin).
bool m_modLeftRightFlag
Switch for modified left/right flag.
void getClosestThetaPoints4Sgm(const double alpha, const double theta, double &wth, unsigned short points[2]) const
Returns the two closest theta points for sigma for the input track incident angle (theta).
DBObjPtr< CDCEDepToADCConversions > * m_eDepToADCConversionsFromDB
Pointer to edep-to-ADC conv.
const double * outerRadiusWireLayer() const
Returns an array of outer radius of wire layers.
double senseWireR(int layerId) const
Returns radius of sense wire in each layer.
double m_senseWireTension
The tension of sense wires.
void setFFactor()
Set fudge factors (from DB).
bool getModLeftRightFlag() const
Get modified left/right flag.
double getMinTrackLength() const
Get minimum track length.
double getThresholdEnergyDeposit() const
Get threshold for Energy Deposit;.
static CDCSimControlPar & getInstance()
Static method to get a reference to the CDCSimControlPar instance.
bool getWireSag() const
Get wiresag flag.
void addCallback(std::function< void(const std::string &)> callback, bool onDestruction=false)
Add a callback method.
Class for accessing arrays of objects in the database.
Definition: DBArray.h:26
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
Definition: FileSystem.cc:151
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
Definition: GearDir.h:69
Optional DBObjPtr: This class behaves the same as the DBObjPtr except that it will not raise errors w...
Definition: DBObjPtr.h:48
Class to identify a wire inside the CDC.
Definition: WireID.h:34
unsigned short getICLayer() const
Getter for continuous layer numbering.
Definition: WireID.cc:24
unsigned short getIWire() const
Getter for wire within the layer.
Definition: WireID.h:145
unsigned short getEWire() const
Getter for encoded wire number.
Definition: WireID.h:154
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
T dot(GeneralVector< T > a, GeneralVector< T > b)
dot product of two general vectors
Definition: beamHelpers.h:163
void openFileB(boost::iostreams::filtering_istream &ifs, const std::string &fileName0)
Open a file using boost (to be able to read a gzipped file)
Definition: OpenFile.cc:45
void openFileA(std::ifstream &ifs, const std::string &fileName0)
Open a file.
Definition: OpenFile.cc:26
Abstract base class for different kinds of events.
STL namespace.